use of org.apache.geode.internal.cache.DistributedTombstoneOperation.TombstoneMessage in project geode by apache.
the class GIIDeltaDUnitTest method testTombstoneGCDuringFullGII.
/**
* Test case to make sure that if a tombstone GC occurs during a full GII, we still have the
* correct RVV on the GII recipient at the end.
*
* @throws Throwable
*/
// GEODE-1137: orphaned AsyncInvocations, time sensitive, GC,
@Category(FlakyTest.class)
// waitForCriterion, thread unsafe test hooks/observers, expiration
@Test
public void testTombstoneGCDuringFullGII() throws Throwable {
prepareForEachTest();
// Create the region in 1 more VM to to a tombstone GC.
VM vm2 = Host.getHost(0).getVM(2);
createDistributedRegion(vm2);
final DiskStoreID memberP = getMemberID(P);
final DiskStoreID memberR = getMemberID(R);
assertEquals(0, DistributedCacheOperation.SLOW_DISTRIBUTION_MS);
prepareCommonTestData(6);
// All members should have "key5" at this point
// shutdown R
closeCache(R);
final VM vmR = R;
// Destroy key5, this will leave a tombstone
doOneDestroy(P, 7, "key5");
// Set tesk hook so that R will pause GII after getting the RVV
R.invoke(new SerializableRunnable() {
public void run() {
// Add hooks before and after receiving the RVV
Mycallback myAfterSavedReceivedRVV = new Mycallback(GIITestHookType.AfterCalculatedUnfinishedOps, REGION_NAME);
InitialImageOperation.setGIITestHook(myAfterSavedReceivedRVV);
}
});
// Set a trigger in vm2 so that it will start up R after determining
// the recipients for a tombstone GC message. vm2 will wait until
// R has already received the RVV before sending the message.
vm2.invoke(new SerializableRunnable() {
@Override
public void run() {
DistributionMessageObserver.setInstance(new DistributionMessageObserver() {
@Override
public void beforeSendMessage(DistributionManager dm, DistributionMessage message) {
if (message instanceof TombstoneMessage && ((TombstoneMessage) message).regionPath.contains(REGION_NAME)) {
System.err.println("DAN DEBUG about to send tombstone message, starting up R - " + message.getSender());
AsyncInvocation async3 = createDistributedRegionAsync(vmR);
// Wait for R to finish requesting the RVV before letting the tombstone GC proceeed.
waitForCallbackStarted(vmR, GIITestHookType.AfterCalculatedUnfinishedOps);
System.err.println("DAN DEBUG R has received the RVV, sending tombstone message");
DistributionMessageObserver.setInstance(null);
}
}
});
}
});
P.invoke(new SerializableRunnable() {
@Override
public void run() {
DistributionMessageObserver.setInstance(new DistributionMessageObserver() {
@Override
public void afterProcessMessage(DistributionManager dm, DistributionMessage message) {
if (message instanceof TombstoneMessage && ((TombstoneMessage) message).regionPath.contains(REGION_NAME)) {
System.err.println("DAN DEBUG P has processed the tombstone message, allowing R to proceed with the GII");
vmR.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.AfterCalculatedUnfinishedOps, true));
DistributionMessageObserver.setInstance(null);
}
}
});
}
});
// Force tombstone GC, this will trigger the R to be started, etc.
vm2.invoke(new SerializableRunnable() {
@Override
public void run() {
GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
try {
cache.getTombstoneService().forceBatchExpirationForTests(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// Wait for P to perform the tombstone GC
waitForToVerifyRVV(P, memberP, 7, null, 7);
System.err.println("DAN DEBUG P has finished the tombstone GC, waiting for R to get the correct RVV");
// Make sure that Rs RVV now reflects the update from P
// P's rvv=r7, gc=7
waitForToVerifyRVV(R, memberP, 7, null, 7);
}
Aggregations