You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2015/09/25 00:44:52 UTC

[15/21] incubator-geode git commit: GEODE-179: fix race in testEntryTtlDestroyEvent

GEODE-179: fix race in testEntryTtlDestroyEvent

A race existed that caused no-ack regions to fail because they
did not see the entry expire.
This race was fixed by suspending expiration until the create
is seen on the remote side and then after permitting expiration
using a wait for the expire to happen.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/15c62f31
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/15c62f31
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/15c62f31

Branch: refs/heads/feature/GEODE-189
Commit: 15c62f316e491376eaa676dca9c17eb33eed9b3a
Parents: 6da9b84
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Wed Aug 5 16:46:45 2015 -0700
Committer: Kirk Lund <kl...@pivotal.io>
Committed: Thu Aug 13 11:39:46 2015 -0700

----------------------------------------------------------------------
 .../gemfire/cache30/MultiVMRegionTestCase.java  | 94 +++++++++++++-------
 1 file changed, 63 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/15c62f31/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
index 5e605dd..ecec932 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/MultiVMRegionTestCase.java
@@ -45,6 +45,7 @@ import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.cache.AttributesFactory;
 import com.gemstone.gemfire.cache.AttributesMutator;
 import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheEvent;
 import com.gemstone.gemfire.cache.CacheException;
 import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.cache.CacheListener;
@@ -84,6 +85,7 @@ import com.gemstone.gemfire.internal.InternalDataSerializer;
 import com.gemstone.gemfire.internal.InternalInstantiator;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.cache.EntryExpiryTask;
+import com.gemstone.gemfire.internal.cache.ExpiryTask;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 import com.gemstone.gemfire.internal.cache.LocalRegion;
 import com.gemstone.gemfire.internal.cache.PartitionedRegion;
@@ -3822,7 +3824,7 @@ public abstract class MultiVMRegionTestCase extends RegionTestCase {
         return;
       
       final String name = this.getUniqueName();
-      final int timeout = 40; // ms
+      final int timeout = 22; // ms
       final Object key = "KEY";
       final Object value = "VALUE";
 
@@ -3857,81 +3859,111 @@ public abstract class MultiVMRegionTestCase extends RegionTestCase {
       }
 
 
-      SerializableRunnable create = new CacheSerializableRunnable("Populate") {
+      SerializableRunnable createRegion = new CacheSerializableRunnable("Create with Listener") {
         public void run2() throws CacheException {
           AttributesFactory fac = new AttributesFactory(getRegionAttributes());
           fac.addCacheListener(destroyListener = new DestroyListener());
-          Region region = null;
-          System.setProperty(LocalRegion.EXPIRY_MS_PROPERTY, "true");
-          try {
-            region = createRegion(name, fac.create());
-          } 
-          finally {
-            System.getProperties().remove(LocalRegion.EXPIRY_MS_PROPERTY);
-          }
+          createRegion(name, fac.create());
         }
       };
 
-      vm1.invoke(create);
+      vm1.invoke(createRegion);
 
       vm0.invoke(new CacheSerializableRunnable("Create with TTL") {
           public void run2() throws CacheException {
             AttributesFactory factory = new AttributesFactory(getRegionAttributes());
-            final boolean partitioned = getRegionAttributes().getPartitionAttributes() != null ||
-            getRegionAttributes().getDataPolicy().withPartitioning();
             factory.setStatisticsEnabled(true);
             ExpirationAttributes expire =
               new ExpirationAttributes(timeout,
                                        ExpirationAction.DESTROY);
             factory.setEntryTimeToLive(expire);
-            if (!getRegionAttributes().getDataPolicy().withReplication()&& ! partitioned) {
+            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 create finish before setting up other cache
+      // let region create finish before doing put
       //pause(10);
 
       vm1.invoke(new SerializableCallable() {
         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(((DestroyListener)region.getAttributes().
-            getCacheListeners()[0]).wasInvoked());
+          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") {
+        public void run2() throws CacheException {
+          final Region region = getRootRegion().getSubregion(name);
+          WaitCriterion waitForCreate = new WaitCriterion() {
+            public boolean done() {
+              return region.getEntry(key) != null;
+            }
+            public String description() {
+              return "never saw create of " + key;
+            }
+          };
+          DistributedTestCase.waitForCriterion(waitForCreate, 3000, 10, true);
+        }
+      });
+      
+      } finally {
+        vm0.invoke(new CacheSerializableRunnable("resume expiration") {
+          public void run2() throws CacheException {
+            ExpiryTask.permitExpiration();
+          }
+        });
+      }
+      
+      // now wait for it to expire
       vm0.invoke(new CacheSerializableRunnable("Check local destroy") {
           public void run2() throws CacheException {
-            Region region =
-              getRootRegion().getSubregion(name);
-            int retries = 10;
-            while (region.getEntry(key) != null && retries-- > 0) {
-              pause(timeout);
-            }
-            assertNull(region.getEntry(key));
+            final Region region = getRootRegion().getSubregion(name);
+            WaitCriterion waitForExpire = new WaitCriterion() {
+              public boolean done() {
+                return region.getEntry(key) == null;
+              }
+              public String description() {
+                return "never saw expire of " + key + " entry=" + region.getEntry(key);
+              }
+            };
+            DistributedTestCase.waitForCriterion(waitForExpire, 4000, 10, true);
           }
         });
 
       vm1.invoke(new CacheSerializableRunnable("Verify destroyed and event") {
           public void run2() throws CacheException {
-            Region region = getRootRegion().getSubregion(name);
-            int retries = 10;
-            while (region.getEntry(key) != null && retries-- > 0) {
-              pause(timeout);
-            }
-            assertNull(region.getEntry(key));
+            final Region region = getRootRegion().getSubregion(name);
+            WaitCriterion waitForExpire = new WaitCriterion() {
+              public boolean done() {
+                return region.getEntry(key) == null;
+              }
+              public String description() {
+                return "never saw expire of " + key + " entry=" + region.getEntry(key);
+              }
+            };
+            DistributedTestCase.waitForCriterion(waitForExpire, 4000, 10, true);
             assertTrue(destroyListener.waitForInvocation(555));
             assertTrue(((DestroyListener)destroyListener).eventIsExpiration);
           }