[jbosscache-commits] JBoss Cache SVN: r4461 - in core/branches/1.4.X/tests/functional/org/jboss/cache: lock/pessimistic and 1 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Sep 14 11:50:44 EDT 2007


Author: manik.surtani at jboss.com
Date: 2007-09-14 11:50:44 -0400 (Fri, 14 Sep 2007)
New Revision: 4461

Added:
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockNotReleasedTest.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockUpgradeTest.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/AsyncRollbackTxLockTest.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java
Log:
Added tests for a series of bugs, including JBCACHE-923, JBCACHE-1164, JBCACHE-1165, JBCACHE-1166, JBCACHE-1168, JBCACHE-1183.

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java	2007-09-14 15:50:44 UTC (rev 4461)
@@ -0,0 +1,107 @@
+package org.jboss.cache.lock.pessimistic;
+
+import junit.framework.TestCase;
+import org.jboss.cache.DummyTransactionManagerLookup;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.lock.IsolationLevel;
+
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ConcurrentPutRemoveTest extends TestCase
+{
+
+   private TransactionManager tm;
+
+   public ConcurrentPutRemoveTest(String s)
+   {
+      super(s);
+   }
+
+   private TreeCache cache;
+
+   protected void setUp() throws Exception
+   {
+      cache = new TreeCache();
+      cache.setCacheMode(TreeCache.LOCAL);
+      cache.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+      cache.setTransactionManagerLookup(new DummyTransactionManagerLookup());
+      cache.setLockAcquisitionTimeout(10000);
+      cache.create();
+      cache.start();
+      tm = cache.getTransactionManager();
+   }
+
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      cache.stop();
+      cache.destroy();
+   }
+
+   public void testLock() throws Exception
+   {
+      List threads = new ArrayList();
+      for (int x = 0; x < 2; x++)
+      {
+         SeparateThread t = new SeparateThread(x);
+         threads.add(t);
+         t.start();
+      }
+      for (Iterator i = threads.iterator(); i.hasNext();)
+      {
+         SeparateThread separateThread = (SeparateThread) i.next();
+         separateThread.join();
+         if (separateThread.getException() != null)
+         {
+            throw separateThread.getException();
+         }
+      }
+
+   }
+
+   private class SeparateThread extends Thread
+   {
+      Exception e = null;
+
+      private int num = 0;
+
+      public SeparateThread(int num)
+      {
+         this.num = num;
+      }
+
+      public Exception getException()
+      {
+         return e;
+      }
+
+      public void run()
+      {
+         Thread.currentThread().setName("Thread:" + num);
+         try
+         {
+            for (int x = 0; x < 1000; x++)
+            {
+               tm.begin();
+               System.out.println("R" + Thread.currentThread().getName());
+               //inside transaction
+               cache.remove("/a");
+               System.out.println("AR" + Thread.currentThread().getName());
+               tm.commit();
+               //outside transaction
+               System.out.println("P" + Thread.currentThread().getName());
+               cache.put("/a/b/c/d", "text" + x, "b");
+               System.out.println("AP" + Thread.currentThread().getName());
+            }
+         }
+         catch (Exception e)
+         {
+            this.e = e;
+         }
+      }
+   }
+
+}

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockNotReleasedTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockNotReleasedTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockNotReleasedTest.java	2007-09-14 15:50:44 UTC (rev 4461)
@@ -0,0 +1,175 @@
+package org.jboss.cache.lock.pessimistic;
+
+import junit.framework.TestCase;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.DummyTransactionManagerLookup;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.lock.IsolationLevel;
+
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+public class LockNotReleasedTest extends TestCase
+{
+   Random rand = new Random(System.currentTimeMillis());
+
+   private TransactionManager tm;
+
+   private TreeCache cache;
+
+   private void startTest() throws Exception
+   {
+      cache = new TreeCache();
+      cache.setCacheMode(TreeCache.LOCAL);
+      cache.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+      cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      cache.setLockAcquisitionTimeout(1000);
+      cache.create();
+      cache.start();
+      tm = cache.getTransactionManager();
+   }
+
+   public void tearDown() throws Exception
+   {
+      cache.stop();
+      cache.destroy();
+   }
+
+
+   public int getNumberOfLocksHeld()
+   {
+      return numLocks((Node) cache.getRoot());
+   }
+
+   private int numLocks(Node n)
+   {
+      int num = 0;
+      Map children;
+
+      if (n.getLock().isLocked())
+      {
+         num++;
+         System.out.println("Node [" + n.getFqn() + "] is locked");
+      }
+      if ((children = n.getChildren(true)) != null)
+      {
+         for (Iterator i = children.values().iterator(); i.hasNext();)
+         {
+            num += numLocks((Node) i.next());
+         }
+      }
+      return num;
+   }
+
+   public void testTransactionStorm() throws Exception
+   {
+      startTest();
+      List threads = new ArrayList();
+//		System.out.println(cache.getNumberOfLocksHeld());
+      assertEquals(0, getNumberOfLocksHeld());
+      while (true)
+      {
+         for (int x = 0; x < 2; x++)
+         {
+            WorkThread t = new WorkThread(x == 1);
+            threads.add(t);
+            t.start();
+         }
+         for (Iterator i = threads.iterator(); i.hasNext();)
+         {
+            WorkThread separateThread = (WorkThread) i.next();
+            separateThread.join();
+            if (separateThread.getException() != null)
+            {
+               //separateThread.getException().getMessage();
+            }
+         }
+         int locksNum = getNumberOfLocksHeld();
+//			System.out.println("Locks="+locksNum);
+         // checkpoint
+         if (cache.getNumberOfLocksHeld() > 0)
+         {
+            System.out.println("ERROR, locks=" + locksNum);
+            doDomethingOnCache(1);
+         }
+         assertEquals(0, locksNum);
+      }
+
+   }
+
+   private class WorkThread extends Thread
+   {
+      Exception e = null;
+
+      private boolean remove;
+
+      public WorkThread(boolean remove)
+      {
+         this.remove = remove;
+      }
+
+      public Exception getException()
+      {
+         return e;
+      }
+
+      public void run()
+      {
+         try
+         {
+            for (int x = 0; x < 100; x++)
+            {
+               tm.begin();
+               try
+               {
+                  doDomethingOnCache(x);
+               }
+               finally
+               {
+                  if (x % 3 == 0)
+                  {
+                     tm.commit();
+                  }
+                  else
+                  {
+                     tm.rollback();
+                  }
+               }
+            }
+         }
+         catch (Exception e)
+         {
+//				System.out.println(e.getMessage());
+            this.e = e;
+         }
+      }
+
+   }
+
+   private void doDomethingOnCache(int x) throws CacheException, InterruptedException
+   {
+      cache.put(Fqn.fromString("/a/b/c/a"), "text1" + x, "");
+      cache.remove(Fqn.fromString("/q/b/c/d"));
+      cache.put(Fqn.fromString("/a/b/c/b"), "text2" + x, "");
+      cache.remove(Fqn.fromString("/q/b/c/c"));
+      cache.put(Fqn.fromString("/a/b/c/c"), "text3" + x, "");
+      cache.remove(Fqn.fromString("/q/b/c/b"));
+      cache.put(Fqn.fromString("/a/b/c/d"), "text4" + x, "");
+      cache.remove(Fqn.fromString("/q/b/c/a"));
+      cache.put(Fqn.fromString("/q/b/c/a"), "text5" + x, "");
+      cache.remove(Fqn.fromString("/a/b/c/d"));
+      cache.put(Fqn.fromString("/q/b/c/b"), "text6" + x, "");
+      cache.remove(Fqn.fromString("/a/b/c/c"));
+      cache.put(Fqn.fromString("/q/b/c/c"), "text7" + x, "");
+      cache.remove(Fqn.fromString("/a/b/c/b"));
+      cache.put(Fqn.fromString("/q/b/c/d"), "text8" + x, "");
+      cache.remove(Fqn.fromString("/a/b/c/a"));
+   }
+
+}

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockUpgradeTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockUpgradeTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/LockUpgradeTest.java	2007-09-14 15:50:44 UTC (rev 4461)
@@ -0,0 +1,107 @@
+package org.jboss.cache.lock.pessimistic;
+
+import junit.framework.TestCase;
+import org.jboss.cache.DummyTransactionManagerLookup;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.transaction.DummyTransactionManager;
+
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Test behaviour of concurent put/remove
+ *
+ * @author jhalat
+ */
+public class LockUpgradeTest extends TestCase
+{
+
+   private TransactionManager tm;
+
+   public LockUpgradeTest(String s)
+   {
+      super(s);
+   }
+
+   private TreeCache cache;
+
+   protected void setUp() throws Exception
+   {
+      cache = new TreeCache();
+      cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      cache.start();
+      tm = DummyTransactionManager.getInstance();
+   }
+
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+      cache.stop();
+      cache.destroy();
+   }
+
+   public void testLock() throws Exception
+   {
+      List threads = new ArrayList();
+      for (int x = 0; x < 2; x++)
+      {
+         WorkThread t = new WorkThread(x == 1);
+         threads.add(t);
+         t.start();
+      }
+      for (Iterator i = threads.iterator(); i.hasNext();)
+      {
+         WorkThread separateThread = (WorkThread) i.next();
+         separateThread.join();
+         if (separateThread.getException() != null)
+         {
+            throw separateThread.getException();
+         }
+      }
+   }
+
+   private class WorkThread extends Thread
+   {
+      Exception e = null;
+
+      private boolean remove;
+
+      public WorkThread(boolean remove)
+      {
+         this.remove = remove;
+      }
+
+      public Exception getException()
+      {
+         return e;
+      }
+
+      public void run()
+      {
+         try
+         {
+            for (int x = 0; x < 1000; x++)
+            {
+               tm.begin();
+               if (remove)
+               {
+                  cache.remove("/a/b/c/d");
+                  cache.remove("/a");
+               }
+               else
+               {
+                  cache.put("/a/b/c/d", "key", "text" + x);
+               }
+               tm.commit();
+               Thread.sleep(1);
+            }
+         }
+         catch (Exception e)
+         {
+            this.e = e;
+         }
+      }
+   }
+}

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/AsyncRollbackTxLockTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/AsyncRollbackTxLockTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/AsyncRollbackTxLockTest.java	2007-09-14 15:50:44 UTC (rev 4461)
@@ -0,0 +1,89 @@
+package org.jboss.cache.transaction;
+
+import junit.framework.TestCase;
+import org.jboss.cache.TreeCache;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * Test behaviour of async rollback timeouted transaction
+ *
+ * @author <a href="mailto:jhalat at infovide.pl">Jacek Halat</a>
+ */
+public class AsyncRollbackTxLockTest extends TestCase
+{
+   private TreeCache cache;
+   private TransactionManager tm;
+
+   protected void setUp() throws Exception
+   {
+      cache = new TreeCache();
+
+      cache.setTransactionManagerLookupClass("org.jboss.cache.transaction.AsyncRollbackTransactionManagerLookup");
+      cache.startService();
+      tm = cache.getTransactionManager();
+      tm.setTransactionTimeout(2);
+   }
+
+   protected void tearDown()
+   {
+      try
+      {
+         if (tm != null && tm.getTransaction() != null)
+         {
+            try
+            {
+               tm.rollback();
+            }
+            catch (SystemException e)
+            {
+               // do nothing
+            }
+         }
+      }
+      catch (SystemException e)
+      {
+         // do nothing
+      }
+      if (cache != null) cache.stopService();
+      cache = null;
+      tm = null;
+   }
+
+
+   public void testTxTimeoutAndRemovePutAfter() throws Exception
+   {
+      Thread.currentThread().setName("Thread-0");
+      System.out.println("Main Thread:" + Thread.currentThread());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.setTransactionTimeout(1);//short transaction timeout
+      cache.put("/a/b/c/d", "k", "v");
+      tm.begin();
+      Transaction transaction = tm.getTransaction();
+      transaction.registerSynchronization(new Synchronization()
+      {
+
+         public void afterCompletion(int arg0)
+         {
+            System.out.println("Synchronization Thread:" + Thread.currentThread());
+         }
+
+         public void beforeCompletion()
+         {
+         }
+
+      });
+      assertNotNull(tm.getTransaction());
+      Thread.sleep(500);//transaction should be rolledback in another thread
+      cache.put("/a", "k", "v");
+      tm.rollback();
+      assertNull(tm.getTransaction());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      cache.put("/a", "k", "v");
+   }
+
+}
+

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java	2007-09-14 15:50:44 UTC (rev 4461)
@@ -0,0 +1,95 @@
+package org.jboss.cache.transaction;
+
+import junit.framework.TestCase;
+import org.jboss.cache.DummyTransactionManagerLookup;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * To test JBCACHE-923
+ *
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
+ */
+public class SimultaneousRollbackAndPutTest extends TestCase
+{
+   private TreeCache cache;
+   private TransactionManager tm;
+   private Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b");
+
+   protected void setUp() throws Exception
+   {
+      cache = new TreeCache();
+      cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      cache.start();
+      tm = cache.getTransactionManager();
+      cache.put(A, "k", "v");
+   }
+
+   protected void tearDown()
+   {
+      cache.stop();
+   }
+
+   public void testStaleLocks() throws Exception
+   {
+      // repeat this test several times.
+      for (int i = 0; i < 1000; i++)
+      {
+         System.out.println("In loop " + i);
+         doTest();
+         cache.remove(B);
+         cache.removeData(A);
+         cache.put(A, "k", "v");
+      }
+
+   }
+
+
+   private void doTest() throws Exception
+   {
+      // scenario:
+      // Thread starts tx in cache.  E.g., create and put into B
+      tm.begin();
+      final Transaction t = tm.getTransaction();
+      final List exceptions = new ArrayList();
+
+      cache.put(B, "k", "v");
+
+      // now the container should attempt to rollback the tx in a separate thread.
+      new Thread()
+      {
+         public void run()
+         {
+            try
+            {
+               t.rollback();
+            }
+            catch (Exception e)
+            {
+               exceptions.add(e);
+            }
+         }
+      }.start();
+
+      // now try and put stuff in the main thread again
+      cache.put(A, "k2", "v2");
+      try
+      {
+         tm.commit();
+      }
+      catch (RollbackException expected)
+      {
+         // this is expected.
+      }
+
+      assertEquals("No stale locks should be around", 0, cache.getNumberOfLocksHeld());
+
+      if (exceptions.size() > 0) throw ((Exception) exceptions.get(0));
+   }
+}




More information about the jbosscache-commits mailing list