use of org.apache.geode.internal.cache.persistence.DiskStoreID in project geode by apache.
the class GIIDeltaDUnitTest method testTombstoneGCInMiddleOfGII.
/**
* vm0 and vm1 are peers, each holds a DR. create some exception list. Then shutdown R. Before
* GII, P's RVV is P7,R6(3-6), RVVGC is P0,R0; R's RVV is P3,R6, RVVGC is P0,R0 vm1 becomes
* offline then restarts. Use testHook to pause the GII, then do tombstone GC at P only. The
* deltaGII should send correct tombstonedelta to R, revoke unfinished opeation R4,R5
*
* There's member T doing GII from P at the same time.
*
* In this test, GII thread will get the GIILock before tombstone GC, so tombstone GC should wait
* for all GIIs to finish
*/
// GEODE-633: SLOW_DISTRIBUTION_MS, non-thread safe test hook, async
@Category(FlakyTest.class)
// actions, time sensitive, waitForCriterion, thread joins, forceGC
@Test
public void testTombstoneGCInMiddleOfGII() throws Throwable {
prepareForEachTest();
final DiskStoreID memberP = getMemberID(P);
final DiskStoreID memberR = getMemberID(R);
final long[] exceptionlist = { 4, 5 };
Host host = Host.getHost(0);
VM T = host.getVM(2);
createDistributedRegion(T);
final DiskStoreID memberT = getMemberID(T);
closeCache(T);
assertEquals(0, DistributedCacheOperation.SLOW_DISTRIBUTION_MS);
prepareCommonTestData(3);
// P's rvv=p3, gc=0
waitForToVerifyRVV(P, memberP, 3, null, 0);
VersionTag expect_tag = getVersionTag(R, "key5");
createUnfinishedOperationsR4R5();
// R's rvv=p3, gc=0
waitForToVerifyRVV(R, memberP, 3, null, 0);
byte[] R_rvv_bytes = getRVVByteArray(R, REGION_NAME);
closeCache(R);
// p4-7 only apply at P
doOneDestroy(P, 4, "key2");
doOnePut(P, 5, "key1");
doOnePut(P, 6, "key3");
doOnePut(P, 7, "key1");
// add test hook
// 8
P.invoke(new SerializableRunnable() {
public void run() {
Mycallback myDuringPackingImage = new Mycallback(GIITestHookType.DuringPackingImage, REGION_NAME);
InitialImageOperation.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);
// restart R and gii, it will be blocked at test hook
AsyncInvocation async4 = createDistributedRegionAsync(T);
// 8
waitForCallbackStarted(P, GIITestHookType.DuringPackingImage);
WaitCriterion ev = new WaitCriterion() {
public boolean done() {
int count = getDeltaGIICount(P);
return (count == 2);
}
public String description() {
return null;
}
};
Wait.waitForCriterion(ev, 30000, 200, true);
int count = getDeltaGIICount(P);
assertEquals(2, count);
// force tombstone GC to let RVVGC to become P4:R0, but R already sent its old RVV/RVVGC over
// this tombstone GC happens AFTER GII thread got the GIILock, so it will be ignored since GII
// is ongoing
changeTombstoneTimout(R, MAX_WAIT);
changeTombstoneTimout(P, MAX_WAIT);
changeTombstoneTimout(T, MAX_WAIT);
Wait.pause((int) MAX_WAIT);
forceGC(P, 2);
// P's rvv=p7, gc=0
waitForToVerifyRVV(P, memberP, 7, null, 0);
// let GII continue
P.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.DuringPackingImage, false));
P.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.DuringPackingImage, true));
WaitCriterion ev2 = new WaitCriterion() {
public boolean done() {
int count = getDeltaGIICount(P);
return (count == 0);
}
public String description() {
return null;
}
};
Wait.waitForCriterion(ev2, 30000, 200, true);
count = getDeltaGIICount(P);
assertEquals(0, count);
// expect key2 is still tombstone during and after
verifyTombstoneExist(P, "key2", true, true);
// GIIs
// expect key2 is still tombstone during and after
verifyTombstoneExist(R, "key2", true, true);
// GIIs
// expect key2 is still tombstone during and after
verifyTombstoneExist(T, "key2", true, true);
// GIIs
// trigger to GC the tombstones in expired queue
forceGC(P, 1);
async3.join(MAX_WAIT);
async4.join(MAX_WAIT);
// after GII, tombstone GC happened
// P's rvv=p6, gc=4
waitForToVerifyRVV(P, memberP, 7, null, 4);
// P's rvv=r6(3-6), gc=0
waitForToVerifyRVV(P, memberR, 6, exceptionlist, 0);
// R's rvv=p7, gc=4
waitForToVerifyRVV(R, memberP, 7, null, 4);
// R's rvv=r6, gc=0
waitForToVerifyRVV(R, memberR, 6, exceptionlist, 0);
// expect tombstone key2 is GCed at P
verifyTombstoneExist(P, "key2", false, true);
// expect tombstone key2 is GCed at R
verifyTombstoneExist(R, "key2", false, true);
// T got everything from P
verifyTombstoneExist(T, "key2", false, true);
// do a put from T
doOnePut(T, 1, "key1");
RegionVersionVector p_rvv = getRVV(P);
RegionVersionVector r_rvv = getRVV(R);
RegionVersionVector t_rvv = getRVV(R);
assertSameRVV(p_rvv, r_rvv);
assertSameRVV(t_rvv, r_rvv);
// If fullGII, the key size in gii chunk is 4, i.e. key1,key3,key5,key2 is a tombstone.
// If delta GII, it should be 4, (key1, key2, key3) and (key5(T) which is unfinished operation)
verifyDeltaSizeFromStats(R, 4, 1);
// verify unfinished op for key5 is revoked
waitToVerifyKey(R, "key5", generateValue(R));
VersionTag tag = getVersionTag(R, "key5");
assertTrue(expect_tag.equals(tag));
// P.invoke(() -> InitialImageOperation.resetAllGIITestHooks());
}
use of org.apache.geode.internal.cache.persistence.DiskStoreID 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);
}
use of org.apache.geode.internal.cache.persistence.DiskStoreID in project geode by apache.
the class GIIDeltaDUnitTest method testFullGIINotDorminatedByProviderRVVGC.
/**
* vm0 and vm1 are peers, each holds a DR. unifinished P8: destroy(key1), finished P9: put(key3).
* Shutdown R, then GC tombstones at P. P's RVV=P9,R6(3-6), RVVGC=P8,R0, R's RVV=P9(7-9),R6, RVV
* It should trigger fullGII
*/
@Test
public void testFullGIINotDorminatedByProviderRVVGC() throws Throwable {
prepareForEachTest();
final DiskStoreID memberP = getMemberID(P);
final DiskStoreID memberR = getMemberID(R);
final long[] exceptionlist = { 4, 5 };
assertEquals(0, DistributedCacheOperation.SLOW_DISTRIBUTION_MS);
prepareCommonTestData(3);
createUnfinishedOperationsR4R5();
// P's rvv=p3, gc=0
waitForToVerifyRVV(P, memberP, 3, null, 0);
// P's rvv=r6(3-6), gc=0
waitForToVerifyRVV(P, memberR, 6, exceptionlist, 0);
// R's rvv=p3, gc=0
waitForToVerifyRVV(R, memberP, 3, null, 0);
// R's rvv=r6, gc=0
waitForToVerifyRVV(R, memberR, 6, null, 0);
// p4-7 only apply at P
doOneDestroy(P, 4, "key2");
doOnePut(P, 5, "key1");
doOnePut(P, 6, "key3");
doOnePut(P, 7, "key1");
final long[] exceptionlist2 = { 8 };
// let p9 to succeed, p8 to be blocked
P.invoke(() -> GIIDeltaDUnitTest.slowGII(exceptionlist2));
AsyncInvocation async1 = doOneDestroyAsync(P, 8, "key1");
waitForToVerifyRVV(P, memberP, 8, null, 0);
doOnePut(P, 9, "key3");
waitForToVerifyRVV(P, memberP, 9, null, 0);
waitForToVerifyRVV(R, memberP, 9, exceptionlist2, 0);
byte[] R_rvv_bytes = getRVVByteArray(R, REGION_NAME);
closeCache(R);
forceGC(P, 3);
// now P's RVV=P9,R6(3-6), RVVGC=P8,R0, R's RVV=P9(7-9), R6
// P's rvv=p9, gc=8
waitForToVerifyRVV(P, memberP, 9, null, 8);
// P's rvv=r6(3-6), gc=0
waitForToVerifyRVV(P, memberR, 6, exceptionlist, 0);
P.invoke(() -> GIIDeltaDUnitTest.resetSlowGII());
// restart and gii, R's rvv should be the same as P's
checkIfFullGII(P, REGION_NAME, R_rvv_bytes, true);
createDistributedRegion(R);
// R's rvv=p9, gc=8
waitForToVerifyRVV(R, memberP, 9, null, 8);
// R's rvv=r6, gc=0
waitForToVerifyRVV(R, memberR, 6, exceptionlist, 0);
RegionVersionVector p_rvv = getRVV(P);
RegionVersionVector r_rvv = getRVV(R);
// after gii, rvv should be the same
assertSameRVV(p_rvv, r_rvv);
// In fullGII, the key size in gii chunk is 2. They are: key3, key5
verifyDeltaSizeFromStats(R, 2, 0);
}
use of org.apache.geode.internal.cache.persistence.DiskStoreID in project geode by apache.
the class GIIDeltaDUnitTest method testRecoverFromUntrustedRVV.
/**
* Test the case where a member has an untrusted RVV and still initializes from the local data.
* See bug 48066
*
* @throws Throwable
*/
@Test
public void testRecoverFromUntrustedRVV() throws Throwable {
prepareForEachTest();
final DiskStoreID memberP = getMemberID(P);
final DiskStoreID memberR = getMemberID(R);
assertEquals(0, DistributedCacheOperation.SLOW_DISTRIBUTION_MS);
prepareCommonTestData(6);
// let r4,r5,r6 to succeed
doOnePut(R, 4, "key4");
doOneDestroy(R, 5, "key5");
doOnePut(R, 6, "key1");
// P's rvv=p6, gc=0
waitForToVerifyRVV(P, memberP, 6, null, 0);
// P's rvv=r6, gc=0
waitForToVerifyRVV(P, memberR, 6, null, 0);
// R's rvv=P6, gc=0
waitForToVerifyRVV(R, memberP, 6, null, 0);
// R's rvv=r6, gc=0
waitForToVerifyRVV(R, memberR, 6, null, 0);
// set tesk hook
R.invoke(new SerializableRunnable() {
public void run() {
// Add hooks before and after receiving the RVV
Mycallback myBeforeSavedReceivedRVV = new Mycallback(GIITestHookType.BeforeSavedReceivedRVV, REGION_NAME);
InitialImageOperation.setGIITestHook(myBeforeSavedReceivedRVV);
Mycallback myAfterSavedReceivedRVV = new Mycallback(GIITestHookType.AfterSavedReceivedRVV, REGION_NAME);
InitialImageOperation.setGIITestHook(myAfterSavedReceivedRVV);
}
});
// shutdown R
closeCache(R);
// retart R
AsyncInvocation async3 = createDistributedRegionAsync(R);
// when chunk arrived, do clear()
waitForCallbackStarted(R, GIITestHookType.BeforeSavedReceivedRVV);
// Before R saves the RVV, do a put. This will be recording in Rs region
// and RVV, but it will be wiped out in the RVV when R applies the RVV
// from P.
doOnePut(P, 7, "key1");
R.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.BeforeSavedReceivedRVV, true));
// Wait until the new RVV is applied
waitForCallbackStarted(R, GIITestHookType.AfterSavedReceivedRVV);
// destroy the region on P (which will force R to recover with it's own
// data
destroyRegion(P);
// Allow the GII to continue.
R.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.AfterSavedReceivedRVV, true));
async3.join(MAX_WAIT);
// createDistributedRegion(R);
// Make sure that Rs RVV now reflects the update from P
// P's rvv=r8, gc=0
waitForToVerifyRVV(R, memberP, 7, null, 0);
// P's rvv=r6, gc=0
waitForToVerifyRVV(R, memberR, 6, null, 0);
}
use of org.apache.geode.internal.cache.persistence.DiskStoreID in project geode by apache.
the class GIIDeltaDUnitTest method getMemberID.
private DiskStoreID getMemberID(VM vm) {
SerializableCallable getDiskStoreID = new SerializableCallable("get DiskStoreID as member id") {
public Object call() {
LocalRegion lr = (LocalRegion) getCache().getRegion(REGION_NAME);
assertTrue(lr != null && lr.getDiskStore() != null);
DiskStoreID dsid = lr.getDiskStore().getDiskStoreID();
return dsid;
}
};
return (DiskStoreID) vm.invoke(getDiskStoreID);
}
Aggregations