From 13632e6363a2629e615882ecee00378e3c731e8b Mon Sep 17 00:00:00 2001
From: Vikas Saurabh <vsaurabh@adobe.com>
Date: Wed, 5 Aug 2015 20:24:02 +0530
Subject: [PATCH] OAK-2623 Add test for GC of previous docs of a deleted
 document

---
 .../plugins/document/VersionGCDeletionTest.java    | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCDeletionTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCDeletionTest.java
index 5165c20..3873942 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCDeletionTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCDeletionTest.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
 
+import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -164,6 +165,62 @@ public class VersionGCDeletionTest {
         }
     }
 
+    @Test
+    public void gcForPreviousDocs() throws Exception{
+        DocumentStore ts = new MemoryDocumentStore();
+        store = new DocumentMK.Builder()
+                .clock(clock)
+                .setDocumentStore(ts)
+                .setAsyncDelay(0)
+                .getNodeStore();
+
+        //Baseline the clock
+        clock.waitUntil(Revision.getCurrentTimestamp());
+
+        NodeBuilder b1;
+        NodeBuilder xb;
+
+        //Create/remove "/x/split" sufficient times to split it
+        boolean create = true;
+        for (int i = 0; create || i < NodeDocument.NUM_REVS_THRESHOLD ; i++) {
+            b1 = store.getRoot().builder();
+            xb = b1.child("x").child("split");
+            if (!create) {
+                xb.remove();
+            }
+            store.merge(b1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+            create = !create;
+        }
+        store.runBackgroundOperations();
+
+        //Count split docs
+        NodeDocument doc = ts.find(Collection.NODES, "2:/x/split");
+        int splitDocCount = Iterators.size(doc.getAllPreviousDocs());
+
+        long maxAge = 1; //hours
+        long delta = TimeUnit.MINUTES.toMillis(10);
+
+        //Remove "/x"
+        NodeBuilder b2 = store.getRoot().builder();
+        b2.child("x").remove();
+        store.merge(b2, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        store.runBackgroundOperations();
+
+        //Pass some time and run GC
+        clock.waitUntil(clock.getTime() + HOURS.toMillis(maxAge * 2) + delta);
+        VersionGarbageCollector gc = store.getVersionGarbageCollector();
+        VersionGCStats stats = gc.gc(maxAge * 2, HOURS);
+
+        //Asset GC stats
+        assertEquals(2, stats.deletedDocGCCount);
+        assertEquals(splitDocCount, stats.splitDocGCCount);
+
+        //check if the deleted docs are really gone after GC
+        assertNull(ts.find(Collection.NODES, "1:/x"));
+        assertNull(ts.find(Collection.NODES, "2:/x/split"));
+    }
+
     // OAK-2420
     @Test
     public void queryWhileDocsAreRemoved() throws Exception {
-- 
2.1.4

