blob: 04d64eafe832873db32780ba2a3962aa33a25289 [file] [log] [blame]
/*
* 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