| /* |
| * 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. |
| */ |
| |
| /* |
| * CacheMapTxnDUnitTest.java |
| * |
| * Created on August 9, 2005, 11:18 AM |
| */ |
| package org.apache.geode.cache30; |
| |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.util.Properties; |
| import java.util.Set; |
| |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.AttributesFactory; |
| import org.apache.geode.cache.Cache; |
| import org.apache.geode.cache.CacheFactory; |
| import org.apache.geode.cache.CacheTransactionManager; |
| import org.apache.geode.cache.DataPolicy; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.RegionAttributes; |
| import org.apache.geode.cache.Scope; |
| import org.apache.geode.cache.UnsupportedOperationInTransactionException; |
| import org.apache.geode.distributed.DistributedSystem; |
| import org.apache.geode.test.dunit.Assert; |
| import org.apache.geode.test.dunit.AsyncInvocation; |
| import org.apache.geode.test.dunit.Host; |
| import org.apache.geode.test.dunit.ThreadUtils; |
| import org.apache.geode.test.dunit.VM; |
| import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; |
| |
| |
| public class CacheMapTxnDUnitTest extends JUnit4DistributedTestCase { // TODO: reformat |
| |
| protected static Cache cache; |
| protected static Properties props = new Properties(); |
| static DistributedSystem ds = null; |
| static Region region; |
| static Region mirroredRegion; |
| protected static CacheTransactionManager cacheTxnMgr; |
| |
| @Override |
| public final void postSetUp() throws Exception { |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| VM vm1 = host.getVM(1); |
| vm0.invoke(CacheMapTxnDUnitTest::createCache); |
| vm1.invoke(CacheMapTxnDUnitTest::createCache); |
| postSetUpCacheMapTxnDUnitTest(); |
| } |
| |
| protected void postSetUpCacheMapTxnDUnitTest() throws Exception {} |
| |
| @Override |
| public final void preTearDown() throws Exception { |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| VM vm1 = host.getVM(1); |
| vm0.invoke(CacheMapTxnDUnitTest::closeCache); |
| vm1.invoke(CacheMapTxnDUnitTest::closeCache); |
| } |
| |
| public static void createCache() { |
| try { |
| // props.setProperty(DistributionConfig.SystemConfigurationProperties.MCAST_PORT, "1234"); |
| // ds = DistributedSystem.connect(props); |
| ds = (new CacheMapTxnDUnitTest()).getSystem(props); |
| cache = CacheFactory.create(ds); |
| AttributesFactory factory = new AttributesFactory(); |
| factory.setScope(Scope.DISTRIBUTED_ACK); |
| factory.setDataPolicy(DataPolicy.REPLICATE); |
| RegionAttributes attr = factory.create(); |
| region = cache.createRegion("map", attr); |
| |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } |
| } |
| |
| public static void closeCache() { |
| try { |
| cache.close(); |
| ds.disconnect(); |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } |
| } |
| |
| @Test |
| public void testCommitTxn() { |
| // this is to test single VM region transactions |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| vm0.invoke(CacheMapTxnDUnitTest::commitTxn); |
| }// end of testCommitTxn |
| |
| @Test |
| public void testRollbackTxn() { |
| // this is to test single VM region transactions |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| vm0.invoke(CacheMapTxnDUnitTest::rollbackTxn); |
| }// end of testRollbackTxn |
| |
| @Test |
| public void testRollbackTxnClear() { |
| // this is to test single VM region transactions |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| VM vm1 = host.getVM(1); |
| int i = 0; |
| Object ob2; |
| Object[] objArr = new Object[1]; |
| |
| for (i = 0; i < 5; i++) { |
| objArr[0] = "" + i; |
| vm1.invoke(CacheMapTxnDUnitTest.class, "putMethod", objArr); |
| } |
| |
| vm0.invoke(CacheMapTxnDUnitTest::rollbackTxnClear); |
| |
| i = 3; |
| objArr[0] = "" + i; |
| ob2 = vm1.invoke(CacheMapTxnDUnitTest.class, "getMethod", objArr); |
| |
| if (ob2 != null) { |
| fail("failed in testRollbackTxnClear"); |
| } |
| }// end of testRollbackTxnClear |
| |
| @Test |
| public void testMiscMethods() throws Throwable { |
| Host host = Host.getHost(0); |
| VM vm0 = host.getVM(0); |
| VM vm1 = host.getVM(1); |
| vm0.invoke(CacheMapTxnDUnitTest::miscMethodsOwner); |
| // invoke in same vm but in separate thread |
| AsyncInvocation<Void> o2 = vm0.invokeAsync(CacheMapTxnDUnitTest::miscMethodsNotOwner); |
| // invoke in another vm |
| AsyncInvocation<Void> o3 = vm1.invokeAsync(CacheMapTxnDUnitTest::miscMethodsNotOwner); |
| |
| ThreadUtils.join(o2, 30 * 1000); |
| ThreadUtils.join(o3, 30 * 1000); |
| |
| if (o2.exceptionOccurred()) { |
| Assert.fail("o2 failed", o2.getException()); |
| } |
| |
| if (o3.exceptionOccurred()) { |
| Assert.fail("o3 failed", o3.getException()); |
| } |
| |
| }// end of testMiscMethods |
| |
| |
| // methods to be executed in remote vms...and called through vm.invoke |
| |
| public static void commitTxn() { |
| try { |
| cacheTxnMgr = cache.getCacheTransactionManager(); |
| int[] i = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
| Object o3; |
| o3 = "init"; |
| region.put("" + i[0], "zero"); |
| region.create("" + i[5], "fifth"); |
| // begin transaction |
| cacheTxnMgr.begin(); |
| region.put("" + i[1], "first"); |
| // test get |
| o3 = region.get("" + i[1]); |
| if (!(o3.toString().equals("first"))) { |
| fail("get inside transaction returns incorrect object"); |
| } |
| |
| // test remove |
| region.put("" + i[2], "second"); |
| o3 = region.remove("" + i[2]); |
| if (!(o3.toString().equals("second"))) { |
| fail("remove inside transaction returns incorrect object"); |
| } |
| |
| boolean flag = region.containsKey("" + i[2]); |
| if (flag) { |
| fail("region.containsKey after region.remove inside txn returns incorrect value"); |
| } |
| |
| region.put("" + i[3], "third"); |
| region.put("" + i[0], "updatedZero"); |
| |
| // test putIfAbsent |
| region.putIfAbsent("" + i[4], "fourth"); |
| if (!region.get("" + i[4]).toString().equals("fourth")) { |
| fail("putIfAbsent inside transaction returns incorrect object"); |
| } |
| |
| // test replace |
| region.replace("" + i[4], "fourth2"); |
| if (!region.get("" + i[4]).toString().equals("fourth2")) { |
| fail("replace inside transaction returns incorrect object)"); |
| } |
| |
| // test replace |
| region.replace("" + i[4], "fourth2", "fourth3"); |
| if (!region.get("" + i[4]).toString().equals("fourth3")) { |
| fail("replace inside transaction returns incorrect object)"); |
| } |
| |
| // test a failed removal |
| boolean succeeded = region.remove("" + i[5], new Object()); |
| assertTrue(!succeeded); |
| assertTrue(region.get("" + i[5]).equals("fifth")); |
| |
| // test remove |
| region.remove("" + i[5]); |
| |
| // commit the transaction |
| cacheTxnMgr.commit(); |
| |
| // verify for persistent data now |
| o3 = region.get("" + i[1]); |
| if (!(o3.toString().equals("first"))) { |
| fail("get after committed transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[2]); |
| if (o3 != null) { |
| fail("get after committed transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[3]); |
| if (!(o3.toString().equals("third"))) { |
| fail("get after committed transaction returns incorrect object"); |
| } |
| |
| if (!region.get("" + i[4]).toString().equals("fourth3")) { |
| fail("get after committed transaction returns incorrect object"); |
| } |
| |
| if (region.containsKey("" + i[5])) { |
| fail("containsKey after committed transaction was true"); |
| } |
| |
| boolean val = region.containsValue("updatedZero"); |
| if (!val) { |
| fail("containsValue after committed transaction returns incorrect result"); |
| } |
| |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } finally { |
| if (cacheTxnMgr.exists()) { |
| try { |
| cacheTxnMgr.commit(); |
| } catch (Exception cce) { |
| cce.printStackTrace(); |
| } |
| } |
| } |
| |
| }// end of commitTxn |
| |
| |
| public static void rollbackTxn() { |
| try { |
| cacheTxnMgr = cache.getCacheTransactionManager(); |
| int[] i = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
| Object o3; |
| o3 = "init"; |
| region.put("" + i[0], "zero"); |
| region.put("" + i[5], "fifth"); |
| cacheTxnMgr.begin(); |
| region.put("" + i[1], "first"); |
| // test get |
| o3 = region.get("" + i[1]); |
| if (!(o3.toString().equals("first"))) { |
| fail("get inside transaction returns incorrect object"); |
| } |
| |
| // test containsValue |
| boolean flag = region.containsValue("first"); |
| // assertIndexDetailsEquals(true, flag); |
| |
| // test remove |
| region.put("" + i[2], "second"); |
| o3 = region.remove("" + i[2]); |
| if (!(o3.toString().equals("second"))) { |
| fail("remove inside transaction returns incorrect object"); |
| } |
| |
| region.put("" + i[3], "third"); |
| region.put("" + i[0], "updatedZero"); |
| |
| |
| // test putIfAbsent |
| region.putIfAbsent("" + i[4], "fourth"); |
| if (!region.get("" + i[4]).toString().equals("fourth")) { |
| fail("putIfAbsent inside transaction returns incorrect object"); |
| } |
| |
| // test replace |
| region.replace("" + i[4], "fourth2"); |
| if (!region.get("" + i[4]).toString().equals("fourth2")) { |
| fail("replace inside transaction returns incorrect object)"); |
| } |
| |
| // test replace |
| region.replace("" + i[4], "fourth2", "fourth3"); |
| if (!region.get("" + i[4]).toString().equals("fourth3")) { |
| fail("replace inside transaction returns incorrect object)"); |
| } |
| |
| // test a failed removal |
| boolean succeeded = region.remove("" + i[5], new Object()); |
| assertTrue(!succeeded); |
| assertTrue(region.get("" + i[5]).equals("fifth")); |
| |
| // test remove |
| region.remove("" + i[5]); |
| |
| // rollback the transaction |
| cacheTxnMgr.rollback(); |
| |
| // verify for persistent data now |
| o3 = region.get("" + i[1]); |
| if (o3 != null) { // null? |
| fail("get after rolled back transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[2]); |
| if (o3 != null) { // null? |
| fail("get after rolled back transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[3]); |
| if (o3 != null) { // null? |
| fail("get after rolled back transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[4]); |
| if (o3 != null) { // null? |
| fail("get after rolled back transaction returns incorrect object"); |
| } |
| |
| o3 = region.get("" + i[5]); |
| if (o3 == null) { |
| fail("get after rolled back transaction returns incorrect object"); |
| } |
| |
| // boolean val = region.containsValue("zero"); |
| // if( !val){ |
| // fail("containsValue after rolled back transaction returns incorrect result"); |
| // } |
| |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } finally { |
| if (cacheTxnMgr.exists()) { |
| try { |
| cacheTxnMgr.commit(); |
| } catch (Exception cce) { |
| cce.printStackTrace(); |
| } |
| } |
| } |
| |
| }// end of rollbackTxn |
| |
| public static void rollbackTxnClear() { |
| try { |
| cacheTxnMgr = cache.getCacheTransactionManager(); |
| int[] i = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
| region.put("" + i[0], "zero"); |
| // begin transaction |
| cacheTxnMgr.begin(); |
| region.put("" + i[1], "first"); |
| region.put("" + i[0], "updatedZero"); |
| |
| try { |
| region.clear(); // clear is not transactional operation |
| fail("excpected exception not thrown"); |
| } catch (UnsupportedOperationInTransactionException ignored) { |
| } |
| |
| // rollback the transaction |
| cacheTxnMgr.rollback(); |
| |
| // verify for persistent data now |
| |
| boolean val = region.containsValue("updatedZero"); |
| if (val) { |
| fail("containsValue after region.clear & rolled back transaction returns incorrect result"); |
| } |
| region.clear(); |
| val = region.containsValue("first"); |
| if (val) { |
| fail("containsValue after region.clear & rolled back transaction returns incorrect result"); |
| } |
| |
| } catch (Exception ex) { |
| cacheTxnMgr = null; |
| throw new AssertionError(ex); |
| } |
| |
| }// end of rollbackTxnClear |
| |
| public static void miscMethodsOwner() { |
| try { |
| cacheTxnMgr = cache.getCacheTransactionManager(); |
| int[] i = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
| region.clear(); |
| region.put("" + i[0], "zero"); |
| region.put("" + i[1], "first"); |
| region.put("" + i[2], "second"); |
| region.put("" + i[3], "third"); |
| |
| cacheTxnMgr.begin(); |
| region.put("" + i[4], "forth"); |
| region.put("" + i[5], "fifth"); |
| |
| // test size method |
| int j = region.size(); |
| if (j != 6) { |
| fail("region.size inside transaction returns incorrect results"); |
| } |
| |
| // test entrySet method |
| Set set = region.entrySet(); |
| int k = set.size(); |
| if (j != 6) { |
| fail("region.entrySet inside transaction returns incorrect results"); |
| } |
| |
| // test keySet method |
| set = region.keySet(); |
| k = set.size(); |
| if (j != 6) { |
| fail("region.keySet inside transaction returns incorrect results"); |
| } |
| |
| boolean val = region.containsValue("forth"); |
| if (!val) { |
| fail("containsValue inside transaction returns incorrect result"); |
| } |
| |
| // commit the transaction |
| cacheTxnMgr.rollback(); |
| |
| // verify for persistent data now |
| |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } finally { |
| if (cacheTxnMgr.exists()) { |
| try { |
| cacheTxnMgr.commit(); |
| } catch (Exception cce) { |
| cce.printStackTrace(); |
| } |
| } |
| } |
| |
| }// end of miscMethodsOwner |
| |
| public static void miscMethodsNotOwner() { |
| try { |
| // int [] i = {0,1,2,3,4,5,6,7,8,9}; |
| // it is assumed that there are already four committed entried inside region |
| // test size method |
| int j = region.size(); |
| if (j != 4) { |
| fail("region.size for not owner of transaction returns incorrect results, size is " + j |
| + " but expected 4"); |
| } |
| |
| // test entrySet method |
| Set set = region.entrySet(); |
| int k = set.size(); |
| if (j != 4) { |
| fail("region.entrySet for not owner of transaction returns incorrect results"); |
| } |
| |
| // test keySet method |
| set = region.keySet(); |
| k = set.size(); |
| if (j != 4) { |
| fail("region.keySet for not owner of transaction returns incorrect results"); |
| } |
| boolean val = region.containsKey("forth"); |
| if (val) { |
| fail("containsValue for not owner of transaction returns incorrect result"); |
| } |
| |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } |
| }// end of miscMethodsNotOwner |
| |
| |
| |
| // helper methods |
| public static Object putMethod(Object ob) { |
| Object obj = null; |
| try { |
| if (ob != null) { |
| String str = "first"; |
| obj = region.put(ob, str); |
| } |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } |
| return obj; |
| } |
| |
| public static Object getMethod(Object ob) { |
| Object obj = null; |
| try { |
| obj = region.get(ob); |
| } catch (Exception ex) { |
| throw new AssertionError(ex); |
| } |
| return obj; |
| } |
| |
| |
| }// end of test class |