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 st...@apache.org on 2023/11/08 10:07:22 UTC
(jackrabbit-oak) branch OAK-10542 created (now 0ce7e9c65e)
This is an automated email from the ASF dual-hosted git repository.
stefanegli pushed a change to branch OAK-10542
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
at 0ce7e9c65e OAK-10542 : test reproducing ignorance of split deleted properties
This branch includes the following new commits:
new 0ce7e9c65e OAK-10542 : test reproducing ignorance of split deleted properties
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(jackrabbit-oak) 01/01: OAK-10542 : test reproducing ignorance of split deleted properties
Posted by st...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
stefanegli pushed a commit to branch OAK-10542
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 0ce7e9c65ed5c6dd9ee39475222abcdef7dd186b
Author: Stefan Egli <st...@apache.org>
AuthorDate: Wed Nov 8 11:07:07 2023 +0100
OAK-10542 : test reproducing ignorance of split deleted properties
---
.../document/VersionGarbageCollectorIT.java | 108 +++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
index 1ecbd73cb7..744b15ce2d 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
@@ -289,6 +289,114 @@ public class VersionGarbageCollectorIT {
//assertTrue(ImmutableList.copyOf(getDoc("/test2/foo").getAllPreviousDocs()).isEmpty());
}
+ /**
+ * OAK-10542 : This reproduces a case where a split doc is created that contains
+ * a revision of _deleted that is still referred to by a checkpoint. The fact
+ * that d_deleted is split later used to confuse the getLiveRevision lookup, as
+ * it was not considering split document for the _deleted property. This variant
+ * tests a checkpoint when /t/target is deleted.
+ */
+ @Test
+ @Ignore(value = "requires fix for OAK-10542 first")
+ public void gcSplitDocWithReferencedDeleted_true() throws Exception {
+ // step 1 : create some _deleted entries with clusterId 2
+ final DocumentNodeStore store2 = createSecondary();
+ createLeaf(store2, "t", "target");
+ deleteLeaf(store2, "t", "target");
+ store2.runBackgroundOperations();
+
+ // step 2 : create a _deleted=true entry with clusterId 1
+ store.runBackgroundOperations();
+ createLeaf(store, "t", "target");
+ // create a checkpoint where /t/target should exist
+ final String checkpoint = store.checkpoint(TimeUnit.DAYS.toMillis(42));
+
+ // step 3 : cause a split doc with _deleted with clusterId 1
+ for (int i = 0; i < NUM_REVS_THRESHOLD; i++) {
+ createLeaf(store, "t", "target");
+ deleteLeaf(store, "t", "target");
+ }
+ store.runBackgroundOperations();
+
+ // step 4 : make assertions about /t/target at root and checkpoint
+ // invalidate node cache to ensure readNode is called below
+ store.getNodeCache().invalidateAll();
+ assertFalse(store.getRoot().getChildNode("t").getChildNode("target").exists());
+ // invalidate node cache to ensure readNode is called below
+ store.getNodeCache().invalidateAll();
+ assertEquals(true, store.retrieve(checkpoint).getChildNode("t")
+ .getChildNode("target").exists());
+
+ }
+
+ /**
+ * OAK-10542 : This reproduces a case where a split doc is created that contains
+ * a revision of _deleted that is still referred to by a checkpoint. The fact
+ * that d_deleted is split later used to confuse the getLiveRevision lookup, as
+ * it was not considering split document for the _deleted property. This variant
+ * tests a checkpoint when /t/target exists.
+ */
+ @Test
+ @Ignore(value = "requires fix for OAK-10542 first")
+ public void gcSplitDocWithReferencedDeleted_false() throws Exception {
+ // step 1 : create a _delete entry with clusterId 2
+ final DocumentNodeStore store2 = createSecondary();
+ createLeaf(store2, "t", "target");
+ store2.runBackgroundOperations();
+
+ // step 2 : create a _deleted=true entry with clusterId 1
+ store.runBackgroundOperations();
+ deleteLeaf(store, "t", "target");
+ // clusterId 1 leaves /t/target according to !exists param before checkpoint
+ final String checkpoint = store.checkpoint(TimeUnit.DAYS.toMillis(42));
+
+ // step 2 : cause a split doc with _deleted with clusterId 1
+ for (int i = 0; i < NUM_REVS_THRESHOLD; i++) {
+ createLeaf(store, "t", "target");
+ deleteLeaf(store, "t", "target");
+ }
+ store.runBackgroundOperations();
+
+ // step 4 : make assertions about /t/target at root and checkpoint
+ // invalidate node cache to ensure readNode/getNodeAtRevision is called below
+ store.getNodeCache().invalidateAll();
+ assertFalse(store.getRoot().getChildNode("t").getChildNode("target").exists());
+ // invalidate node cache to ensure readNode/getNodeAtRevision is called below
+ store.getNodeCache().invalidateAll();
+ assertEquals(false, store.retrieve(checkpoint).getChildNode("t")
+ .getChildNode("target").exists());
+
+ }
+
+ private DocumentNodeStore createSecondary() {
+ return new DocumentMK.Builder().clock(clock)
+ .setLeaseCheckMode(LeaseCheckMode.DISABLED)
+ .setDocumentStore(store.getDocumentStore()).setAsyncDelay(0)
+ .setClusterId(2).getNodeStore();
+ }
+
+ private void createLeaf(DocumentNodeStore s, String... pathElems) throws Exception {
+ createOrDeleteLeaf(s, false, pathElems);
+ }
+
+ private void deleteLeaf(DocumentNodeStore s, String... pathElems) throws Exception {
+ createOrDeleteLeaf(s, true, pathElems);
+ }
+
+ private void createOrDeleteLeaf(DocumentNodeStore s, boolean delete,
+ String... pathElems) throws Exception {
+ clock.waitUntil(clock.getTime() + TimeUnit.SECONDS.toMillis(10));
+ final NodeBuilder rb = s.getRoot().builder();
+ NodeBuilder b = rb;
+ for (String pathElem : pathElems) {
+ b = b.child(pathElem);
+ }
+ if (delete) {
+ b.remove();
+ }
+ s.merge(rb, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+ }
+
/**
* OAK-10526 : This reproduces a case where a split doc is created then GCed,
* while there is a checkpoint that still refers to a revision contained in that