[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