This is an automated email from the ASF dual-hosted git repository.

zhouxj pushed a commit to branch feature/GEODE-8430
in repository https://gitbox.apache.org/repos/asf/geode.git

commit 7b2e91b516fec924e0e6b403276c5ae586d673f9
Author: zhouxh <[email protected]>
AuthorDate: Thu Aug 13 10:38:31 2020 -0700

    GEODE-8430: add dunit test to verify tombstoneGC will not happen in 
uninitialized region
---
 .../geode/internal/cache/GIIDeltaDUnitTest.java    | 105 +++++++++++++++++++--
 1 file changed, 97 insertions(+), 8 deletions(-)

diff --git 
a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GIIDeltaDUnitTest.java
 
b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GIIDeltaDUnitTest.java
index 23b98fc..1f3fcc1 100644
--- 
a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GIIDeltaDUnitTest.java
+++ 
b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/GIIDeltaDUnitTest.java
@@ -1452,12 +1452,13 @@ public class GIIDeltaDUnitTest extends 
JUnit4CacheTestCase {
   /**
    * vm0 and vm1 are peers, each holds a DR. Let P and R have the same RVV and 
RVVGC: P7,R6, RVVGC
    * is P0,R0. vm1 becomes offline then restarts. Use testHook to pause the 
GII, then do tombstone
-   * GC triggered by expireBatch (not by forceGC) at R only. The tombstone GC 
will be executed at R,
-   * but igored at P. The deltaGII should send nothing to R since the RVVs are 
the same. So after
-   * GII, P and R will have different tombstone number. But P's tombstones 
should be expired.
+   * GC triggered by expireBatch (not by forceGC) at R only. The tombstone GC 
will not be executed
+   * at R
+   * because R's region is not initialized. Tombstone GC is ignored at P 
because GII is on-going.
+   * The deltaGII should send nothing to R since the RVVs are the same.
    */
   @Test
-  public void testExpiredTombstoneSkippedAtProviderOnly() throws Throwable {
+  public void testExpiredTombstoneSkippedGC() throws Throwable {
     prepareForEachTest();
     final DiskStoreID memberP = getMemberID(P);
     final DiskStoreID memberR = getMemberID(R);
@@ -1518,8 +1519,8 @@ public class GIIDeltaDUnitTest extends 
JUnit4CacheTestCase {
     int count = getDeltaGIICount(P);
     assertEquals(1, count);
 
-    // let tombstone expired at R to trigger tombstoneGC.
-    // Wait for tombstone is GCed at R, but still exists in P
+    // let tombstone expired at P & R to trigger tombstoneGC.
+    // Wait for tombstoneGC is started at P & R, but nothing will be GCed
     changeTombstoneTimout(R, MAX_WAIT);
     changeTombstoneTimout(P, MAX_WAIT);
     pause((int) MAX_WAIT);
@@ -1527,8 +1528,7 @@ public class GIIDeltaDUnitTest extends 
JUnit4CacheTestCase {
     forceGC(P, 3);
 
     // let GII continue
-    P.invoke(
-        () -> resetGIITestHook(DuringPackingImage, true));
+    P.invoke(() -> resetGIITestHook(DuringPackingImage, true));
     async3.join(MAX_WAIT * 2);
     count = getDeltaGIICount(P);
     assertEquals(0, count);
@@ -1553,6 +1553,95 @@ public class GIIDeltaDUnitTest extends 
JUnit4CacheTestCase {
   }
 
   /**
+   * vm0 and vm1 are peers, each holds a DR. Let P and R have the same RVV and 
RVVGC: P7,R6, RVVGC
+   * is P0,R0. vm1 becomes offline then restarts. Use testHook to pause the 
GII, then do tombstone
+   * GC triggered by expireBatch (not by forceGC) at R only. The tombstone GC 
will be executed at P,
+   * but ignored at R, because P has not started providing GII and R is not 
initialized yet.
+   * The deltaGII should send nothing to R since the RVVs are the same. So 
after
+   * GII, P and R will have different tombstone number. But P's tombstones 
should be expired.
+   */
+  @Test
+  public void testExpiredTombstoneSkippedGCAtRequesterOnly() throws Throwable {
+    prepareForEachTest();
+    final DiskStoreID memberP = getMemberID(P);
+    final DiskStoreID memberR = getMemberID(R);
+
+    assertEquals(0, SLOW_DISTRIBUTION_MS);
+    prepareCommonTestData(6);
+
+    // let r4,r5,r6 to succeed
+    doOnePut(R, 4, "key4");
+    doOneDestroy(R, 5, "key5");
+    doOnePut(R, 6, "key1");
+
+    waitForToVerifyRVV(R, memberP, 6, null, 0); // P's rvv=p6, gc=0
+    waitForToVerifyRVV(R, memberR, 6, null, 0); // P's rvv=r6, gc=0
+    // now the rvv and rvvgc at P and R should be the same
+
+    // save R's rvv in byte array, check if it will be fullGII
+    byte[] R_rvv_bytes = getRVVByteArray(R, REGION_NAME);
+    // shutdown R and restart
+    closeCache(R);
+
+    // let p7 to succeed
+    doOnePut(P, 7, "key1");
+
+    waitForToVerifyRVV(P, memberP, 7, null, 0); // P's rvv=p7, gc=0
+    waitForToVerifyRVV(P, memberR, 6, null, 0); // P's rvv=r6, gc=0
+
+    // add test hook
+    P.invoke(new SerializableRunnable() {
+      @Override
+      public void run() {
+        Mycallback myDuringPackingImage =
+            new Mycallback(GIITestHookType.AfterReceivedRequestImage, 
REGION_NAME);
+        setGIITestHook(myDuringPackingImage);
+      }
+    });
+
+    checkIfFullGII(P, REGION_NAME, R_rvv_bytes, false);
+
+    // restart R and gii, it will be blocked at test hook
+    AsyncInvocation async3 = createDistributedRegionAsync(R);
+    // 8
+    waitForCallbackStarted(P, GIITestHookType.AfterReceivedRequestImage);
+    int count = getDeltaGIICount(P);
+    assertEquals(0, count);
+
+    // let tombstone expired at both P & R to trigger tombstoneGC.
+    // Wait for tombstone is GCed at P, but still exists in R
+    changeTombstoneTimout(R, MAX_WAIT);
+    changeTombstoneTimout(P, MAX_WAIT);
+    pause((int) MAX_WAIT);
+    forceGC(R, 3);
+    forceGC(P, 3);
+
+    // let GII continue
+    P.invoke(() -> resetGIITestHook(GIITestHookType.AfterReceivedRequestImage, 
true));
+    async3.join(MAX_WAIT * 2);
+    count = getDeltaGIICount(P);
+    assertEquals(0, count);
+    verifyDeltaSizeFromStats(R, 1, 1); // deltaGII, key1 in delta
+
+    // tombstone key2, key5 should still exist and expired at R
+    verifyTombstoneExist(R, "key2", true, true);
+    verifyTombstoneExist(R, "key5", true, true);
+
+    // tombstone key2, key5 should be GCed at P
+    verifyTombstoneExist(P, "key2", false, true);
+    verifyTombstoneExist(P, "key5", false, true);
+
+    RegionVersionVector p_rvv = getRVV(P);
+    RegionVersionVector r_rvv = getRVV(R);
+    out.println("p_rvv=" + p_rvv.fullToString() + ":r_rvv=" + 
r_rvv.fullToString());
+
+    waitForToVerifyRVV(R, memberP, 7, null, 4); // R's rvv=p7, gc=4
+    waitForToVerifyRVV(R, memberR, 6, null, 5); // R's rvv=r6, gc=5
+    waitForToVerifyRVV(P, memberP, 7, null, 4); // P's rvv=p7, gc=4
+    waitForToVerifyRVV(P, memberR, 6, null, 5); // P's rvv=r6, gc=5
+  }
+
+  /**
    * vm0 and vm1 are peers, each holds a DR. Each does a few operations to 
make RVV=P7,R6,
    * RVVGC=P4,R0 for both members. vm1 becomes offline then restarts. The 
deltaGII should only
    * exchange RVV. No need to send data from vm0 to vm1.

Reply via email to