You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by da...@apache.org on 2026/10/06 04:40:18 UTC
(jackrabbit-oak) 07/15: OAK-12425 : add test coverage for receive() broadcast metadata replacement
This is an automated email from the ASF dual-hosted git repository.
rishabhdaim pushed a commit to branch issue/OAK-12436
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 4808204297ccddf16ab875ac76e33c44bbd831c1
Author: rishabhdaim <ri...@gmail.com>
AuthorDate: Wed Sep 30 14:33:45 2026 +0530
OAK-12425 : add test coverage for receive() broadcast metadata replacement
Adds a regression test verifying that NodeCache.receive() correctly
replaces CacheMetadata for the received value, so a late eviction of
the previously-cached (stale) value is not persisted while eviction
of the newly-received value is.
Co-authored-by: Copilot <22...@users.noreply.github.com>
---
.../document/persistentCache/AsyncQueueTest.java | 64 +++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/AsyncQueueTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/AsyncQueueTest.java
index d40bf8e8d2..13f5e7e3e1 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/AsyncQueueTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/AsyncQueueTest.java
@@ -25,12 +25,14 @@ import org.apache.jackrabbit.oak.cache.api.EvictionCause;
import org.apache.jackrabbit.oak.cache.CacheLIRS;
import org.apache.jackrabbit.oak.commons.collections.ListUtils;
import org.apache.jackrabbit.oak.plugins.document.DocumentMKBuilderProvider;
+import org.apache.jackrabbit.oak.plugins.document.MemoryDiffCache;
import org.apache.jackrabbit.oak.plugins.document.Path;
import org.apache.jackrabbit.oak.plugins.document.PathRev;
import org.apache.jackrabbit.oak.plugins.document.Revision;
import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
import org.apache.jackrabbit.oak.plugins.document.persistentCache.async.CacheWriteQueue;
import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
+import org.h2.mvstore.WriteBuffer;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -39,6 +41,7 @@ import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -76,7 +79,7 @@ public class AsyncQueueTest {
@Before
public void setup() throws IOException {
FileUtils.deleteDirectory(new File("target/cacheTest"));
- pCache = new PersistentCache("target/cacheTest");
+ pCache = new PersistentCache("target/cacheTest,+asyncDiff");
final AtomicReference<NodeCache<PathRev, StringValue>> nodeCacheRef = new AtomicReference<NodeCache<PathRev, StringValue>>();
CacheLIRS<PathRev, StringValue> lirs = new CacheLIRS.Builder<PathRev, StringValue>().maximumSize(1).evictionCallback((key, value, cause) -> {
if (nodeCacheRef.get() != null) {
@@ -133,6 +136,35 @@ public class AsyncQueueTest {
assertEquals(asList(k), putActions);
}
+ @Test
+ public void receivedBroadcastReplacesMetadataWithoutPersistingStaleValue() {
+ NodeCache<MemoryDiffCache.Key, StringValue> cache = newDiffCache(
+ CacheBuilder.<MemoryDiffCache.Key, StringValue>newBuilder().maximumSize(100).build());
+ DiffCacheWriteQueueWrapper writeQueue = (DiffCacheWriteQueueWrapper) cache.writeQueue;
+ MemoryDiffCache.Key key = new MemoryDiffCache.Key(Path.fromString("/broadcast"),
+ RevisionVector.fromString("r1-0-1"), RevisionVector.fromString("r2-0-1"));
+ StringValue receivedValue = new StringValue("received");
+ cache.put(key, VAL);
+ cache.getIfPresent(key);
+
+ WriteBuffer broadcast = new WriteBuffer(1024);
+ CacheType.DIFF.writeKey(broadcast, key);
+ broadcast.put((byte) 1);
+ CacheType.DIFF.writeValue(broadcast, receivedValue);
+ ByteBuffer buffer = broadcast.getBuffer();
+ buffer.rewind();
+ cache.receive(buffer);
+
+ cache.evicted(key, VAL, EvictionCause.SIZE);
+ assertEquals(emptyList(), writeQueue.putActions);
+
+ StringValue cachedValue = cache.getIfPresent(key);
+ assertEquals(receivedValue, cachedValue);
+ cache.evicted(key, cachedValue, EvictionCause.SIZE);
+ assertEquals(asList(key), writeQueue.putActions);
+ assertEquals(Collections.singletonList("received"), writeQueue.putValues);
+ }
+
@Test
public void staleEvictionShouldNotPersistReinsertedValue() {
PathRev k = generatePathRev();
@@ -378,6 +410,15 @@ public class AsyncQueueTest {
return cache;
}
+ private NodeCache<MemoryDiffCache.Key, StringValue> newDiffCache(
+ Cache<MemoryDiffCache.Key, StringValue> memCache) {
+ NodeCache<MemoryDiffCache.Key, StringValue> cache =
+ (NodeCache<MemoryDiffCache.Key, StringValue>) pCache.wrap(
+ builderProvider.newBuilder().getNodeStore(), null, memCache, CacheType.DIFF);
+ cache.writeQueue = new DiffCacheWriteQueueWrapper(cache.writeQueue);
+ return cache;
+ }
+
private interface Replacement {
void apply(NodeCache<PathRev, StringValue> cache, PathRev key, StringValue newValue);
}
@@ -420,4 +461,25 @@ public class AsyncQueueTest {
}
}
+ private static class DiffCacheWriteQueueWrapper extends CacheWriteQueue<MemoryDiffCache.Key, StringValue> {
+
+ private final CacheWriteQueue<MemoryDiffCache.Key, StringValue> wrapped;
+
+ private final List<MemoryDiffCache.Key> putActions = new ArrayList<>();
+
+ private final List<String> putValues = new ArrayList<>();
+
+ public DiffCacheWriteQueueWrapper(CacheWriteQueue<MemoryDiffCache.Key, StringValue> wrapped) {
+ super(null, null, null);
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public boolean addPut(MemoryDiffCache.Key key, StringValue value) {
+ putActions.add(key);
+ putValues.add(value.asString());
+ return wrapped.addPut(key, value);
+ }
+ }
+
}