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.
