GEODE-1278: Catch and translate CacheClosedException

- Catch the exception and add unit tests for
 AbstractPeerTxRegionStub.getRegionKeysForIteration.
- Refactored AbstractRegion to support testing.
This closes #138


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

Branch: refs/heads/feature/GEODE-1255
Commit: 62bfa59cd14af6e07da1ecda082aa9714925ac47
Parents: e63acce
Author: Ken Howe <kh...@pivotal.io>
Authored: Fri Apr 22 15:28:04 2016 -0700
Committer: Darrel Schneider <dschnei...@pivotal.io>
Committed: Wed May 4 14:27:36 2016 -0700

----------------------------------------------------------------------
 .../gemfire/internal/cache/AbstractRegion.java  |   2 +-
 .../cache/tx/AbstractPeerTXRegionStub.java      |   8 +-
 .../cache/tx/AbstractPeerTXRegionStubTest.java  | 164 +++++++++++++++++++
 3 files changed, 170 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/62bfa59c/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java
index d37f025..ef7e4e3 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java
@@ -1921,7 +1921,7 @@ public abstract class AbstractRegion implements Region, 
RegionAttributes,
     return getSystem().getDistributionManager();
   }
 
-  public final InternalDistributedSystem getSystem() {
+  public InternalDistributedSystem getSystem() {
     return getCache().getDistributedSystem();
   }
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/62bfa59c/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStub.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStub.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStub.java
index 77116eb..a24d2b7 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStub.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStub.java
@@ -18,7 +18,9 @@ package com.gemstone.gemfire.internal.cache.tx;
 
 import java.util.Set;
 
+import com.gemstone.gemfire.cache.CacheClosedException;
 import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.TransactionDataNodeHasDepartedException;
 import com.gemstone.gemfire.cache.TransactionDataNotColocatedException;
 import com.gemstone.gemfire.cache.TransactionException;
 import com.gemstone.gemfire.internal.cache.LocalRegion;
@@ -36,16 +38,16 @@ public abstract class AbstractPeerTXRegionStub implements 
TXRegionStub {
     this.region = r;
   }
 
+  @Override
   public Set getRegionKeysForIteration(LocalRegion currRegion) {
-    /*
-     * txtodo: not sure about c/s for this?
-     */
     try {
       RemoteFetchKeysMessage.FetchKeysResponse response = 
RemoteFetchKeysMessage.send(currRegion, state.getTarget());
       return response.waitForKeys();
     } catch (RegionDestroyedException e) {
       throw new 
TransactionDataNotColocatedException(LocalizedStrings.RemoteMessage_REGION_0_NOT_COLOCATED_WITH_TRANSACTION
               .toLocalizedString(e.getRegionFullPath()), e);
+    } catch(CacheClosedException e) {
+      throw new TransactionDataNodeHasDepartedException("Cache was closed 
while fetching keys");
     } catch (Exception e) {
       throw new TransactionException(e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/62bfa59c/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStubTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStubTest.java
 
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStubTest.java
new file mode 100644
index 0000000..0461721
--- /dev/null
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tx/AbstractPeerTXRegionStubTest.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.gemstone.gemfire.internal.cache.tx;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.Region.Entry;
+import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.TransactionDataNodeHasDepartedException;
+import com.gemstone.gemfire.cache.TransactionDataNotColocatedException;
+import com.gemstone.gemfire.internal.cache.DistributedPutAllOperation;
+import com.gemstone.gemfire.internal.cache.DistributedRemoveAllOperation;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.KeyInfo;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.TXStateStub;
+import 
com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class AbstractPeerTXRegionStubTest {
+  private AbstractPeerTXRegionStub txrStub;
+  private TXStateStub state;
+  private LocalRegion region;
+
+  private class TestingAbstractPeerTXRegionStub extends 
AbstractPeerTXRegionStub {
+
+    private TestingAbstractPeerTXRegionStub(TXStateStub txState, LocalRegion 
r) {
+      super(txState, r);
+    }
+
+    @Override
+    public void destroyExistingEntry(EntryEventImpl event, boolean cacheWrite, 
Object expectedOldValue) {
+    }
+
+    @Override
+    public Entry getEntry(KeyInfo keyInfo, boolean allowTombstone) {
+      return null;
+    }
+
+    @Override
+    public void invalidateExistingEntry(EntryEventImpl event, boolean 
invokeCallbacks, boolean forceNewEntry) {
+    }
+
+    @Override
+    public boolean containsKey(KeyInfo keyInfo) {
+      return false;
+    }
+
+    @Override
+    public boolean containsValueForKey(KeyInfo keyInfo) {
+      return false;
+    }
+
+    @Override
+    public Object findObject(KeyInfo keyInfo, boolean isCreate,
+        boolean generateCallbacks, Object value, boolean preferCD,
+        ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent) {
+      return null;
+    }
+
+    @Override
+    public Object getEntryForIterator(KeyInfo keyInfo, boolean allowTombstone) 
{
+      return null;
+    }
+
+    @Override
+    public boolean putEntry(EntryEventImpl event, boolean ifNew, boolean 
ifOld, Object expectedOldValue, boolean requireOldValue, long lastModified,
+        boolean overwriteDestroyed) {
+      return false;
+    }
+
+    @Override
+    public int entryCount() {
+      return 0;
+    }
+
+    @Override
+    public void postPutAll(DistributedPutAllOperation putallOp, 
VersionedObjectList successfulPuts, LocalRegion region) {
+    }
+
+    @Override
+    public void postRemoveAll(DistributedRemoveAllOperation op, 
VersionedObjectList successfulOps, LocalRegion region) {
+    }
+
+    @Override
+    public void cleanup() {
+    }
+  }
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    state = mock(TXStateStub.class);
+    region = mock(LocalRegion.class);
+    txrStub = new TestingAbstractPeerTXRegionStub(state, region);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void getRegionKeysForIterationTranslatesCacheClosedException() {
+    expectedException.expect(TransactionDataNodeHasDepartedException.class);
+
+    //  Mocking to cause getSystem() to throw exceptions for testing
+    //  getSystem is called when creating FetchKeysResponse in 
RemoteFetchKeysResponse.send, which is called from getRegionKeysForIteration
+    when((region).getSystem()).thenThrow(CacheClosedException.class);
+
+    txrStub.getRegionKeysForIteration(region);
+    fail("AbstractPeerTXRegionStub expected to transalate CacheClosedException 
to TransactionDataNodeHasDepartedException ");
+  }
+
+  @Test
+  public void getRegionKeysForIterationTranslatesRegionDestroyedException() {
+    expectedException.expect(TransactionDataNotColocatedException.class);
+
+    //  Mocking to cause getSystem() to throw exceptions for testing
+    //  getSystem is called when creating FetchKeysResponse in 
RemoteFetchKeysResponse.send, which is called from getRegionKeysForIteration
+    when((region).getSystem()).thenThrow(RegionDestroyedException.class);
+
+    txrStub.getRegionKeysForIteration(region);
+    fail("AbstractPeerTXRegionStub expected to transalate CacheClosedException 
to TransactionDataNodeHasDepartedException ");
+  }
+
+}

Reply via email to