[jboss-cvs] JBossCache/tests/functional/org/jboss/cache/transaction ...
Manik Surtani
msurtani at jboss.com
Tue Dec 5 10:27:51 EST 2006
User: msurtani
Date: 06/12/05 10:27:51
Modified: tests/functional/org/jboss/cache/transaction Tag:
Branch_JBossCache_1_4_0 TransactionTest.java
Log:
Ported stuff from 1.3.0.SP4 + upgraded JGroups
Revision Changes Path
No revision
No revision
1.9.4.1 +285 -65 JBossCache/tests/functional/org/jboss/cache/transaction/TransactionTest.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TransactionTest.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/transaction/TransactionTest.java,v
retrieving revision 1.9
retrieving revision 1.9.4.1
diff -u -b -r1.9 -r1.9.4.1
--- TransactionTest.java 9 Feb 2006 16:01:45 -0000 1.9
+++ TransactionTest.java 5 Dec 2006 15:27:51 -0000 1.9.4.1
@@ -27,7 +27,7 @@
* Tests transactional access to a local TreeCache.
* Note: we use DummpyTranasctionManager to replace jta
*
- * @version $Id: TransactionTest.java,v 1.9 2006/02/09 16:01:45 bela Exp $
+ * @version $Id: TransactionTest.java,v 1.9.4.1 2006/12/05 15:27:51 msurtani Exp $
*/
public class TransactionTest extends TestCase {
TreeCache cache=null;
@@ -121,6 +121,40 @@
}
}
+ public void testGetAfterRemovalRollback() throws Exception
+ {
+ cache.put("/a/b", null);
+ assertTrue(cache.exists("/a/b"));
+ tx.begin();
+ cache.remove("/a/b");
+ assertFalse(cache.exists("/a/b"));
+ tx.rollback();
+ assertTrue(cache.exists("/a/b"));
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ // new tx in new thread
+ Thread th = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ cache.getTransactionManager().begin();
+ assertNotNull(cache.get("/a/b"));
+ cache.getTransactionManager().rollback();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail("Caught exception");
+ }
+ }
+ };
+
+ th.start();
+ th.join();
+
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
public void testRollbackTx2() {
try {
@@ -285,91 +319,275 @@
- public void testNodeDeletionRollback3() {
+ public void testNodeCreation() throws Exception {
+ GlobalTransaction gtx;
+ cache.put("/a/b", null);
+ tx.begin();
+ gtx=cache.getCurrentTransaction();
+ cache.put("/a/b/c", null);
+ assertLocked(gtx, "/a", false);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(gtx, "/a/b/c", true);
+ System.out.println("locks: " + cache.printLockInfo());
+ }
+
+
+ public void testNodeCreation2() throws Exception {
+ GlobalTransaction gtx;
+ tx.begin();
+ gtx=cache.getCurrentTransaction();
+ cache.put("/a/b/c", null);
+ assertLocked(gtx, "/a", true);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(gtx, "/a/b/c", true);
+ System.out.println("locks: " + cache.printLockInfo());
+ }
+
+
+ public void testNodeRemoval() {
GlobalTransaction gtx;
try {
+ cache.put("/a/b/c", null);
+ tx.begin();
+ gtx=cache.getCurrentTransaction();
+ cache.remove("/a/b/c"); // need to remove the node, not just the data in the node.
+ assertLocked(gtx, "/a", false);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(gtx, "/a/b/c", true);
+ System.out.println("locks: " + cache.printLockInfo());
+ }
+ catch(Throwable t) {
+ t.printStackTrace();
+ fail(t.toString());
+ }
+ }
+
+
+ public void testNodeRemoval2() {
+ GlobalTransaction gtx;
+ try {
+ cache.put("/a/b/c", null);
+ tx.begin();
+ gtx=cache.getCurrentTransaction();
+ cache.remove("/a/b"); // need to remove the node, not just the data in the node.
+ assertLocked(gtx, "/a", true);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(gtx, "/a/b/c", true);
+ System.out.println("locks: " + cache.printLockInfo());
+ }
+ catch(Throwable t) {
+ t.printStackTrace();
+ fail(t.toString());
+ }
+ }
+
+ public void testIntermediateNodeCreationOnWrite() throws Exception
+ {
+ cache.put("/a", null);
+ tx.begin();
+ cache.put("/a/b/c", null);
+ // expecting WLs on /a, /a/b and /a/b/c.
+ GlobalTransaction gtx=cache.getCurrentTransaction();
+ assertLocked(gtx, "/a", true);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(gtx, "/a/b/c", true);
+ tx.rollback();
+
+ }
+
+ public void testIntermediateNodeCreationOnRead() throws Exception
+ {
+ cache.put("/a", null);
+ tx.begin();
+ cache.get("/a/b/c");
+
+ // expecting RLs on /, /a
+ // /a/b, /a/b/c should NOT be created!
+ GlobalTransaction gtx=cache.getCurrentTransaction();
+ assertLocked(gtx, "/", false);
+ assertLocked(gtx, "/a", false);
+ assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
+ assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
+ tx.rollback();
+ assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
+ assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
+
+ }
+
+
+ public void testIntermediateNodeCreationOnRemove() throws Exception
+ {
+ cache.put("/a", null);
+ tx.begin();
+ cache.remove("/a/b/c");
+
+ // expecting RLs on /, /a
+ // /a/b, /a/b/c should NOT be created!
+ GlobalTransaction gtx=cache.getCurrentTransaction();
+ assertLocked(gtx, "/", false);
+ assertLocked(gtx, "/a", false);
+ assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
+ assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
+ tx.rollback();
+ assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b")));
+ assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c")));
+
+ }
+
+
+ public void testNodeDeletionRollback3() throws Exception{
+ GlobalTransaction gtx;
+ cache.put("/a/b/c1", null);
+
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);
+ assertLocked(gtx, "/a", false);
+ assertLocked(gtx, "/a/b", false);
+ assertLocked(gtx, "/a/b/c1", true);
cache.put("/a/b/c2", null);
- checkLock(gtx, "/a/b/c2", true);
+ assertLocked(gtx, "/a/b", true);
+ assertLocked(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);
+ assertLocked(gtx, "/a/b/c1", true);
+ assertLocked(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);
+ assertLocked(gtx, "/a/b/c1", true);
+ assertLocked(gtx, "/a/b/c1/one", true);
+ assertLocked(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);
+ assertLocked(gtx, "/a/b/c1", true);
+ assertLocked(gtx, "/a/b/c1/two", true);
+ assertLocked(gtx, "/a/b/c1/two/2", true);
+ assertLocked(gtx, "/a/b/c1/two/2/3", true);
+ assertLocked(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());
- }
+ assertTrue(cache.getChildrenNames("/a/b/c1").isEmpty());
+ Set cn = cache.getChildrenNames("/a/b");
+ assertEquals(1, cn.size());
+ assertEquals("c1", cn.iterator().next());
}
- public void testDoubleLocks() {
- try {
+ public void testDoubleLocks() throws Exception{
tx.begin();
+ GlobalTransaction gtx = cache.getCurrentTransaction();
cache.put("/a/b/c", null);
cache.put("/a/b/c", null);
DataNode n=cache.get("/a");
IdentityLock lock=n.getLock();
int num=lock.getReaderOwners().size();
- assertEquals(1, num);
+ assertEquals(0, num);
+ // make sure this is write locked.
+ assertLocked(gtx, "/a", true);
n=cache.get("/a/b");
lock=n.getLock();
num=lock.getReaderOwners().size();
- assertEquals(1, num);
- // added this here since we had stale gtxs lurking about. - Manik, 02Jan06
+ assertEquals(0, num);
+ // make sure this is write locked.
+ assertLocked(gtx, "/a/b", true);
+
+ n=cache.get("/a/b/c");
+ lock=n.getLock();
+ num=lock.getReaderOwners().size();
+ assertEquals(0, num);
+ // make sure this is write locked.
+ assertLocked(gtx, "/a/b/c", true);
+
tx.rollback();
- }
- catch(Throwable t) {
- t.printStackTrace();
- fail(t.toString());
- }
+ assertEquals(0, cache.getNumberOfLocksHeld());
}
- private void checkLock(Object owner, String fqn, boolean write_locked) throws Exception {
- DataNode n=cache.get(fqn);
+ private void assertLocked(Object owner, String fqn, boolean write_locked) throws Exception{
+ DataNode n=cache.peek(Fqn.fromString(fqn));
IdentityLock lock=n.getLock();
if(owner == null)
owner=Thread.currentThread();
- if(lock.isLocked() == false)
- throw new Exception("node " + fqn + " is not locked");
+ assertTrue("node " + fqn + " is not locked", lock.isLocked());
if(write_locked) {
- if(lock.isWriteLocked() == false)
- throw new Exception("node " + fqn + " is not write-locked");
+ assertTrue("node " + fqn + " is not write-locked" + (lock.isReadLocked() ? " but is read-locked instead!" : "!"), lock.isWriteLocked());
}
else {
- if(lock.isReadLocked() == false)
- throw new Exception("node " + fqn + " is not read-locked");
+ assertTrue("node " + fqn + " is not read-locked" + (lock.isWriteLocked() ? " but is write-locked instead!" : "!"), lock.isReadLocked());
+ }
+ assertTrue("owner " + owner + "is not owner", lock.isOwner(owner));
+ }
+
+ public void testConcurrentNodeAccessOnRemovalWithTx() throws Exception
+ {
+ cache.put("/a/b/c", null);
+ tx.begin();
+ cache.remove("/a/b/c");
+ // this node should now be locked.
+ Transaction t = cache.getTransactionManager().suspend();
+ Transaction t2 = null;
+ try
+ {
+ System.out.println(cache.printLockInfo());
+ // start a new tx
+ cache.getTransactionManager().begin();
+ t2 = cache.getTransactionManager().getTransaction();
+ cache.get("/a/b/c"); // should fail
+ t2.commit();
+ fail("Should not be able to get a hold of /a/b/c until the deleting tx completes");
+ }
+ catch (Exception e)
+ {
+ // expected
+ t2.commit();
+ }
+
+ cache.getTransactionManager().resume(t);
+ tx.rollback();
+
+ assertNotNull(cache.get("/a/b/c"));
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+
+ public void testConcurrentNodeAccessOnRemovalWithoutTx() throws Exception
+ {
+ cache.put("/a/b/c", null);
+ tx.begin();
+ cache.remove("/a/b/c");
+ // this node should now be locked.
+ Transaction t = cache.getTransactionManager().suspend();
+ Thread th = new Thread(){
+ public void run(){
+ try
+ {
+ System.out.println(cache.printLockInfo());
+ cache.get("/a/b/c"); // should fail
+
+ fail("Should not be able to get a hold of /a/b/c until the deleting tx completes");
+ }
+ catch (Exception e)
+ {
+ // expected
}
- if(lock.isOwner(owner) == false)
- throw new Exception("owner " + owner + "is not owner");
}
+ };
+
+ th.start();
+ th.join();
+
+ cache.getTransactionManager().resume(t);
+ tx.rollback();
+
+ assertNotNull(cache.get("/a/b/c"));
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+
public void testRemove() throws CacheException, SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
@@ -385,7 +603,9 @@
tx.begin();
cache.remove("/a/b/c");
System.out.println("locks held (after removing /a/b/c): \n" + cache.printLockInfo());
- assertEquals(2, cache.getNumberOfLocksHeld());
+ // this used to test for 2 locks held. After the fixes for JBCACHE-875 however, 2 more locks are acquired - for the root node as well as the deleted node.
+ // and since we would lock all children of the deleted node as well, we have 10 locks here.
+ assertEquals(10, cache.getNumberOfLocksHeld());
tx.commit();
System.out.println("locks held (after committing /a/b/c): \n" + cache.printLockInfo());
assertEquals(0, cache.getNumberOfLocksHeld());
@@ -406,7 +626,7 @@
System.out.println("locks held (before removing /a/b/c): \n" + cache.printLockInfo());
cache.remove("/a/b/c");
System.out.println("locks held (after removing /a/b/c): \n" + cache.printLockInfo());
- assertEquals(2, cache.getNumberOfLocksHeld());
+ assertEquals(10, cache.getNumberOfLocksHeld());
tx.rollback();
System.out.println("locks held (after rollback): \n" + cache.printLockInfo());
assertEquals(0, cache.getNumberOfLocksHeld());
@@ -594,7 +814,7 @@
cache.remove(FQN);
cache.put(FQN, "entry", "rollback");
tx.rollback();
- assertEquals("Node should keep the commited value", "commit", cache.get(FQN).get("entry")); // THIS FAILS
+ assertEquals("Node should keep the commited value", "commit", cache.get(FQN).get("entry"));
}
More information about the jboss-cvs-commits
mailing list