use of org.apache.geode.test.dunit.DUnitBlackboard in project geode by apache.
the class PdxSerializableDUnitTest method testVmWaitsForPdxType.
@Test
public void testVmWaitsForPdxType() throws Throwable {
VM vm0 = Host.getHost(0).getVM(0);
VM vm1 = Host.getHost(0).getVM(1);
getBlackboard().initBlackboard();
final Properties properties = getDistributedSystemProperties();
properties.put("conserve-sockets", "false");
// steps:
// 1 create two caches and define a PdxType
// 2 install a block in VM1 that delays receipt of new PDX types
// 3 update the value of the PdxInstance in VM0 using a new Enum type
// 4 get the value in VM0
// The result should be that step 4 hangs unless the bug is fixed
vm0.invoke("create cache", () -> {
Cache cache = getCache(properties);
Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create("testRegion");
region.put("TestObject", new TestPdxObject("aString", 1, 1.0, TestPdxObject.AnEnum.ONE));
});
vm1.invoke("create cache and region", () -> {
Cache cache = getCache(properties);
// note that initial image transfer in testRegion will cause the object to be serialized in
// vm0
// and populate the PdxRegion in this vm
cache.createRegionFactory(RegionShortcut.REPLICATE).create("testRegion");
// this message observer will ensure that a new PDX registration doesn't occur
final DUnitBlackboard bb = getBlackboard();
DistributionMessageObserver.setInstance(new DistributionMessageObserver() {
@Override
public void beforeProcessMessage(DistributionManager dm, DistributionMessage msg) {
if (msg instanceof DistributedCacheOperation.CacheOperationMessage) {
try {
DistributedCacheOperation.CacheOperationMessage cmsg = (DistributedCacheOperation.CacheOperationMessage) msg;
String path = cmsg.getRegionPath();
if (path.equals(PeerTypeRegistration.REGION_FULL_PATH)) {
System.out.println("message observer found a PDX update message and is stalling: " + msg);
try {
bb.signalGate("listenerWasInvoked");
bb.waitForGate("pdxObjectGetStarting", 3, TimeUnit.SECONDS);
// let the get() commence and block
Thread.sleep(30000);
System.out.println("message observer after sleep ");
} catch (InterruptedException e) {
System.out.println("message observer is done stalling1 ");
bb.setMailbox("listenerProblem", e);
} catch (TimeoutException e) {
System.out.println("message observer is done stalling2");
bb.setMailbox("listenerProblem", e);
} finally {
System.out.println("message observer is done stalling");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
});
AsyncInvocation async0 = vm0.invokeAsync("propagate value with new pdx enum type", () -> {
Cache cache = getCache(properties);
final Region pdxRegion = cache.getRegion(PeerTypeRegistration.REGION_FULL_PATH);
final DUnitBlackboard bb = getBlackboard();
// now we register a new Id for our enum in a different thread. This will
// block in vm1 due to its message observer
Thread t = new Thread("PdxSerializableDUnitTest async thread") {
public void run() {
bb.signalGate("asyncThreadReady");
// pdxRegion.put(new EnumId(0x3010101), new EnumInfo(TestPdxObject.AnEnum.TWO));
((GemFireCacheImpl) cache).getPdxRegistry().addRemoteEnum(0x3010101, new EnumInfo(TestPdxObject.AnEnum.TWO));
}
};
t.setDaemon(true);
t.start();
try {
bb.waitForGate("asyncThreadReady", 20, TimeUnit.SECONDS);
} catch (TimeoutException e) {
fail("timed out");
}
// reserialization will use the new Enumeration PDX type
Region region = cache.getRegion("testRegion");
bb.waitForGate("listenerWasInvoked", 20, TimeUnit.SECONDS);
region.put("TestObject", new TestPdxObject("TestObject'", 2, 2.0, TestPdxObject.AnEnum.TWO));
System.out.println("TestObject added put");
bb.signalGate("pdxObjectPut");
});
// vm0 has sent a new TestObject but vm1 does not have the enum type needed to
// deserialize it.
AsyncInvocation async1 = vm1.invokeAsync("try to read object w/o enum type", () -> {
DUnitBlackboard bb = getBlackboard();
bb.waitForGate("pdxObjectPut", 10, TimeUnit.SECONDS);
Region region = getCache(properties).getRegion("testRegion");
bb.signalGate("pdxObjectGetStarting");
Object testObject = region.get("TestObject");
System.out.println("found " + testObject);
});
DUnitBlackboard bb = getBlackboard();
try {
async0.join(20000);
async1.join(10000);
if (async0.exceptionOccurred()) {
throw async0.getException();
}
if (async1.exceptionOccurred()) {
throw async1.getException();
}
assertTrue(bb.isGateSignaled("listenerWasInvoked"));
/*
* Throwable throwable = (Throwable)bb.getMailbox("listenerProblem"); if (throwable != null) {
* RuntimeException rte = new RuntimeException("message observer had a problem", throwable);
* throw rte; }
*/
} finally {
bb.signalGate("pdxObjectGetStarting");
bb.signalGate("pdxObjectPut");
bb.initBlackboard();
}
}
Aggregations