You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by zh...@apache.org on 2020/08/13 17:59:14 UTC

[geode] 01/01: GEODE-8430: add dunit test to verify tombstoneGC will not happen in uninitialized region

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 <gz...@pivotal.io>
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.