[jbosscache-commits] JBoss Cache SVN: r6611 - in core/trunk/src: main/java/org/jboss/cache/jmx and 8 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Mon Aug 25 13:50:21 EDT 2008


Author: mircea.markus
Date: 2008-08-25 13:50:21 -0400 (Mon, 25 Aug 2008)
New Revision: 6611

Added:
   core/trunk/src/test/java/org/jboss/cache/multiplexer/PessimisticSyncReplTxTest.java
   core/trunk/src/test/java/org/jboss/cache/options/PessimisticFailSilentlyTest.java
   core/trunk/src/test/java/org/jboss/cache/options/PessimisticLockAcquisitionTimeoutTest.java
   core/trunk/src/test/java/org/jboss/cache/options/PessimisticSuppressLockingTest.java
   core/trunk/src/test/java/org/jboss/cache/replicated/PessimisticSyncReplTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AbortionTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AsyncRollbackTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/ConcurrentTransactionalTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/IsolationLevelNoneTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PessimisticTransactionTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PrepareTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/StatusUnknownTest.java
Removed:
   core/trunk/src/test/java/org/jboss/cache/multiplexer/SyncReplTxTest.java
   core/trunk/src/test/java/org/jboss/cache/options/FailSilentlyTest.java
   core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
   core/trunk/src/test/java/org/jboss/cache/options/SuppressLockingTest.java
   core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/AbortionTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/AsyncRollbackTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/ConcurrentTransactionalTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/IsolationLevelNoneTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/PrepareTxTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/StatusUnknownTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/TransactionTest.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java
   core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransaction.java
   core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransactionManager.java
   core/trunk/src/test/java/org/jboss/cache/notifications/RemoteCacheListenerTest.java
   core/trunk/src/test/java/org/jboss/cache/transaction/isolationlevels/IsolationLevelTestBase.java
Log:
fixed tests after changing default node locking  scheme to MVCC

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -176,6 +176,7 @@
     */
    private void removeNodeFromCacheLoader(Fqn fqn) throws Throwable
    {
+      if (fqn == null) return;
       InternalNode n;
       if (((n = dataContainer.peekInternalNode(fqn, true)) != null) && n.isDataLoaded() && loader.exists(fqn))
       {

Modified: core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -91,8 +91,8 @@
       int i = 0;
       if (log.isInfoEnabled())
       {
-         log.info("Processing class " + instance.getClass());
-         log.info("Number of attributes: " + atts.size());
+         log.trace("Processing class " + instance.getClass());
+         log.trace("Number of attributes: " + atts.size());
       }
       MBeanAttributeInfo info;
       for (AttributeEntry entry : atts.values())
@@ -101,7 +101,7 @@
          attrInfo[i++] = info;
          if (log.isInfoEnabled())
          {
-            log.info("Attribute " + info.getName()
+            log.trace("Attribute " + info.getName()
                   + "[r="
                   + info.isReadable()
                   + ",w="
@@ -120,10 +120,10 @@
       if (log.isInfoEnabled())
       {
          if (ops.size() > 0)
-            log.info("Operations are:");
+            log.trace("Operations are:");
          for (MBeanOperationInfo op : opInfo)
          {
-            log.info("Operation " + op.getReturnType() + " " + op.getName());
+            log.trace("Operation " + op.getReturnType() + " " + op.getName());
          }
       }
    }

Modified: core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransaction.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransaction.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransaction.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -24,7 +24,7 @@
 {
    private int status = Status.STATUS_UNKNOWN;
    private static final Log log = LogFactory.getLog(DummyTransaction.class);
-   DummyBaseTransactionManager tm_;
+   protected DummyBaseTransactionManager tm_;
 
    protected final Set<Synchronization> participants = new CopyOnWriteArraySet<Synchronization>();
 

Modified: core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransactionManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransactionManager.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/DummyTransactionManager.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -19,10 +19,10 @@
  */
 public class DummyTransactionManager extends DummyBaseTransactionManager
 {
-   static DummyTransactionManager instance = null;
-   static DummyUserTransaction utx = null;
+   protected static DummyTransactionManager instance = null;
+   protected  static DummyUserTransaction utx = null;
 
-   static Log log = LogFactory.getLog(DummyTransactionManager.class);
+   protected  static Log log = LogFactory.getLog(DummyTransactionManager.class);
 
    private static final long serialVersionUID = 4396695354693176535L;
 

Copied: core/trunk/src/test/java/org/jboss/cache/multiplexer/PessimisticSyncReplTxTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/multiplexer/SyncReplTxTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/multiplexer/PessimisticSyncReplTxTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/multiplexer/PessimisticSyncReplTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,77 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.cache.multiplexer;
+
+import org.jboss.cache.Cache;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Repeats the superclass tests, but with the multiplexer enabled.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision$
+ */
+ at Test(groups = {"functional", "jgroups"}, enabled = true)
+public class PessimisticSyncReplTxTest extends org.jboss.cache.replicated.PessimisticSyncReplTxTest
+{
+   private MultiplexerTestHelper muxHelper;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      muxHelper = new MultiplexerTestHelper();
+
+      super.setUp();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      try
+      {
+         super.tearDown();
+      }
+      finally
+      {
+         if (muxHelper != null)
+         {
+            muxHelper.tearDown();
+            muxHelper = null;
+         }
+      }
+   }
+
+   @Override
+   protected void configureMultiplexer(Cache cache) throws Exception
+   {
+      muxHelper.configureCacheForMux(cache);
+   }
+
+   @Override
+   protected void validateMultiplexer(Cache cache)
+   {
+      AssertJUnit.assertTrue("Cache is using multiplexer", cache.getConfiguration().isUsingMultiplexer());
+   }
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/multiplexer/PessimisticSyncReplTxTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Deleted: core/trunk/src/test/java/org/jboss/cache/multiplexer/SyncReplTxTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/multiplexer/SyncReplTxTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/multiplexer/SyncReplTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,77 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.cache.multiplexer;
-
-import org.jboss.cache.Cache;
-import org.testng.AssertJUnit;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * Repeats the superclass tests, but with the multiplexer enabled.
- *
- * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
- * @version $Revision$
- */
- at Test(groups = {"functional", "jgroups"}, enabled = true)
-public class SyncReplTxTest extends org.jboss.cache.replicated.SyncReplTxTest
-{
-   private MultiplexerTestHelper muxHelper;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      muxHelper = new MultiplexerTestHelper();
-
-      super.setUp();
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      try
-      {
-         super.tearDown();
-      }
-      finally
-      {
-         if (muxHelper != null)
-         {
-            muxHelper.tearDown();
-            muxHelper = null;
-         }
-      }
-   }
-
-   @Override
-   protected void configureMultiplexer(Cache cache) throws Exception
-   {
-      muxHelper.configureCacheForMux(cache);
-   }
-
-   @Override
-   protected void validateMultiplexer(Cache cache)
-   {
-      AssertJUnit.assertTrue("Cache is using multiplexer", cache.getConfiguration().isUsingMultiplexer());
-   }
-}

Modified: core/trunk/src/test/java/org/jboss/cache/notifications/RemoteCacheListenerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/RemoteCacheListenerTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/RemoteCacheListenerTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -615,6 +615,7 @@
       expected.add(new EventImpl(false, cache1, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
       expected.add(new EventImpl(true, cache1, null, null, fqn, tx, true, newFqn, false, null, NODE_MOVED));
       expected.add(new EventImpl(false, cache1, null, null, fqn, tx, true, newFqn, false, null, NODE_MOVED));
+      assertEquals(expected.size(), eventLog1.events.size());
       assertEquals(expected, eventLog1.events);
       assertEquals("Events log should be empty until commit time", 0, eventLog2.events.size());
       tm1.commit();

Deleted: core/trunk/src/test/java/org/jboss/cache/options/FailSilentlyTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/FailSilentlyTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/options/FailSilentlyTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,167 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.options;
-
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import static org.testng.AssertJUnit.assertEquals;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests passing in the failSilently option in various scenarios.
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- */
- at Test(groups = {"functional"})
-public class FailSilentlyTest
-{
-   private CacheSPI cache;
-   private TransactionManager manager;
-   private Transaction tx;
-   private Fqn fqn = Fqn.fromString("/a");
-   private String key = "key";
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      if (cache != null)
-         tearDown();
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI) instance.createCache(false);
-      // very short acquisition timeout
-      cache.getConfiguration().setLockAcquisitionTimeout(100);
-      cache.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
-      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
-      cache.start();
-      manager = cache.getTransactionManager();
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown()
-   {
-      if (tx != null)
-      {
-         try
-         {
-            manager.resume(tx);
-            manager.rollback();
-         }
-         catch (Exception e)
-         {
-            // who cares
-         }
-      }
-      if (cache != null)
-      {
-         cache.stop();
-         cache = null;
-      }
-   }
-
-   public void testPutKeyValue() throws Exception
-   {
-      manager.begin();
-      cache.put(fqn, key, "value");
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.put(fqn, key, "value2");
-   }
-
-   public void testPutData() throws Exception
-   {
-      Map<String, String> data = new HashMap<String, String>();
-      data.put(key, "value");
-      manager.begin();
-      cache.put(fqn, data);
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.put(fqn, data);
-   }
-
-   public void testRemoveNode() throws Exception
-   {
-      cache.put(fqn, key, "value");
-      manager.begin();
-      // get a read lock
-      cache.get(fqn, key);
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.removeNode(fqn);
-   }
-
-   public void testRemoveKey() throws Exception
-   {
-      cache.put(fqn, key, "value");
-      manager.begin();
-      // get a read lock
-      cache.get(fqn, key);
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.remove(fqn, key);
-   }
-
-   public void testGetNode() throws Exception
-   {
-      cache.put(fqn, key, "value");
-      manager.begin();
-      // get a WL
-      cache.put(fqn, key, "value2");
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.getNode(fqn);
-   }
-
-   public void testGetKey() throws Exception
-   {
-      cache.put(fqn, key, "value");
-      manager.begin();
-      // get a WL
-      cache.put(fqn, key, "value2");
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.get(fqn, key);
-   }
-
-   public void testGetChildrenNames() throws Exception
-   {
-      cache.put(fqn, key, "value");
-      manager.begin();
-      // get a WL
-      cache.put(fqn, key, "value2");
-      tx = manager.suspend();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.getChildrenNames(fqn);
-
-   }
-
-   public void testPutThatWillFail() throws Exception
-   {
-      manager.begin();
-      cache.put(fqn, "k", "v");// this will get WLs on / and /a
-      tx = manager.suspend();
-
-      assertEquals(2, cache.getNumberOfLocksHeld());
-
-      // now this call WILL fail, but should fail silently - i.e., not roll back.
-      manager.begin();
-      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
-      cache.put(fqn, "x", "y");
-
-      // should not roll back, despite the cache put call failing/timing out.
-      manager.commit();
-   }
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,359 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.options;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.Option;
-import org.jboss.cache.lock.TimeoutException;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.TransactionManager;
-
-/**
- * Test functionality of {@link Option#setLockAcquisitionTimeout(int)}.
- *
- * @author Brian Stansberry
- */
- at Test(groups = {"functional"})
-public class LockAcquisitionTimeoutTest
-{
-   private static final Log log = LogFactory.getLog(LockAcquisitionTimeoutTest.class);
-
-   private static final Fqn FQNA = Fqn.fromString("/A");
-   private static final Fqn FQNB = Fqn.fromString("/B");
-   private static final String KEY = "key";
-   private static final String VALUE1 = "value1";
-   private static final String VALUE2 = "value2";
-
-   private CacheSPI<Object, Object> cache;
-   private Option option;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
-      Configuration c = cache.getConfiguration();
-      c.setCacheMode("REPL_SYNC");
-      c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
-
-      cache.start();
-
-      option = new Option();
-      option.setLockAcquisitionTimeout(0);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown()
-   {
-      if (cache != null)
-      {
-         cache.stop();
-         cache = null;
-      }
-   }
-
-   /**
-    * Confirms that doing a put with a lockAcquisitionTime option set
-    * does the put as expected. There is no other thread or tx contesting
-    * the lock the put needs, so this is just a simple test that the option
-    * doesn't somehow screw up the put.
-    *
-    * @throws Exception
-    */
-   public void testSimplePut() throws Exception
-   {
-      log.info("++++ testSimplePut() ++++");
-      simplePutTest(false);
-   }
-
-   /**
-    * Confirms that doing a put with a lockAcquisitionTime option set
-    * does the put as expected when executed within a transaction. There is no
-    * other thread or tx contesting the lock the put needs, so this is just a
-    * simple test that the option doesn't somehow screw up the put.
-    *
-    * @throws Exception
-    */
-   public void testSimplePutWithTx() throws Exception
-   {
-      log.info("++++ testSimplePutWithTx() ++++");
-      simplePutTest(true);
-   }
-
-   private void simplePutTest(boolean useTx) throws Exception
-   {
-      TransactionManager tm = useTx ? cache.getTransactionManager() : null;
-      LowTimeoutSetter setter = new LowTimeoutSetter(tm);
-      setter.start();
-
-      setter.join(2000);
-      if (!setter.finished)
-      {
-         setter.interrupt();
-         fail("Puts failed to complete in a timely manner");
-      }
-
-      assertNull("LowTimeoutSetter saw no TimeoutException", setter.te);
-      assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
-      assertEquals("Cache correct for " + FQNA, VALUE2, cache.get(FQNA, KEY));
-      assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
-   }
-
-   /**
-    * Confirms that a put with a lockAcquisitionTimeout option set to zero
-    * fails promptly in the presence of a lock on the target node.
-    *
-    * @throws Exception
-    */
-   public void testContestedPut() throws Exception
-   {
-      log.info("++++ testContestedPut() ++++");
-      contestedPutTest(false);
-   }
-
-   /**
-    * Confirms that a put with a lockAcquisitionTimeout option set to zero
-    * is ignored if executed within a transaction.
-    *
-    * @throws Exception
-    */
-   public void testContestedPutWithTx() throws Exception
-   {
-      log.info("++++ testContestedPutWithTx() ++++");
-      contestedPutTest(true);
-   }
-
-   private void contestedPutTest(boolean tx) throws Exception
-   {
-      TransactionManager mgr = cache.getTransactionManager();
-      mgr.begin();
-
-      LowTimeoutSetter setter = null;
-      try
-      {
-         // Put a WL on /A
-         cache.put(FQNA, KEY, VALUE1);
-
-         // Launch a thread that tries to write to /A
-         setter = new LowTimeoutSetter(tx ? mgr : null);
-         setter.start();
-
-         setter.join(2000);
-         if (!setter.finished)
-         {
-            setter.interrupt();
-            fail("Puts failed to complete in a timely manner");
-         }
-      }
-      finally
-      {
-         // always commit the tx
-         mgr.commit();
-      }
-
-      assertNotNull("LowTimeoutSetter saw TimeoutException", setter.te);
-      assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
-      assertEquals("Cache correct for " + FQNA, VALUE1, cache.get(FQNA, KEY));
-      assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
-
-   }
-
-   public void testSimpleRead() throws Exception
-   {
-      log.info("++++++ testSimpleRead() ++++++");
-      simpleReadTest(false);
-   }
-
-   public void testSimpleReadWithTx() throws Exception
-   {
-      log.info("++++++ testSimpleReadWithTx() ++++++");
-      simpleReadTest(true);
-   }
-
-   private void simpleReadTest(boolean useTx) throws Exception
-   {
-      TransactionManager tm = useTx ? cache.getTransactionManager() : null;
-      LowTimeoutReader reader = new LowTimeoutReader(tm);
-
-      cache.put(FQNA, KEY, VALUE1);
-
-      reader.start();
-
-      reader.join(2000);
-      if (!reader.finished)
-      {
-         reader.interrupt();
-         fail("Read failed to complete in a timely manner");
-      }
-
-      assertNull("LowTimeoutSetter saw no TimeoutException", reader.te);
-      assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
-      assertEquals("LowTimeoutSetter correct for " + FQNA, VALUE1, reader.value);
-
-   }
-
-   public void testContestedRead() throws Exception
-   {
-      log.info("++++++ testContestedRead() ++++++");
-      contestedReadTest(false);
-   }
-
-   public void testContestedReadWithTx() throws Exception
-   {
-      log.info("++++++ testContestedReadWithTx() ++++++");
-      contestedReadTest(true);
-   }
-
-   private void contestedReadTest(boolean tx) throws Exception
-   {
-      TransactionManager mgr = cache.getTransactionManager();
-      mgr.begin();
-
-      LowTimeoutReader reader = null;
-      try
-      {
-         // Put a WL on /A
-         cache.put(FQNA, KEY, VALUE1);
-
-         // Launch a thread that tries to read from /A
-         reader = new LowTimeoutReader(tx ? mgr : null);
-         reader.start();
-
-         reader.join(2000);
-         if (!reader.finished)
-         {
-            reader.interrupt();
-            fail("Read failed to complete in a timely manner");
-         }
-      }
-      finally
-      {
-         // always commit the tx
-         mgr.commit();
-      }
-
-      assertNotNull("LowTimeoutSetter saw TimeoutException", reader.te);
-      assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
-      assertNull("LowTimeoutSetter unable to read " + FQNA, reader.value);
-
-   }
-
-   class LowTimeoutSetter extends Thread
-   {
-      TransactionManager tm;
-      TimeoutException te;
-      Throwable failure;
-      boolean finished;
-
-      LowTimeoutSetter(TransactionManager tm)
-      {
-         this.tm = tm;
-      }
-
-      public void run()
-      {
-         try
-         {
-            try
-            {
-               if (tm != null)
-               {
-                  tm.begin();
-               }
-
-               cache.put(FQNB, KEY, VALUE2);
-
-               cache.getInvocationContext().setOptionOverrides(option);
-               cache.put(FQNA, KEY, VALUE2);
-            }
-            catch (TimeoutException te)
-            {
-               this.te = te;
-            }
-            catch (Exception e)
-            {
-               if (tm != null)
-                  tm.setRollbackOnly();
-               throw e;
-            }
-            finally
-            {
-               if (tm != null)
-               {
-                  tm.commit();
-               }
-               finished = true;
-            }
-         }
-         catch (Throwable t)
-         {
-            failure = t;
-         }
-      }
-   }
-
-   class LowTimeoutReader extends Thread
-   {
-      TransactionManager tm;
-      TimeoutException te;
-      Throwable failure;
-      Object value;
-      boolean finished;
-
-      LowTimeoutReader(TransactionManager tm)
-      {
-         this.tm = tm;
-      }
-
-      public void run()
-      {
-         try
-         {
-            try
-            {
-               if (tm != null)
-               {
-                  tm.begin();
-               }
-
-               cache.getInvocationContext().setOptionOverrides(option);
-               value = cache.get(FQNA, KEY);
-            }
-            catch (TimeoutException te)
-            {
-               this.te = te;
-            }
-            catch (Exception e)
-            {
-               if (tm != null)
-                  tm.setRollbackOnly();
-               throw e;
-            }
-            finally
-            {
-               if (tm != null)
-               {
-                  tm.commit();
-               }
-               finished = true;
-            }
-         }
-         catch (Throwable t)
-         {
-            failure = t;
-         }
-      }
-   }
-}

Copied: core/trunk/src/test/java/org/jboss/cache/options/PessimisticFailSilentlyTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/options/FailSilentlyTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/PessimisticFailSilentlyTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/options/PessimisticFailSilentlyTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.options;
+
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import static org.testng.AssertJUnit.assertEquals;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests passing in the failSilently option in various scenarios.
+ *
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ */
+ at Test(groups = {"functional"})
+public class PessimisticFailSilentlyTest
+{
+   private CacheSPI cache;
+   private TransactionManager manager;
+   private Transaction tx;
+   private Fqn fqn = Fqn.fromString("/a");
+   private String key = "key";
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      if (cache != null)
+         tearDown();
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache = (CacheSPI) instance.createCache(false);
+      // very short acquisition timeout
+      cache.getConfiguration().setLockAcquisitionTimeout(100);
+      cache.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.start();
+      manager = cache.getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      if (tx != null)
+      {
+         try
+         {
+            manager.resume(tx);
+            manager.rollback();
+         }
+         catch (Exception e)
+         {
+            // who cares
+         }
+      }
+      if (cache != null)
+      {
+         cache.stop();
+         cache = null;
+      }
+   }
+
+   public void testPutKeyValue() throws Exception
+   {
+      manager.begin();
+      cache.put(fqn, key, "value");
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.put(fqn, key, "value2");
+   }
+
+   public void testPutData() throws Exception
+   {
+      Map<String, String> data = new HashMap<String, String>();
+      data.put(key, "value");
+      manager.begin();
+      cache.put(fqn, data);
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.put(fqn, data);
+   }
+
+   public void testRemoveNode() throws Exception
+   {
+      cache.put(fqn, key, "value");
+      manager.begin();
+      // get a read lock
+      cache.get(fqn, key);
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.removeNode(fqn);
+   }
+
+   public void testRemoveKey() throws Exception
+   {
+      cache.put(fqn, key, "value");
+      manager.begin();
+      // get a read lock
+      cache.get(fqn, key);
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.remove(fqn, key);
+   }
+
+   public void testGetNode() throws Exception
+   {
+      cache.put(fqn, key, "value");
+      manager.begin();
+      // get a WL
+      cache.put(fqn, key, "value2");
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.getNode(fqn);
+   }
+
+   public void testGetKey() throws Exception
+   {
+      cache.put(fqn, key, "value");
+      manager.begin();
+      // get a WL
+      cache.put(fqn, key, "value2");
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.get(fqn, key);
+   }
+
+   public void testGetChildrenNames() throws Exception
+   {
+      cache.put(fqn, key, "value");
+      manager.begin();
+      // get a WL
+      cache.put(fqn, key, "value2");
+      tx = manager.suspend();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.getChildrenNames(fqn);
+
+   }
+
+   public void testPutThatWillFail() throws Exception
+   {
+      manager.begin();
+      cache.put(fqn, "k", "v");// this will get WLs on / and /a
+      tx = manager.suspend();
+
+      assertEquals(2, cache.getNumberOfLocksHeld());
+
+      // now this call WILL fail, but should fail silently - i.e., not roll back.
+      manager.begin();
+      cache.getInvocationContext().getOptionOverrides().setFailSilently(true);
+      cache.put(fqn, "x", "y");
+
+      // should not roll back, despite the cache put call failing/timing out.
+      manager.commit();
+   }
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/options/PessimisticFailSilentlyTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/options/PessimisticLockAcquisitionTimeoutTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/PessimisticLockAcquisitionTimeoutTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/options/PessimisticLockAcquisitionTimeoutTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,360 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.options;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.TimeoutException;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * Test functionality of {@link Option#setLockAcquisitionTimeout(int)}.
+ *
+ * @author Brian Stansberry
+ */
+ at Test(groups = {"functional"})
+public class PessimisticLockAcquisitionTimeoutTest
+{
+   private static final Log log = LogFactory.getLog(PessimisticLockAcquisitionTimeoutTest.class);
+
+   private static final Fqn FQNA = Fqn.fromString("/A");
+   private static final Fqn FQNB = Fqn.fromString("/B");
+   private static final String KEY = "key";
+   private static final String VALUE1 = "value1";
+   private static final String VALUE2 = "value2";
+
+   private CacheSPI<Object, Object> cache;
+   private Option option;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
+      Configuration c = cache.getConfiguration();
+      c.setCacheMode("REPL_SYNC");
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+
+      cache.start();
+
+      option = new Option();
+      option.setLockAcquisitionTimeout(0);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      if (cache != null)
+      {
+         cache.stop();
+         cache = null;
+      }
+   }
+
+   /**
+    * Confirms that doing a put with a lockAcquisitionTime option set
+    * does the put as expected. There is no other thread or tx contesting
+    * the lock the put needs, so this is just a simple test that the option
+    * doesn't somehow screw up the put.
+    *
+    * @throws Exception
+    */
+   public void testSimplePut() throws Exception
+   {
+      log.info("++++ testSimplePut() ++++");
+      simplePutTest(false);
+   }
+
+   /**
+    * Confirms that doing a put with a lockAcquisitionTime option set
+    * does the put as expected when executed within a transaction. There is no
+    * other thread or tx contesting the lock the put needs, so this is just a
+    * simple test that the option doesn't somehow screw up the put.
+    *
+    * @throws Exception
+    */
+   public void testSimplePutWithTx() throws Exception
+   {
+      log.info("++++ testSimplePutWithTx() ++++");
+      simplePutTest(true);
+   }
+
+   private void simplePutTest(boolean useTx) throws Exception
+   {
+      TransactionManager tm = useTx ? cache.getTransactionManager() : null;
+      LowTimeoutSetter setter = new LowTimeoutSetter(tm);
+      setter.start();
+
+      setter.join(2000);
+      if (!setter.finished)
+      {
+         setter.interrupt();
+         fail("Puts failed to complete in a timely manner");
+      }
+
+      assertNull("LowTimeoutSetter saw no TimeoutException", setter.te);
+      assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
+      assertEquals("Cache correct for " + FQNA, VALUE2, cache.get(FQNA, KEY));
+      assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
+   }
+
+   /**
+    * Confirms that a put with a lockAcquisitionTimeout option set to zero
+    * fails promptly in the presence of a lock on the target node.
+    *
+    * @throws Exception
+    */
+   public void testContestedPut() throws Exception
+   {
+      log.info("++++ testContestedPut() ++++");
+      contestedPutTest(false);
+   }
+
+   /**
+    * Confirms that a put with a lockAcquisitionTimeout option set to zero
+    * is ignored if executed within a transaction.
+    *
+    * @throws Exception
+    */
+   public void testContestedPutWithTx() throws Exception
+   {
+      log.info("++++ testContestedPutWithTx() ++++");
+      contestedPutTest(true);
+   }
+
+   private void contestedPutTest(boolean tx) throws Exception
+   {
+      TransactionManager mgr = cache.getTransactionManager();
+      mgr.begin();
+
+      LowTimeoutSetter setter = null;
+      try
+      {
+         // Put a WL on /A
+         cache.put(FQNA, KEY, VALUE1);
+
+         // Launch a thread that tries to write to /A
+         setter = new LowTimeoutSetter(tx ? mgr : null);
+         setter.start();
+
+         setter.join(2000);
+         if (!setter.finished)
+         {
+            setter.interrupt();
+            fail("Puts failed to complete in a timely manner");
+         }
+      }
+      finally
+      {
+         // always commit the tx
+         mgr.commit();
+      }
+
+      assertNotNull("LowTimeoutSetter saw TimeoutException", setter.te);
+      assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
+      assertEquals("Cache correct for " + FQNA, VALUE1, cache.get(FQNA, KEY));
+      assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
+
+   }
+
+   public void testSimpleRead() throws Exception
+   {
+      log.info("++++++ testSimpleRead() ++++++");
+      simpleReadTest(false);
+   }
+
+   public void testSimpleReadWithTx() throws Exception
+   {
+      log.info("++++++ testSimpleReadWithTx() ++++++");
+      simpleReadTest(true);
+   }
+
+   private void simpleReadTest(boolean useTx) throws Exception
+   {
+      TransactionManager tm = useTx ? cache.getTransactionManager() : null;
+      LowTimeoutReader reader = new LowTimeoutReader(tm);
+
+      cache.put(FQNA, KEY, VALUE1);
+
+      reader.start();
+
+      reader.join(2000);
+      if (!reader.finished)
+      {
+         reader.interrupt();
+         fail("Read failed to complete in a timely manner");
+      }
+
+      assertNull("LowTimeoutSetter saw no TimeoutException", reader.te);
+      assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
+      assertEquals("LowTimeoutSetter correct for " + FQNA, VALUE1, reader.value);
+
+   }
+
+   public void testContestedRead() throws Exception
+   {
+      log.info("++++++ testContestedRead() ++++++");
+      contestedReadTest(false);
+   }
+
+   public void testContestedReadWithTx() throws Exception
+   {
+      log.info("++++++ testContestedReadWithTx() ++++++");
+      contestedReadTest(true);
+   }
+
+   private void contestedReadTest(boolean tx) throws Exception
+   {
+      TransactionManager mgr = cache.getTransactionManager();
+      mgr.begin();
+
+      LowTimeoutReader reader = null;
+      try
+      {
+         // Put a WL on /A
+         cache.put(FQNA, KEY, VALUE1);
+
+         // Launch a thread that tries to read from /A
+         reader = new LowTimeoutReader(tx ? mgr : null);
+         reader.start();
+
+         reader.join(2000);
+         if (!reader.finished)
+         {
+            reader.interrupt();
+            fail("Read failed to complete in a timely manner");
+         }
+      }
+      finally
+      {
+         // always commit the tx
+         mgr.commit();
+      }
+
+      assertNotNull("LowTimeoutSetter saw TimeoutException", reader.te);
+      assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
+      assertNull("LowTimeoutSetter unable to read " + FQNA, reader.value);
+
+   }
+
+   class LowTimeoutSetter extends Thread
+   {
+      TransactionManager tm;
+      TimeoutException te;
+      Throwable failure;
+      boolean finished;
+
+      LowTimeoutSetter(TransactionManager tm)
+      {
+         this.tm = tm;
+      }
+
+      public void run()
+      {
+         try
+         {
+            try
+            {
+               if (tm != null)
+               {
+                  tm.begin();
+               }
+
+               cache.put(FQNB, KEY, VALUE2);
+
+               cache.getInvocationContext().setOptionOverrides(option);
+               cache.put(FQNA, KEY, VALUE2);
+            }
+            catch (TimeoutException te)
+            {
+               this.te = te;
+            }
+            catch (Exception e)
+            {
+               if (tm != null)
+                  tm.setRollbackOnly();
+               throw e;
+            }
+            finally
+            {
+               if (tm != null)
+               {
+                  tm.commit();
+               }
+               finished = true;
+            }
+         }
+         catch (Throwable t)
+         {
+            failure = t;
+         }
+      }
+   }
+
+   class LowTimeoutReader extends Thread
+   {
+      TransactionManager tm;
+      TimeoutException te;
+      Throwable failure;
+      Object value;
+      boolean finished;
+
+      LowTimeoutReader(TransactionManager tm)
+      {
+         this.tm = tm;
+      }
+
+      public void run()
+      {
+         try
+         {
+            try
+            {
+               if (tm != null)
+               {
+                  tm.begin();
+               }
+
+               cache.getInvocationContext().setOptionOverrides(option);
+               value = cache.get(FQNA, KEY);
+            }
+            catch (TimeoutException te)
+            {
+               this.te = te;
+            }
+            catch (Exception e)
+            {
+               if (tm != null)
+                  tm.setRollbackOnly();
+               throw e;
+            }
+            finally
+            {
+               if (tm != null)
+               {
+                  tm.commit();
+               }
+               finished = true;
+            }
+         }
+         catch (Throwable t)
+         {
+            failure = t;
+         }
+      }
+   }
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/options/PessimisticLockAcquisitionTimeoutTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/options/PessimisticSuppressLockingTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/options/SuppressLockingTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/PessimisticSuppressLockingTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/options/PessimisticSuppressLockingTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.options;
+
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests the suppression of locking nodes
+ *
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ */
+ at Test(groups = {"functional"})
+public class PessimisticSuppressLockingTest
+{
+   private Fqn fqn = Fqn.fromString("/blah");
+   private Fqn fqn1 = Fqn.fromString("/blah/1");
+
+   private CacheSPI<String, String> cache;
+
+   private TransactionManager m;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp()
+   {
+      Configuration config = new Configuration();
+      config.setCacheMode(Configuration.CacheMode.LOCAL);
+      config.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      config.setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache = (CacheSPI<String, String>) instance.createCache(config);
+      m = cache.getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      if (cache != null)
+      {
+         cache.stop();
+         cache = null;
+      }
+      m = null;
+   }
+
+   public void testSuppressionOfWriteLocks() throws Exception
+   {
+      TransactionManager m = cache.getTransactionManager();
+
+      m.begin();
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.put(fqn, "x", "1");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      cache.removeNode(fqn);
+
+      m.begin();
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      assertTrue(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.put(fqn, "x", "2");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      // test normal operation again
+      cache.removeNode(fqn);
+
+      m.begin();
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.put(fqn, "x", "3");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   /**
+    * This one fails now.
+    *
+    * @throws Exception
+    */
+   public void testSuppressionOf2WriteLocks() throws Exception
+   {
+      TransactionManager m = cache.getTransactionManager();
+
+      m.begin();
+      cache.put(fqn, "x", "1");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      cache.removeNode(fqn);
+
+      m.begin();
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache.put(fqn, "x", "2");
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache.put(fqn1, "y", "3");
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      Map<String, String> map = new HashMap<String, String>();
+      map.put("x", "1");
+      m.begin();
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache.put(fqn, map);
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache.put(fqn1, map);
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      // test normal operation again
+      cache.removeNode(fqn);
+
+      m.begin();
+      cache.put(fqn, "x", "3");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testSuppressionOfReadLocks() throws Exception
+   {
+      cache.put(fqn, "x", "y");
+
+      m.begin();
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.get(fqn, "x");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      m.begin();
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      assertTrue(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.get(fqn, "x");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      // test normal operation again
+
+      m.begin();
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      cache.get(fqn, "x");
+      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      m.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testNodeCreation()
+   {
+      assertNull(cache.getRoot().getChild(fqn));
+      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache.put(fqn, "x", "y");
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      assertEquals("y", cache.getRoot().getChild(fqn).get("x"));
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/options/PessimisticSuppressLockingTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Deleted: core/trunk/src/test/java/org/jboss/cache/options/SuppressLockingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/SuppressLockingTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/options/SuppressLockingTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,184 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.options;
-
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.transaction.DummyTransactionManagerLookup;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.TransactionManager;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests the suppression of locking nodes
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- */
- at Test(groups = {"functional"})
-public class SuppressLockingTest
-{
-   private Fqn fqn = Fqn.fromString("/blah");
-   private Fqn fqn1 = Fqn.fromString("/blah/1");
-
-   private CacheSPI<String, String> cache;
-
-   private TransactionManager m;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp()
-   {
-      Configuration config = new Configuration();
-      config.setCacheMode(Configuration.CacheMode.LOCAL);
-      config.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(config);
-      m = cache.getTransactionManager();
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown()
-   {
-      if (cache != null)
-      {
-         cache.stop();
-         cache = null;
-      }
-      m = null;
-   }
-
-   public void testSuppressionOfWriteLocks() throws Exception
-   {
-      TransactionManager m = cache.getTransactionManager();
-
-      m.begin();
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.put(fqn, "x", "1");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      cache.removeNode(fqn);
-
-      m.begin();
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      assertTrue(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.put(fqn, "x", "2");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      // test normal operation again
-      cache.removeNode(fqn);
-
-      m.begin();
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.put(fqn, "x", "3");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   /**
-    * This one fails now.
-    *
-    * @throws Exception
-    */
-   public void testSuppressionOf2WriteLocks() throws Exception
-   {
-      TransactionManager m = cache.getTransactionManager();
-
-      m.begin();
-      cache.put(fqn, "x", "1");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      cache.removeNode(fqn);
-
-      m.begin();
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache.put(fqn, "x", "2");
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache.put(fqn1, "y", "3");
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      Map<String, String> map = new HashMap<String, String>();
-      map.put("x", "1");
-      m.begin();
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache.put(fqn, map);
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache.put(fqn1, map);
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      // test normal operation again
-      cache.removeNode(fqn);
-
-      m.begin();
-      cache.put(fqn, "x", "3");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testSuppressionOfReadLocks() throws Exception
-   {
-      cache.put(fqn, "x", "y");
-
-      m.begin();
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.get(fqn, "x");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      m.begin();
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      assertTrue(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.get(fqn, "x");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      // test normal operation again
-
-      m.begin();
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      cache.get(fqn, "x");
-      assertFalse(cache.getInvocationContext().getOptionOverrides().isSuppressLocking());
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      m.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testNodeCreation()
-   {
-      assertNull(cache.getRoot().getChild(fqn));
-      cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache.put(fqn, "x", "y");
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      assertEquals("y", cache.getRoot().getChild(fqn).get("x"));
-   }
-
-}

Copied: core/trunk/src/test/java/org/jboss/cache/replicated/PessimisticSyncReplTxTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTxTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/replicated/PessimisticSyncReplTxTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/replicated/PessimisticSyncReplTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,1239 @@
+/*
+ *
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.replicated;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.lock.TimeoutException;
+import org.jboss.cache.util.TestingUtil;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.event.NodeEvent;
+import org.jboss.cache.transaction.TransactionSetup;
+import org.jboss.cache.util.CachePrinter;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+
+/**
+ * Replicated unit test for sync transactional CacheImpl
+ * Note: we use DummyTransactionManager for Tx purpose instead of relying on
+ * jta.
+ *
+ * @version $Revision$
+ */
+ at Test(groups = {"functional", "jgroups", "transaction"})
+public class PessimisticSyncReplTxTest
+{
+   private static Log log = LogFactory.getLog(PessimisticSyncReplTxTest.class);
+   private CacheSPI<Object, Object> cache1;
+   private CacheSPI<Object, Object> cache2;
+
+   Semaphore lock;
+   private Throwable t1_ex;
+   private Throwable t2_ex;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      t1_ex = t2_ex = null;
+      lock = new Semaphore(1);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      TransactionSetup.cleanup();
+      destroyCaches();
+   }
+
+   private TransactionManager beginTransaction() throws SystemException, NotSupportedException
+   {
+      return beginTransaction(cache1);
+   }
+
+   private TransactionManager beginTransaction(CacheSPI c) throws SystemException, NotSupportedException
+   {
+      TransactionManager mgr = c.getConfiguration().getRuntimeConfig().getTransactionManager();
+      mgr.begin();
+      return mgr;
+   }
+
+   private void initCaches(Configuration.CacheMode caching_mode) throws Exception
+   {
+      cache1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
+      cache2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
+      cache1.getConfiguration().setCacheMode(caching_mode);
+      cache2.getConfiguration().setCacheMode(caching_mode);
+      cache1.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache2.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache1.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
+      cache2.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
+
+      cache1.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      cache2.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      cache1.getConfiguration().setLockAcquisitionTimeout(5000);
+      cache2.getConfiguration().setLockAcquisitionTimeout(5000);
+
+      configureMultiplexer(cache1);
+      configureMultiplexer(cache2);
+
+      cache1.start();
+      cache2.start();
+
+      validateMultiplexer(cache1);
+      validateMultiplexer(cache2);
+   }
+
+   /**
+    * Provides a hook for multiplexer integration. This default implementation
+    * is a no-op; subclasses that test mux integration would override
+    * to integrate the given cache with a multiplexer.
+    * <p/>
+    * param cache a cache that has been configured but not yet created.
+    *
+    * @param cache cache
+    * @throws Exception exception
+    */
+   protected void configureMultiplexer(Cache cache) throws Exception
+   {
+      // default does nothing
+   }
+
+   /**
+    * Provides a hook to check that the cache's channel came from the
+    * multiplexer, or not, as expected.  This default impl asserts that
+    * the channel did not come from the multiplexer.
+    *
+    * @param cache a cache that has already been started
+    */
+   protected void validateMultiplexer(Cache cache)
+   {
+      assertFalse("Cache is not using multiplexer", cache.getConfiguration().isUsingMultiplexer());
+   }
+
+   private void destroyCaches()
+   {
+      if (cache1 != null)
+      {
+         cache1.stop();
+      }
+      if (cache2 != null)
+      {
+         cache2.stop();
+      }
+      cache1 = null;
+      cache2 = null;
+   }
+
+   public void testLockRemoval() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      cache1.getConfiguration().setSyncCommitPhase(true);
+      TestingUtil.extractLockManager(cache1).unlockAll(cache1.getRoot());
+      TransactionManager tm = beginTransaction();
+      cache1.put("/bela/ban", "name", "Bela Ban");
+      assertEquals(3, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+      tm.commit();
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+   }
+
+   public void testSyncRepl() throws Exception
+   {
+      Integer age;
+      Transaction tx;
+
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      cache1.getConfiguration().setSyncCommitPhase(true);
+      cache2.getConfiguration().setSyncCommitPhase(true);
+
+      TransactionManager mgr = beginTransaction();
+      cache1.put("/a/b/c", "age", 38);
+      tx = mgr.suspend();
+      assertNull("age on cache2 must be null as the TX has not yet been committed", cache2.get("/a/b/c", "age"));
+      log.debug("cache1: locks held before commit: " + CachePrinter.printCacheLockingInfo(cache1));
+      log.debug("cache2: locks held before commit: " + CachePrinter.printCacheLockingInfo(cache2));
+      mgr.resume(tx);
+      mgr.commit();
+      log.debug("cache1: locks held after commit: " + CachePrinter.printCacheLockingInfo(cache1));
+      log.debug("cache2: locks held after commit: " + CachePrinter.printCacheLockingInfo(cache2));
+
+      // value on cache2 must be 38
+      age = (Integer) cache2.get("/a/b/c", "age");
+      assertNotNull("\"age\" obtained from cache2 must be non-null ", age);
+      assertTrue("\"age\" must be 38", age == 38);
+   }
+
+   public void testSimplePut() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+
+      cache1.put("/JSESSION/localhost/192.168.1.10:32882/Courses/0", "Instructor", "Ben Wang");
+
+      cache1.put("/JSESSION/localhost/192.168.1.10:32882/1", "Number", 10);
+   }
+
+   public void testSimpleTxPut() throws Exception
+   {
+      TransactionManager tm;
+      final Fqn NODE1 = Fqn.fromString("/one/two/three");
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+
+      tm = beginTransaction();
+      cache1.put(NODE1, "age", 38);
+      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
+      tm.commit();
+
+      /*
+       tx=beginTransaction();
+       cache1.put(NODE1, "age", new Integer(38));
+       cache1.put(NODE2, "name", "Ben of The Far East");
+       cache1.put(NODE3, "key", "UnknowKey");
+       System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
+
+       tx.commit();
+       */
+
+      /*
+       tx=beginTransaction();
+       cache1.put(NODE1, "age", new Integer(38));
+       cache1.put(NODE1, "AOPInstance", new AOPInstance());
+       cache1.put(NODE2, "AOPInstance", new AOPInstance());
+       cache1.put(NODE1, "AOPInstance", new AOPInstance());
+       tx.commit();
+       System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
+       */
+   }
+
+   public void testSyncReplWithModficationsOnBothCaches() throws Exception
+   {
+      TransactionManager tm;
+      final Fqn NODE1 = Fqn.fromString("/one/two/three");
+      final Fqn NODE2 = Fqn.fromString("/eins/zwei/drei");
+
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+
+      // create roots first
+      cache1.put("/one/two", null);
+      cache2.put("/eins/zwei", null);
+
+      cache1.getConfiguration().setSyncCommitPhase(true);
+      cache2.getConfiguration().setSyncCommitPhase(true);
+
+      tm = beginTransaction();
+      cache1.put(NODE1, "age", 38);
+      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
+
+      cache2.put(NODE2, "age", 39);
+      System.out.println("TransactionTable for cache2 after cache2.put():\n" + cache2.getTransactionTable().toString(true));
+
+      System.out.println("cache1 before commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 before commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      try
+      {
+         tm.commit();
+         fail("Should not succeed with SERIALIZABLE semantics");
+      }
+      catch (Exception e)
+      {
+         //should be a classic deadlock here.
+      }
+
+      System.out.println("cache1 after commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 after commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      /*
+       assertTrue(cache1.exists(NODE1));
+       assertTrue(cache1.exists(NODE2));
+       assertTrue(cache1.exists(NODE1));
+       assertTrue(cache2.exists(NODE2));
+
+       age = (Integer) cache1.get(NODE1, "age");
+       assertNotNull("\"age\" obtained from cache1 for " + NODE1 + " must be non-null ", age);
+       assertTrue("\"age\" must be 38", age == 38);
+
+       age = (Integer) cache2.get(NODE1, "age");
+       assertNotNull("\"age\" obtained from cache2 for " + NODE1 + " must be non-null ", age);
+       assertTrue("\"age\" must be 38", age == 38);
+
+       age = (Integer) cache1.get(NODE2, "age");
+       assertNotNull("\"age\" obtained from cache1 for " + NODE2 + " must be non-null ", age);
+       assertTrue("\"age\" must be 39", age == 39);
+
+       age = (Integer) cache2.get(NODE2, "age");
+       assertNotNull("\"age\" obtained from cache2 for " + NODE2 + " must be non-null ", age);
+       assertTrue("\"age\" must be 39", age == 39);
+       */
+
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+      System.out.println("TransactionTable for cache1:\n" + cache1.getTransactionTable().toString(true));
+      System.out.println("TransactionTable for cache2:\n" + cache2.getTransactionTable().toString(true));
+   }
+
+   public void testSyncReplWithModficationsOnBothCachesSameData() throws Exception
+   {
+      TransactionManager tm;
+      final Fqn NODE = Fqn.fromString("/one/two/three");
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      tm = beginTransaction();
+      cache1.put(NODE, "age", 38);
+      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
+
+      cache2.put(NODE, "age", 39);
+      System.out.println("TransactionTable for cache2 after cache2.put():\n" + cache2.getTransactionTable().toString(true));
+
+      System.out.println("cache1 before commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 before commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      try
+      {
+         tm.commit();
+         fail("commit should throw a RollbackException, we should not get here");
+      }
+      catch (RollbackException rollback)
+      {
+         System.out.println("Transaction was rolled back, this is correct");
+      }
+
+      System.out.println("cache1 after commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 after commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+
+      assertEquals(0, cache1.getNumberOfNodes());
+      assertEquals(0, cache2.getNumberOfNodes());
+   }
+
+   public void testSyncReplWithModficationsOnBothCachesWithRollback() throws Exception
+   {
+      TransactionManager tm;
+      final Fqn fqn1 = Fqn.fromString("/one/two/three");
+      final Fqn fqn2 = Fqn.fromString("/eins/zwei/drei");
+
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+
+      cache1.getConfiguration().setSyncRollbackPhase(true);
+      cache2.getConfiguration().setSyncRollbackPhase(true);
+
+      tm = beginTransaction();
+      cache1.put(fqn1, "age", 38);
+      cache2.put(fqn2, "age", 39);
+
+      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      // this will rollback the transaction
+      Transaction tx = tm.getTransaction();
+      tx.registerSynchronization(new TransactionAborter(tx));
+
+      try
+      {
+         tm.commit();
+         fail("commit should throw a RollbackException, we should not get here");
+      }
+      catch (RollbackException rollback)
+      {
+         System.out.println("Transaction was rolled back, this is correct");
+      }
+
+      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+
+      assertEquals(0, cache1.getNumberOfNodes());
+      assertEquals(0, cache2.getNumberOfNodes());
+   }
+
+   /**
+    * Test for JBCACHE-361 -- does marking a tx on the remote side
+    * rollback-only cause a rollback on the originating side?
+    */
+   public void testSyncReplWithRemoteRollback() throws Exception
+   {
+      TransactionManager tm;
+      final Fqn NODE1 = Fqn.fromString("/one/two/three");
+
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+
+      cache1.getConfiguration().setSyncRollbackPhase(true);
+      cache2.getConfiguration().setSyncRollbackPhase(true);
+
+      // Test with a rollback on the remote side
+
+      // listener aborts any active tx
+      //TransactionAborterListener tal = new TransactionAborterListener(cache2);
+
+      tm = beginTransaction();
+      cache1.put(NODE1, "age", 38);
+
+      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      // instead of a listener lets just get a WL on ROOT on cache2. And hold on to it.
+      Transaction tx = tm.suspend();
+
+      tm.begin();
+      cache2.getRoot().put("x", "y");
+      Transaction tx2 = cache2.getTransactionManager().suspend();
+
+      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
+      tm.resume(tx);
+
+      try
+      {
+         tm.commit();
+         fail("commit should throw a RollbackException, we should not get here");
+      }
+      catch (RollbackException rollback)
+      {
+         System.out.println("Transaction was rolled back, this is correct");
+      }
+      finally
+      {
+         tm.resume(tx2);
+         tm.rollback();
+      }
+
+      // Sleep, as the commit call to cache2 is async
+      TestingUtil.sleepThread(1000);
+
+      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
+      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
+
+      //assertNull(tal.getCallbackException());
+
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+
+      assertEquals(0, cache1.getNumberOfNodes());
+      assertEquals(0, cache2.getNumberOfNodes());
+
+   }
+
+   public void testASyncRepl() throws Exception
+   {
+      Integer age;
+      TransactionManager tm;
+
+      initCaches(Configuration.CacheMode.REPL_ASYNC);
+
+      tm = beginTransaction();
+      cache1.put("/a/b/c", "age", 38);
+      Thread.sleep(1000);
+      assertNull("age on cache2 must be null as the TX has not yet been committed", cache2.get("/a/b/c", "age"));
+      tm.commit();
+      Thread.sleep(1000);
+
+      // value on cache2 must be 38
+      age = (Integer) cache2.get("/a/b/c", "age");
+      assertNotNull("\"age\" obtained from cache2 is null ", age);
+      assertTrue("\"age\" must be 38", age == 38);
+
+   }
+
+   /**
+    * Tests concurrent modifications: thread1 succeeds and thread2 is blocked until thread1 is done, and then succeeds
+    * too. However, this is flawed with the introduction of interceptors, here's why.<br/>
+    * <ul>
+    * <li>Thread1 acquires the lock for /bela/ban on cache1
+    * <li>Thread2 blocks on Thread1 to release the lock
+    * <li>Thread1 commits: this means the TransactionInterceptor and the ReplicationInterceptor are called in
+    * the sequence in which they registered. Unfortunately, the TransactionInterceptor registered first. In the
+    * PREPARE phase, the ReplicationInterceptor calls prepare() in cache2 synchronously. The TxInterceptor
+    * does nothing. The the COMMIT phase, the TxInterceptor commits the data by releasing the locks locally and
+    * then the ReplicationInterceptor sends an asynchronous COMMIT to cache2.
+    * <li>Because the TxInterceptor for Thread1 releases the locks locally <em>before</em> sending the async COMMIT,
+    * Thread2 is able to acquire the lock for /bela/ban in cache1 and then starts the PREPARE phase by sending a
+    * synchronous PREPARE to cache2. If this PREPARE arrives at cache2 <em>before</em> the COMMIT from Thread1,
+    * the PREPARE will block because it attempts to acquire a lock on /bela/ban on cache2 still held by Thread1
+    * (which would be released by Thread1's COMMIT). This results in deadlock, which is resolved by Thread2 running
+    * into a timeout with subsequent rollback and Thread1 succeeding.<br/>
+    * </ul>
+    * There are 3 solutions to this:
+    * <ol>
+    * <li>Do nothing. This is standard behavior for concurrent access to the same data. Same thing if the 2 threads
+    * operated on the same data in <em>separate</em> caches, e.g. Thread1 on /bela/ban in cache1 and Thread2 on
+    * /bela/ban in cache2. The semantics of Tx commit as handled by the interceptors is: after tx1.commit() returns
+    * the locks held by tx1 are release and a COMMIT message is on the way (if sent asynchronously).
+    * <li>Force an order over TxInterceptor and ReplicationInterceptor. This would require ReplicationInterceptor
+    * to always be fired first on TX commit. Downside: the interceptors have an implicit dependency, which is not
+    * nice.
+    * <li>Priority-order requests at the receiver; e.g. a COMMIT could release a blocked PREPARE. This is bad because
+    * it violates JGroups' FIFO ordering guarantees.
+    * </ol>
+    * I'm currently investigating solution #2, ie. creating an OrderedSynchronizationHandler, which allows other
+    * SynchronizationHandlers to register (atHead, atTail), and the OrderedSynchronizationHandler would call the
+    * SynchronizationHandler in the order in which they are defined.
+    *
+    * @throws Exception exception
+    */
+   public void testConcurrentPuts() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      cache1.getConfiguration().setSyncCommitPhase(true);
+
+      Thread t1 = new Thread("Thread1")
+      {
+         TransactionManager tm;
+
+         public void run()
+         {
+            try
+            {
+               tm = beginTransaction();
+               cache1.put("/bela/ban", "name", "Bela Ban");
+               TestingUtil.sleepThread(2000);// Thread2 will be blocked until we commit
+               tm.commit();
+               System.out.println("[Thread1] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
+               System.out.println("[Thread1] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t1_ex = ex;
+            }
+         }
+      };
+
+      Thread t2 = new Thread("Thread2")
+      {
+         TransactionManager tm;
+
+         public void run()
+         {
+            try
+            {
+               TestingUtil.sleepThread(1000);// give Thread1 time to acquire the lock
+               tm = beginTransaction();
+               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
+               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
+               cache1.put("/bela/ban", "name", "Michelle Ban");
+               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
+               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
+               tm.commit();
+               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
+               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t2_ex = ex;
+            }
+         }
+      };
+
+      // Let the game start
+      t1.start();
+      t2.start();
+
+      // Wait for threads to die
+      t1.join();
+      t2.join();
+
+      if (t1_ex != null)
+      {
+         fail("Thread1 failed: " + t1_ex);
+      }
+      if (t2_ex != null)
+      {
+         fail("Thread2 failed: " + t2_ex);
+      }
+
+      assertEquals("Michelle Ban", cache1.get("/bela/ban", "name"));
+   }
+
+   /**
+    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
+    */
+   public void testConcurrentCommitsWith1Thread() throws Exception
+   {
+      _testConcurrentCommits(1);
+   }
+
+   /**
+    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
+    */
+   public void testConcurrentCommitsWith5Threads() throws Exception
+   {
+      _testConcurrentCommits(5);
+   }
+
+   /**
+    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
+    */
+   private void _testConcurrentCommits(int num_threads)
+   {
+      Object myMutex = new Object();
+
+      final CacheSPI<Object, Object> c1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
+      final CacheSPI<Object, Object> c2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
+      c1.getConfiguration().setClusterName("TempCluster");
+      c2.getConfiguration().setClusterName("TempCluster");
+      c1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
+      c2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
+      c1.getConfiguration().setSyncCommitPhase(true);
+      c2.getConfiguration().setSyncCommitPhase(true);
+      c1.getConfiguration().setSyncRollbackPhase(true);
+      c2.getConfiguration().setSyncRollbackPhase(true);
+      c1.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
+      c2.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
+      c1.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+      c2.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+      c1.getConfiguration().setLockAcquisitionTimeout(5000);
+      c2.getConfiguration().setLockAcquisitionTimeout(5000);
+      c1.start();
+      c2.start();
+      final List<Exception> exceptions = new ArrayList<Exception>();
+
+      class MyThread extends Thread
+      {
+         final Object mutex;
+
+         public MyThread(String name, Object mutex)
+         {
+            super(name);
+            this.mutex = mutex;
+         }
+
+         public void run()
+         {
+            TransactionManager tm = null;
+
+            try
+            {
+               tm = beginTransaction(c1);
+               c1.put("/thread/" + getName(), null);
+               System.out.println("Thread " + getName() + " after put(): " + c1.toString());
+               System.out.println("Thread " + getName() + " waiting on mutex");
+               synchronized (mutex)
+               {
+                  mutex.wait();
+               }
+               System.out.println("Thread " + getName() + " committing");
+               tm.commit();
+               System.out.println("Thread " + getName() + " committed successfully");
+            }
+            catch (Exception e)
+            {
+               exceptions.add(e);
+            }
+            finally
+            {
+               try
+               {
+                  if (tm != null)
+                     tm.rollback();
+               }
+               catch (Exception e)
+               {
+                  // do nothing
+               }
+            }
+         }
+      }
+
+      MyThread[] threads = new MyThread[num_threads];
+      for (int i = 0; i < threads.length; i++)
+      {
+         threads[i] = new MyThread("#" + i, myMutex);
+      }
+      for (int i = 0; i < threads.length; i++)
+      {
+         MyThread thread = threads[i];
+         System.out.println("starting thread #" + i);
+         thread.start();
+      }
+
+      TestingUtil.sleepThread(6000);
+      synchronized (myMutex)
+      {
+         System.out.println("cache is " + CachePrinter.printCacheLockingInfo(c1));
+         System.out.println("******************* SIGNALLING THREADS ********************");
+         myMutex.notifyAll();
+      }
+
+      for (MyThread thread : threads)
+      {
+         try
+         {
+            thread.join();
+            System.out.println("Joined thread " + thread.getName());
+         }
+         catch (InterruptedException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      System.out.println("FINAL c1:\n" + CachePrinter.printCacheDetails(c1) + "\nlocks:\n" + CachePrinter.printCacheLockingInfo(c1));
+
+      assertEquals(0, c1.getNumberOfLocksHeld());
+      assertEquals(0, c2.getNumberOfLocksHeld());
+
+      c1.stop();
+      c2.stop();
+
+      //      if(ex != null)
+      //      {
+      //         ex.printStackTrace();
+      //         fail("Thread failed: " + ex);
+      //      }
+
+      // we can only expect 1 thread to succeed.  The others will fail.  So, threads.length -1 exceptions.
+      // this is a timing issue - 2 threads still may succeed on a multi cpu system
+      // assertEquals(threads.length - 1, exceptions.size());
+
+      for (Exception exception : exceptions)
+         assertEquals(TimeoutException.class, exception.getClass());
+   }
+
+   /**
+    * Conncurrent put on 2 different instances.
+    */
+   public void testConcurrentPutsOnTwoInstances() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      final CacheSPI<Object, Object> c1 = this.cache1;
+      final CacheSPI<Object, Object> c2 = this.cache2;
+
+      Thread t1 = new Thread()
+      {
+         TransactionManager tm;
+
+         public void run()
+         {
+            try
+            {
+               tm = beginTransaction();
+               c1.put("/ben/wang", "name", "Ben Wang");
+               TestingUtil.sleepThread(8000);
+               tm.commit();// This should go thru
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t1_ex = ex;
+            }
+         }
+      };
+
+      Thread t2 = new Thread()
+      {
+         TransactionManager tm;
+
+         public void run()
+         {
+            try
+            {
+               TestingUtil.sleepThread(1000);// give Thread1 time to acquire the lock
+               tm = beginTransaction();
+               c2.put("/ben/wang", "name", "Ben Jr.");
+               tm.commit();// This will time out and rollback first because Thread1 has a tx going as well.
+            }
+            catch (RollbackException rollback_ex)
+            {
+               System.out.println("received rollback exception as expected");
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t2_ex = ex;
+            }
+         }
+      };
+
+      // Let the game start
+      t1.start();
+      t2.start();
+
+      // Wait for thread to die but put an insurance of 5 seconds on it.
+      t1.join();
+      t2.join();
+
+      if (t1_ex != null)
+      {
+         fail("Thread1 failed: " + t1_ex);
+      }
+      if (t2_ex != null)
+      {
+         fail("Thread2 failed: " + t2_ex);
+      }
+      assertEquals("Ben Wang", c1.get("/ben/wang", "name"));
+   }
+
+   public void testPut() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      final CacheSPI<Object, Object> c1 = this.cache1;
+
+      Thread t1 = new Thread()
+      {
+         public void run()
+         {
+            try
+            {
+               lock.acquire();
+               System.out.println("-- t1 has lock");
+               c1.put("/a/b/c", "age", 38);
+               System.out.println("[Thread1] set value to 38");
+
+               System.out.println("-- t1 releases lock");
+               lock.release();
+               TestingUtil.sleepThread(300);
+               Thread.yield();
+
+               lock.acquire();
+               System.out.println("-- t1 has lock");
+               c1.put("/a/b/c", "age", 39);
+               System.out.println("[Thread1] set value to 39");
+
+               System.out.println("-- t1 releases lock");
+               lock.release();
+               assertEquals(39, c1.get("/a/b/c", "age"));
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t1_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      Thread t2 = new Thread()
+      {
+         public void run()
+         {
+            try
+            {
+               TestingUtil.sleepThread(100);
+               Thread.yield();
+               lock.acquire();
+               System.out.println("-- t2 has lock");
+               // Should replicate the value right away.
+               Integer val = (Integer) cache2.get("/a/b/c", "age");
+               System.out.println("[Thread2] value is " + val);
+               assertEquals(new Integer(38), val);
+               System.out.println("-- t2 releases lock");
+               lock.release();
+               TestingUtil.sleepThread(300);
+               Thread.yield();
+               TestingUtil.sleepThread(500);
+               lock.acquire();
+               System.out.println("-- t2 has lock");
+               val = (Integer) cache2.get("/a/b/c", "age");
+               System.out.println("-- t2 releases lock");
+               lock.release();
+               assertEquals(new Integer(39), val);
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t2_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      // Let the game start
+      t1.start();
+      t2.start();
+
+      // Wait for thread to die but put an insurance of 5 seconds on it.
+      t1.join();
+      t2.join();
+      if (t1_ex != null)
+      {
+         fail("Thread1 failed: " + t1_ex);
+      }
+      if (t2_ex != null)
+      {
+         fail("Thread2 failed: " + t2_ex);
+      }
+   }
+
+   /**
+    * Test replicated cache with transaction. Idea is to have two threads running
+    * a local cache each that is replicating. Depending on whether cache1 commit/rollback or not,
+    * the cache2.get will get different values.
+    * Note that we have used sleep to interpose thread execution sequence.
+    * Although it's not fool proof, it is rather simple and intuitive.
+    */
+   public void testPutTx() throws Exception
+   {
+      TransactionManager tm;
+
+      try
+      {
+         initCaches(Configuration.CacheMode.REPL_SYNC);
+         cache1.getConfiguration().setSyncCommitPhase(true);
+         cache2.getConfiguration().setSyncCommitPhase(true);
+         tm = beginTransaction();
+         cache1.put("/a/b/c", "age", 38);
+         cache1.put("/a/b/c", "age", 39);
+         Object val = cache2.get("/a/b/c", "age");// must be null as not yet committed
+         assertNull(val);
+         tm.commit();
+
+         tm = beginTransaction();
+         assertEquals(39, cache2.get("/a/b/c", "age"));// must not be null
+         tm.commit();
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         t1_ex = t;
+      }
+      finally
+      {
+         lock.release();
+      }
+   }
+
+   /**
+    * Have both cache1 and cache2 do add and commit. cache1 commit should time out
+    * since it can't obtain the lock when trying to replicate cache2. On the other hand,
+    * cache2 commit will succeed since now that cache1 is rollbacked and lock is
+    * released.
+    */
+   public void testPutTx1() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      final CacheSPI<Object, Object> c1 = this.cache1;
+      Thread t1 = new Thread()
+      {
+         public void run()
+         {
+            TransactionManager tm;
+
+            try
+            {
+               lock.acquire();
+               tm = beginTransaction();
+               c1.put("/a/b/c", "age", 38);
+               c1.put("/a/b/c", "age", 39);
+               lock.release();
+
+               TestingUtil.sleepThread(300);
+               lock.acquire();
+               try
+               {
+                  tm.commit();
+               }
+               catch (RollbackException ex)
+               {
+                  System.out.println("[Thread1] received RollbackException, as expected. Rolling back changes");
+               }
+               finally
+               {
+                  lock.release();
+               }
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t1_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      Thread t2 = new Thread()
+      {
+         public void run()
+         {
+            TransactionManager tm;
+
+            try
+            {
+               sleep(200);
+               Thread.yield();
+               lock.acquire();
+               tm = beginTransaction();
+               assertNull(cache2.get("/a/b/c", "age"));// must be null as not yet committed
+               cache2.put("/a/b/c", "age", 40);
+               lock.release();
+
+               TestingUtil.sleepThread(300);
+               lock.acquire();
+               assertEquals(40, cache2.get("/a/b/c", "age"));// must not be null
+               tm.commit();
+               lock.release();
+
+               TestingUtil.sleepThread(1000);
+               tm = beginTransaction();
+               assertEquals("After cache2 commit", 40, cache2.get("/a/b/c", "age"));
+               tm.commit();
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t2_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      // Let the game start
+      t1.start();
+      t2.start();
+
+      t1.join();
+      t2.join();
+
+      if (t1_ex != null)
+      {
+         fail("Thread1 failed: " + t1_ex);
+      }
+      if (t2_ex != null)
+      {
+         fail("Thread2 failed: " + t2_ex);
+      }
+   }
+
+   public void testPutTxWithRollback() throws Exception
+   {
+      initCaches(Configuration.CacheMode.REPL_SYNC);
+      final CacheSPI<Object, Object> c2 = this.cache1;
+      Thread t1 = new Thread()
+      {
+         public void run()
+         {
+            TransactionManager tm;
+
+            try
+            {
+               lock.acquire();
+               tm = beginTransaction();
+               c2.put("/a/b/c", "age", 38);
+               c2.put("/a/b/c", "age", 39);
+               lock.release();
+
+               TestingUtil.sleepThread(100);
+               lock.acquire();
+               tm.rollback();
+               lock.release();
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t1_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      Thread t2 = new Thread()
+      {
+         public void run()
+         {
+            TransactionManager tm;
+
+            try
+            {
+               sleep(200);
+               Thread.yield();
+               lock.acquire();
+               tm = beginTransaction();
+               assertNull(cache2.get("/a/b/c", "age"));// must be null as not yet committed
+               lock.release();
+
+               TestingUtil.sleepThread(100);
+               lock.acquire();
+               assertNull(cache2.get("/a/b/c", "age"));// must be null as rolledback
+               tm.commit();
+               lock.release();
+            }
+            catch (Throwable ex)
+            {
+               ex.printStackTrace();
+               t2_ex = ex;
+            }
+            finally
+            {
+               lock.release();
+            }
+         }
+      };
+
+      // Let the game start
+      t1.start();
+      t2.start();
+
+      // Wait for thread to die but put an insurance of 5 seconds on it.
+      t1.join();
+      t2.join();
+      if (t1_ex != null)
+      {
+         fail("Thread1 failed: " + t1_ex);
+      }
+      if (t2_ex != null)
+      {
+         fail("Thread2 failed: " + t2_ex);
+      }
+   }
+
+   static class TransactionAborter implements Synchronization
+   {
+      Transaction ltx = null;
+
+      public TransactionAborter(Transaction ltx)
+      {
+         this.ltx = ltx;
+      }
+
+      public void beforeCompletion()
+      {
+         try
+         {
+            ltx.setRollbackOnly();
+         }
+         catch (SystemException e)
+         {
+            // who cares
+         }
+      }
+
+      public void afterCompletion(int status)
+      {
+      }
+   }
+
+   @CacheListener
+   static class CallbackListener
+   {
+
+      CacheSPI<Object, Object> callbackCache;
+      Object callbackKey;
+      Exception ex;
+      final Object mutex = new Object();
+
+      CallbackListener(CacheSPI<Object, Object> cache, Object callbackKey)
+      {
+         this.callbackCache = cache;
+         this.callbackKey = callbackKey;
+         cache.getNotifier().addCacheListener(this);
+      }
+
+      @NodeModified
+      public void nodeModified(NodeEvent e)
+      {
+         if (!e.isPre())
+         {
+            // Lock on a mutex so test can't check for an exception
+            // until the get call completes
+            synchronized (mutex)
+            {
+               try
+               {
+                  callbackCache.get(e.getFqn(), callbackKey);
+               }
+               catch (CacheException exc)
+               {
+                  exc.printStackTrace();
+                  ex = exc;
+               }
+            }
+         }
+      }
+
+      Exception getCallbackException()
+      {
+         synchronized (mutex)
+         {
+            return ex;
+         }
+      }
+
+   }
+
+   static class TransactionAborterCallbackListener extends CallbackListener
+   {
+
+      TransactionManager callbackTM;
+
+      TransactionAborterCallbackListener(CacheSPI<Object, Object> cache, Object callbackKey)
+      {
+         super(cache, callbackKey);
+         callbackTM = callbackCache.getTransactionManager();
+      }
+
+      @NodeModified
+      public void nodeModified(NodeEvent ne)
+      {
+         if (!ne.isPre())
+         {
+            try
+            {
+               Transaction tx = callbackTM.getTransaction();
+               if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE)
+               {
+                  // this will rollback the transaction
+                  tx.registerSynchronization(new TransactionAborter(tx));
+               }
+               else
+               {
+                  super.nodeModified(ne);
+               }
+
+            }
+            catch (Exception e)
+            {
+               e.printStackTrace();
+               if (ex == null)
+               {
+                  ex = e;
+               }
+            }
+         }
+      }
+
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/replicated/PessimisticSyncReplTxTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Deleted: core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTxTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTxTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,1327 +0,0 @@
-/*
- *
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.replicated;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.lock.TimeoutException;
-import org.jboss.cache.util.TestingUtil;
-import org.jboss.cache.notifications.annotation.CacheListener;
-import org.jboss.cache.notifications.annotation.NodeModified;
-import org.jboss.cache.notifications.event.NodeEvent;
-import org.jboss.cache.transaction.TransactionSetup;
-import org.jboss.cache.util.CachePrinter;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-
-/**
- * Replicated unit test for sync transactional CacheImpl
- * Note: we use DummyTransactionManager for Tx purpose instead of relying on
- * jta.
- *
- * @version $Revision$
- */
- at Test(groups = {"functional", "jgroups", "transaction"})
-public class SyncReplTxTest
-{
-   private static Log log = LogFactory.getLog(SyncReplTxTest.class);
-   private CacheSPI<Object, Object> cache1;
-   private CacheSPI<Object, Object> cache2;
-
-   Semaphore lock;
-   private Throwable t1_ex;
-   private Throwable t2_ex;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      t1_ex = t2_ex = null;
-      lock = new Semaphore(1);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      TransactionSetup.cleanup();
-      destroyCaches();
-   }
-
-   private TransactionManager beginTransaction() throws SystemException, NotSupportedException
-   {
-      return beginTransaction(cache1);
-   }
-
-   private TransactionManager beginTransaction(CacheSPI c) throws SystemException, NotSupportedException
-   {
-      TransactionManager mgr = c.getConfiguration().getRuntimeConfig().getTransactionManager();
-      mgr.begin();
-      return mgr;
-   }
-
-   private void initCaches(Configuration.CacheMode caching_mode) throws Exception
-   {
-      cache1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
-      cache2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
-      cache1.getConfiguration().setCacheMode(caching_mode);
-      cache2.getConfiguration().setCacheMode(caching_mode);
-      cache1.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
-      cache2.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
-
-      cache1.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache2.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache1.getConfiguration().setLockAcquisitionTimeout(5000);
-      cache2.getConfiguration().setLockAcquisitionTimeout(5000);
-
-      configureMultiplexer(cache1);
-      configureMultiplexer(cache2);
-
-      cache1.start();
-      cache2.start();
-
-      validateMultiplexer(cache1);
-      validateMultiplexer(cache2);
-   }
-
-   /**
-    * Provides a hook for multiplexer integration. This default implementation
-    * is a no-op; subclasses that test mux integration would override
-    * to integrate the given cache with a multiplexer.
-    * <p/>
-    * param cache a cache that has been configured but not yet created.
-    *
-    * @param cache cache
-    * @throws Exception exception
-    */
-   protected void configureMultiplexer(Cache cache) throws Exception
-   {
-      // default does nothing
-   }
-
-   /**
-    * Provides a hook to check that the cache's channel came from the
-    * multiplexer, or not, as expected.  This default impl asserts that
-    * the channel did not come from the multiplexer.
-    *
-    * @param cache a cache that has already been started
-    */
-   protected void validateMultiplexer(Cache cache)
-   {
-      assertFalse("Cache is not using multiplexer", cache.getConfiguration().isUsingMultiplexer());
-   }
-
-   private void destroyCaches()
-   {
-      if (cache1 != null)
-      {
-         cache1.stop();
-      }
-      if (cache2 != null)
-      {
-         cache2.stop();
-      }
-      cache1 = null;
-      cache2 = null;
-   }
-
-   public void testLockRemoval() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      cache1.getConfiguration().setSyncCommitPhase(true);
-      TestingUtil.extractLockManager(cache1).unlockAll(cache1.getRoot());
-      TransactionManager tm = beginTransaction();
-      cache1.put("/bela/ban", "name", "Bela Ban");
-      assertEquals(3, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-      tm.commit();
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-   }
-
-   public void testSyncRepl() throws Exception
-   {
-      Integer age;
-      Transaction tx;
-
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      cache1.getConfiguration().setSyncCommitPhase(true);
-      cache2.getConfiguration().setSyncCommitPhase(true);
-
-      TransactionManager mgr = beginTransaction();
-      cache1.put("/a/b/c", "age", 38);
-      tx = mgr.suspend();
-      assertNull("age on cache2 must be null as the TX has not yet been committed", cache2.get("/a/b/c", "age"));
-      log.debug("cache1: locks held before commit: " + CachePrinter.printCacheLockingInfo(cache1));
-      log.debug("cache2: locks held before commit: " + CachePrinter.printCacheLockingInfo(cache2));
-      mgr.resume(tx);
-      mgr.commit();
-      log.debug("cache1: locks held after commit: " + CachePrinter.printCacheLockingInfo(cache1));
-      log.debug("cache2: locks held after commit: " + CachePrinter.printCacheLockingInfo(cache2));
-
-      // value on cache2 must be 38
-      age = (Integer) cache2.get("/a/b/c", "age");
-      assertNotNull("\"age\" obtained from cache2 must be non-null ", age);
-      assertTrue("\"age\" must be 38", age == 38);
-   }
-
-   public void testSimplePut() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-
-      cache1.put("/JSESSION/localhost/192.168.1.10:32882/Courses/0", "Instructor", "Ben Wang");
-
-      cache1.put("/JSESSION/localhost/192.168.1.10:32882/1", "Number", 10);
-   }
-
-   public void testSimpleTxPut() throws Exception
-   {
-      TransactionManager tm;
-      final Fqn NODE1 = Fqn.fromString("/one/two/three");
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-
-      tm = beginTransaction();
-      cache1.put(NODE1, "age", 38);
-      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
-      tm.commit();
-
-      /*
-       tx=beginTransaction();
-       cache1.put(NODE1, "age", new Integer(38));
-       cache1.put(NODE2, "name", "Ben of The Far East");
-       cache1.put(NODE3, "key", "UnknowKey");
-       System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
-
-       tx.commit();
-       */
-
-      /*
-       tx=beginTransaction();
-       cache1.put(NODE1, "age", new Integer(38));
-       cache1.put(NODE1, "AOPInstance", new AOPInstance());
-       cache1.put(NODE2, "AOPInstance", new AOPInstance());
-       cache1.put(NODE1, "AOPInstance", new AOPInstance());
-       tx.commit();
-       System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
-       */
-   }
-
-   public void testSyncReplWithModficationsOnBothCaches() throws Exception
-   {
-      TransactionManager tm;
-      final Fqn NODE1 = Fqn.fromString("/one/two/three");
-      final Fqn NODE2 = Fqn.fromString("/eins/zwei/drei");
-
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-
-      // create roots first
-      cache1.put("/one/two", null);
-      cache2.put("/eins/zwei", null);
-
-      cache1.getConfiguration().setSyncCommitPhase(true);
-      cache2.getConfiguration().setSyncCommitPhase(true);
-
-      tm = beginTransaction();
-      cache1.put(NODE1, "age", 38);
-      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
-
-      cache2.put(NODE2, "age", 39);
-      System.out.println("TransactionTable for cache2 after cache2.put():\n" + cache2.getTransactionTable().toString(true));
-
-      System.out.println("cache1 before commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 before commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      try
-      {
-         tm.commit();
-         fail("Should not succeed with SERIALIZABLE semantics");
-      }
-      catch (Exception e)
-      {
-         //should be a classic deadlock here.
-      }
-
-      System.out.println("cache1 after commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 after commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      /*
-       assertTrue(cache1.exists(NODE1));
-       assertTrue(cache1.exists(NODE2));
-       assertTrue(cache1.exists(NODE1));
-       assertTrue(cache2.exists(NODE2));
-
-       age = (Integer) cache1.get(NODE1, "age");
-       assertNotNull("\"age\" obtained from cache1 for " + NODE1 + " must be non-null ", age);
-       assertTrue("\"age\" must be 38", age == 38);
-
-       age = (Integer) cache2.get(NODE1, "age");
-       assertNotNull("\"age\" obtained from cache2 for " + NODE1 + " must be non-null ", age);
-       assertTrue("\"age\" must be 38", age == 38);
-
-       age = (Integer) cache1.get(NODE2, "age");
-       assertNotNull("\"age\" obtained from cache1 for " + NODE2 + " must be non-null ", age);
-       assertTrue("\"age\" must be 39", age == 39);
-
-       age = (Integer) cache2.get(NODE2, "age");
-       assertNotNull("\"age\" obtained from cache2 for " + NODE2 + " must be non-null ", age);
-       assertTrue("\"age\" must be 39", age == 39);
-       */
-
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-      System.out.println("TransactionTable for cache1:\n" + cache1.getTransactionTable().toString(true));
-      System.out.println("TransactionTable for cache2:\n" + cache2.getTransactionTable().toString(true));
-   }
-
-   public void testSyncReplWithModficationsOnBothCachesSameData() throws Exception
-   {
-      TransactionManager tm;
-      final Fqn NODE = Fqn.fromString("/one/two/three");
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      tm = beginTransaction();
-      cache1.put(NODE, "age", 38);
-      System.out.println("TransactionTable for cache1 after cache1.put():\n" + cache1.getTransactionTable().toString(true));
-
-      cache2.put(NODE, "age", 39);
-      System.out.println("TransactionTable for cache2 after cache2.put():\n" + cache2.getTransactionTable().toString(true));
-
-      System.out.println("cache1 before commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 before commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      try
-      {
-         tm.commit();
-         fail("commit should throw a RollbackException, we should not get here");
-      }
-      catch (RollbackException rollback)
-      {
-         System.out.println("Transaction was rolled back, this is correct");
-      }
-
-      System.out.println("cache1 after commit:\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 after commit:\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-
-      assertEquals(0, cache1.getNumberOfNodes());
-      assertEquals(0, cache2.getNumberOfNodes());
-   }
-
-   public void testSyncReplWithModficationsOnBothCachesWithRollback() throws Exception
-   {
-      TransactionManager tm;
-      final Fqn fqn1 = Fqn.fromString("/one/two/three");
-      final Fqn fqn2 = Fqn.fromString("/eins/zwei/drei");
-
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-
-      cache1.getConfiguration().setSyncRollbackPhase(true);
-      cache2.getConfiguration().setSyncRollbackPhase(true);
-
-      tm = beginTransaction();
-      cache1.put(fqn1, "age", 38);
-      cache2.put(fqn2, "age", 39);
-
-      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      // this will rollback the transaction
-      Transaction tx = tm.getTransaction();
-      tx.registerSynchronization(new TransactionAborter(tx));
-
-      try
-      {
-         tm.commit();
-         fail("commit should throw a RollbackException, we should not get here");
-      }
-      catch (RollbackException rollback)
-      {
-         System.out.println("Transaction was rolled back, this is correct");
-      }
-
-      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-
-      assertEquals(0, cache1.getNumberOfNodes());
-      assertEquals(0, cache2.getNumberOfNodes());
-   }
-
-   /**
-    * Test for JBCACHE-359 -- does a callback into cache from a listener
-    * interfere with transaction rollback.
-    *
-    * @throws Exception
-    */
-
-   // Is this test still valid after JBCACHE-1022 ?
-   //   public void testSyncReplWithRollbackAndListener() throws Exception
-   //   {
-   //      Transaction tx;
-   //      final Fqn NODE1 = Fqn.fromString("/one/two/three");
-   //
-   //      initCaches(Configuration.CacheMode.REPL_SYNC);
-   //
-   //      cache1.getConfiguration().setSyncRollbackPhase(true);
-   //      cache2.getConfiguration().setSyncRollbackPhase(true);
-   //
-   //      // Test with a rollback on the sending side
-   //
-   //      CallbackListener cbl1 = new CallbackListener(cache1, "age");
-   //      CallbackListener cbl2 = new CallbackListener(cache2, "age");
-   //
-   //      tx = beginTransaction();
-   //      cache1.put(NODE1, "age", 38);
-   //
-   //      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
-   //      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
-   //
-   //      // this will rollback the transaction
-   //      tx.registerSynchronization(new TransactionAborter(tx));
-   //
-   //      try
-   //      {
-   //         tx.commit();
-   //         fail("commit should throw a RollbackException, we should not get here");
-   //      }
-   //      catch (RollbackException rollback)
-   //      {
-   //         rollback.printStackTrace();
-   //         System.out.println("Transaction was rolled back, this is correct");
-   //      }
-   //
-   //      // Sleep, as the rollback call to cache2 is async
-   //      TestingUtil.sleepThread(1000);
-   //
-   //      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
-   //      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
-   //
-   //      assertNull(cbl1.getCallbackException());
-   //      assertNull(cbl2.getCallbackException());
-   //
-   //      assertEquals(0, cache1.getNumberOfLocksHeld());
-   //      assertEquals(0, cache2.getNumberOfLocksHeld());
-   //
-   //      assertEquals(0, cache1.getNumberOfNodes());
-   //      assertEquals(0, cache2.getNumberOfNodes());
-   //
-   //      // Test with a rollback on the receiving side
-   //
-   //      cache2.getNotifier().removeCacheListener(cbl2);
-   //      // listener aborts any active tx
-   //      cbl2 = new TransactionAborterCallbackListener(cache2, "age");
-   //
-   //      tx = beginTransaction();
-   //      cache1.put(NODE1, "age", 38);
-   //
-   //      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
-   //      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
-   //
-   //      tx.commit();
-   //
-   //      // Sleep, as the commit call to cache2 is async
-   //      TestingUtil.sleepThread(1000);
-   //
-   //      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
-   //      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
-   //
-   //      assertNull(cbl1.getCallbackException());
-   //      assertNull(cbl2.getCallbackException());
-   //
-   //      assertEquals(0, cache1.getNumberOfLocksHeld());
-   //      assertEquals(0, cache2.getNumberOfLocksHeld());
-   //
-   //      // cache1 didn't fail, so should have 3 nodes
-   //      assertEquals(3, cache1.getNumberOfNodes());
-   //      assertEquals(0, cache2.getNumberOfNodes());
-   //
-   //   }
-
-   /**
-    * Test for JBCACHE-361 -- does marking a tx on the remote side
-    * rollback-only cause a rollback on the originating side?
-    */
-   public void testSyncReplWithRemoteRollback() throws Exception
-   {
-      TransactionManager tm;
-      final Fqn NODE1 = Fqn.fromString("/one/two/three");
-
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-
-      cache1.getConfiguration().setSyncRollbackPhase(true);
-      cache2.getConfiguration().setSyncRollbackPhase(true);
-
-      // Test with a rollback on the remote side
-
-      // listener aborts any active tx
-      //TransactionAborterListener tal = new TransactionAborterListener(cache2);
-
-      tm = beginTransaction();
-      cache1.put(NODE1, "age", 38);
-
-      System.out.println("cache1 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      // instead of a listener lets just get a WL on ROOT on cache2. And hold on to it.
-      Transaction tx = tm.suspend();
-
-      tm.begin();
-      cache2.getRoot().put("x", "y");
-      Transaction tx2 = cache2.getTransactionManager().suspend();
-
-      System.out.println("cache2 (before commit):\n" + CachePrinter.printCacheLockingInfo(cache2));
-      tm.resume(tx);
-
-      try
-      {
-         tm.commit();
-         fail("commit should throw a RollbackException, we should not get here");
-      }
-      catch (RollbackException rollback)
-      {
-         System.out.println("Transaction was rolled back, this is correct");
-      }
-      finally
-      {
-         tm.resume(tx2);
-         tm.rollback();
-      }
-
-      // Sleep, as the commit call to cache2 is async
-      TestingUtil.sleepThread(1000);
-
-      System.out.println("cache1 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache1));
-      System.out.println("cache2 (after rollback):\n" + CachePrinter.printCacheLockingInfo(cache2));
-
-      //assertNull(tal.getCallbackException());
-
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-
-      assertEquals(0, cache1.getNumberOfNodes());
-      assertEquals(0, cache2.getNumberOfNodes());
-
-   }
-
-   public void testASyncRepl() throws Exception
-   {
-      Integer age;
-      TransactionManager tm;
-
-      initCaches(Configuration.CacheMode.REPL_ASYNC);
-
-      tm = beginTransaction();
-      cache1.put("/a/b/c", "age", 38);
-      Thread.sleep(1000);
-      assertNull("age on cache2 must be null as the TX has not yet been committed", cache2.get("/a/b/c", "age"));
-      tm.commit();
-      Thread.sleep(1000);
-
-      // value on cache2 must be 38
-      age = (Integer) cache2.get("/a/b/c", "age");
-      assertNotNull("\"age\" obtained from cache2 is null ", age);
-      assertTrue("\"age\" must be 38", age == 38);
-
-   }
-
-   /**
-    * Tests concurrent modifications: thread1 succeeds and thread2 is blocked until thread1 is done, and then succeeds
-    * too. However, this is flawed with the introduction of interceptors, here's why.<br/>
-    * <ul>
-    * <li>Thread1 acquires the lock for /bela/ban on cache1
-    * <li>Thread2 blocks on Thread1 to release the lock
-    * <li>Thread1 commits: this means the TransactionInterceptor and the ReplicationInterceptor are called in
-    * the sequence in which they registered. Unfortunately, the TransactionInterceptor registered first. In the
-    * PREPARE phase, the ReplicationInterceptor calls prepare() in cache2 synchronously. The TxInterceptor
-    * does nothing. The the COMMIT phase, the TxInterceptor commits the data by releasing the locks locally and
-    * then the ReplicationInterceptor sends an asynchronous COMMIT to cache2.
-    * <li>Because the TxInterceptor for Thread1 releases the locks locally <em>before</em> sending the async COMMIT,
-    * Thread2 is able to acquire the lock for /bela/ban in cache1 and then starts the PREPARE phase by sending a
-    * synchronous PREPARE to cache2. If this PREPARE arrives at cache2 <em>before</em> the COMMIT from Thread1,
-    * the PREPARE will block because it attempts to acquire a lock on /bela/ban on cache2 still held by Thread1
-    * (which would be released by Thread1's COMMIT). This results in deadlock, which is resolved by Thread2 running
-    * into a timeout with subsequent rollback and Thread1 succeeding.<br/>
-    * </ul>
-    * There are 3 solutions to this:
-    * <ol>
-    * <li>Do nothing. This is standard behavior for concurrent access to the same data. Same thing if the 2 threads
-    * operated on the same data in <em>separate</em> caches, e.g. Thread1 on /bela/ban in cache1 and Thread2 on
-    * /bela/ban in cache2. The semantics of Tx commit as handled by the interceptors is: after tx1.commit() returns
-    * the locks held by tx1 are release and a COMMIT message is on the way (if sent asynchronously).
-    * <li>Force an order over TxInterceptor and ReplicationInterceptor. This would require ReplicationInterceptor
-    * to always be fired first on TX commit. Downside: the interceptors have an implicit dependency, which is not
-    * nice.
-    * <li>Priority-order requests at the receiver; e.g. a COMMIT could release a blocked PREPARE. This is bad because
-    * it violates JGroups' FIFO ordering guarantees.
-    * </ol>
-    * I'm currently investigating solution #2, ie. creating an OrderedSynchronizationHandler, which allows other
-    * SynchronizationHandlers to register (atHead, atTail), and the OrderedSynchronizationHandler would call the
-    * SynchronizationHandler in the order in which they are defined.
-    *
-    * @throws Exception exception
-    */
-   public void testConcurrentPuts() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      cache1.getConfiguration().setSyncCommitPhase(true);
-
-      Thread t1 = new Thread("Thread1")
-      {
-         TransactionManager tm;
-
-         public void run()
-         {
-            try
-            {
-               tm = beginTransaction();
-               cache1.put("/bela/ban", "name", "Bela Ban");
-               TestingUtil.sleepThread(2000);// Thread2 will be blocked until we commit
-               tm.commit();
-               System.out.println("[Thread1] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
-               System.out.println("[Thread1] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t1_ex = ex;
-            }
-         }
-      };
-
-      Thread t2 = new Thread("Thread2")
-      {
-         TransactionManager tm;
-
-         public void run()
-         {
-            try
-            {
-               TestingUtil.sleepThread(1000);// give Thread1 time to acquire the lock
-               tm = beginTransaction();
-               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
-               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
-               cache1.put("/bela/ban", "name", "Michelle Ban");
-               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
-               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
-               tm.commit();
-               System.out.println("[Thread2] ** LOCK INFO cache1: " + CachePrinter.printCacheLockingInfo(cache1));
-               System.out.println("[Thread2] ** LOCK INFO cache2: " + CachePrinter.printCacheLockingInfo(cache2));
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t2_ex = ex;
-            }
-         }
-      };
-
-      // Let the game start
-      t1.start();
-      t2.start();
-
-      // Wait for threads to die
-      t1.join();
-      t2.join();
-
-      if (t1_ex != null)
-      {
-         fail("Thread1 failed: " + t1_ex);
-      }
-      if (t2_ex != null)
-      {
-         fail("Thread2 failed: " + t2_ex);
-      }
-
-      assertEquals("Michelle Ban", cache1.get("/bela/ban", "name"));
-   }
-
-   /**
-    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
-    */
-   public void testConcurrentCommitsWith1Thread() throws Exception
-   {
-      _testConcurrentCommits(1);
-   }
-
-   /**
-    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
-    */
-   public void testConcurrentCommitsWith5Threads() throws Exception
-   {
-      _testConcurrentCommits(5);
-   }
-
-   /**
-    * Should reproduce JBCACHE-32 problem (http://jira.jboss.com/jira/browse/JBCACHE-32)
-    */
-   private void _testConcurrentCommits(int num_threads)
-   {
-      Object myMutex = new Object();
-
-      final CacheSPI<Object, Object> c1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
-      final CacheSPI<Object, Object> c2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
-      c1.getConfiguration().setClusterName("TempCluster");
-      c2.getConfiguration().setClusterName("TempCluster");
-      c1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
-      c2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
-      c1.getConfiguration().setSyncCommitPhase(true);
-      c2.getConfiguration().setSyncCommitPhase(true);
-      c1.getConfiguration().setSyncRollbackPhase(true);
-      c2.getConfiguration().setSyncRollbackPhase(true);
-      c1.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-      c2.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-      c1.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
-      c2.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
-      c1.getConfiguration().setLockAcquisitionTimeout(5000);
-      c2.getConfiguration().setLockAcquisitionTimeout(5000);
-      c1.start();
-      c2.start();
-      final List<Exception> exceptions = new ArrayList<Exception>();
-
-      class MyThread extends Thread
-      {
-         final Object mutex;
-
-         public MyThread(String name, Object mutex)
-         {
-            super(name);
-            this.mutex = mutex;
-         }
-
-         public void run()
-         {
-            TransactionManager tm = null;
-
-            try
-            {
-               tm = beginTransaction(c1);
-               c1.put("/thread/" + getName(), null);
-               System.out.println("Thread " + getName() + " after put(): " + c1.toString());
-               System.out.println("Thread " + getName() + " waiting on mutex");
-               synchronized (mutex)
-               {
-                  mutex.wait();
-               }
-               System.out.println("Thread " + getName() + " committing");
-               tm.commit();
-               System.out.println("Thread " + getName() + " committed successfully");
-            }
-            catch (Exception e)
-            {
-               exceptions.add(e);
-            }
-            finally
-            {
-               try
-               {
-                  if (tm != null)
-                     tm.rollback();
-               }
-               catch (Exception e)
-               {
-                  // do nothing
-               }
-            }
-         }
-      }
-
-      MyThread[] threads = new MyThread[num_threads];
-      for (int i = 0; i < threads.length; i++)
-      {
-         threads[i] = new MyThread("#" + i, myMutex);
-      }
-      for (int i = 0; i < threads.length; i++)
-      {
-         MyThread thread = threads[i];
-         System.out.println("starting thread #" + i);
-         thread.start();
-      }
-
-      TestingUtil.sleepThread(6000);
-      synchronized (myMutex)
-      {
-         System.out.println("cache is " + CachePrinter.printCacheLockingInfo(c1));
-         System.out.println("******************* SIGNALLING THREADS ********************");
-         myMutex.notifyAll();
-      }
-
-      for (MyThread thread : threads)
-      {
-         try
-         {
-            thread.join();
-            System.out.println("Joined thread " + thread.getName());
-         }
-         catch (InterruptedException e)
-         {
-            e.printStackTrace();
-         }
-      }
-
-      System.out.println("FINAL c1:\n" + CachePrinter.printCacheDetails(c1) + "\nlocks:\n" + CachePrinter.printCacheLockingInfo(c1));
-
-      assertEquals(0, c1.getNumberOfLocksHeld());
-      assertEquals(0, c2.getNumberOfLocksHeld());
-
-      c1.stop();
-      c2.stop();
-
-      //      if(ex != null)
-      //      {
-      //         ex.printStackTrace();
-      //         fail("Thread failed: " + ex);
-      //      }
-
-      // we can only expect 1 thread to succeed.  The others will fail.  So, threads.length -1 exceptions.
-      // this is a timing issue - 2 threads still may succeed on a multi cpu system
-      // assertEquals(threads.length - 1, exceptions.size());
-
-      for (Exception exception : exceptions)
-         assertEquals(TimeoutException.class, exception.getClass());
-   }
-
-   /**
-    * Conncurrent put on 2 different instances.
-    */
-   public void testConcurrentPutsOnTwoInstances() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      final CacheSPI<Object, Object> c1 = this.cache1;
-      final CacheSPI<Object, Object> c2 = this.cache2;
-
-      Thread t1 = new Thread()
-      {
-         TransactionManager tm;
-
-         public void run()
-         {
-            try
-            {
-               tm = beginTransaction();
-               c1.put("/ben/wang", "name", "Ben Wang");
-               TestingUtil.sleepThread(8000);
-               tm.commit();// This should go thru
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t1_ex = ex;
-            }
-         }
-      };
-
-      Thread t2 = new Thread()
-      {
-         TransactionManager tm;
-
-         public void run()
-         {
-            try
-            {
-               TestingUtil.sleepThread(1000);// give Thread1 time to acquire the lock
-               tm = beginTransaction();
-               c2.put("/ben/wang", "name", "Ben Jr.");
-               tm.commit();// This will time out and rollback first because Thread1 has a tx going as well.
-            }
-            catch (RollbackException rollback_ex)
-            {
-               System.out.println("received rollback exception as expected");
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t2_ex = ex;
-            }
-         }
-      };
-
-      // Let the game start
-      t1.start();
-      t2.start();
-
-      // Wait for thread to die but put an insurance of 5 seconds on it.
-      t1.join();
-      t2.join();
-
-      if (t1_ex != null)
-      {
-         fail("Thread1 failed: " + t1_ex);
-      }
-      if (t2_ex != null)
-      {
-         fail("Thread2 failed: " + t2_ex);
-      }
-      assertEquals("Ben Wang", c1.get("/ben/wang", "name"));
-   }
-
-   public void testPut() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      final CacheSPI<Object, Object> c1 = this.cache1;
-
-      Thread t1 = new Thread()
-      {
-         public void run()
-         {
-            try
-            {
-               lock.acquire();
-               System.out.println("-- t1 has lock");
-               c1.put("/a/b/c", "age", 38);
-               System.out.println("[Thread1] set value to 38");
-
-               System.out.println("-- t1 releases lock");
-               lock.release();
-               TestingUtil.sleepThread(300);
-               Thread.yield();
-
-               lock.acquire();
-               System.out.println("-- t1 has lock");
-               c1.put("/a/b/c", "age", 39);
-               System.out.println("[Thread1] set value to 39");
-
-               System.out.println("-- t1 releases lock");
-               lock.release();
-               assertEquals(39, c1.get("/a/b/c", "age"));
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t1_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      Thread t2 = new Thread()
-      {
-         public void run()
-         {
-            try
-            {
-               TestingUtil.sleepThread(100);
-               Thread.yield();
-               lock.acquire();
-               System.out.println("-- t2 has lock");
-               // Should replicate the value right away.
-               Integer val = (Integer) cache2.get("/a/b/c", "age");
-               System.out.println("[Thread2] value is " + val);
-               assertEquals(new Integer(38), val);
-               System.out.println("-- t2 releases lock");
-               lock.release();
-               TestingUtil.sleepThread(300);
-               Thread.yield();
-               TestingUtil.sleepThread(500);
-               lock.acquire();
-               System.out.println("-- t2 has lock");
-               val = (Integer) cache2.get("/a/b/c", "age");
-               System.out.println("-- t2 releases lock");
-               lock.release();
-               assertEquals(new Integer(39), val);
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t2_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      // Let the game start
-      t1.start();
-      t2.start();
-
-      // Wait for thread to die but put an insurance of 5 seconds on it.
-      t1.join();
-      t2.join();
-      if (t1_ex != null)
-      {
-         fail("Thread1 failed: " + t1_ex);
-      }
-      if (t2_ex != null)
-      {
-         fail("Thread2 failed: " + t2_ex);
-      }
-   }
-
-   /**
-    * Test replicated cache with transaction. Idea is to have two threads running
-    * a local cache each that is replicating. Depending on whether cache1 commit/rollback or not,
-    * the cache2.get will get different values.
-    * Note that we have used sleep to interpose thread execution sequence.
-    * Although it's not fool proof, it is rather simple and intuitive.
-    */
-   public void testPutTx() throws Exception
-   {
-      TransactionManager tm;
-
-      try
-      {
-         initCaches(Configuration.CacheMode.REPL_SYNC);
-         cache1.getConfiguration().setSyncCommitPhase(true);
-         cache2.getConfiguration().setSyncCommitPhase(true);
-         tm = beginTransaction();
-         cache1.put("/a/b/c", "age", 38);
-         cache1.put("/a/b/c", "age", 39);
-         Object val = cache2.get("/a/b/c", "age");// must be null as not yet committed
-         assertNull(val);
-         tm.commit();
-
-         tm = beginTransaction();
-         assertEquals(39, cache2.get("/a/b/c", "age"));// must not be null
-         tm.commit();
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         t1_ex = t;
-      }
-      finally
-      {
-         lock.release();
-      }
-   }
-
-   /**
-    * Have both cache1 and cache2 do add and commit. cache1 commit should time out
-    * since it can't obtain the lock when trying to replicate cache2. On the other hand,
-    * cache2 commit will succeed since now that cache1 is rollbacked and lock is
-    * released.
-    */
-   public void testPutTx1() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      final CacheSPI<Object, Object> c1 = this.cache1;
-      Thread t1 = new Thread()
-      {
-         public void run()
-         {
-            TransactionManager tm;
-
-            try
-            {
-               lock.acquire();
-               tm = beginTransaction();
-               c1.put("/a/b/c", "age", 38);
-               c1.put("/a/b/c", "age", 39);
-               lock.release();
-
-               TestingUtil.sleepThread(300);
-               lock.acquire();
-               try
-               {
-                  tm.commit();
-               }
-               catch (RollbackException ex)
-               {
-                  System.out.println("[Thread1] received RollbackException, as expected. Rolling back changes");
-               }
-               finally
-               {
-                  lock.release();
-               }
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t1_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      Thread t2 = new Thread()
-      {
-         public void run()
-         {
-            TransactionManager tm;
-
-            try
-            {
-               sleep(200);
-               Thread.yield();
-               lock.acquire();
-               tm = beginTransaction();
-               assertNull(cache2.get("/a/b/c", "age"));// must be null as not yet committed
-               cache2.put("/a/b/c", "age", 40);
-               lock.release();
-
-               TestingUtil.sleepThread(300);
-               lock.acquire();
-               assertEquals(40, cache2.get("/a/b/c", "age"));// must not be null
-               tm.commit();
-               lock.release();
-
-               TestingUtil.sleepThread(1000);
-               tm = beginTransaction();
-               assertEquals("After cache2 commit", 40, cache2.get("/a/b/c", "age"));
-               tm.commit();
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t2_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      // Let the game start
-      t1.start();
-      t2.start();
-
-      t1.join();
-      t2.join();
-
-      if (t1_ex != null)
-      {
-         fail("Thread1 failed: " + t1_ex);
-      }
-      if (t2_ex != null)
-      {
-         fail("Thread2 failed: " + t2_ex);
-      }
-   }
-
-   public void testPutTxWithRollback() throws Exception
-   {
-      initCaches(Configuration.CacheMode.REPL_SYNC);
-      final CacheSPI<Object, Object> c2 = this.cache1;
-      Thread t1 = new Thread()
-      {
-         public void run()
-         {
-            TransactionManager tm;
-
-            try
-            {
-               lock.acquire();
-               tm = beginTransaction();
-               c2.put("/a/b/c", "age", 38);
-               c2.put("/a/b/c", "age", 39);
-               lock.release();
-
-               TestingUtil.sleepThread(100);
-               lock.acquire();
-               tm.rollback();
-               lock.release();
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t1_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      Thread t2 = new Thread()
-      {
-         public void run()
-         {
-            TransactionManager tm;
-
-            try
-            {
-               sleep(200);
-               Thread.yield();
-               lock.acquire();
-               tm = beginTransaction();
-               assertNull(cache2.get("/a/b/c", "age"));// must be null as not yet committed
-               lock.release();
-
-               TestingUtil.sleepThread(100);
-               lock.acquire();
-               assertNull(cache2.get("/a/b/c", "age"));// must be null as rolledback
-               tm.commit();
-               lock.release();
-            }
-            catch (Throwable ex)
-            {
-               ex.printStackTrace();
-               t2_ex = ex;
-            }
-            finally
-            {
-               lock.release();
-            }
-         }
-      };
-
-      // Let the game start
-      t1.start();
-      t2.start();
-
-      // Wait for thread to die but put an insurance of 5 seconds on it.
-      t1.join();
-      t2.join();
-      if (t1_ex != null)
-      {
-         fail("Thread1 failed: " + t1_ex);
-      }
-      if (t2_ex != null)
-      {
-         fail("Thread2 failed: " + t2_ex);
-      }
-   }
-
-   static class TransactionAborter implements Synchronization
-   {
-      Transaction ltx = null;
-
-      public TransactionAborter(Transaction ltx)
-      {
-         this.ltx = ltx;
-      }
-
-      public void beforeCompletion()
-      {
-         try
-         {
-            ltx.setRollbackOnly();
-         }
-         catch (SystemException e)
-         {
-            // who cares
-         }
-      }
-
-      public void afterCompletion(int status)
-      {
-      }
-   }
-
-   @CacheListener
-   static class CallbackListener
-   {
-
-      CacheSPI<Object, Object> callbackCache;
-      Object callbackKey;
-      Exception ex;
-      final Object mutex = new Object();
-
-      CallbackListener(CacheSPI<Object, Object> cache, Object callbackKey)
-      {
-         this.callbackCache = cache;
-         this.callbackKey = callbackKey;
-         cache.getNotifier().addCacheListener(this);
-      }
-
-      @NodeModified
-      public void nodeModified(NodeEvent e)
-      {
-         if (!e.isPre())
-         {
-            // Lock on a mutex so test can't check for an exception
-            // until the get call completes
-            synchronized (mutex)
-            {
-               try
-               {
-                  callbackCache.get(e.getFqn(), callbackKey);
-               }
-               catch (CacheException exc)
-               {
-                  exc.printStackTrace();
-                  ex = exc;
-               }
-            }
-         }
-      }
-
-      Exception getCallbackException()
-      {
-         synchronized (mutex)
-         {
-            return ex;
-         }
-      }
-
-   }
-
-   static class TransactionAborterCallbackListener extends CallbackListener
-   {
-
-      TransactionManager callbackTM;
-
-      TransactionAborterCallbackListener(CacheSPI<Object, Object> cache, Object callbackKey)
-      {
-         super(cache, callbackKey);
-         callbackTM = callbackCache.getTransactionManager();
-      }
-
-      @NodeModified
-      public void nodeModified(NodeEvent ne)
-      {
-         if (!ne.isPre())
-         {
-            try
-            {
-               Transaction tx = callbackTM.getTransaction();
-               if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE)
-               {
-                  // this will rollback the transaction
-                  tx.registerSynchronization(new TransactionAborter(tx));
-               }
-               else
-               {
-                  super.nodeModified(ne);
-               }
-
-            }
-            catch (Exception e)
-            {
-               e.printStackTrace();
-               if (ex == null)
-               {
-                  ex = e;
-               }
-            }
-         }
-      }
-
-   }
-
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/AbortionTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/AbortionTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/AbortionTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,199 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
-import org.jboss.cache.transaction.NotifyingTransactionManager.Notification;
-import org.jboss.cache.util.TestingUtil;
-import org.jgroups.JChannel;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.RollbackException;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- */
- at Test(groups = {"functional"})
-public class AbortionTest
-{
-   private CacheSPI cache1, cache2, cache3;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      cache1 = initCache(false);
-      TestingUtil.sleepThread(1500); // to ensure cache1 is the coordinator
-      cache2 = initCache(false);
-      cache3 = initCache(true);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      TestingUtil.killCaches(cache3, cache2, cache1);
-   }
-
-   private CacheSPI initCache(boolean notifying)
-   {
-      CacheSPI c = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(false);
-      c.getConfiguration().setCacheMode("REPL_SYNC");
-      c.getConfiguration().setClusterConfig(getJGroupsStack());
-      c.getConfiguration().setFetchInMemoryState(false);
-      if (!notifying)
-      {
-         c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
-      }
-      else
-      {
-         c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.NotifyingTransactionManager");
-      }
-      c.start();
-      return c;
-   }
-
-   // we need a 'special' stack that does not attempt redelivery since we kill a channel midway during a tx in this test.
-   private String getJGroupsStack()
-   {
-      return JChannel.DEFAULT_PROTOCOL_STACK;
-   }
-
-   private void destroyCache(CacheSPI c)
-   {
-      if (c != null)
-      {
-         c.stop();
-         c.destroy();
-      }
-   }
-
-   public void testSyncCaches() throws Exception
-   {
-      performTest(false, false);
-   }
-
-   public void testSyncCachesSyncCommitRollback() throws Exception
-   {
-      performTest(true, false);
-   }
-
-   /**
-    * Note that this tests a *remote* beforeCompletion abort - which is a part of the calling instance's afterCompletion.
-    *
-    * @throws Exception
-    */
-   public void testAbortBeforeCompletion() throws Exception
-   {
-      performTest(true, true);
-   }
-
-   private void performTest(boolean syncCommitRollback, boolean abortBeforeCompletion) throws Exception
-   {
-      cache1.getConfiguration().setSyncCommitPhase(syncCommitRollback);
-      cache1.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
-      cache2.getConfiguration().setSyncCommitPhase(syncCommitRollback);
-      cache2.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
-      cache3.getConfiguration().setSyncCommitPhase(syncCommitRollback);
-      cache3.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
-
-      TransactionManager mgr1 = cache1.getTransactionManager();
-      TransactionManager mgr2 = cache2.getTransactionManager();
-      assertTrue(cache3.getTransactionManager() instanceof NotifyingTransactionManager);
-      NotifyingTransactionManager mgr3 = (NotifyingTransactionManager) cache3.getTransactionManager();
-      mgr3.setCache(cache3);
-
-      assertSame(mgr1, mgr2);
-      assertNotSame(mgr1, mgr3);
-      assertNotSame(mgr2, mgr3);
-
-      assertTrue(mgr1 instanceof DummyTransactionManager);
-      assertTrue(mgr2 instanceof DummyTransactionManager);
-
-      cache1.put("/test", "key", "value");
-
-      assertEquals("value", cache1.get("/test", "key"));
-      assertEquals("value", cache2.get("/test", "key"));
-      assertEquals("value", cache3.get("/test", "key"));
-
-      mgr3.setNotification(new TestNotification(abortBeforeCompletion));
-
-      mgr1.begin();
-      cache1.put("/test", "key", "value2");
-      mgr1.commit();
-
-      TestingUtil.sleepThread(5000);
-
-      // only test cache1 and cache2.  Assume cache3 has crashed out.
-      assertEquals(0, cache1.getNumberOfLocksHeld());
-      assertEquals(0, cache2.getNumberOfLocksHeld());
-      assertEquals("put in transaction should NOT have been rolled back", "value2", cache1.get("/test", "key"));
-      assertEquals("put in transaction should NOT have been rolled back", "value2", cache2.get("/test", "key"));
-
-   }
-
-   class TestNotification implements Notification
-   {
-      boolean abortBeforeCompletion;
-
-      public TestNotification(boolean abortBeforeCompletion)
-      {
-         this.abortBeforeCompletion = abortBeforeCompletion;
-      }
-
-      public void notify(Transaction tx, TransactionContext transactionContext) throws SystemException, RollbackException
-      {
-         OrderedSynchronizationHandler osh = transactionContext.getOrderedSynchronizationHandler();
-
-         final Transaction finalTx = tx;
-         System.out.println("Notify called.");
-         // add an aborting sync handler.
-         Synchronization abort = new Synchronization()
-         {
-
-            public void beforeCompletion()
-            {
-               if (abortBeforeCompletion)
-               {
-                  cache3.getConfiguration().getRuntimeConfig().getChannel().close();
-                  System.out.println("Returning from abort.beforeCompletion");
-                  try
-                  {
-                     finalTx.setRollbackOnly();
-                  }
-                  catch (SystemException e)
-                  {
-                     throw new RuntimeException("Unable to set rollback", e);
-                  }
-                  throw new RuntimeException("Dummy exception");
-               }
-            }
-
-            public void afterCompletion(int i)
-            {
-               if (!abortBeforeCompletion)
-               {
-                  cache3.getConfiguration().getRuntimeConfig().getChannel().close();
-                  System.out.println("Returning from abort.afterCompletion");
-                  throw new RuntimeException("Dummy exception");
-               }
-            }
-         };
-
-         osh.registerAtHead(abort);
-         System.out.println("Added sync handler.");
-      }
-
-   }
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/AsyncRollbackTxTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/AsyncRollbackTxTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/AsyncRollbackTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,239 +0,0 @@
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
-
-/**
- * Test behaviour of async rollback timeouted transaction
- *
- * @author <a href="mailto:jhalat at infovide.pl">Jacek Halat</a>
- * @since 1.4.0
- */
- at Test(groups = {"functional"})
-public class AsyncRollbackTxTest
-{
-   private CacheSPI<String, String> cache;
-   private TransactionManager tm;
-   private Fqn fqn = Fqn.fromString("/test");
-   // This sleep time (millis) should be longer than the transaction timeout time.
-   private long sleepTime = 2500;
-   // seconds
-   private int txTimeout = 2;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      Configuration c = new Configuration();
-      c.setTransactionManagerLookupClass("org.jboss.cache.transaction.AsyncRollbackTransactionManagerLookup");
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(c);
-      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-      tm.setTransactionTimeout(txTimeout);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public 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.stop();
-      cache = null;
-      tm = null;
-   }
-
-   public void testCommitCreationInSameTx() throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      tm.begin();
-      cache.put(fqn, "k", "v");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      Thread.sleep(sleepTime);
-      tm.commit();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testRollbackCreationInSameTx() throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      tm.begin();
-      cache.put(fqn, "k", "v");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      Thread.sleep(sleepTime);
-      tm.rollback();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      // make sure the node was NOT added!!
-      assertFalse(cache.exists(fqn));
-      // even in a "deleted" form
-      assertNull(cache.peek(fqn, true));
-   }
-
-   private void doTest(boolean commit, boolean writeLock) throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      cache.put(fqn, "k", "v");//Executed in Not transactional context
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      SeparateThread t = new SeparateThread(commit, writeLock);
-      t.start();
-      t.join();
-      if (t.getException() != null)
-      {
-         throw t.getException();
-      }
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      assertEquals("v", cache.get(fqn, "k"));
-   }
-
-   public void testRollbackCreationInDifferentTxReadLock() throws Exception
-   {
-      doTest(false, false);
-   }
-
-   public void testCommitCreationInDifferentTxReadLock() throws Exception
-   {
-      doTest(true, false);
-   }
-
-   public void testRollbackCreationInDifferentTxWriteLock() throws Exception
-   {
-      doTest(false, true);
-   }
-
-   public void testCommitCreationInDifferentTxWriteLock() throws Exception
-   {
-      doTest(true, true);
-   }
-
-   public void testTxTimeoutAndPutAfter() throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      tm.begin();
-      cache.put(fqn, "k", "v");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      assertNotNull(tm.getTransaction());
-      Thread.sleep(sleepTime);
-      tm.rollback();
-      assertNull(tm.getTransaction());
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      // make sure the node was NOT added!!
-      assertFalse(cache.exists(fqn));
-      // even in a "deleted" form
-      assertNull(cache.peek(fqn, true));
-
-      //Put not some data into cache. Because no transaction is used
-      //no locks should be helds after this line.
-      cache.put(fqn, "k", "v");
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testTxTimeoutAndPutGetAfter() throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      tm.begin();
-      cache.put(fqn, "k", "v");
-      assertEquals(2, cache.getNumberOfLocksHeld());
-      assertNotNull(tm.getTransaction());
-      Thread.sleep(sleepTime);
-      tm.rollback();
-      // make sure the node was NOT added!!
-      assertFalse(cache.exists(fqn));
-      // even in a "deleted" form
-      assertNull(cache.peek(fqn, true));
-      assertNull(tm.getTransaction());
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      //Put not some data into cache. Because no transaction is used
-      //no locks should be helds after this line.
-      cache.put(fqn, "k", "v");
-      cache.get(fqn, "k");
-
-      // Make sure no write lock is retained by the main thread.  Test that another thread can read.
-      SeparateThread t = new SeparateThread(false, false);
-      t.start();
-      t.join();
-      if (t.getException() != null)
-      {
-         throw t.getException();
-      }
-   }
-
-   private class SeparateThread extends Thread
-   {
-      Exception e = null;
-      boolean commit, writeLock;
-
-      public SeparateThread(boolean commit, boolean writeLock)
-      {
-         this.commit = commit;
-         this.writeLock = writeLock;
-      }
-
-      public Exception getException()
-      {
-         return e;
-      }
-
-      public void run()
-      {
-         try
-         {
-            tm.begin();
-            if (writeLock)
-            {
-               cache.put(fqn, "k", "v2");// obtain write lock on node
-            }
-            else
-            {
-               cache.get(fqn, "k");// obtain read lock on node
-            }
-
-            // sleep to ensure tx times out.
-            sleep(2500);
-
-            if (commit)
-            {
-               tm.commit();
-            }
-            else
-            {
-               tm.rollback();
-            }
-
-            assertEquals(0, cache.getNumberOfLocksHeld());
-
-         }
-         catch (Exception e)
-         {
-            this.e = e;
-         }
-      }
-   }
-
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/ConcurrentTransactionalTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/ConcurrentTransactionalTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/ConcurrentTransactionalTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,200 +0,0 @@
-/*
- *
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.transaction;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.lock.IsolationLevel;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.fail;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.UserTransaction;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Unit test for local CacheSPI. Use locking and multiple threads to test
- * concurrent access to the tree.
- *
- * @version $Id$
- */
- at Test(groups = {"functional", "transaction"})
-public class ConcurrentTransactionalTest
-{
-   private CacheSPI<Integer, String> cache;
-   private Log logger_ = LogFactory.getLog(ConcurrentTransactionalTest.class);
-   private static Throwable thread_ex = null;
-   private static final int NUM = 10000;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-   }
-
-   private void createCache(IsolationLevel level)
-   {
-      CacheFactory<Integer, String> factory = new DefaultCacheFactory<Integer, String>();
-      Configuration conf = UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.LOCAL, true);
-      conf.setCacheMode(Configuration.CacheMode.LOCAL);
-      conf.setIsolationLevel(level);
-      conf.setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(conf);
-      cache.put("/a/b/c", null);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      cache.stop();
-      thread_ex = null;
-      TransactionSetup.cleanup();
-   }
-
-   public void testConcurrentAccessWithRWLock() throws Throwable
-   {
-      createCache(IsolationLevel.REPEATABLE_READ);
-      work_();
-   }
-
-   public void testConcurrentAccessWithExclusiveLock() throws Throwable
-   {
-      createCache(IsolationLevel.SERIALIZABLE);
-      work_();
-   }
-
-   private void work_() throws Throwable
-   {
-      Updater one, two;
-      try
-      {
-         one = new Updater("Thread one");
-         two = new Updater("Thread two");
-         long current = System.currentTimeMillis();
-         one.start();
-         two.start();
-         one.join();
-         two.join();
-         if (thread_ex != null)
-         {
-            throw thread_ex;
-         }
-
-         long now = System.currentTimeMillis();
-         log("*** Time elapsed: " + (now - current));
-
-         System.out.println("cache content: " + cache.toString());
-         Set<Integer> keys = cache.getNode(Fqn.fromString("/a/b/c")).getKeys();
-         System.out.println("number of keys=" + keys.size());
-
-         if (keys.size() != NUM)
-         {
-            scanForNullValues(keys);
-
-            try
-            {
-               System.out.println("size=" + keys.size());
-               List<Integer> l = new LinkedList<Integer>(keys);
-               Collections.sort(l);
-               System.out.println("keys: " + l);
-               for (int i = 0; i < NUM; i++)
-               {
-                  if (!l.contains(new Integer(i)))
-                  {
-                     System.out.println("missing: " + i);
-                  }
-               }
-
-               LinkedList<Integer> duplicates = new LinkedList<Integer>();
-               for (Integer integer : l)
-               {
-                  if (duplicates.contains(integer))
-                  {
-                     System.out.println(integer + " is a duplicate");
-                  }
-                  else
-                  {
-                     duplicates.add(integer);
-                  }
-               }
-            }
-            catch (Exception e1)
-            {
-               e1.printStackTrace();
-            }
-         }
-
-         assertEquals(NUM, keys.size());
-      }
-      catch (Exception e)
-      {
-         e.printStackTrace();
-         fail(e.toString());
-      }
-   }
-
-   private void scanForNullValues(Set<Integer> keys)
-   {
-      for (Object o : keys)
-      {
-         if (o == null)
-         {
-            System.err.println("found a null value in keys");
-         }
-      }
-   }
-
-   private void log(String msg)
-   {
-      logger_.debug(" [" + Thread.currentThread() + "]: " + msg);
-   }
-
-   private class Updater extends Thread
-   {
-      private String val = null;
-      private UserTransaction tx;
-
-      public Updater(String name)
-      {
-         this.val = name;
-      }
-
-      public void run()
-      {
-         try
-         {
-            log("adding data");
-            tx = TransactionSetup.getUserTransaction();
-            for (int i = 0; i < NUM; i++)
-            {
-               log("adding data i=" + i);
-               tx.begin();
-               cache.put("/a/b/c", i, val);
-               tx.commit();
-               yield();
-            }
-         }
-         catch (Throwable t)
-         {
-            t.printStackTrace();
-            thread_ex = t;
-         }
-      }
-   }
-
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/IsolationLevelNoneTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/IsolationLevelNoneTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/IsolationLevelNoneTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,102 +0,0 @@
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.lock.IsolationLevel;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.NotSupportedException;
-import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
-
-/**
- * Tests whether modifications within callbacks (TreeCacheListener) are handled correctly
- *
- * @author Bela Ban
- * @version $Id$
- */
- at Test(groups = {"functional", "transaction"})
-public class IsolationLevelNoneTest
-{
-   CacheSPI<String, String> cache = null;
-   final Fqn FQN = Fqn.fromString("/a/b/c");
-   final String KEY = "key";
-   final String VALUE = "value";
-   TransactionManager tm;
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      if (cache != null)
-      {
-         cache.stop();
-         cache.destroy();
-         cache = null;
-      }
-   }
-
-   public void testWithoutTransactions() throws Exception
-   {
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(false);
-      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
-      cache.getConfiguration().setIsolationLevel(IsolationLevel.NONE);
-      cache.start();
-      cache.put(FQN, KEY, VALUE);
-      cache.put(FQN + "/d", KEY, VALUE);
-      Node node = cache.peek(FQN, false, false);
-      assertTrue(node != null && node.getKeys().contains(KEY));
-      assertEquals(VALUE, cache.get(FQN, KEY));
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testWithTransactions() throws Exception
-   {
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(false);
-      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
-      cache.getConfiguration().setIsolationLevel(IsolationLevel.NONE);
-      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache.start();
-      tm = startTransaction();
-      cache.put(FQN, KEY, VALUE);
-      cache.put(FQN + "/d", KEY, VALUE);
-      Node node = cache.peek(FQN, false, false);
-      assertTrue(node != null && node.getKeys().contains(KEY));
-      assertEquals(VALUE, cache.get(FQN, KEY));
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      tm.commit();
-   }
-
-   public void testWithTransactionsRepeatableRead() throws Exception
-   {
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(false);
-      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
-      cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache.start();
-      tm = startTransaction();
-      cache.put(FQN, KEY, VALUE);
-      cache.put(FQN + "/d", KEY, VALUE);
-      Node node = cache.peek(FQN, false, false);
-      assertTrue(node != null && node.getKeys().contains(KEY));
-      assertEquals(VALUE, cache.get(FQN, KEY));
-      assertEquals(5, cache.getNumberOfLocksHeld());
-      tm.commit();
-   }
-
-   private TransactionManager startTransaction() throws SystemException, NotSupportedException
-   {
-      TransactionManager mgr = cache.getTransactionManager();
-      mgr.begin();
-      return mgr;
-   }
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/PrepareTxTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/PrepareTxTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/PrepareTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,154 +0,0 @@
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import static org.testng.AssertJUnit.assertEquals;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.NotSupportedException;
-import javax.transaction.Synchronization;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * Created by IntelliJ IDEA.
- * User: bela
- * Date: Jun 9, 2004
- * Time: 9:05:19 AM
- */
- at Test(groups = {"functional", "transaction"})
-public class PrepareTxTest
-{
-   CacheSPI<String, String> cache;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
-      cache = (CacheSPI<String, String>) instance.createCache(false);
-      cache.getConfiguration().setCacheMode("local");
-      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      cache.create();
-      cache.start();
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      cache.stop();
-      cache.destroy();
-   }
-
-   /**
-    * Tests cache modification <em>inside</em> the afterCompletion() callback. Reproduces a bug fixed in
-    * connection with JBossCache being used as Hibernate's second level cache
-    *
-    * @throws Exception
-    * @throws NotSupportedException
-    */
-   public void testCacheModificationInBeforeCompletionPhase() throws Exception
-   {
-      int numLocks = 0;
-      TransactionManager mgr = cache.getTransactionManager();
-      mgr.begin();
-      Transaction tx = mgr.getTransaction();
-
-      // this will cause the cache to register with TransactionManager for TX completion callbacks
-      cache.put("/one/two/three", "key1", "val1");
-      numLocks = cache.getNumberOfLocksHeld();
-      assertEquals(4, numLocks);
-
-      // we register *second*
-      tx.registerSynchronization(new Synchronization()
-      {
-
-         public void beforeCompletion()
-         {
-            try
-            {
-               cache.put("/a/b/c", null);
-            }
-            catch (CacheException e)
-            {
-               e.printStackTrace();
-            }
-         }
-
-         public void afterCompletion(int status)
-         {
-         }
-      });
-
-      mgr.commit();
-      numLocks = cache.getNumberOfLocksHeld();
-      assertEquals(0, numLocks);
-
-      int num_local_txs, num_global_txs;
-      TransactionTable tx_table = cache.getTransactionTable();
-      num_local_txs = tx_table.getNumLocalTransactions();
-      num_global_txs = tx_table.getNumGlobalTransactions();
-      System.out.println("Number of Transactions: " + num_local_txs + "\nNumber of GlobalTransactions: " + num_global_txs + "\nTransactionTable:\n "
-            + tx_table.toString(true));
-      assertEquals(num_local_txs, num_global_txs);
-      assertEquals(0, num_local_txs);
-   }
-
-   /**
-    * Tests cache modification <em>inside</em> the afterCompletion() callback. Reproduces a bug fixed in
-    * connection with JBossCache being used as Hibernate's second level cache
-    *
-    * @throws Exception
-    * @throws NotSupportedException
-    */
-   public void testCacheModificationInAfterCompletionPhase() throws Exception
-   {
-      int numLocks = 0;
-      TransactionManager mgr = cache.getTransactionManager();
-      mgr.begin();
-      Transaction tx = mgr.getTransaction();
-
-      // this will cause the cache to register with TransactionManager for TX completion callbacks
-      cache.put("/one/two/three", "key1", "val1");
-      numLocks = cache.getNumberOfLocksHeld();
-      assertEquals(4, numLocks);
-
-      // we register *second*
-      tx.registerSynchronization(new Synchronization()
-      {
-
-         public void beforeCompletion()
-         {
-         }
-
-         public void afterCompletion(int status)
-         {
-            try
-            {
-               cache.put("/a/b/c", null);
-            }
-            catch (CacheException e)
-            {
-               e.printStackTrace();
-            }
-         }
-      });
-
-      mgr.commit();
-      numLocks = cache.getNumberOfLocksHeld();
-      assertEquals(0, numLocks);
-
-      int num_local_txs, num_global_txs;
-      TransactionTable tx_table = cache.getTransactionTable();
-      num_local_txs = tx_table.getNumLocalTransactions();
-      num_global_txs = tx_table.getNumGlobalTransactions();
-      System.out.println("Number of Transactions: " + num_local_txs + "\nNumber of GlobalTransactions: " + num_global_txs + "\nTransactionTable:\n "
-            + tx_table.toString(true));
-      assertEquals(num_local_txs, num_global_txs);
-      assertEquals(0, num_local_txs);
-   }
-
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/StatusUnknownTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/StatusUnknownTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/StatusUnknownTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,162 +0,0 @@
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * This test checks how the cache behaves when a JTA STATUS_UNKNOWN is passed in to the cache during afterCompletion().
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
- */
- at Test(groups = "functional")
-public class StatusUnknownTest
-{
-   private Cache<String, String> cache;
-   private TransactionManager tm;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-      cache = new DefaultCacheFactory<String, String>().createCache(false);
-      cache.getConfiguration().setTransactionManagerLookupClass(HeuristicFailingDummyTransactionManagerLookup.class.getName());
-      cache.start();
-      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown()
-   {
-      cache.stop();
-   }
-
-   public void testStatusUnknown() throws Exception
-   {
-      tm.begin();
-      Fqn fqn = Fqn.fromString("/a/b/c");
-
-      cache.put(fqn, "k", "v");
-      assertEquals(4, ((CacheSPI) cache).getNumberOfLocksHeld());
-      assertTrue(cache.getRoot().hasChild(fqn));
-      tm.commit();
-
-      assertEquals(0, ((CacheSPI) cache).getNumberOfLocksHeld());
-      assertFalse(cache.getRoot().hasChild(fqn));
-   }
-
-   public static class HeuristicFailingDummyTransactionManager extends DummyTransactionManager
-   {
-      private static final long serialVersionUID = 6325631394461739211L;
-
-      @Override
-      public void begin() throws SystemException, NotSupportedException
-      {
-         super.begin();
-
-         Transaction tx = new HeuristicFailingDummyTransaction(this);
-         setTransaction(tx);
-      }
-
-      public static DummyTransactionManager getInstance()
-      {
-         if (instance == null)
-         {
-            instance = new HeuristicFailingDummyTransactionManager();
-            try
-            {
-               Properties p = new Properties();
-               p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
-               Context ctx = new InitialContext(p);
-               ctx.bind("java:/TransactionManager", instance);
-               ctx.bind("UserTransaction", new DummyUserTransaction(instance));
-            }
-            catch (NamingException e)
-            {
-               log.error("binding of DummyTransactionManager failed", e);
-            }
-         }
-         return instance;
-      }
-   }
-
-   public static class HeuristicFailingDummyTransaction extends DummyTransaction
-   {
-      public HeuristicFailingDummyTransaction(DummyBaseTransactionManager mgr)
-      {
-         super(mgr);
-      }
-
-      @Override
-      public void commit() throws RollbackException
-      {
-         try
-         {
-            notifyBeforeCompletion();
-            notifyAfterCompletion(Status.STATUS_UNKNOWN);
-         }
-         finally
-         {
-            // Disassociate tx from thread.
-            tm_.setTransaction(null);
-         }
-      }
-
-      @Override
-      protected void notifyAfterCompletion(int status)
-      {
-         List<Synchronization> tmp;
-
-         synchronized (participants)
-         {
-            tmp = new LinkedList<Synchronization>(participants);
-         }
-
-         for (Synchronization s : tmp)
-         {
-            try
-            {
-               s.afterCompletion(status);
-            }
-            catch (Throwable t)
-            {
-               throw (RuntimeException) t;
-            }
-         }
-
-         synchronized (participants)
-         {
-            participants.clear();
-         }
-      }
-   }
-
-   public static class HeuristicFailingDummyTransactionManagerLookup implements TransactionManagerLookup
-   {
-
-      public TransactionManager getTransactionManager() throws Exception
-      {
-         return HeuristicFailingDummyTransactionManager.getInstance();
-      }
-   }
-}
-
-

Deleted: core/trunk/src/test/java/org/jboss/cache/transaction/TransactionTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/TransactionTest.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/TransactionTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -1,1068 +0,0 @@
-/*
- *
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.transaction;
-
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.cache.NodeSPI;
-import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.lock.LockManager;
-import static org.jboss.cache.lock.LockType.READ;
-import static org.jboss.cache.lock.LockType.WRITE;
-import org.jboss.cache.util.CachePrinter;
-import org.jboss.cache.util.TestingUtil;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tests transactional access to a local CacheImpl.
- * Note: we use DummpyTranasctionManager to replace jta
- *
- * @version $Id$
- */
- at Test(groups = {"functional", "transaction"})
-public class TransactionTest
-{
-   CacheSPI<String, Comparable> cache = null;
-   UserTransaction tx = null;
-   Exception exception;
-   LockManager lockManager;
-
-   @BeforeMethod(alwaysRun = true)
-   public void setUp() throws Exception
-   {
-
-      CacheFactory<String, Comparable> instance = new DefaultCacheFactory<String, Comparable>();
-      cache = (CacheSPI<String, Comparable>) instance.createCache(false);
-      cache.getConfiguration().setClusterName("test");
-      cache.getConfiguration().setStateRetrievalTimeout(10000);
-      cache.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
-      cache.getConfiguration().setLockParentForChildInsertRemove(true);// this test case is written to assume this.
-      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
-      tx = TransactionSetup.getUserTransaction();
-
-      cache.create();
-      cache.start();
-      exception = null;
-      lockManager = TestingUtil.extractLockManager(cache);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   public void tearDown() throws Exception
-   {
-      if (cache != null)
-      {
-         cache.stop();
-         cache = null;
-      }
-
-      // BW. kind of a hack to destroy jndi binding and thread local tx before next run.
-      TransactionSetup.cleanup();
-
-      if (tx != null)
-      {
-         try
-         {
-            tx.rollback();
-         }
-         catch (Throwable t)
-         {
-            // do nothing
-         }
-         tx = null;
-      }
-   }
-
-   public void testPutTx() throws Exception
-   {
-      tx.begin();
-      cache.put("/a/b/c", "age", 38);
-      // the tx interceptor should know that we're in the same tx.
-      assertEquals(cache.get("/a/b/c", "age"), 38);
-
-      cache.put("/a/b/c", "age", 39);
-      tx.commit();
-
-      // This test is done outside the TX, it wouldn't work if someone else
-      // modified "age". This works because we're the only TX running.
-      assertEquals(cache.get("/a/b/c", "age"), 39);
-   }
-
-   public void testRollbackTx1()
-   {
-      try
-      {
-         tx.begin();
-         cache.put("/a/b/c", "age", 38);
-         cache.put("/a/b/c", "age", 39);
-         tx.rollback();
-
-         // This test is done outside the TX, it wouldn't work if someone else
-         // modified "age". This works because we're the only TX running.
-         assertNull(cache.get("/a/b/c", "age"));
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   public void testGetAfterRemovalRollback() throws Exception
-   {
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      cache.put("/a/b", null);
-      assertEquals(0, cache.getNumberOfLocksHeld());
-      assertTrue(cache.exists("/a/b"));
-      tx.begin();
-      cache.removeNode("/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.getNode("/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
-      {
-         tx.begin();
-         cache.put("/a/b/c", "age", 38);
-         cache.remove("/a/b/c", "age");
-         tx.rollback();
-
-         // This test is done outside the TX, it wouldn't work if someone else
-         // modified "age". This works because we're the only TX running.
-         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", 38);
-         tx.begin();
-         cache.remove("/a/b/c", "age");
-         tx.rollback();
-
-         // This test is done outside the TX, it wouldn't work if someone else
-         // modified "age". This works because we're the only TX running.
-         assertEquals(38, cache.get("/a/b/c", "age"));
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   public void testRollbackTx3()
-   {
-      try
-      {
-         java.util.Map<String, Comparable> map1 = new java.util.HashMap<String, Comparable>();
-         map1.put("age", 38);
-         java.util.Map<String, Comparable> map2 = new java.util.HashMap<String, Comparable>();
-         map2.put("age", 39);
-         tx.begin();
-         cache.put("/a/b/c", map1);
-         cache.put("/a/b/c", map2);
-         tx.rollback();
-
-         // This test is done outside the TX, it wouldn't work if someone else
-         // modified "age". This works because we're the only TX running.
-         assertNull(cache.get("/a/b/c", "age"));
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   public void testRollbackTx4()
-   {
-      try
-      {
-         Map<String, Comparable> map = new HashMap<String, Comparable>();
-         map.put("age", 38);
-         tx.begin();
-         cache.put("/a/b/c", map);
-         cache.removeNode("/a/b/c");
-         tx.rollback();
-
-         // This test is done outside the TX, it wouldn't work if someone else
-         // modified "age". This works because we're the only TX running.
-         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", "key", "value");
-         System.out.println("after put():\n" + cache);
-         tx.rollback();
-         System.out.println("after rollback():\n" + cache);
-
-         assertNull("node should be not existent", cache.getNode("/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.getNode("/bela/ban"));
-         assertNull("node should be not existent", cache.getNode("/bela/ban/michelle"));
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   public void testNodeDeletionRollback()
-   {
-      try
-      {
-         cache.put("/a/b/c", null);
-         tx.begin();
-         cache.removeNode("/a/b/c");
-         assertNull(cache.getNode("/a/b/c"));
-         cache.removeNode("/a/b");
-         assertNull(cache.getNode("/a/b"));
-         cache.removeNode("/a");
-         assertNull(cache.getNode("/a"));
-         tx.rollback();
-         assertNotNull(cache.getNode("/a/b/c"));
-         assertNotNull(cache.getNode("/a/b"));
-         assertNotNull(cache.getNode("/a"));
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   public void testNodeDeletionRollback2() throws Exception
-   {
-      cache.put("/a/b/c", null);
-      cache.put("/a/b/c1", null);
-      cache.put("/a/b/c2", null);
-      tx.begin();
-      cache.removeNode("/a");
-      assertNull(cache.getNode("/a/b/c"));
-      assertNull(cache.getNode("/a/b/c1"));
-      assertNull(cache.getNode("/a/b/c2"));
-      assertNull(cache.getNode("/a/b"));
-      assertNull(cache.getNode("/a"));
-      Set children = cache.getChildrenNames(Fqn.fromString("/a/b"));
-      assertTrue(children.isEmpty());
-      children = cache.getChildrenNames("/a");
-      assertTrue(children.isEmpty());
-      tx.rollback();
-      assertNotNull(cache.getNode("/a"));
-      assertNotNull(cache.getNode("/a/b"));
-      assertNotNull(cache.getNode("/a/b/c"));
-      assertNotNull(cache.getNode("/a/b/c1"));
-      assertNotNull(cache.getNode("/a/b/c2"));
-      children = cache.getChildrenNames(Fqn.fromString("/a/b"));
-      assertEquals(3, children.size());
-   }
-
-   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);
-   }
-
-   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);
-   }
-
-   public void testNodeRemoval() throws SystemException, NotSupportedException
-   {
-      GlobalTransaction gtx;
-      cache.put("/a/b/c", null);
-      tx.begin();
-      gtx = cache.getCurrentTransaction();
-      cache.removeNode("/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);
-      tx.rollback();
-   }
-
-   public void testNodeRemoval2() throws SystemException, NotSupportedException
-   {
-      GlobalTransaction gtx;
-      cache.put("/a/b/c", null);
-      tx.begin();
-      gtx = cache.getCurrentTransaction();
-      cache.removeNode("/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);
-      tx.rollback();
-   }
-
-   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.getNode("/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"), true));
-      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
-      tx.rollback();
-      assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b"), true));
-      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
-
-   }
-
-   public void testIntermediateNodeCreationOnRemove() throws Exception
-   {
-      cache.put("/a", null);
-      tx.begin();
-      cache.removeNode("/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", true);
-      assertLocked(gtx, "/a/b", true);
-      assertLocked(gtx, "/a/b/c", true);
-      assertNotNull("/a/b should exist", cache.peek(Fqn.fromString("/a/b"), true));
-      assertNotNull("/a/b/c should exist", cache.peek(Fqn.fromString("/a/b/c"), true));
-      assertNotNull("/a/b should NOT be visible", cache.exists(Fqn.fromString("/a/b")));
-      assertNotNull("/a/b/c should NOT be visible", cache.exists(Fqn.fromString("/a/b/c")));
-      tx.rollback();
-      assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b"), true));
-      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
-
-   }
-
-   public void testNodeDeletionRollback3() throws Exception
-   {
-      GlobalTransaction gtx;
-      cache.put("/a/b/c1", null);
-
-      tx.begin();
-      gtx = cache.getCurrentTransaction();
-      cache.put("/a/b/c1", null);
-      assertLocked(gtx, "/a", false);
-      assertLocked(gtx, "/a/b", false);
-      assertLocked(gtx, "/a/b/c1", true);
-
-      cache.put("/a/b/c2", null);
-      assertLocked(gtx, "/a/b", true);
-      assertLocked(gtx, "/a/b/c2", true);
-
-      cache.put("/a/b/c3", null);
-      cache.put("/a/b/c1/one", null);
-      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);
-      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);
-      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);
-
-      cache.removeNode("/a/b");
-      tx.rollback();
-      assertTrue(cache.getChildrenNames("/a/b/c1").isEmpty());
-      Set cn = cache.getChildrenNames(Fqn.fromString("/a/b"));
-      assertEquals(1, cn.size());
-      assertEquals("c1", cn.iterator().next());
-   }
-
-   public void testDoubleLocks() throws Exception
-   {
-      tx.begin();
-      GlobalTransaction gtx = cache.getCurrentTransaction();
-      cache.put("/a/b/c", null);
-      cache.put("/a/b/c", null);
-
-      NodeSPI n = cache.getNode("/a");
-      assert !lockManager.isLocked(n, READ);
-      // make sure this is write locked.
-      assertLocked(gtx, "/a", true);
-
-      n = cache.getNode("/a/b");
-      assert !lockManager.isLocked(n, READ);
-      // make sure this is write locked.
-      assertLocked(gtx, "/a/b", true);
-
-      n = cache.getNode("/a/b/c");
-      assert !lockManager.isLocked(n, READ);
-      // make sure this is write locked.
-      assertLocked(gtx, "/a/b/c", true);
-
-      tx.rollback();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   private void assertLocked(Object owner, String fqn, boolean writeLocked)
-   {
-      NodeSPI<String, Comparable> n = cache.peek(Fqn.fromString(fqn), true);
-      if (owner == null) owner = Thread.currentThread();
-      assertTrue("node " + fqn + " is not locked", lockManager.isLocked(n));
-      if (writeLocked)
-      {
-         assertTrue("node " + fqn + " is not write-locked by owner " + owner + ". Lock details: " + lockManager.printLockInfo(n), lockManager.ownsLock(Fqn.fromString(fqn), WRITE, owner));
-      }
-      else
-      {
-         assertTrue("node " + fqn + " is not read-locked by owner " + owner + ". Lock details: " + lockManager.printLockInfo(n), lockManager.ownsLock(Fqn.fromString(fqn), READ, owner));
-      }
-   }
-
-   public void testConcurrentNodeAccessOnRemovalWithTx() throws Exception
-   {
-      cache.put("/a/b/c", null);
-      tx.begin();
-      cache.removeNode("/a/b/c");
-      // this node should now be locked.
-      TransactionManager tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-      Transaction t = tm.suspend();
-      // start a new tx
-      tm.begin();
-      try
-      {
-         cache.getNode("/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
-         //cache.getTransactionManager().commit();
-         tm.commit();
-      }
-
-      tm.resume(t);
-      tx.rollback();
-
-      assertNotNull(cache.getNode("/a/b/c"));
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testConcurrentNodeAccessOnRemovalWithoutTx() throws Exception
-   {
-      cache.put("/a/b/c", null);
-      tx.begin();
-      cache.removeNode("/a/b/c");
-      // this node should now be locked.
-      Transaction t = cache.getTransactionManager().suspend();
-      Thread th = new Thread()
-      {
-         public void run()
-         {
-            try
-            {
-               cache.getNode("/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
-            }
-         }
-      };
-
-      th.start();
-      th.join();
-
-      cache.getTransactionManager().resume(t);
-      tx.rollback();
-
-      assertNotNull(cache.getNode("/a/b/c"));
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testRemove() throws CacheException, SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException, RollbackException
-   {
-      cache.put("/a/b/c", null);
-      cache.put("/a/b/c/1", null);
-      cache.put("/a/b/c/2", null);
-      cache.put("/a/b/c/3", null);
-      cache.put("/a/b/c/3/a/b/c", null);
-
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      tx.begin();
-      cache.removeNode("/a/b/c");
-      // 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();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-   }
-
-   public void testRemoveAndRollback() throws CacheException, SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException,
-         RollbackException
-   {
-      cache.put("/a/b/c", null);
-      cache.put("/a/b/c/1", null);
-      cache.put("/a/b/c/2", null);
-      cache.put("/a/b/c/3", null);
-      cache.put("/a/b/c/3/a/b/c", null);
-
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      tx.begin();
-      cache.removeNode("/a/b/c");
-      assertEquals(10, cache.getNumberOfLocksHeld());
-      tx.rollback();
-      assertEquals(0, cache.getNumberOfLocksHeld());
-
-      assertTrue(cache.exists("/a/b/c"));
-      assertTrue(cache.exists("/a/b/c/1"));
-      assertTrue(cache.exists("/a/b/c/2"));
-      assertTrue(cache.exists("/a/b/c/3"));
-      assertTrue(cache.exists("/a/b/c/3/a"));
-      assertTrue(cache.exists("/a/b/c/3/a/b"));
-      assertTrue(cache.exists("/a/b/c/3/a/b/c"));
-   }
-
-   public void testRemoveKeyRollback() throws CacheException, SystemException, NotSupportedException
-   {
-      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"));
-   }
-
-   public void testRemoveKeyRollback2()
-   {
-      try
-      {
-         Map<String, Comparable> m = new HashMap<String, Comparable>();
-         m.put("name", "Bela");
-         m.put("id", 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() throws Exception
-   {
-      tx.begin();
-      cache.put("/foo/1", "item", 1);
-      assertEquals(cache.get("/foo/1", "item"), 1);
-      cache.removeNode("/foo/1");
-      assertNull(cache.get("/foo/1", "item"));
-      cache.removeNode("/foo/1");
-      assertNull(cache.get("/foo/1", "item"));
-      tx.rollback();
-      assertFalse(cache.exists("/foo/1"));
-      assertNull(cache.get("/foo/1", "item"));
-   }
-
-   /**
-    * put(Fqn, Map) with a previous null map
-    */
-   public void testPutDataRollback1()
-   {
-      try
-      {
-         cache.put("/bela/ban", null);// create a node /bela/ban with a null map
-         tx.begin();
-         Map<String, Comparable> m = new HashMap<String, Comparable>();
-         m.put("name", "Bela");
-         m.put("id", 322649);
-         cache.put("/bela/ban", m);
-         tx.rollback();
-
-         Node n = cache.getNode("/bela/ban");
-         if (n.getData() == null)
-            return;
-         assertEquals("map should be empty", 0, n.getData().size());
-      }
-      catch (Throwable t)
-      {
-         t.printStackTrace();
-         fail(t.toString());
-      }
-   }
-
-   /**
-    * put(Fqn, Map) with a previous non-null map
-    */
-   public void testputDataRollback2() throws Exception
-   {
-      Map<String, Comparable> m1, m2;
-      m1 = new HashMap<String, Comparable>();
-      m1.put("name", "Bela");
-      m1.put("id", 322649);
-      m2 = new HashMap<String, Comparable>();
-      m2.put("other", "bla");
-      m2.put("name", "Michelle");
-
-      cache.put("/bela/ban", m1);
-      tx.begin();
-
-      cache.put("/bela/ban", m2);
-      Map tmp = cache.getNode("/bela/ban").getData();
-      assertEquals(3, tmp.size());
-      assertEquals("Michelle", tmp.get("name"));
-      assertEquals(tmp.get("id"), 322649);
-      assertEquals("bla", tmp.get("other"));
-      tx.rollback();
-
-      tmp = cache.getNode("/bela/ban").getData();
-      assertEquals(2, tmp.size());
-      assertEquals("Bela", tmp.get("name"));
-      assertEquals(tmp.get("id"), 322649);
-   }
-
-   public void testPutRollback()
-   {
-      try
-      {
-         cache.put("/bela/ban", null);// /bela/ban needs to exist
-         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");// /bela/ban needs to exist
-         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 void testSimpleRollbackTransactions() throws Exception
-   {
-      final Fqn fqn = Fqn.fromString("/a/b/c");
-      tx.begin();
-      cache.put(fqn, "entry", "commit");
-      tx.commit();
-
-      tx.begin();
-      cache.put(fqn, "entry", "rollback");
-      cache.removeNode(fqn);
-      tx.rollback();
-      assertEquals("Node should keep the commited value", "commit", cache.getNode(fqn).get("entry"));
-
-      tx.begin();
-      cache.removeNode(fqn);
-      cache.put(fqn, "entry", "rollback");
-      tx.rollback();
-
-      System.out.println("Cache: " + CachePrinter.printCacheDetails(cache));
-
-      assertEquals("Node should keep the commited value", "commit", cache.getNode(fqn).get("entry"));// THIS FAILS
-   }
-
-   private TransactionManager startTransaction() throws Exception
-   {
-      TransactionManager mgr = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-      mgr.begin();
-      return mgr;
-   }
-
-   public void testConcurrentReadAndWriteAccess() throws Exception
-   {
-      cache.stop();
-      cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-      cache.start();
-
-      cache.put("/1/2/3/4", "foo", "bar");// no TX, no locks held after put() returns
-
-      class Reader extends Thread
-      {
-         TransactionManager thread_tx;
-
-         public Reader()
-         {
-            super("Reader");
-         }
-
-         public void run()
-         {
-            try
-            {
-               thread_tx = startTransaction();
-               log("acquiring RL");
-               cache.get("/1/2/3", "foo");// acquires RLs on all 3 nodes
-               log("RL acquired successfully");
-               sleep(2000);
-               log("committing TX");
-               thread_tx.commit();// releases RLs
-               log("committed TX");
-            }
-            catch (Exception e)
-            {
-               exception = e;
-            }
-         }
-      }
-
-      class Writer extends Thread
-      {
-         TransactionManager thread_tx;
-
-         public Writer()
-         {
-            super("Writer");
-         }
-
-         public void run()
-         {
-            try
-            {
-               sleep(500);// give the Reader a chance to acquire the RLs
-               thread_tx = startTransaction();
-               log("acquiring WL");
-               cache.put("/1", "foo", "bar2");// needs to acquired a WL on /1
-               log("acquired WL successfully");
-               log("committing TX");
-               thread_tx.commit();
-               log("committed TX");
-            }
-            catch (Exception e)
-            {
-               exception = e;
-            }
-         }
-      }
-
-      Reader reader = new Reader();
-      Writer writer = new Writer();
-      reader.start();
-      writer.start();
-      reader.join();
-      writer.join();
-      if (exception != null)
-      {
-         throw exception;
-      }
-   }
-
-   public void testRemoveAndGetInTx() throws Exception
-   {
-      Fqn A_B = Fqn.fromString("/a/b");
-      Fqn A = Fqn.fromString("/a");
-
-      cache.put(A_B, "k", "v");
-
-      assertTrue(cache.exists(A_B));
-      assertTrue(cache.exists(A));
-
-      cache.getTransactionManager().begin();
-      cache.removeNode(A);
-      cache.get(A_B, "k");
-      cache.getTransactionManager().commit();
-   }
-
-   public void testRemoveAndPutInTx() throws Exception
-   {
-      Fqn A_B = Fqn.fromString("/a/b");
-      Fqn A = Fqn.fromString("/a");
-
-      cache.put(A_B, "k", "v");
-
-      assertTrue(cache.exists(A_B));
-      assertTrue(cache.exists(A));
-
-      cache.getTransactionManager().begin();
-      cache.removeNode(A_B);
-      cache.put(A_B, "k", "v2");
-      cache.getTransactionManager().commit();
-
-      assertTrue(cache.exists(A_B));
-      assertTrue(cache.exists(A));
-
-      assert cache.peek(A, true, true).isValid();
-      assert cache.peek(A_B, true, true).isValid();
-
-      assertEquals("v2", cache.get(A_B, "k"));
-   }
-
-   public void testRemoveParentAndPutInTx() throws Exception
-   {
-      Fqn A_B = Fqn.fromString("/a/b");
-      Fqn A = Fqn.fromString("/a");
-
-      cache.put(A_B, "k", "v");
-
-      assertTrue(cache.exists(A_B));
-      assertTrue(cache.exists(A));
-
-      cache.getTransactionManager().begin();
-      cache.removeNode(A);
-      cache.put(A_B, "k", "v2");
-      cache.getTransactionManager().commit();
-
-      assertTrue(cache.exists(A_B));
-      assertTrue(cache.exists(A));
-
-      assertEquals("v2", cache.get(A_B, "k"));
-   }
-
-   public void testRemoveGrandParentAndPutInTx() throws Exception
-   {
-      Fqn A_B_C = Fqn.fromString("/a/b/c");
-      Fqn A = Fqn.fromString("/a");
-
-      cache.put(A_B_C, "k", "v");
-
-      assertTrue(cache.exists(A_B_C));
-      assertTrue(cache.exists(A));
-
-      cache.getTransactionManager().begin();
-      cache.removeNode(A);
-      cache.put(A_B_C, "k", "v2");
-      cache.getTransactionManager().commit();
-
-      assertTrue(cache.exists(A_B_C));
-      assertTrue(cache.exists(A));
-
-      assertEquals("v2", cache.get(A_B_C, "k"));
-   }
-
-   public void testRootNodeRemoval() throws Exception
-   {
-      Fqn root = Fqn.ROOT;
-      Fqn fqn = Fqn.fromElements(1);
-      //put first time
-      tx.begin();
-      this.cache.put(fqn, "k", "v");
-      tx.commit();
-
-      //get works fine
-      tx.begin();
-      assertEquals("v", this.cache.get(fqn, "k"));
-      tx.commit();
-
-      //remove all
-      tx.begin();
-      this.cache.removeNode(root);
-      tx.commit();
-
-      //get returns null - ok
-      //put - endless loop
-      tx.begin();
-      assertNull(this.cache.get(fqn, "k"));
-      this.cache.put(fqn, "k", "v");
-      tx.commit();
-   }
-
-   public void testNodeAdditionAfterRemoval() throws Exception
-   {
-      Fqn fqn = Fqn.fromString("/1/2/3/4");
-      //put first time
-      tx.begin();
-      this.cache.put(fqn, "k", "v");
-      tx.commit();
-
-      //get works fine
-      tx.begin();
-      assertEquals("v", this.cache.get(fqn, "k"));
-      tx.commit();
-
-      //remove all
-      tx.begin();
-      this.cache.removeNode(Fqn.ROOT);
-      tx.commit();
-
-      //get returns null - ok
-      //put - endless loop
-      tx.begin();
-      assertNull(this.cache.get(fqn, "k"));
-      this.cache.put(fqn, "k", "v");
-      tx.commit();
-   }
-
-   public void testRootNodeRemovalRollback() throws Exception
-   {
-      Fqn root = Fqn.ROOT;
-      Fqn fqn = Fqn.fromRelativeElements(root, 1);
-      //put first time
-      tx.begin();
-      this.cache.put(fqn, "k", "v");
-      tx.commit();
-
-      //get works fine
-      tx.begin();
-      assertEquals("v", this.cache.get(fqn, "k"));
-      tx.commit();
-
-      //remove all
-      tx.begin();
-      this.cache.removeNode(root);
-      tx.rollback();
-
-      assertEquals("v", this.cache.get(fqn, "k"));
-   }
-
-   private static void log(String msg)
-   {
-      System.out.println(Thread.currentThread().getName() + ": " + msg);
-   }
-
-}

Modified: core/trunk/src/test/java/org/jboss/cache/transaction/isolationlevels/IsolationLevelTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/isolationlevels/IsolationLevelTestBase.java	2008-08-23 12:40:58 UTC (rev 6610)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/isolationlevels/IsolationLevelTestBase.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -4,6 +4,7 @@
 import org.jboss.cache.CacheFactory;
 import org.jboss.cache.DefaultCacheFactory;
 import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
 import org.jboss.cache.lock.IsolationLevel;
 import static org.jboss.cache.lock.IsolationLevel.*;
 import org.jboss.cache.transaction.TransactionSetup;
@@ -40,7 +41,8 @@
    {
       CacheFactory<String, String> cf = new DefaultCacheFactory<String, String>();
       cache = cf.createCache(false);
-      cache.getConfiguration().setIsolationLevel(isolationLevel);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+     cache.getConfiguration().setIsolationLevel(isolationLevel);
       cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
       // very short so the tests don't take ages
       cache.getConfiguration().setLockAcquisitionTimeout(250);

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AbortionTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/AbortionTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AbortionTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AbortionTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,204 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
+import org.jboss.cache.transaction.NotifyingTransactionManager.Notification;
+import org.jboss.cache.transaction.NotifyingTransactionManager;
+import org.jboss.cache.transaction.DummyTransactionManager;
+import org.jboss.cache.transaction.TransactionContext;
+import org.jboss.cache.util.TestingUtil;
+import org.jgroups.JChannel;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ */
+ at Test(groups = {"functional"})
+public class AbortionTest
+{
+   private CacheSPI cache1, cache2, cache3;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      cache1 = initCache(false);
+      TestingUtil.sleepThread(1500); // to ensure cache1 is the coordinator
+      cache2 = initCache(false);
+      cache3 = initCache(true);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      TestingUtil.killCaches(cache3, cache2, cache1);
+   }
+
+   private CacheSPI initCache(boolean notifying)
+   {
+      CacheSPI c = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(false);
+      c.getConfiguration().setCacheMode("REPL_SYNC");
+      c.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      c.getConfiguration().setClusterConfig(getJGroupsStack());
+      c.getConfiguration().setFetchInMemoryState(false);
+      if (!notifying)
+      {
+         c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+      }
+      else
+      {
+         c.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.NotifyingTransactionManager");
+      }
+      c.start();
+      return c;
+   }
+
+   // we need a 'special' stack that does not attempt redelivery since we kill a channel midway during a tx in this test.
+   private String getJGroupsStack()
+   {
+      return JChannel.DEFAULT_PROTOCOL_STACK;
+   }
+
+   private void destroyCache(CacheSPI c)
+   {
+      if (c != null)
+      {
+         c.stop();
+         c.destroy();
+      }
+   }
+
+   public void testSyncCaches() throws Exception
+   {
+      performTest(false, false);
+   }
+
+   public void testSyncCachesSyncCommitRollback() throws Exception
+   {
+      performTest(true, false);
+   }
+
+   /**
+    * Note that this tests a *remote* beforeCompletion abort - which is a part of the calling instance's afterCompletion.
+    *
+    * @throws Exception
+    */
+   public void testAbortBeforeCompletion() throws Exception
+   {
+      performTest(true, true);
+   }
+
+   private void performTest(boolean syncCommitRollback, boolean abortBeforeCompletion) throws Exception
+   {
+      cache1.getConfiguration().setSyncCommitPhase(syncCommitRollback);
+      cache1.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
+      cache2.getConfiguration().setSyncCommitPhase(syncCommitRollback);
+      cache2.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
+      cache3.getConfiguration().setSyncCommitPhase(syncCommitRollback);
+      cache3.getConfiguration().setSyncRollbackPhase(syncCommitRollback);
+
+      TransactionManager mgr1 = cache1.getTransactionManager();
+      TransactionManager mgr2 = cache2.getTransactionManager();
+      assertTrue(cache3.getTransactionManager() instanceof NotifyingTransactionManager);
+      NotifyingTransactionManager mgr3 = (NotifyingTransactionManager) cache3.getTransactionManager();
+      mgr3.setCache(cache3);
+
+      assertSame(mgr1, mgr2);
+      assertNotSame(mgr1, mgr3);
+      assertNotSame(mgr2, mgr3);
+
+      assertTrue(mgr1 instanceof DummyTransactionManager);
+      assertTrue(mgr2 instanceof DummyTransactionManager);
+
+      cache1.put("/test", "key", "value");
+
+      assertEquals("value", cache1.get("/test", "key"));
+      assertEquals("value", cache2.get("/test", "key"));
+      assertEquals("value", cache3.get("/test", "key"));
+
+      mgr3.setNotification(new TestNotification(abortBeforeCompletion));
+
+      mgr1.begin();
+      cache1.put("/test", "key", "value2");
+      mgr1.commit();
+
+      TestingUtil.sleepThread(5000);
+
+      // only test cache1 and cache2.  Assume cache3 has crashed out.
+      assertEquals(0, cache1.getNumberOfLocksHeld());
+      assertEquals(0, cache2.getNumberOfLocksHeld());
+      assertEquals("put in transaction should NOT have been rolled back", "value2", cache1.get("/test", "key"));
+      assertEquals("put in transaction should NOT have been rolled back", "value2", cache2.get("/test", "key"));
+
+   }
+
+   class TestNotification implements Notification
+   {
+      boolean abortBeforeCompletion;
+
+      public TestNotification(boolean abortBeforeCompletion)
+      {
+         this.abortBeforeCompletion = abortBeforeCompletion;
+      }
+
+      public void notify(Transaction tx, TransactionContext transactionContext) throws SystemException, RollbackException
+      {
+         OrderedSynchronizationHandler osh = transactionContext.getOrderedSynchronizationHandler();
+
+         final Transaction finalTx = tx;
+         System.out.println("Notify called.");
+         // add an aborting sync handler.
+         Synchronization abort = new Synchronization()
+         {
+
+            public void beforeCompletion()
+            {
+               if (abortBeforeCompletion)
+               {
+                  cache3.getConfiguration().getRuntimeConfig().getChannel().close();
+                  System.out.println("Returning from abort.beforeCompletion");
+                  try
+                  {
+                     finalTx.setRollbackOnly();
+                  }
+                  catch (SystemException e)
+                  {
+                     throw new RuntimeException("Unable to set rollback", e);
+                  }
+                  throw new RuntimeException("Dummy exception");
+               }
+            }
+
+            public void afterCompletion(int i)
+            {
+               if (!abortBeforeCompletion)
+               {
+                  cache3.getConfiguration().getRuntimeConfig().getChannel().close();
+                  System.out.println("Returning from abort.afterCompletion");
+                  throw new RuntimeException("Dummy exception");
+               }
+            }
+         };
+
+         osh.registerAtHead(abort);
+         System.out.println("Added sync handler.");
+      }
+
+   }
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AbortionTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AsyncRollbackTxTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/AsyncRollbackTxTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AsyncRollbackTxTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AsyncRollbackTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,240 @@
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+/**
+ * Test behaviour of async rollback timeouted transaction
+ *
+ * @author <a href="mailto:jhalat at infovide.pl">Jacek Halat</a>
+ * @since 1.4.0
+ */
+ at Test(groups = {"functional"})
+public class AsyncRollbackTxTest
+{
+   private CacheSPI<String, String> cache;
+   private TransactionManager tm;
+   private Fqn fqn = Fqn.fromString("/test");
+   // This sleep time (millis) should be longer than the transaction timeout time.
+   private long sleepTime = 2500;
+   // seconds
+   private int txTimeout = 2;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      Configuration c = new Configuration();
+      c.setTransactionManagerLookupClass("org.jboss.cache.transaction.AsyncRollbackTransactionManagerLookup");
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache = (CacheSPI<String, String>) instance.createCache(c);
+      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+      tm.setTransactionTimeout(txTimeout);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public 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.stop();
+      cache = null;
+      tm = null;
+   }
+
+   public void testCommitCreationInSameTx() throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.begin();
+      cache.put(fqn, "k", "v");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      Thread.sleep(sleepTime);
+      tm.commit();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testRollbackCreationInSameTx() throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.begin();
+      cache.put(fqn, "k", "v");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      Thread.sleep(sleepTime);
+      tm.rollback();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      // make sure the node was NOT added!!
+      assertFalse(cache.exists(fqn));
+      // even in a "deleted" form
+      assertNull(cache.peek(fqn, true));
+   }
+
+   private void doTest(boolean commit, boolean writeLock) throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      cache.put(fqn, "k", "v");//Executed in Not transactional context
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      SeparateThread t = new SeparateThread(commit, writeLock);
+      t.start();
+      t.join();
+      if (t.getException() != null)
+      {
+         throw t.getException();
+      }
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      assertEquals("v", cache.get(fqn, "k"));
+   }
+
+   public void testRollbackCreationInDifferentTxReadLock() throws Exception
+   {
+      doTest(false, false);
+   }
+
+   public void testCommitCreationInDifferentTxReadLock() throws Exception
+   {
+      doTest(true, false);
+   }
+
+   public void testRollbackCreationInDifferentTxWriteLock() throws Exception
+   {
+      doTest(false, true);
+   }
+
+   public void testCommitCreationInDifferentTxWriteLock() throws Exception
+   {
+      doTest(true, true);
+   }
+
+   public void testTxTimeoutAndPutAfter() throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.begin();
+      cache.put(fqn, "k", "v");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      assertNotNull(tm.getTransaction());
+      Thread.sleep(sleepTime);
+      tm.rollback();
+      assertNull(tm.getTransaction());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      // make sure the node was NOT added!!
+      assertFalse(cache.exists(fqn));
+      // even in a "deleted" form
+      assertNull(cache.peek(fqn, true));
+
+      //Put not some data into cache. Because no transaction is used
+      //no locks should be helds after this line.
+      cache.put(fqn, "k", "v");
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testTxTimeoutAndPutGetAfter() throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.begin();
+      cache.put(fqn, "k", "v");
+      assertEquals(2, cache.getNumberOfLocksHeld());
+      assertNotNull(tm.getTransaction());
+      Thread.sleep(sleepTime);
+      tm.rollback();
+      // make sure the node was NOT added!!
+      assertFalse(cache.exists(fqn));
+      // even in a "deleted" form
+      assertNull(cache.peek(fqn, true));
+      assertNull(tm.getTransaction());
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      //Put not some data into cache. Because no transaction is used
+      //no locks should be helds after this line.
+      cache.put(fqn, "k", "v");
+      cache.get(fqn, "k");
+
+      // Make sure no write lock is retained by the main thread.  Test that another thread can read.
+      SeparateThread t = new SeparateThread(false, false);
+      t.start();
+      t.join();
+      if (t.getException() != null)
+      {
+         throw t.getException();
+      }
+   }
+
+   private class SeparateThread extends Thread
+   {
+      Exception e = null;
+      boolean commit, writeLock;
+
+      public SeparateThread(boolean commit, boolean writeLock)
+      {
+         this.commit = commit;
+         this.writeLock = writeLock;
+      }
+
+      public Exception getException()
+      {
+         return e;
+      }
+
+      public void run()
+      {
+         try
+         {
+            tm.begin();
+            if (writeLock)
+            {
+               cache.put(fqn, "k", "v2");// obtain write lock on node
+            }
+            else
+            {
+               cache.get(fqn, "k");// obtain read lock on node
+            }
+
+            // sleep to ensure tx times out.
+            sleep(2500);
+
+            if (commit)
+            {
+               tm.commit();
+            }
+            else
+            {
+               tm.rollback();
+            }
+
+            assertEquals(0, cache.getNumberOfLocksHeld());
+
+         }
+         catch (Exception e)
+         {
+            this.e = e;
+         }
+      }
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/AsyncRollbackTxTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/ConcurrentTransactionalTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/ConcurrentTransactionalTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/ConcurrentTransactionalTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/ConcurrentTransactionalTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,202 @@
+/*
+ *
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.transaction.pessimistic;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.transaction.TransactionSetup;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.lock.IsolationLevel;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.fail;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.UserTransaction;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Unit test for local CacheSPI. Use locking and multiple threads to test
+ * concurrent access to the tree.
+ *
+ * @version $Id$
+ */
+ at Test(groups = {"functional", "transaction"})
+public class ConcurrentTransactionalTest
+{
+   private CacheSPI<Integer, String> cache;
+   private Log logger_ = LogFactory.getLog(ConcurrentTransactionalTest.class);
+   private static Throwable thread_ex = null;
+   private static final int NUM = 10000;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+   }
+
+   private void createCache(IsolationLevel level)
+   {
+      CacheFactory<Integer, String> factory = new DefaultCacheFactory<Integer, String>();
+      Configuration conf = UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.LOCAL, true);
+      conf.setCacheMode(Configuration.CacheMode.LOCAL);
+      conf.setIsolationLevel(level);
+      conf.setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      conf.setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(conf);
+      cache.put("/a/b/c", null);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      cache.stop();
+      thread_ex = null;
+      TransactionSetup.cleanup();
+   }
+
+   public void testConcurrentAccessWithRWLock() throws Throwable
+   {
+      createCache(IsolationLevel.REPEATABLE_READ);
+      work_();
+   }
+
+   public void testConcurrentAccessWithExclusiveLock() throws Throwable
+   {
+      createCache(IsolationLevel.SERIALIZABLE);
+      work_();
+   }
+
+   private void work_() throws Throwable
+   {
+      Updater one, two;
+      try
+      {
+         one = new Updater("Thread one");
+         two = new Updater("Thread two");
+         long current = System.currentTimeMillis();
+         one.start();
+         two.start();
+         one.join();
+         two.join();
+         if (thread_ex != null)
+         {
+            throw thread_ex;
+         }
+
+         long now = System.currentTimeMillis();
+         log("*** Time elapsed: " + (now - current));
+
+         System.out.println("cache content: " + cache.toString());
+         Set<Integer> keys = cache.getNode(Fqn.fromString("/a/b/c")).getKeys();
+         System.out.println("number of keys=" + keys.size());
+
+         if (keys.size() != NUM)
+         {
+            scanForNullValues(keys);
+
+            try
+            {
+               System.out.println("size=" + keys.size());
+               List<Integer> l = new LinkedList<Integer>(keys);
+               Collections.sort(l);
+               System.out.println("keys: " + l);
+               for (int i = 0; i < NUM; i++)
+               {
+                  if (!l.contains(new Integer(i)))
+                  {
+                     System.out.println("missing: " + i);
+                  }
+               }
+
+               LinkedList<Integer> duplicates = new LinkedList<Integer>();
+               for (Integer integer : l)
+               {
+                  if (duplicates.contains(integer))
+                  {
+                     System.out.println(integer + " is a duplicate");
+                  }
+                  else
+                  {
+                     duplicates.add(integer);
+                  }
+               }
+            }
+            catch (Exception e1)
+            {
+               e1.printStackTrace();
+            }
+         }
+
+         assertEquals(NUM, keys.size());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+         fail(e.toString());
+      }
+   }
+
+   private void scanForNullValues(Set<Integer> keys)
+   {
+      for (Object o : keys)
+      {
+         if (o == null)
+         {
+            System.err.println("found a null value in keys");
+         }
+      }
+   }
+
+   private void log(String msg)
+   {
+      logger_.debug(" [" + Thread.currentThread() + "]: " + msg);
+   }
+
+   private class Updater extends Thread
+   {
+      private String val = null;
+      private UserTransaction tx;
+
+      public Updater(String name)
+      {
+         this.val = name;
+      }
+
+      public void run()
+      {
+         try
+         {
+            log("adding data");
+            tx = TransactionSetup.getUserTransaction();
+            for (int i = 0; i < NUM; i++)
+            {
+               log("adding data i=" + i);
+               tx.begin();
+               cache.put("/a/b/c", i, val);
+               tx.commit();
+               yield();
+            }
+         }
+         catch (Throwable t)
+         {
+            t.printStackTrace();
+            thread_ex = t;
+         }
+      }
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/ConcurrentTransactionalTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/IsolationLevelNoneTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/IsolationLevelNoneTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/IsolationLevelNoneTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/IsolationLevelNoneTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,106 @@
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.transaction.TransactionSetup;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.lock.IsolationLevel;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.NotSupportedException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+/**
+ * Tests whether modifications within callbacks (TreeCacheListener) are handled correctly
+ *
+ * @author Bela Ban
+ * @version $Id$
+ */
+ at Test(groups = {"functional", "transaction"})
+public class IsolationLevelNoneTest
+{
+   CacheSPI<String, String> cache = null;
+   final Fqn FQN = Fqn.fromString("/a/b/c");
+   final String KEY = "key";
+   final String VALUE = "value";
+   TransactionManager tm;
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      if (cache != null)
+      {
+         cache.stop();
+         cache.destroy();
+         cache = null;
+      }
+   }
+
+   public void testWithoutTransactions() throws Exception
+   {
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache = (CacheSPI<String, String>) instance.createCache(false);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
+      cache.getConfiguration().setIsolationLevel(IsolationLevel.NONE);
+      cache.start();
+      cache.put(FQN, KEY, VALUE);
+      cache.put(FQN + "/d", KEY, VALUE);
+      Node node = cache.peek(FQN, false, false);
+      assertTrue(node != null && node.getKeys().contains(KEY));
+      assertEquals(VALUE, cache.get(FQN, KEY));
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testWithTransactions() throws Exception
+   {
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache = (CacheSPI<String, String>) instance.createCache(false);
+      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setIsolationLevel(IsolationLevel.NONE);
+      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      cache.start();
+      tm = startTransaction();
+      cache.put(FQN, KEY, VALUE);
+      cache.put(FQN + "/d", KEY, VALUE);
+      Node node = cache.peek(FQN, false, false);
+      assertTrue(node != null && node.getKeys().contains(KEY));
+      assertEquals(VALUE, cache.get(FQN, KEY));
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      tm.commit();
+   }
+
+   public void testWithTransactionsRepeatableRead() throws Exception
+   {
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache = (CacheSPI<String, String>) instance.createCache(false);
+      cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
+      cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      cache.start();
+      tm = startTransaction();
+      cache.put(FQN, KEY, VALUE);
+      cache.put(FQN + "/d", KEY, VALUE);
+      Node node = cache.peek(FQN, false, false);
+      assertTrue(node != null && node.getKeys().contains(KEY));
+      assertEquals(VALUE, cache.get(FQN, KEY));
+      assertEquals(5, cache.getNumberOfLocksHeld());
+      tm.commit();
+   }
+
+   private TransactionManager startTransaction() throws SystemException, NotSupportedException
+   {
+      TransactionManager mgr = cache.getTransactionManager();
+      mgr.begin();
+      return mgr;
+   }
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/IsolationLevelNoneTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PessimisticTransactionTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/TransactionTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PessimisticTransactionTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PessimisticTransactionTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,1072 @@
+/*
+ *
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.transaction.TransactionSetup;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.lock.LockManager;
+import static org.jboss.cache.lock.LockType.READ;
+import static org.jboss.cache.lock.LockType.WRITE;
+import org.jboss.cache.util.CachePrinter;
+import org.jboss.cache.util.TestingUtil;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests transactional access to a local CacheImpl.
+ * Note: we use DummpyTranasctionManager to replace jta
+ *
+ * @version $Id$
+ */
+ at Test(groups = {"functional", "transaction"})
+public class PessimisticTransactionTest
+{
+   CacheSPI<String, Comparable> cache = null;
+   UserTransaction tx = null;
+   Exception exception;
+   LockManager lockManager;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+
+      CacheFactory<String, Comparable> instance = new DefaultCacheFactory<String, Comparable>();
+      cache = (CacheSPI<String, Comparable>) instance.createCache(false);
+      cache.getConfiguration().setClusterName("test");
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setStateRetrievalTimeout(10000);
+      cache.getConfiguration().setIsolationLevel(IsolationLevel.SERIALIZABLE);
+      cache.getConfiguration().setLockParentForChildInsertRemove(true);// this test case is written to assume this.
+      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      tx = TransactionSetup.getUserTransaction();
+
+      cache.create();
+      cache.start();
+      exception = null;
+      lockManager = TestingUtil.extractLockManager(cache);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      if (cache != null)
+      {
+         cache.stop();
+         cache = null;
+      }
+
+      // BW. kind of a hack to destroy jndi binding and thread local tx before next run.
+      TransactionSetup.cleanup();
+
+      if (tx != null)
+      {
+         try
+         {
+            tx.rollback();
+         }
+         catch (Throwable t)
+         {
+            // do nothing
+         }
+         tx = null;
+      }
+   }
+
+   public void testPutTx() throws Exception
+   {
+      tx.begin();
+      cache.put("/a/b/c", "age", 38);
+      // the tx interceptor should know that we're in the same tx.
+      assertEquals(cache.get("/a/b/c", "age"), 38);
+
+      cache.put("/a/b/c", "age", 39);
+      tx.commit();
+
+      // This test is done outside the TX, it wouldn't work if someone else
+      // modified "age". This works because we're the only TX running.
+      assertEquals(cache.get("/a/b/c", "age"), 39);
+   }
+
+   public void testRollbackTx1()
+   {
+      try
+      {
+         tx.begin();
+         cache.put("/a/b/c", "age", 38);
+         cache.put("/a/b/c", "age", 39);
+         tx.rollback();
+
+         // This test is done outside the TX, it wouldn't work if someone else
+         // modified "age". This works because we're the only TX running.
+         assertNull(cache.get("/a/b/c", "age"));
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   public void testGetAfterRemovalRollback() throws Exception
+   {
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      cache.put("/a/b", null);
+      assertEquals(0, cache.getNumberOfLocksHeld());
+      assertTrue(cache.exists("/a/b"));
+      tx.begin();
+      cache.removeNode("/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.getNode("/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
+      {
+         tx.begin();
+         cache.put("/a/b/c", "age", 38);
+         cache.remove("/a/b/c", "age");
+         tx.rollback();
+
+         // This test is done outside the TX, it wouldn't work if someone else
+         // modified "age". This works because we're the only TX running.
+         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", 38);
+         tx.begin();
+         cache.remove("/a/b/c", "age");
+         tx.rollback();
+
+         // This test is done outside the TX, it wouldn't work if someone else
+         // modified "age". This works because we're the only TX running.
+         assertEquals(38, cache.get("/a/b/c", "age"));
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   public void testRollbackTx3()
+   {
+      try
+      {
+         java.util.Map<String, Comparable> map1 = new java.util.HashMap<String, Comparable>();
+         map1.put("age", 38);
+         java.util.Map<String, Comparable> map2 = new java.util.HashMap<String, Comparable>();
+         map2.put("age", 39);
+         tx.begin();
+         cache.put("/a/b/c", map1);
+         cache.put("/a/b/c", map2);
+         tx.rollback();
+
+         // This test is done outside the TX, it wouldn't work if someone else
+         // modified "age". This works because we're the only TX running.
+         assertNull(cache.get("/a/b/c", "age"));
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   public void testRollbackTx4()
+   {
+      try
+      {
+         Map<String, Comparable> map = new HashMap<String, Comparable>();
+         map.put("age", 38);
+         tx.begin();
+         cache.put("/a/b/c", map);
+         cache.removeNode("/a/b/c");
+         tx.rollback();
+
+         // This test is done outside the TX, it wouldn't work if someone else
+         // modified "age". This works because we're the only TX running.
+         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", "key", "value");
+         System.out.println("after put():\n" + cache);
+         tx.rollback();
+         System.out.println("after rollback():\n" + cache);
+
+         assertNull("node should be not existent", cache.getNode("/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.getNode("/bela/ban"));
+         assertNull("node should be not existent", cache.getNode("/bela/ban/michelle"));
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   public void testNodeDeletionRollback()
+   {
+      try
+      {
+         cache.put("/a/b/c", null);
+         tx.begin();
+         cache.removeNode("/a/b/c");
+         assertNull(cache.getNode("/a/b/c"));
+         cache.removeNode("/a/b");
+         assertNull(cache.getNode("/a/b"));
+         cache.removeNode("/a");
+         assertNull(cache.getNode("/a"));
+         tx.rollback();
+         assertNotNull(cache.getNode("/a/b/c"));
+         assertNotNull(cache.getNode("/a/b"));
+         assertNotNull(cache.getNode("/a"));
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   public void testNodeDeletionRollback2() throws Exception
+   {
+      cache.put("/a/b/c", null);
+      cache.put("/a/b/c1", null);
+      cache.put("/a/b/c2", null);
+      tx.begin();
+      cache.removeNode("/a");
+      assertNull(cache.getNode("/a/b/c"));
+      assertNull(cache.getNode("/a/b/c1"));
+      assertNull(cache.getNode("/a/b/c2"));
+      assertNull(cache.getNode("/a/b"));
+      assertNull(cache.getNode("/a"));
+      Set children = cache.getChildrenNames(Fqn.fromString("/a/b"));
+      assertTrue(children.isEmpty());
+      children = cache.getChildrenNames("/a");
+      assertTrue(children.isEmpty());
+      tx.rollback();
+      assertNotNull(cache.getNode("/a"));
+      assertNotNull(cache.getNode("/a/b"));
+      assertNotNull(cache.getNode("/a/b/c"));
+      assertNotNull(cache.getNode("/a/b/c1"));
+      assertNotNull(cache.getNode("/a/b/c2"));
+      children = cache.getChildrenNames(Fqn.fromString("/a/b"));
+      assertEquals(3, children.size());
+   }
+
+   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);
+   }
+
+   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);
+   }
+
+   public void testNodeRemoval() throws SystemException, NotSupportedException
+   {
+      GlobalTransaction gtx;
+      cache.put("/a/b/c", null);
+      tx.begin();
+      gtx = cache.getCurrentTransaction();
+      cache.removeNode("/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);
+      tx.rollback();
+   }
+
+   public void testNodeRemoval2() throws SystemException, NotSupportedException
+   {
+      GlobalTransaction gtx;
+      cache.put("/a/b/c", null);
+      tx.begin();
+      gtx = cache.getCurrentTransaction();
+      cache.removeNode("/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);
+      tx.rollback();
+   }
+
+   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.getNode("/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"), true));
+      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
+      tx.rollback();
+      assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b"), true));
+      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
+
+   }
+
+   public void testIntermediateNodeCreationOnRemove() throws Exception
+   {
+      cache.put("/a", null);
+      tx.begin();
+      cache.removeNode("/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", true);
+      assertLocked(gtx, "/a/b", true);
+      assertLocked(gtx, "/a/b/c", true);
+      assertNotNull("/a/b should exist", cache.peek(Fqn.fromString("/a/b"), true));
+      assertNotNull("/a/b/c should exist", cache.peek(Fqn.fromString("/a/b/c"), true));
+      assertNotNull("/a/b should NOT be visible", cache.exists(Fqn.fromString("/a/b")));
+      assertNotNull("/a/b/c should NOT be visible", cache.exists(Fqn.fromString("/a/b/c")));
+      tx.rollback();
+      assertNull("/a/b should not exist", cache.peek(Fqn.fromString("/a/b"), true));
+      assertNull("/a/b/c should not exist", cache.peek(Fqn.fromString("/a/b/c"), true));
+
+   }
+
+   public void testNodeDeletionRollback3() throws Exception
+   {
+      GlobalTransaction gtx;
+      cache.put("/a/b/c1", null);
+
+      tx.begin();
+      gtx = cache.getCurrentTransaction();
+      cache.put("/a/b/c1", null);
+      assertLocked(gtx, "/a", false);
+      assertLocked(gtx, "/a/b", false);
+      assertLocked(gtx, "/a/b/c1", true);
+
+      cache.put("/a/b/c2", null);
+      assertLocked(gtx, "/a/b", true);
+      assertLocked(gtx, "/a/b/c2", true);
+
+      cache.put("/a/b/c3", null);
+      cache.put("/a/b/c1/one", null);
+      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);
+      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);
+      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);
+
+      cache.removeNode("/a/b");
+      tx.rollback();
+      assertTrue(cache.getChildrenNames("/a/b/c1").isEmpty());
+      Set cn = cache.getChildrenNames(Fqn.fromString("/a/b"));
+      assertEquals(1, cn.size());
+      assertEquals("c1", cn.iterator().next());
+   }
+
+   public void testDoubleLocks() throws Exception
+   {
+      tx.begin();
+      GlobalTransaction gtx = cache.getCurrentTransaction();
+      cache.put("/a/b/c", null);
+      cache.put("/a/b/c", null);
+
+      NodeSPI n = cache.getNode("/a");
+      assert !lockManager.isLocked(n, READ);
+      // make sure this is write locked.
+      assertLocked(gtx, "/a", true);
+
+      n = cache.getNode("/a/b");
+      assert !lockManager.isLocked(n, READ);
+      // make sure this is write locked.
+      assertLocked(gtx, "/a/b", true);
+
+      n = cache.getNode("/a/b/c");
+      assert !lockManager.isLocked(n, READ);
+      // make sure this is write locked.
+      assertLocked(gtx, "/a/b/c", true);
+
+      tx.rollback();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   private void assertLocked(Object owner, String fqn, boolean writeLocked)
+   {
+      NodeSPI<String, Comparable> n = cache.peek(Fqn.fromString(fqn), true);
+      if (owner == null) owner = Thread.currentThread();
+      assertTrue("node " + fqn + " is not locked", lockManager.isLocked(n));
+      if (writeLocked)
+      {
+         assertTrue("node " + fqn + " is not write-locked by owner " + owner + ". Lock details: " + lockManager.printLockInfo(n), lockManager.ownsLock(Fqn.fromString(fqn), WRITE, owner));
+      }
+      else
+      {
+         assertTrue("node " + fqn + " is not read-locked by owner " + owner + ". Lock details: " + lockManager.printLockInfo(n), lockManager.ownsLock(Fqn.fromString(fqn), READ, owner));
+      }
+   }
+
+   public void testConcurrentNodeAccessOnRemovalWithTx() throws Exception
+   {
+      cache.put("/a/b/c", null);
+      tx.begin();
+      cache.removeNode("/a/b/c");
+      // this node should now be locked.
+      TransactionManager tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+      Transaction t = tm.suspend();
+      // start a new tx
+      tm.begin();
+      try
+      {
+         cache.getNode("/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
+         //cache.getTransactionManager().commit();
+         tm.commit();
+      }
+
+      tm.resume(t);
+      tx.rollback();
+
+      assertNotNull(cache.getNode("/a/b/c"));
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testConcurrentNodeAccessOnRemovalWithoutTx() throws Exception
+   {
+      cache.put("/a/b/c", null);
+      tx.begin();
+      cache.removeNode("/a/b/c");
+      // this node should now be locked.
+      Transaction t = cache.getTransactionManager().suspend();
+      Thread th = new Thread()
+      {
+         public void run()
+         {
+            try
+            {
+               cache.getNode("/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
+            }
+         }
+      };
+
+      th.start();
+      th.join();
+
+      cache.getTransactionManager().resume(t);
+      tx.rollback();
+
+      assertNotNull(cache.getNode("/a/b/c"));
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testRemove() throws CacheException, SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException, RollbackException
+   {
+      cache.put("/a/b/c", null);
+      cache.put("/a/b/c/1", null);
+      cache.put("/a/b/c/2", null);
+      cache.put("/a/b/c/3", null);
+      cache.put("/a/b/c/3/a/b/c", null);
+
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      tx.begin();
+      cache.removeNode("/a/b/c");
+      // 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();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+   }
+
+   public void testRemoveAndRollback() throws CacheException, SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException,
+         RollbackException
+   {
+      cache.put("/a/b/c", null);
+      cache.put("/a/b/c/1", null);
+      cache.put("/a/b/c/2", null);
+      cache.put("/a/b/c/3", null);
+      cache.put("/a/b/c/3/a/b/c", null);
+
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      tx.begin();
+      cache.removeNode("/a/b/c");
+      assertEquals(10, cache.getNumberOfLocksHeld());
+      tx.rollback();
+      assertEquals(0, cache.getNumberOfLocksHeld());
+
+      assertTrue(cache.exists("/a/b/c"));
+      assertTrue(cache.exists("/a/b/c/1"));
+      assertTrue(cache.exists("/a/b/c/2"));
+      assertTrue(cache.exists("/a/b/c/3"));
+      assertTrue(cache.exists("/a/b/c/3/a"));
+      assertTrue(cache.exists("/a/b/c/3/a/b"));
+      assertTrue(cache.exists("/a/b/c/3/a/b/c"));
+   }
+
+   public void testRemoveKeyRollback() throws CacheException, SystemException, NotSupportedException
+   {
+      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"));
+   }
+
+   public void testRemoveKeyRollback2()
+   {
+      try
+      {
+         Map<String, Comparable> m = new HashMap<String, Comparable>();
+         m.put("name", "Bela");
+         m.put("id", 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() throws Exception
+   {
+      tx.begin();
+      cache.put("/foo/1", "item", 1);
+      assertEquals(cache.get("/foo/1", "item"), 1);
+      cache.removeNode("/foo/1");
+      assertNull(cache.get("/foo/1", "item"));
+      cache.removeNode("/foo/1");
+      assertNull(cache.get("/foo/1", "item"));
+      tx.rollback();
+      assertFalse(cache.exists("/foo/1"));
+      assertNull(cache.get("/foo/1", "item"));
+   }
+
+   /**
+    * put(Fqn, Map) with a previous null map
+    */
+   public void testPutDataRollback1()
+   {
+      try
+      {
+         cache.put("/bela/ban", null);// create a node /bela/ban with a null map
+         tx.begin();
+         Map<String, Comparable> m = new HashMap<String, Comparable>();
+         m.put("name", "Bela");
+         m.put("id", 322649);
+         cache.put("/bela/ban", m);
+         tx.rollback();
+
+         Node n = cache.getNode("/bela/ban");
+         if (n.getData() == null)
+            return;
+         assertEquals("map should be empty", 0, n.getData().size());
+      }
+      catch (Throwable t)
+      {
+         t.printStackTrace();
+         fail(t.toString());
+      }
+   }
+
+   /**
+    * put(Fqn, Map) with a previous non-null map
+    */
+   public void testputDataRollback2() throws Exception
+   {
+      Map<String, Comparable> m1, m2;
+      m1 = new HashMap<String, Comparable>();
+      m1.put("name", "Bela");
+      m1.put("id", 322649);
+      m2 = new HashMap<String, Comparable>();
+      m2.put("other", "bla");
+      m2.put("name", "Michelle");
+
+      cache.put("/bela/ban", m1);
+      tx.begin();
+
+      cache.put("/bela/ban", m2);
+      Map tmp = cache.getNode("/bela/ban").getData();
+      assertEquals(3, tmp.size());
+      assertEquals("Michelle", tmp.get("name"));
+      assertEquals(tmp.get("id"), 322649);
+      assertEquals("bla", tmp.get("other"));
+      tx.rollback();
+
+      tmp = cache.getNode("/bela/ban").getData();
+      assertEquals(2, tmp.size());
+      assertEquals("Bela", tmp.get("name"));
+      assertEquals(tmp.get("id"), 322649);
+   }
+
+   public void testPutRollback()
+   {
+      try
+      {
+         cache.put("/bela/ban", null);// /bela/ban needs to exist
+         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");// /bela/ban needs to exist
+         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 void testSimpleRollbackTransactions() throws Exception
+   {
+      final Fqn fqn = Fqn.fromString("/a/b/c");
+      tx.begin();
+      cache.put(fqn, "entry", "commit");
+      tx.commit();
+
+      tx.begin();
+      cache.put(fqn, "entry", "rollback");
+      cache.removeNode(fqn);
+      tx.rollback();
+      assertEquals("Node should keep the commited value", "commit", cache.getNode(fqn).get("entry"));
+
+      tx.begin();
+      cache.removeNode(fqn);
+      cache.put(fqn, "entry", "rollback");
+      tx.rollback();
+
+      System.out.println("Cache: " + CachePrinter.printCacheDetails(cache));
+
+      assertEquals("Node should keep the commited value", "commit", cache.getNode(fqn).get("entry"));// THIS FAILS
+   }
+
+   private TransactionManager startTransaction() throws Exception
+   {
+      TransactionManager mgr = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+      mgr.begin();
+      return mgr;
+   }
+
+   public void testConcurrentReadAndWriteAccess() throws Exception
+   {
+      cache.stop();
+      cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
+      cache.start();
+
+      cache.put("/1/2/3/4", "foo", "bar");// no TX, no locks held after put() returns
+
+      class Reader extends Thread
+      {
+         TransactionManager thread_tx;
+
+         public Reader()
+         {
+            super("Reader");
+         }
+
+         public void run()
+         {
+            try
+            {
+               thread_tx = startTransaction();
+               log("acquiring RL");
+               cache.get("/1/2/3", "foo");// acquires RLs on all 3 nodes
+               log("RL acquired successfully");
+               sleep(2000);
+               log("committing TX");
+               thread_tx.commit();// releases RLs
+               log("committed TX");
+            }
+            catch (Exception e)
+            {
+               exception = e;
+            }
+         }
+      }
+
+      class Writer extends Thread
+      {
+         TransactionManager thread_tx;
+
+         public Writer()
+         {
+            super("Writer");
+         }
+
+         public void run()
+         {
+            try
+            {
+               sleep(500);// give the Reader a chance to acquire the RLs
+               thread_tx = startTransaction();
+               log("acquiring WL");
+               cache.put("/1", "foo", "bar2");// needs to acquired a WL on /1
+               log("acquired WL successfully");
+               log("committing TX");
+               thread_tx.commit();
+               log("committed TX");
+            }
+            catch (Exception e)
+            {
+               exception = e;
+            }
+         }
+      }
+
+      Reader reader = new Reader();
+      Writer writer = new Writer();
+      reader.start();
+      writer.start();
+      reader.join();
+      writer.join();
+      if (exception != null)
+      {
+         throw exception;
+      }
+   }
+
+   public void testRemoveAndGetInTx() throws Exception
+   {
+      Fqn A_B = Fqn.fromString("/a/b");
+      Fqn A = Fqn.fromString("/a");
+
+      cache.put(A_B, "k", "v");
+
+      assertTrue(cache.exists(A_B));
+      assertTrue(cache.exists(A));
+
+      cache.getTransactionManager().begin();
+      cache.removeNode(A);
+      cache.get(A_B, "k");
+      cache.getTransactionManager().commit();
+   }
+
+   public void testRemoveAndPutInTx() throws Exception
+   {
+      Fqn A_B = Fqn.fromString("/a/b");
+      Fqn A = Fqn.fromString("/a");
+
+      cache.put(A_B, "k", "v");
+
+      assertTrue(cache.exists(A_B));
+      assertTrue(cache.exists(A));
+
+      cache.getTransactionManager().begin();
+      cache.removeNode(A_B);
+      cache.put(A_B, "k", "v2");
+      cache.getTransactionManager().commit();
+
+      assertTrue(cache.exists(A_B));
+      assertTrue(cache.exists(A));
+
+      assert cache.peek(A, true, true).isValid();
+      assert cache.peek(A_B, true, true).isValid();
+
+      assertEquals("v2", cache.get(A_B, "k"));
+   }
+
+   public void testRemoveParentAndPutInTx() throws Exception
+   {
+      Fqn A_B = Fqn.fromString("/a/b");
+      Fqn A = Fqn.fromString("/a");
+
+      cache.put(A_B, "k", "v");
+
+      assertTrue(cache.exists(A_B));
+      assertTrue(cache.exists(A));
+
+      cache.getTransactionManager().begin();
+      cache.removeNode(A);
+      cache.put(A_B, "k", "v2");
+      cache.getTransactionManager().commit();
+
+      assertTrue(cache.exists(A_B));
+      assertTrue(cache.exists(A));
+
+      assertEquals("v2", cache.get(A_B, "k"));
+   }
+
+   public void testRemoveGrandParentAndPutInTx() throws Exception
+   {
+      Fqn A_B_C = Fqn.fromString("/a/b/c");
+      Fqn A = Fqn.fromString("/a");
+
+      cache.put(A_B_C, "k", "v");
+
+      assertTrue(cache.exists(A_B_C));
+      assertTrue(cache.exists(A));
+
+      cache.getTransactionManager().begin();
+      cache.removeNode(A);
+      cache.put(A_B_C, "k", "v2");
+      cache.getTransactionManager().commit();
+
+      assertTrue(cache.exists(A_B_C));
+      assertTrue(cache.exists(A));
+
+      assertEquals("v2", cache.get(A_B_C, "k"));
+   }
+
+   public void testRootNodeRemoval() throws Exception
+   {
+      Fqn root = Fqn.ROOT;
+      Fqn fqn = Fqn.fromElements(1);
+      //put first time
+      tx.begin();
+      this.cache.put(fqn, "k", "v");
+      tx.commit();
+
+      //get works fine
+      tx.begin();
+      assertEquals("v", this.cache.get(fqn, "k"));
+      tx.commit();
+
+      //remove all
+      tx.begin();
+      this.cache.removeNode(root);
+      tx.commit();
+
+      //get returns null - ok
+      //put - endless loop
+      tx.begin();
+      assertNull(this.cache.get(fqn, "k"));
+      this.cache.put(fqn, "k", "v");
+      tx.commit();
+   }
+
+   public void testNodeAdditionAfterRemoval() throws Exception
+   {
+      Fqn fqn = Fqn.fromString("/1/2/3/4");
+      //put first time
+      tx.begin();
+      this.cache.put(fqn, "k", "v");
+      tx.commit();
+
+      //get works fine
+      tx.begin();
+      assertEquals("v", this.cache.get(fqn, "k"));
+      tx.commit();
+
+      //remove all
+      tx.begin();
+      this.cache.removeNode(Fqn.ROOT);
+      tx.commit();
+
+      //get returns null - ok
+      //put - endless loop
+      tx.begin();
+      assertNull(this.cache.get(fqn, "k"));
+      this.cache.put(fqn, "k", "v");
+      tx.commit();
+   }
+
+   public void testRootNodeRemovalRollback() throws Exception
+   {
+      Fqn root = Fqn.ROOT;
+      Fqn fqn = Fqn.fromRelativeElements(root, 1);
+      //put first time
+      tx.begin();
+      this.cache.put(fqn, "k", "v");
+      tx.commit();
+
+      //get works fine
+      tx.begin();
+      assertEquals("v", this.cache.get(fqn, "k"));
+      tx.commit();
+
+      //remove all
+      tx.begin();
+      this.cache.removeNode(root);
+      tx.rollback();
+
+      assertEquals("v", this.cache.get(fqn, "k"));
+   }
+
+   private static void log(String msg)
+   {
+      System.out.println(Thread.currentThread().getName() + ": " + msg);
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PessimisticTransactionTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PrepareTxTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/PrepareTxTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PrepareTxTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PrepareTxTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,158 @@
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.transaction.TransactionSetup;
+import org.jboss.cache.transaction.TransactionTable;
+import org.jboss.cache.config.Configuration;
+import static org.testng.AssertJUnit.assertEquals;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.NotSupportedException;
+import javax.transaction.Synchronization;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: bela
+ * Date: Jun 9, 2004
+ * Time: 9:05:19 AM
+ */
+ at Test(groups = {"functional", "transaction"})
+public class PrepareTxTest
+{
+   CacheSPI<String, String> cache;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      CacheFactory<String, String> instance = new DefaultCacheFactory<String, String>();
+      cache = (CacheSPI<String, String>) instance.createCache(false);
+      cache.getConfiguration().setCacheMode("local");
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setTransactionManagerLookupClass(TransactionSetup.getManagerLookup());
+      cache.create();
+      cache.start();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      cache.stop();
+      cache.destroy();
+   }
+
+   /**
+    * Tests cache modification <em>inside</em> the afterCompletion() callback. Reproduces a bug fixed in
+    * connection with JBossCache being used as Hibernate's second level cache
+    *
+    * @throws Exception
+    * @throws NotSupportedException
+    */
+   public void testCacheModificationInBeforeCompletionPhase() throws Exception
+   {
+      int numLocks = 0;
+      TransactionManager mgr = cache.getTransactionManager();
+      mgr.begin();
+      Transaction tx = mgr.getTransaction();
+
+      // this will cause the cache to register with TransactionManager for TX completion callbacks
+      cache.put("/one/two/three", "key1", "val1");
+      numLocks = cache.getNumberOfLocksHeld();
+      assertEquals(4, numLocks);
+
+      // we register *second*
+      tx.registerSynchronization(new Synchronization()
+      {
+
+         public void beforeCompletion()
+         {
+            try
+            {
+               cache.put("/a/b/c", null);
+            }
+            catch (CacheException e)
+            {
+               e.printStackTrace();
+            }
+         }
+
+         public void afterCompletion(int status)
+         {
+         }
+      });
+
+      mgr.commit();
+      numLocks = cache.getNumberOfLocksHeld();
+      assertEquals(0, numLocks);
+
+      int num_local_txs, num_global_txs;
+      TransactionTable tx_table = cache.getTransactionTable();
+      num_local_txs = tx_table.getNumLocalTransactions();
+      num_global_txs = tx_table.getNumGlobalTransactions();
+      System.out.println("Number of Transactions: " + num_local_txs + "\nNumber of GlobalTransactions: " + num_global_txs + "\nTransactionTable:\n "
+            + tx_table.toString(true));
+      assertEquals(num_local_txs, num_global_txs);
+      assertEquals(0, num_local_txs);
+   }
+
+   /**
+    * Tests cache modification <em>inside</em> the afterCompletion() callback. Reproduces a bug fixed in
+    * connection with JBossCache being used as Hibernate's second level cache
+    *
+    * @throws Exception
+    * @throws NotSupportedException
+    */
+   public void testCacheModificationInAfterCompletionPhase() throws Exception
+   {
+      int numLocks = 0;
+      TransactionManager mgr = cache.getTransactionManager();
+      mgr.begin();
+      Transaction tx = mgr.getTransaction();
+
+      // this will cause the cache to register with TransactionManager for TX completion callbacks
+      cache.put("/one/two/three", "key1", "val1");
+      numLocks = cache.getNumberOfLocksHeld();
+      assertEquals(4, numLocks);
+
+      // we register *second*
+      tx.registerSynchronization(new Synchronization()
+      {
+
+         public void beforeCompletion()
+         {
+         }
+
+         public void afterCompletion(int status)
+         {
+            try
+            {
+               cache.put("/a/b/c", null);
+            }
+            catch (CacheException e)
+            {
+               e.printStackTrace();
+            }
+         }
+      });
+
+      mgr.commit();
+      numLocks = cache.getNumberOfLocksHeld();
+      assertEquals(0, numLocks);
+
+      int num_local_txs, num_global_txs;
+      TransactionTable tx_table = cache.getTransactionTable();
+      num_local_txs = tx_table.getNumLocalTransactions();
+      num_global_txs = tx_table.getNumGlobalTransactions();
+      System.out.println("Number of Transactions: " + num_local_txs + "\nNumber of GlobalTransactions: " + num_global_txs + "\nTransactionTable:\n "
+            + tx_table.toString(true));
+      assertEquals(num_local_txs, num_global_txs);
+      assertEquals(0, num_local_txs);
+   }
+
+}


Property changes on: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/PrepareTxTest.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Copied: core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/StatusUnknownTest.java (from rev 6585, core/trunk/src/test/java/org/jboss/cache/transaction/StatusUnknownTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/StatusUnknownTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/pessimistic/StatusUnknownTest.java	2008-08-25 17:50:21 UTC (rev 6611)
@@ -0,0 +1,165 @@
+package org.jboss.cache.transaction.pessimistic;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.transaction.*;
+import org.jboss.cache.config.Configuration;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * This test checks how the cache behaves when a JTA STATUS_UNKNOWN is passed in to the cache during afterCompletion().
+ *
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
+ */
+ at Test(groups = "functional")
+public class StatusUnknownTest
+{
+   private Cache<String, String> cache;
+   private TransactionManager tm;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      cache = new DefaultCacheFactory<String, String>().createCache(false);
+      cache.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
+      cache.getConfiguration().setTransactionManagerLookupClass(HeuristicFailingDummyTransactionManagerLookup.class.getName());
+      cache.start();
+      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      cache.stop();
+   }
+
+   public void testStatusUnknown() throws Exception
+   {
+      tm.begin();
+      Fqn fqn = Fqn.fromString("/a/b/c");
+
+      cache.put(fqn, "k", "v");
+      assertEquals(4, ((CacheSPI) cache).getNumberOfLocksHeld());
+      assertTrue(cache.getRoot().hasChild(fqn));
+      tm.commit();
+
+      assertEquals(0, ((CacheSPI) cache).getNumberOfLocksHeld());
+      assertFalse(cache.getRoot().hasChild(fqn));
+   }
+
+   public static class HeuristicFailingDummyTransactionManager extends DummyTransactionManager
+   {
+      private static final long serialVersionUID = 6325631394461739211L;
+
+      @Override
+      public void begin() throws SystemException, NotSupportedException
+      {
+         super.begin();
+
+         Transaction tx = new HeuristicFailingDummyTransaction(this);
+         setTransaction(tx);
+      }
+
+      public static DummyTransactionManager getInstance()
+      {
+         if (instance == null)
+         {
+            instance = new HeuristicFailingDummyTransactionManager();
+            try
+            {
+               Properties p = new Properties();
+               p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
+               Context ctx = new InitialContext(p);
+               ctx.bind("java:/TransactionManager", instance);
+               ctx.bind("UserTransaction", new DummyUserTransaction(instance));
+            }
+            catch (NamingException e)
+            {
+               log.error("binding of DummyTransactionManager failed", e);
+            }
+         }
+         return instance;
+      }
+   }
+
+   public static class HeuristicFailingDummyTransaction extends DummyTransaction
+   {
+      public HeuristicFailingDummyTransaction(DummyBaseTransactionManager mgr)
+      {
+         super(mgr);
+      }
+
+      @Override
+      public void commit() throws RollbackException
+      {
+         try
+         {
+            notifyBeforeCompletion();
+            notifyAfterCompletion(Status.STATUS_UNKNOWN);
+         }
+         finally
+         {
+            // Disassociate tx from thread.
+            tm_.setTransaction(null);
+         }
+      }
+
+      @Override
+      protected void notifyAfterCompletion(int status)
+      {
+         List<Synchronization> tmp;
+
+         synchronized (participants)
+         {
+            tmp = new LinkedList<Synchronization>(participants);
+         }
+
+         for (Synchronization s : tmp)
+         {
+            try
+            {
+               s.afterCompletion(status);
+            }
+            catch (Throwable t)
+            {
+               throw (RuntimeException) t;
+            }
+         }
+
+         synchronized (participants)
+         {
+            participants.clear();
+         }
+      }
+   }
+
+   public static class HeuristicFailingDummyTransactionManagerLookup implements TransactionManagerLookup
+   {
+
+      public TransactionManager getTransactionManager() throws Exception
+      {
+         return HeuristicFailingDummyTransactionManager.getInstance();
+      }
+   }
+}
+
+




More information about the jbosscache-commits mailing list