package org.jboss.test.cache.test.local;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.GlobalTransaction;
import org.jboss.cache.Node;
import org.jboss.cache.TreeCache;
import org.jboss.cache.lock.IdentityLock;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.transaction.DummyTransactionManager;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class TxUnitTestCase extends TestCase {
TreeCache cache=null;
UserTransaction tx=null;
Properties p=null;
String old_factory=null;
final String FACTORY="org.jboss.cache.transaction.DummyContextFactory";
public TxUnitTestCase(String name) {
super(name);
}
public void setUp() throws Exception {
super.setUp();
old_factory=System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
DummyTransactionManager.getInstance();
if(p == null) {
p=new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
}
tx=(UserTransaction)new InitialContext(p).lookup("UserTransaction");
cache=new TreeCache("test", null, 10000);
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
cache.setIsolationLevel(IsolationLevel.SERIALIZABLE);
cache.createService();
cache.startService();
}
public void tearDown() throws Exception {
super.tearDown();
if(cache != null)
cache.stopService();
DummyTransactionManager.destroy();
if(old_factory != null) {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory);
old_factory=null;
}
if(tx != null) {
try {
tx.rollback();
}
catch(Throwable t) {
}
tx=null;
}
}
public void testPutTx() {
try {
tx.begin();
cache.put("/a/b/c", "age", new Integer(38));
assertEquals(new Integer(38), cache.get("/a/b/c", "age"));
cache.put("/a/b/c", "age", new Integer(39));
tx.commit();
assertEquals(new Integer(39), cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRollbackTx1() {
try {
tx.begin();
cache.put("/a/b/c", "age", new Integer(38));
cache.put("/a/b/c", "age", new Integer(39));
tx.rollback();
assertNull(cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRollbackTx2() {
try {
tx.begin();
cache.put("/a/b/c", "age", new Integer(38));
cache.remove("/a/b/c", "age");
tx.rollback();
assertNull(cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRollbackTx2a() {
try {
cache.put("/a/b/c", "age", new Integer(38));
tx.begin();
cache.remove("/a/b/c", "age");
tx.rollback();
assertEquals(new Integer(38), cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRollbackTx3() {
try {
java.util.Map map1=new java.util.HashMap();
map1.put("age", new Integer(38));
java.util.Map map2=new java.util.HashMap();
map2.put("age", new Integer(39));
tx.begin();
cache.put("/a/b/c", map1);
cache.put("/a/b/c", map2);
tx.rollback();
assertNull(cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRollbackTx4() {
try {
Map map=new HashMap();
map.put("age", new Integer(38));
tx.begin();
cache.put("/a/b/c", map);
cache.remove("/a/b/c");
tx.rollback();
assertNull(cache.get("/a/b/c", "age"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testNodeCreationRollback() {
try {
tx.begin();
System.out.println("initial state:\n" + cache);
cache.put("/bela/ban", null);
System.out.println("after put():\n" + cache);
tx.rollback();
System.out.println("after rollback():\n" + cache);
assertNull("node should be not existent", cache.get("/bela/ban"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testNodeCreationRollback2() {
try {
cache.put("/bela/ban", null);
tx.begin();
cache.put("/bela/ban/michelle", null);
tx.rollback();
assertNotNull("node should be not null", cache.get("/bela/ban"));
assertNull("node should be not existent", cache.get("/bela/ban/michelle"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testNodeDeletionRollback() {
try {
cache.put("/a/b/c", null);
tx.begin();
cache.remove("/a/b/c");
assertNull(cache.get("/a/b/c"));
cache.remove("/a/b");
assertNull(cache.get("/a/b"));
cache.remove("/a");
assertNull(cache.get("/a"));
tx.rollback();
assertNotNull(cache.get("/a/b/c"));
assertNotNull(cache.get("/a/b"));
assertNotNull(cache.get("/a"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testNodeDeletionRollback2() {
try {
cache.put("/a/b/c", null);
cache.put("/a/b/c1", null);
cache.put("/a/b/c2", null);
tx.begin();
cache.remove("/a");
assertNull(cache.get("/a/b/c"));
assertNull(cache.get("/a/b/c1"));
assertNull(cache.get("/a/b/c2"));
assertNull(cache.get("/a/b"));
assertNull(cache.get("/a"));
Set children=cache.getChildrenNames("/a/b");
assertNull(children);
children=cache.getChildrenNames("/a");
assertNull(children);
tx.rollback();
assertNotNull(cache.get("/a"));
assertNotNull(cache.get("/a/b"));
assertNotNull(cache.get("/a/b/c"));
assertNotNull(cache.get("/a/b/c1"));
assertNotNull(cache.get("/a/b/c2"));
children=cache.getChildrenNames("/a/b");
assertTrue(children.size() == 3);
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testNodeDeletionRollback3() {
GlobalTransaction gtx;
try {
tx.begin();
gtx=cache.getCurrentTransaction();
cache.put("/a/b/c1", null);
checkLock(gtx, "/a", false);
checkLock(gtx, "/a/b", false);
checkLock(gtx, "/a/b/c1", true);
cache.put("/a/b/c2", null);
checkLock(gtx, "/a/b/c2", true);
cache.put("/a/b/c3", null);
cache.put("/a/b/c1/one", null);
checkLock(gtx, "/a/b/c1", true);
checkLock(gtx, "/a/b/c1/one", true);
cache.put("/a/b/c1/two", null);
cache.put("/a/b/c1/one/1", null);
checkLock(gtx, "/a/b/c1", true);
checkLock(gtx, "/a/b/c1/one", true);
checkLock(gtx, "/a/b/c1/one/1", true);
cache.put("/a/b/c1/two/2/3/4", null);
checkLock(gtx, "/a/b/c1", true);
checkLock(gtx, "/a/b/c1/two", true);
checkLock(gtx, "/a/b/c1/two/2", false);
checkLock(gtx, "/a/b/c1/two/2/3", false);
checkLock(gtx, "/a/b/c1/two/2/3/4", true);
System.out.println("locks: " + cache.printLockInfo());
cache.remove("/a/b");
tx.rollback();
assertNull(cache.getChildrenNames("/a/b"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testDoubleLocks() {
try {
tx.begin();
cache.put("/a/b/c", null);
cache.put("/a/b/c", null);
Node n=cache.get("/a");
IdentityLock lock=n.getImmutableLock();
int num=lock.getReaderOwners().size();
assertTrue(num == 1);
n=cache.get("/a/b");
lock=n.getImmutableLock();
num=lock.getReaderOwners().size();
assertTrue(num == 1);
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
private void checkLock(Object owner, String fqn, boolean write_locked) throws Exception {
Node n=cache.get(fqn);
IdentityLock lock=n.getImmutableLock();
if(owner == null)
owner=Thread.currentThread();
if(lock.isLocked() == false)
throw new Exception("node " + fqn + " is not locked");
if(write_locked) {
if(lock.isWriteLocked() == false)
throw new Exception("node " + fqn + " is not write-locked");
}
else {
if(lock.isReadLocked() == false)
throw new Exception("node " + fqn + " is not read-locked");
}
if(lock.isOwner(owner) == false)
throw new Exception("owner " + owner + "is not owner");
}
public void testRemoveKeyRollback() {
try {
cache.put("/bela/ban", "name", "Bela");
tx.begin();
cache.remove("/bela/ban", "name");
assertNull(cache.get("/bela/ban", "name"));
tx.rollback();
assertEquals("Bela", cache.get("/bela/ban", "name"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRemoveKeyRollback2() {
try {
Map m=new HashMap();
m.put("name", "Bela");
m.put("id", new Integer(322649));
cache.put("/bela/ban", m);
tx.begin();
cache.remove("/bela/ban", "name");
assertNull(cache.get("/bela/ban", "name"));
tx.rollback();
assertEquals("Bela", cache.get("/bela/ban", "name"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testRemoveKeyRollback3() {
try {
cache.put("/bela/ban", "name", "Bela");
tx.begin();
cache.put("/bela/ban", "name", "Michelle");
cache.remove("/bela/ban", "name");
assertNull(cache.get("/bela/ban", "name"));
tx.rollback();
assertEquals("Bela", cache.get("/bela/ban", "name"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testDoubleRemovalOfSameData() {
try {
tx.begin();
cache.put("/foo/1", "item", new Integer(1));
assertEquals(cache.get("/foo/1", "item"), new Integer(1));
cache.remove("/foo/1");
assertNull(cache.get("/foo/1", "item"));
cache.remove("/foo/1");
assertNull(cache.get("/foo/1", "item"));
tx.rollback();
assertFalse(cache.exists("/foo/1"));
assertNull(cache.get("/foo/1", "item"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testPutDataRollback1() {
try {
cache.put("/bela/ban", null); tx.begin();
Map m=new HashMap();
m.put("name", "Bela");
m.put("id", new Integer(322649));
cache.put("/bela/ban", m);
tx.rollback();
Node n=cache.get("/bela/ban");
if(n.getData() == null) return;
assertEquals("map should be empty", 0, n.getData().size());
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testputDataRollback2() {
Map m1, m2;
m1=new HashMap();
m1.put("name", "Bela");
m1.put("id", new Integer(322649));
m2=new HashMap();
m2.put("other", "bla");
m2.put("name", "Michelle");
try {
cache.put("/bela/ban", m1);
tx.begin();
cache.put("/bela/ban", m2);
Map tmp=cache.get("/bela/ban").getData();
assertTrue(tmp.size() == 3);
assertTrue(tmp.get("name").equals("Michelle"));
assertTrue(tmp.get("id").equals(new Integer(322649)));
assertTrue(tmp.get("other").equals("bla"));
tx.rollback();
tmp=cache.get("/bela/ban").getData();
assertTrue(tmp.size() == 2);
assertTrue(tmp.get("name").equals("Bela"));
assertTrue(tmp.get("id").equals(new Integer(322649)));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testPutRollback() {
try {
cache.put("/bela/ban", null); tx.begin();
cache.put("/bela/ban", "name", "Bela");
assertEquals("Bela", cache.get("/bela/ban", "name"));
tx.rollback();
assertNull(cache.get("/bela/ban", "name"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public void testPutRollback2() {
try {
cache.put("/bela/ban", "name", "Bela"); tx.begin();
cache.put("/bela/ban", "name", "Michelle");
assertEquals("Michelle", cache.get("/bela/ban", "name"));
tx.rollback();
assertEquals("Bela", cache.get("/bela/ban", "name"));
}
catch(Throwable t) {
t.printStackTrace();
fail(t.toString());
}
}
public static Test suite() throws Exception {
return new TestSuite(TxUnitTestCase.class);
}
public static void main(String[] args) throws Exception {
junit.textui.TestRunner.run(suite());
}
}