use of org.apache.geode.test.dunit.WaitCriterion in project geode by apache.
the class MultiVMRegionTestCase method testDistributedRegionDestroy.
/**
* Tests that {@linkplain Region#destroy destroying} a region is propagated to all VMs that define
* that region.
*/
@Test
public void testDistributedRegionDestroy() throws Exception {
assertTrue(getRegionAttributes().getScope().isDistributed());
final String name = this.getUniqueName();
SerializableRunnable create = new CacheSerializableRunnable("Create Region") {
@Override
public void run2() throws CacheException {
createRegion(name);
}
};
Invoke.invokeInEveryVM(create);
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
vm0.invoke(new CacheSerializableRunnable("Destroy Region") {
@Override
public void run2() throws CacheException {
Region region = getRootRegion().getSubregion(name);
region.destroyRegion();
flushIfNecessary(region);
}
});
Invoke.invokeInEveryVM(new CacheSerializableRunnable("Verify region destruction") {
@Override
public void run2() throws CacheException {
WaitCriterion ev = new WaitCriterion() {
@Override
public boolean done() {
return getRootRegion().getSubregion(name) == null;
}
@Override
public String description() {
return "Waiting for region " + name + " to be destroyed";
}
};
Wait.waitForCriterion(ev, 60 * 1000, 10, true);
Region region = getRootRegion().getSubregion(name);
assertNull(region);
}
});
}
use of org.apache.geode.test.dunit.WaitCriterion in project geode by apache.
the class MultiVMRegionTestCase method testNBRegionDestructionDuringGetInitialImage.
@Test
public void testNBRegionDestructionDuringGetInitialImage() throws Exception {
assumeTrue(supportsReplication());
final String name = this.getUniqueName();
final byte[][] values = new byte[NB1_NUM_ENTRIES][];
for (int i = 0; i < NB1_NUM_ENTRIES; i++) {
values[i] = new byte[NB1_VALUE_SIZE];
Arrays.fill(values[i], (byte) 0x42);
}
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm2 = host.getVM(2);
vm0.invoke(new CacheSerializableRunnable("Create Nonmirrored Region") {
@Override
public void run2() throws CacheException {
{
// root region must be DACK because its used to sync up async subregions
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.DISTRIBUTED_ACK);
factory.setDataPolicy(DataPolicy.EMPTY);
createRootRegion(factory.create());
}
{
AttributesFactory factory = new AttributesFactory(getRegionAttributes());
createRegion(name, factory.create());
}
// reset slow
org.apache.geode.internal.cache.InitialImageOperation.slowImageProcessing = 0;
}
});
vm0.invoke(new CacheSerializableRunnable("Put initial data") {
@Override
public void run2() throws CacheException {
Region region = getRootRegion().getSubregion(name);
for (int i = 0; i < NB1_NUM_ENTRIES; i++) {
region.put(new Integer(i), values[i]);
}
assertEquals(NB1_NUM_ENTRIES, region.keySet().size());
}
});
// attachDebugger(vm0, "vm0");
// attachDebugger(vm2, "vm2");
// start asynchronous process that does updates to the data
AsyncInvocation async = vm0.invokeAsync(new CacheSerializableRunnable("Do Nonblocking Operations") {
@Override
public void run2() throws CacheException {
// give the gii guy a chance to start
Wait.pause(200);
Region region = getRootRegion().getSubregion(name);
// wait for profile of getInitialImage cache to show up
final org.apache.geode.internal.cache.CacheDistributionAdvisor adv = ((org.apache.geode.internal.cache.DistributedRegion) region).getCacheDistributionAdvisor();
// int numProfiles;
final int expectedProfiles = 1;
WaitCriterion ev = new WaitCriterion() {
@Override
public boolean done() {
return expectedProfiles == adv.adviseReplicates().size();
}
@Override
public String description() {
return "profile count never became exactly " + expectedProfiles;
}
};
Wait.waitForCriterion(ev, 60 * 1000, 200, true);
// before the get initial image is complete.
for (int i = 1; i < 301; i += 2) {
// getLogWriter().info("doing nonblocking op #"+i);
Object key = new Integer(i);
switch(i % 6) {
case // UPDATE
1:
// use the current timestamp so we know when it happened
// we could have used last modification timestamps, but
// this works without enabling statistics
Object value = new Long(System.currentTimeMillis());
region.put(key, value);
// }
break;
case // INVALIDATE
3:
region.invalidate(key);
if (region.getAttributes().getScope().isDistributedAck()) {
// do a nonblocking netSearch
value = region.get(key);
assertNull("Expected null value for key: " + i + " but got " + value, value);
}
break;
case // DESTROY
5:
region.destroy(key);
if (region.getAttributes().getScope().isDistributedAck()) {
// do a nonblocking netSearch
assertNull(region.get(key));
}
break;
default:
fail("unexpected modulus result: " + i);
break;
}
}
// at magical number 301, do a region destruction
// getLogWriter().info("doing destroyRegion");
region.destroyRegion();
// getLogWriter().info("finished destroyRegion");
// now do a put and our DACK root region which will not complete
// until processed on otherside which means everything done before this
// point has been processed
{
Region rr = getRootRegion();
if (rr != null) {
rr.put("DONE", "FLUSH_OPS");
}
}
}
});
IgnoredException ex = IgnoredException.addIgnoredException("RegionDestroyedException");
try {
// in the meantime, do the get initial image in vm2
AsyncInvocation asyncGII = vm2.invokeAsync(new CacheSerializableRunnable("Create Mirrored Region") {
@Override
public void run2() throws CacheException {
if (!getRegionAttributes().getScope().isGlobal()) {
int pause = 200;
org.apache.geode.internal.cache.InitialImageOperation.slowImageProcessing = pause;
}
beginCacheXml();
{
// root region must be DACK because its used to sync up async subregions
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.DISTRIBUTED_ACK);
factory.setDataPolicy(DataPolicy.NORMAL);
factory.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
createRootRegion(factory.create());
}
{
RegionAttributes ra = getRegionAttributes();
AttributesFactory factory = new AttributesFactory(ra);
if (ra.getDataPolicy().withPersistence()) {
factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
} else {
factory.setDataPolicy(DataPolicy.REPLICATE);
}
createRegion(name, factory.create());
}
finishCacheXml(name);
// reset slow
org.apache.geode.internal.cache.InitialImageOperation.slowImageProcessing = 0;
// if global scope, the region doesn't get destroyed until after region creation
try {
Thread.sleep(3000);
} catch (InterruptedException ie) {
fail("interrupted");
}
assertTrue(getRootRegion().getSubregion(name) == null || getRegionAttributes().getScope().isGlobal());
}
});
if (getRegionAttributes().getScope().isGlobal()) {
// wait for nonblocking operations to complete
ThreadUtils.join(async, 30 * 1000);
if (async.exceptionOccurred()) {
fail("async invocation failed", async.getException());
}
vm2.invoke(new SerializableRunnable("Set fast image processing") {
@Override
public void run() {
org.apache.geode.internal.cache.InitialImageOperation.slowImageProcessing = 0;
}
});
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter().info("after async nonblocking ops complete");
}
// wait for GII to complete
// getLogWriter().info("starting wait for GetInitialImage Completion");
ThreadUtils.join(asyncGII, 30 * 1000);
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter().info("Complete GetInitialImage at: " + System.currentTimeMillis());
if (getRegionAttributes().getScope().isGlobal()) {
// wait for nonblocking operations to complete
ThreadUtils.join(async, 30 * 1000);
}
if (async.exceptionOccurred()) {
fail("async failed", async.getException());
}
if (asyncGII.exceptionOccurred()) {
fail("asyncGII failed", asyncGII.getException());
}
} finally {
ex.remove();
}
}
use of org.apache.geode.test.dunit.WaitCriterion in project geode by apache.
the class MultiVMRegionTestCase method assertCacheCallbackEvents.
public static void assertCacheCallbackEvents(String regionName, TransactionId txId, Object key, Object oldValue, Object newValue) {
Cache johnnyCash = CacheFactory.getAnyInstance();
Region re = johnnyCash.getRegion("root").getSubregion(regionName);
MyTransactionListener tl = (MyTransactionListener) johnnyCash.getCacheTransactionManager().getListeners()[0];
tl.expectedTxId = txId;
assertNotNull("Cannot assert TX Callout Events with a null Region: " + regionName, re);
final CountingDistCacheListener cdcl = (CountingDistCacheListener) re.getAttributes().getCacheListeners()[0];
// May need to wait a bit for the event to be received
WaitCriterion ev = new WaitCriterion() {
@Override
public boolean done() {
return cdcl.getEntryEvent() != null;
}
@Override
public String description() {
return "waiting for entry event";
}
};
Wait.waitForCriterion(ev, 60 * 1000, 200, true);
EntryEvent listenEvent = cdcl.getEntryEvent();
assertNotNull("Cannot assert TX CacheListener Events with a null Entry Event", listenEvent);
assertEquals(re, listenEvent.getRegion());
assertEquals(txId, listenEvent.getTransactionId());
assertEquals(key, listenEvent.getKey());
assertEquals(oldValue, listenEvent.getOldValue());
assertEquals(newValue, listenEvent.getNewValue());
assertEquals(null, listenEvent.getCallbackArgument());
assertEquals(true, listenEvent.isCallbackArgumentAvailable());
assertTrue(!listenEvent.getOperation().isLoad());
assertTrue(!listenEvent.getOperation().isNetLoad());
assertTrue(!listenEvent.getOperation().isNetSearch());
assertTrue(!listenEvent.getOperation().isLocalLoad());
assertTrue(listenEvent.getOperation().isDistributed());
assertTrue(!listenEvent.getOperation().isExpiration());
assertTrue(listenEvent.isOriginRemote());
cdcl.setEntryEvent(null);
}
use of org.apache.geode.test.dunit.WaitCriterion in project geode by apache.
the class MultiVMRegionTestCase method testEntryTtlDestroyEvent.
/**
* Tests that an entry in a distributed region that expires with a distributed destroy causes an
* event in other VM with isExpiration flag set.
*/
// GEODE-583: time sensitive, expiration, waitForCriterion, short
@Category(FlakyTest.class)
// timeouts
@Test
public void testEntryTtlDestroyEvent() throws Exception {
assumeTrue(getRegionAttributes().getPartitionAttributes() == null);
final String name = this.getUniqueName();
// ms
final int timeout = 22;
final Object key = "KEY";
final Object value = "VALUE";
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
class DestroyListener extends TestCacheListener {
boolean eventIsExpiration = false;
@Override
public void afterDestroyBeforeAddEvent(EntryEvent event) {
eventIsExpiration = event.getOperation().isExpiration();
}
@Override
public void afterDestroy2(EntryEvent event) {
if (event.isOriginRemote()) {
assertTrue(!event.getDistributedMember().equals(getSystem().getDistributedMember()));
} else {
assertEquals(getSystem().getDistributedMember(), event.getDistributedMember());
}
assertEquals(Operation.EXPIRE_DESTROY, event.getOperation());
assertEquals(value, event.getOldValue());
eventIsExpiration = event.getOperation().isExpiration();
}
@Override
public void afterCreate2(EntryEvent event) {
// ignore
}
@Override
public void afterUpdate2(EntryEvent event) {
// ignore
}
}
SerializableRunnable createRegion = new CacheSerializableRunnable("Create with Listener") {
@Override
public void run2() throws CacheException {
AttributesFactory fac = new AttributesFactory(getRegionAttributes());
fac.addCacheListener(destroyListener = new DestroyListener());
createRegion(name, fac.create());
}
};
vm1.invoke(createRegion);
vm0.invoke(new CacheSerializableRunnable("Create with TTL") {
@Override
public void run2() throws CacheException {
AttributesFactory factory = new AttributesFactory(getRegionAttributes());
factory.setStatisticsEnabled(true);
ExpirationAttributes expire = new ExpirationAttributes(timeout, ExpirationAction.DESTROY);
factory.setEntryTimeToLive(expire);
if (!getRegionAttributes().getDataPolicy().withReplication()) {
factory.setDataPolicy(DataPolicy.NORMAL);
factory.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
}
System.setProperty(LocalRegion.EXPIRY_MS_PROPERTY, "true");
try {
createRegion(name, factory.create());
ExpiryTask.suspendExpiration();
// suspend to make sure we can see that the put is distributed to this member
} finally {
System.getProperties().remove(LocalRegion.EXPIRY_MS_PROPERTY);
}
}
});
try {
// let region create finish before doing put
// pause(10);
vm1.invoke(new SerializableCallable() {
@Override
public Object call() throws Exception {
Region region = getRootRegion().getSubregion(name);
DestroyListener dl = (DestroyListener) region.getAttributes().getCacheListeners()[0];
dl.enableEventHistory();
region.put(key, value);
// reset listener after create event
assertTrue(dl.wasInvoked());
List<CacheEvent> history = dl.getEventHistory();
CacheEvent ce = history.get(0);
dl.disableEventHistory();
assertEquals(Operation.CREATE, ce.getOperation());
return null;
}
});
vm0.invoke(new CacheSerializableRunnable("Check create received from vm1") {
@Override
public void run2() throws CacheException {
final Region region = getRootRegion().getSubregion(name);
WaitCriterion waitForCreate = new WaitCriterion() {
@Override
public boolean done() {
return region.getEntry(key) != null;
}
@Override
public String description() {
return "never saw create of " + key;
}
};
Wait.waitForCriterion(waitForCreate, 3000, 10, true);
}
});
} finally {
vm0.invoke(new CacheSerializableRunnable("resume expiration") {
@Override
public void run2() throws CacheException {
ExpiryTask.permitExpiration();
}
});
}
// now wait for it to expire
vm0.invoke(new CacheSerializableRunnable("Check local destroy") {
@Override
public void run2() throws CacheException {
final Region region = getRootRegion().getSubregion(name);
WaitCriterion waitForExpire = new WaitCriterion() {
@Override
public boolean done() {
return region.getEntry(key) == null;
}
@Override
public String description() {
return "never saw expire of " + key + " entry=" + region.getEntry(key);
}
};
Wait.waitForCriterion(waitForExpire, 4000, 10, true);
}
});
vm1.invoke(new CacheSerializableRunnable("Verify destroyed and event") {
@Override
public void run2() throws CacheException {
final Region region = getRootRegion().getSubregion(name);
WaitCriterion waitForExpire = new WaitCriterion() {
@Override
public boolean done() {
return region.getEntry(key) == null;
}
@Override
public String description() {
return "never saw expire of " + key + " entry=" + region.getEntry(key);
}
};
Wait.waitForCriterion(waitForExpire, 4000, 10, true);
assertTrue(destroyListener.waitForInvocation(555));
assertTrue(((DestroyListener) destroyListener).eventIsExpiration);
}
});
}
use of org.apache.geode.test.dunit.WaitCriterion in project geode by apache.
the class PRBucketSynchronizationDUnitTest method verifySynchronized.
private void verifySynchronized(VM vm, final InternalDistributedMember crashedMember) {
vm.invoke(new SerializableCallable("check that synchronization happened") {
public Object call() throws Exception {
PartitionedRegion pr = (PartitionedRegion) TestRegion;
final BucketRegion bucket = pr.getDataStore().getLocalBucketById(0);
Wait.waitForCriterion(new WaitCriterion() {
String waitingFor = "primary is still in membership view: " + crashedMember;
boolean dumped = false;
public boolean done() {
if (TestRegion.getCache().getDistributionManager().isCurrentMember(crashedMember)) {
LogWriterUtils.getLogWriter().info(waitingFor);
return false;
}
if (!TestRegion.containsKey("Object3")) {
waitingFor = "entry for Object3 not found";
LogWriterUtils.getLogWriter().info(waitingFor);
return false;
}
RegionEntry re = bucket.getRegionMap().getEntry("Object5");
if (re == null) {
if (!dumped) {
dumped = true;
bucket.dumpBackingMap();
}
waitingFor = "entry for Object5 not found";
LogWriterUtils.getLogWriter().info(waitingFor);
return false;
}
if (!re.isTombstone()) {
if (!dumped) {
dumped = true;
bucket.dumpBackingMap();
}
waitingFor = "Object5 is not a tombstone but should be: " + re;
LogWriterUtils.getLogWriter().info(waitingFor);
return false;
}
return true;
}
public String description() {
return waitingFor;
}
}, 30000, 5000, true);
return null;
}
});
}
Aggregations