You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ud...@apache.org on 2016/09/06 17:23:30 UTC

[06/18] incubator-geode git commit: GEODE-1818: fix NPE in Bug37377DUnitTest

GEODE-1818: fix NPE in Bug37377DUnitTest

This closes #235


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

Branch: refs/heads/feature/GEODE-420
Commit: 8a644c25de9c4bc5a413de96dfac88451fda7fc8
Parents: ea5516c
Author: Scott Jewell <sj...@pivotal.io>
Authored: Wed Aug 31 10:54:05 2016 -0700
Committer: Darrel Schneider <ds...@pivotal.io>
Committed: Thu Sep 1 09:26:03 2016 -0700

----------------------------------------------------------------------
 .../internal/cache/Bug37377DUnitTest.java       | 393 +++++++++----------
 1 file changed, 176 insertions(+), 217 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8a644c25/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/Bug37377DUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/Bug37377DUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/Bug37377DUnitTest.java
index 0531100..35e9caf 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/Bug37377DUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/Bug37377DUnitTest.java
@@ -22,32 +22,22 @@ import org.junit.Test;
 import static org.junit.Assert.*;
 
 import com.gemstone.gemfire.test.dunit.cache.internal.JUnit4CacheTestCase;
-import com.gemstone.gemfire.test.dunit.internal.JUnit4DistributedTestCase;
 import com.gemstone.gemfire.test.junit.categories.DistributedTest;
 
 import java.io.File;
 import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
 
 import com.gemstone.gemfire.cache.AttributesFactory;
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.cache.DataPolicy;
-import com.gemstone.gemfire.cache.EntryEvent;
-import com.gemstone.gemfire.cache.Operation;
 import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.cache.RegionAttributes;
 import com.gemstone.gemfire.cache.Scope;
-import com.gemstone.gemfire.cache30.CacheSerializableRunnable;
-import com.gemstone.gemfire.cache30.CacheTestCase;
 import com.gemstone.gemfire.distributed.DistributedSystem;
-import com.gemstone.gemfire.internal.cache.lru.EnableLRU;
-import com.gemstone.gemfire.internal.util.concurrent.CustomEntryConcurrentHashMap.HashEntry;
-import com.gemstone.gemfire.test.dunit.AsyncInvocation;
 import com.gemstone.gemfire.test.dunit.Host;
-import com.gemstone.gemfire.test.dunit.SerializableRunnable;
-import com.gemstone.gemfire.test.dunit.ThreadUtils;
 import com.gemstone.gemfire.test.dunit.VM;
-import com.gemstone.gemfire.test.dunit.Wait;
 
 /**
  * Bug37377 DUNIT Test: The Clear operation during a GII in progress can leave a
@@ -67,9 +57,7 @@ public class Bug37377DUnitTest extends JUnit4CacheTestCase
 
   protected static DistributedSystem distributedSystem = null;
 
-  private static VM vm0 = null;
-
-  private static VM vm1 = null;
+  VM vm0, vm1;
 
   protected static Cache cache = null;
 
@@ -77,6 +65,10 @@ public class Bug37377DUnitTest extends JUnit4CacheTestCase
 
   private static final int maxEntries = 10000;
 
+  transient private static CountDownLatch clearLatch = new CountDownLatch(1);
+
+  static Boolean clearOccured = false;
+
   public Bug37377DUnitTest() {
     super();
     File file1 = new File(getTestMethodName() + "1");
@@ -99,206 +91,161 @@ public class Bug37377DUnitTest extends JUnit4CacheTestCase
 
   @Override
   public final void preTearDownCacheTestCase() throws Exception {
-    vm1.invoke(destroyRegion());
-    vm0.invoke(destroyRegion());
+    vm1.invoke(() -> destroyRegion());
+    vm0.invoke(() -> destroyRegion());
   }
 
   /**
    * This method is used to create Cache in VM0
-   * 
-   * @return CacheSerializableRunnable
    */
 
-  private CacheSerializableRunnable createCacheForVM0()
-  {
-    SerializableRunnable createCache = new CacheSerializableRunnable(
-        "createCache") {
-      public void run2()
-      {
-        try {
-
-          distributedSystem = (new Bug37377DUnitTest())
-              .getSystem(props);
-          assertTrue(distributedSystem != null);
-          cache = CacheFactory.create(distributedSystem);
-          assertTrue(cache != null);
-          AttributesFactory factory = new AttributesFactory();
-          factory.setScope(Scope.DISTRIBUTED_ACK);
-          factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
-          factory.setDiskSynchronous(false);
-          factory.setDiskStoreName(cache.createDiskStoreFactory()
-                                   .setDiskDirs(dirs)
-                                   .create("Bug37377DUnitTest")
-                                   .getName());
-          RegionAttributes attr = factory.create();
-          cache.createRegion(regionName, attr);
-        }
-        catch (Exception ex) {
-          ex.printStackTrace();
-          fail("Error Creating cache / region ");
-        }
-      }
-    };
-    return (CacheSerializableRunnable)createCache;
+  @SuppressWarnings("deprecation")
+  private void createCacheForVM0() {
+    try {
+
+      distributedSystem = (new Bug37377DUnitTest())
+          .getSystem(props);
+      assertTrue(distributedSystem != null);
+      cache = CacheFactory.create(distributedSystem);
+      assertTrue(cache != null);
+      AttributesFactory factory = new AttributesFactory();
+      factory.setScope(Scope.DISTRIBUTED_ACK);
+      factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
+      factory.setDiskSynchronous(false);
+      factory.setDiskStoreName(cache.createDiskStoreFactory()
+          .setDiskDirs(dirs)
+          .create("Bug37377DUnitTest")
+          .getName());
+      RegionAttributes attr = factory.create();
+      cache.createRegion(regionName, attr);
+    }
+    catch (Exception ex) {
+      ex.printStackTrace();
+      fail("Error Creating cache / region ");
+    }
   }
 
   /**
    * This method is used to create Cache in VM1
-   * 
-   * @return CacheSerializableRunnable
    */
-  private CacheSerializableRunnable createCacheForVM1()
-  {
-    SerializableRunnable createCache = new CacheSerializableRunnable(
-        "createCache") {
-      public void run2()
-      {
-        try {
-          distributedSystem = (new Bug37377DUnitTest())
-              .getSystem(props);
-          assertTrue(distributedSystem != null);
-          cache = CacheFactory.create(distributedSystem);
-          assertTrue("cache found null", cache != null);
-
-          AttributesFactory factory = new AttributesFactory();
-          factory.setScope(Scope.DISTRIBUTED_ACK);
-          factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
-          factory.setDiskSynchronous(false);
-          factory.setDiskStoreName(cache.createDiskStoreFactory()
-                                   .setDiskDirs(dirs)
-                                   .create("Bug37377DUnitTest")
-                                   .getName());
-          RegionAttributes attr = factory.create();
-          DistributedRegion distRegion = new DistributedRegion(regionName,
-              attr, null, (GemFireCacheImpl)cache, new InternalRegionArguments()
-                  .setDestroyLockFlag(true).setRecreateFlag(false)
-                  .setSnapshotInputStream(null).setImageTarget(null));
-//          assertTrue("Distributed Region is null", distRegion != null); (cannot be null)
-
-          ((AbstractRegionMap)distRegion.entries)
-              .setEntryFactory(TestAbstractDiskRegionEntry.getEntryFactory());
-
-          LocalRegion region = (LocalRegion)((GemFireCacheImpl)cache)
-              .createVMRegion(regionName, attr, new InternalRegionArguments()
-                  .setInternalMetaRegion(distRegion).setDestroyLockFlag(true)
-                  .setSnapshotInputStream(null).setImageTarget(null));
-          assertTrue("Local Region is null", region != null);
+  @SuppressWarnings("deprecation")
+  private void createCacheForVM1() {
+    try {
+      distributedSystem = (new Bug37377DUnitTest())
+          .getSystem(props);
+      assertTrue(distributedSystem != null);
+      cache = CacheFactory.create(distributedSystem);
+      assertTrue("cache found null", cache != null);
+
+      AttributesFactory factory = new AttributesFactory();
+      factory.setScope(Scope.DISTRIBUTED_ACK);
+      factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
+      factory.setDiskSynchronous(false);
+      factory.setDiskStoreName(cache.createDiskStoreFactory()
+          .setDiskDirs(dirs)
+          .create("Bug37377DUnitTest")
+          .getName());
+      RegionAttributes attr = factory.create();
+      DistributedRegion distRegion = new DistributedRegion(regionName,
+          attr, null, (GemFireCacheImpl)cache, new InternalRegionArguments()
+          .setDestroyLockFlag(true).setRecreateFlag(false)
+          .setSnapshotInputStream(null).setImageTarget(null));
+      //      assertTrue("Distributed Region is null", distRegion != null); (cannot be null)
+
+      TestAbstractDiskRegionEntry.setMembers(vm1, vm0);    // vm1 is thisVM, vm0 is otherVM
+
+      ((AbstractRegionMap)distRegion.entries)
+      .setEntryFactory(TestAbstractDiskRegionEntry.getEntryFactory());
+
+      LocalRegion region = (LocalRegion)((GemFireCacheImpl)cache)
+          .createVMRegion(regionName, attr, new InternalRegionArguments()
+              .setInternalMetaRegion(distRegion).setDestroyLockFlag(true)
+              .setSnapshotInputStream(null).setImageTarget(null));
+      assertTrue("Local Region is null", region != null);
 
-        }
-        catch (Exception ex) {
-          ex.printStackTrace();
-          fail("Error Creating cache / region " + ex);
-        }
-      }
-    };
-    return (CacheSerializableRunnable)createCache;
+    }
+    catch (Exception ex) {
+      ex.printStackTrace();
+      fail("Error Creating cache / region " + ex);
+    }  
   }
 
   /**
    * This method puts in maxEntries in the Region
-   * 
-   * @return CacheSerializableRunnable
    */
-  private CacheSerializableRunnable putSomeEntries()
-  {
-    SerializableRunnable puts = new CacheSerializableRunnable("putSomeEntries") {
-      public void run2()
-      {
-        assertTrue("Cache is found as null ", cache != null);
-        Region rgn = cache.getRegion(regionName);
-        for (int i = 0; i < maxEntries; i++) {
-          rgn.put(new Long(i), new Long(i));
-        }
-      }
-    };
-    return (CacheSerializableRunnable)puts;
+  private void putSomeEntries() {
+    assertTrue("Cache is found as null ", cache != null);
+    Region rgn = cache.getRegion(regionName);
+    for (int i = 0; i < maxEntries; i++) {
+      rgn.put(new Long(i), new Long(i));
+    }
   }
 
   /**
-   * This method destroys the Region
+   * This method clears the region and 
+   * notifies the other member when complete
    * 
-   * @return CacheSerializableRunnable
+   * @throws InterruptedException 
    */
-  private CacheSerializableRunnable destroyRegion()
-  {
-    SerializableRunnable puts = new CacheSerializableRunnable("destroyRegion") {
-      public void run2()
-      {
-        try {
-          assertTrue("Cache is found as null ", cache != null);
-
-          Region rgn = cache.getRegion(regionName);
-          rgn.localDestroyRegion();
-          cache.close();
-        }
-        catch (Exception ex) {
-
-        }
-      }
-    };
-    return (CacheSerializableRunnable)puts;
+  private static void invokeRemoteClearAndWait(VM remoteVM, VM thisVM) {
+    remoteVM.invoke(() -> clearRegionAndNotify(thisVM));
+    try {
+      clearLatch.await();
+    } catch (InterruptedException e) {
+      fail("wait for remote clear to complete failed");
+    }
   }
 
   /**
-   * This method is used to close cache on the calling VM
-   * 
-   * @return CacheSerializableRunnable
+   * This method clears the region and 
+   * notifies the other member when complete
    */
-  private CacheSerializableRunnable closeCacheForVM(final int vmNo)
-  {
-    SerializableRunnable cclose = new CacheSerializableRunnable(
-        "closeCacheForVM") {
-      public void run2()
-      {
-        if (vmNo == 0) {
-          cache.getRegion(regionName).localDestroyRegion();
-        }
-        assertTrue("Cache is found as null ", cache != null);
-        cache.close();
-      }
-    };
-    return (CacheSerializableRunnable)cclose;
+  private static void clearRegionAndNotify(VM otherVM) {
+    assertTrue("Cache is found as null ", cache != null);
+    Region rgn = cache.getRegion(regionName);
+    rgn.clear();
+    otherVM.invoke(() -> notifyClearComplete());
   }
 
   /**
-   * This method is used to close cache on the calling VM
-   * 
-   * @return CacheSerializableRunnable
+   * Decrement countdown latch to notify clear complete 
    */
-  private CacheSerializableRunnable closeCacheInVM()
-  {
-    SerializableRunnable cclose = new CacheSerializableRunnable(
-        "closeCacheInVM") {
-      public void run2()
-      {
-
-        cache.getRegion(regionName).localDestroyRegion();
-        assertTrue("Cache is found as null ", cache != null);
-        cache.close();
-      }
-    };
-    return (CacheSerializableRunnable)cclose;
+  private static void notifyClearComplete() {
+    clearLatch.countDown();
   }
 
   /**
-   * This method verifies that the reintialized region size should be zero
-   * 
-   * @return CacheSerializableRunnable
+   * This method destroys the Region
    */
-  private CacheSerializableRunnable verifyExtraEntryFromOpLogs()
-  {
-    SerializableRunnable verify = new CacheSerializableRunnable(
-        "verifyExtraEntryFromOpLogs") {
-      public void run2()
-      {
-        assertTrue("Cache is found as null ", cache != null);
-        Region rgn = cache.getRegion(regionName);
-        // should be zero after reinit
-        assertEquals(0, rgn.size());
-      }
-    };
-    return (CacheSerializableRunnable)verify;
+  private void destroyRegion() {
+    try {
+      assertTrue("Cache is found as null ", cache != null);
+      Region rgn = cache.getRegion(regionName);
+      rgn.localDestroyRegion();
+      cache.close();
+    }
+    catch (Exception ex) {}
+  }
 
+  /**
+   * This method closes the cache on the specified VM
+   */
+  private void closeCacheForVM(final int vmNo) {
+    if (vmNo == 0) {
+      cache.getRegion(regionName).localDestroyRegion();
+    }
+    assertTrue("Cache is found as null ", cache != null);
+    cache.close();
+  }
+ 
+  /**
+   * This method verifies that the reintialized region size is zero
+   */
+  private void verifyExtraEntryFromOpLogs() {
+    assertTrue("Cache is found as null ", cache != null);
+    Region rgn = cache.getRegion(regionName);
+    // should be zero after clear
+    assertEquals(0, rgn.size());
   }
 
   /**
@@ -309,44 +256,45 @@ public class Bug37377DUnitTest extends JUnit4CacheTestCase
    */
 
   @Test
-  public void testGIIputWithClear()
-  {
-    vm0.invoke(createCacheForVM0());
-    vm0.invoke(putSomeEntries());
-    AsyncInvocation as1 = vm1.invokeAsync(createCacheForVM1());
-    Wait.pause(10000);
-    ThreadUtils.join(as1, 30 * 1000);
-    vm0.invoke(closeCacheForVM(0));
-    vm1.invoke(closeCacheForVM(1));
-    vm1.invoke(createCacheForVM1());
-    vm1.invoke(verifyExtraEntryFromOpLogs());
+  public void testGIIputWithClear() {
+    vm0.invoke(() -> createCacheForVM0());
+    vm0.invoke(() -> putSomeEntries());
+
+    vm1.invoke(() -> createCacheForVM1());
+
+    vm0.invoke(() -> closeCacheForVM(0));
+    vm1.invoke(() -> closeCacheForVM(1));
+
+    vm1.invoke(() -> createCacheForVM1());
+    vm1.invoke(() -> verifyExtraEntryFromOpLogs());
   }
 
-  static class TestAbstractDiskRegionEntry extends VMThinDiskRegionEntryHeapObjectKey
-  {
-    protected TestAbstractDiskRegionEntry(RegionEntryContext r, Object key,
-        Object value) {
+  static class TestAbstractDiskRegionEntry extends VersionedThinDiskRegionEntryHeapObjectKey {
+    static private VM thisVM, otherVM;
+
+    static void setMembers(VM localVM, VM remoteVM) {
+      thisVM = localVM;
+      otherVM = remoteVM;
+    }
+
+    protected TestAbstractDiskRegionEntry(RegionEntryContext r, Object key, Object value) {
       super(r, key, value);
     }
-    
-    private static RegionEntryFactory factory = new RegionEntryFactory() {
-      public final RegionEntry createEntry(RegionEntryContext r, Object key,
-          Object value)
-      {
 
+    private static RegionEntryFactory factory = new RegionEntryFactory() {
+      
+      public final RegionEntry createEntry(RegionEntryContext r, Object key, Object value) {
         return new TestAbstractDiskRegionEntry(r, key, value);
       }
 
-      public final Class getEntryClass()
-      {
-
+      public final Class getEntryClass() {
         return TestAbstractDiskRegionEntry.class;
       }
 
       public RegionEntryFactory makeVersioned() {
         return this;
       }
-      
+
       public RegionEntryFactory makeOnHeap() {
         return this;
       }
@@ -358,24 +306,35 @@ public class Bug37377DUnitTest extends JUnit4CacheTestCase
      */
     @Override
     public boolean initialImageInit(final LocalRegion r,
-                                    final long lastModifiedTime,
-                                    final Object newValue,
-                                    final boolean create,
-                                    final boolean wasRecovered,
-                                    final boolean versionTagAccepted) throws RegionClearedException
+        final long lastModifiedTime,
+        final Object newValue,
+        final boolean create,
+        final boolean wasRecovered,
+        final boolean versionTagAccepted) throws RegionClearedException
     {
-      RegionEventImpl event = new RegionEventImpl(r, Operation.REGION_CLEAR,
-                                                  null, true /* isOriginRemote */,
-                                                  r.cache.getMyId());
-      ((DistributedRegion)r).cmnClearRegion(event, false, false);
-      boolean result = super.initialImageInit(r, lastModifiedTime, newValue, create, wasRecovered, versionTagAccepted);
-      fail("expected RegionClearedException");
-      return result;
+      synchronized(clearOccured) {
+        if(!clearOccured) {
+          // Force other member to perform a clear during our GII
+          invokeRemoteClearAndWait(otherVM, thisVM);
+          clearOccured = true;
+        }
+      }
+
+      // Continue GII processing, which should throw RegionClearedException after the clear
+      try {
+        boolean result = super.initialImageInit(r, lastModifiedTime, newValue, create, wasRecovered, versionTagAccepted);
+      } catch (RegionClearedException rce) {
+        throw rce;
+      } catch (Exception ex) {
+        fail("Caught exception during initialImageInit: " + ex );
+      }
+
+      return true;
     }
 
-    public static RegionEntryFactory getEntryFactory()
-    {
+    public static RegionEntryFactory getEntryFactory() {
       return factory;
     }
   }
 }
+