[jbosscache-commits] JBoss Cache SVN: r7230 - core/branches/flat/src/test/java/org/jboss/starobrno/api/tree.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Nov 28 10:55:10 EST 2008


Author: manik.surtani at jboss.com
Date: 2008-11-28 10:55:10 -0500 (Fri, 28 Nov 2008)
New Revision: 7230

Added:
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITest.java
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSupport.java
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveAPITest.java
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTest.java
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTxTest.java
   core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheAPITest.java
Log:
Fixed tree related stuff

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeAPITest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITest.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,398 @@
+package org.jboss.starobrno.api.tree;
+
+import org.jboss.cache.transaction.DummyTransactionManager;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.UnitTestCacheFactory;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.tree.Fqn;
+import org.jboss.starobrno.tree.Node;
+import org.jboss.starobrno.tree.TreeCache;
+import org.jboss.starobrno.tree.TreeCacheImpl;
+import org.jboss.starobrno.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.TransactionManager;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests {@link org.jboss.cache.Node}-centric operations
+ *
+ * @author <a href="mailto:manik AT jboss DOT org">Manik Surtani</a>
+ * @since 2.0.0
+ */
+ at Test(groups = {"functional", "pessimistic"})
+public class NodeAPITest
+{
+   protected ThreadLocal<TreeCache<Object, Object>> cacheTL = new ThreadLocal<TreeCache<Object, Object>>();
+   protected static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d");
+   protected Fqn A_B = Fqn.fromRelativeFqn(A, B);
+   protected Fqn A_C = Fqn.fromRelativeFqn(A, C);
+   protected TransactionManager tm;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      // start a single cache instance
+      Configuration c = new Configuration();
+      c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c, false);
+      cache.getConfiguration().setInvocationBatchingEnabled(true);
+      cache.start();
+      cacheTL.set(new TreeCacheImpl(cache));
+      tm = cache.getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TestingUtil.killTreeCaches(cache);
+      cacheTL.set(null);
+   }
+
+   public void testAddingData()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      nodeA.put("key", "value");
+
+      assertEquals("value", nodeA.get("key"));
+   }
+
+   public void testAddingDataTx() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+      tm.begin();
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      nodeA.put("key", "value");
+
+      assertEquals("value", nodeA.get("key"));
+      tm.commit();
+   }
+
+   public void testOverwritingDataTx() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      nodeA.put("key", "value");
+      assertEquals("value", nodeA.get("key"));
+      tm.begin();
+      rootNode.removeChild(A);
+      cache.put(A, "k2", "v2");
+      tm.commit();
+      assertNull(nodeA.get("key"));
+      assertEquals("v2", nodeA.get("k2"));
+   }
+
+
+   /**
+    * Remember, Fqns are relative!!
+    */
+   public void testParentsAndChildren()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      Node<Object, Object> nodeB = nodeA.addChild(B);
+      Node<Object, Object> nodeC = nodeA.addChild(C);
+      Node<Object, Object> nodeD = rootNode.addChild(D);
+
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(nodeA, nodeB.getParent());
+      assertEquals(nodeA, nodeC.getParent());
+      assertEquals(rootNode, nodeD.getParent());
+
+      assertTrue(rootNode.hasChild(A));
+      assertFalse(rootNode.hasChild(B));
+      assertFalse(rootNode.hasChild(C));
+      assertTrue(rootNode.hasChild(D));
+
+      assertTrue(nodeA.hasChild(B));
+      assertTrue(nodeA.hasChild(C));
+
+      assertEquals(nodeA, rootNode.getChild(A));
+      assertEquals(nodeD, rootNode.getChild(D));
+      assertEquals(nodeB, nodeA.getChild(B));
+      assertEquals(nodeC, nodeA.getChild(C));
+
+      assertTrue(nodeA.getChildren().contains(nodeB));
+      assertTrue(nodeA.getChildren().contains(nodeC));
+      assertEquals(2, nodeA.getChildren().size());
+
+      assertTrue(rootNode.getChildren().contains(nodeA));
+      assertTrue(rootNode.getChildren().contains(nodeD));
+      assertEquals(2, rootNode.getChildren().size());
+
+      assertEquals(true, rootNode.removeChild(A));
+      assertFalse(rootNode.getChildren().contains(nodeA));
+      assertTrue(rootNode.getChildren().contains(nodeD));
+      assertEquals(1, rootNode.getChildren().size());
+
+      assertEquals("double remove", false, rootNode.removeChild(A));
+      assertEquals("double remove", false, rootNode.removeChild(A.getLastElement()));
+   }
+
+
+   public void testImmutabilityOfData()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      rootNode.put("key", "value");
+      Map<Object, Object> m = rootNode.getData();
+      try
+      {
+         m.put("x", "y");
+         fail("Map should be immutable!!");
+      }
+      catch (Exception e)
+      {
+         // expected
+      }
+
+      try
+      {
+         rootNode.getKeys().add(new Object());
+         fail("Key set should be immutable");
+      }
+      catch (Exception e)
+      {
+         // expected
+      }
+   }
+
+   public void testDefensiveCopyOfData()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      rootNode.put("key", "value");
+      Map<Object, Object> data = rootNode.getData();
+      Set<Object> keys = rootNode.getKeys();
+
+      assert keys.size() == 1;
+      assert keys.contains("key");
+
+      assert data.size() == 1;
+      assert data.containsKey("key");
+
+      // now change stuff.
+
+      rootNode.put("key2", "value2");
+
+      // assert that the collections we initially got have not changed.
+      assert keys.size() == 1;
+      assert keys.contains("key");
+
+      assert data.size() == 1;
+      assert data.containsKey("key");
+   }
+
+   public void testDefensiveCopyOfChildren()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Fqn childFqn = Fqn.fromString("/child");
+      rootNode.addChild(childFqn).put("k", "v");
+      Set<Node<Object, Object>> children = rootNode.getChildren();
+      Set<Object> childrenNames = rootNode.getChildrenNames();
+
+      assert childrenNames.size() == 1;
+      assert childrenNames.contains(childFqn.getLastElement());
+
+      assert children.size() == 1;
+      assert children.iterator().next().getFqn().equals(childFqn);
+
+      // now change stuff.
+
+      rootNode.addChild(Fqn.fromString("/child2"));
+
+      // assert that the collections we initially got have not changed.
+      assert childrenNames.size() == 1;
+      assert childrenNames.contains(childFqn.getLastElement());
+
+      assert children.size() == 1;
+      assert children.iterator().next().getFqn().equals(childFqn);
+   }
+
+
+   public void testImmutabilityOfChildren()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      rootNode.addChild(A);
+
+      try
+      {
+         rootNode.getChildren().clear();
+         fail("Collection of child nodes returned in getChildren() should be immutable");
+      }
+      catch (Exception e)
+      {
+         // expected
+      }
+   }
+
+   public void testGetChildAPI()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      // creates a Node<Object, Object> with fqn /a/b/c
+      Node childA = rootNode.addChild(A);
+      childA.addChild(B).addChild(C);
+
+      rootNode.getChild(A).put("key", "value");
+      rootNode.getChild(A).getChild(B).put("key", "value");
+      rootNode.getChild(A).getChild(B).getChild(C).put("key", "value");
+
+      assertEquals("value", rootNode.getChild(A).get("key"));
+      assertEquals("value", rootNode.getChild(A).getChild(B).get("key"));
+      assertEquals("value", rootNode.getChild(A).getChild(B).getChild(C).get("key"));
+
+      assertNull(rootNode.getChild(Fqn.fromElements("nonexistent")));
+   }
+
+   public void testClearingData()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      rootNode.put("k", "v");
+      rootNode.put("k2", "v2");
+      assertEquals(2, rootNode.getKeys().size());
+      rootNode.clearData();
+      assertEquals(0, rootNode.getKeys().size());
+      assertTrue(rootNode.getData().isEmpty());
+   }
+
+   public void testClearingDataTx() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      tm.begin();
+      rootNode.put("k", "v");
+      rootNode.put("k2", "v2");
+      assertEquals(2, rootNode.getKeys().size());
+      rootNode.clearData();
+      assertEquals(0, rootNode.getKeys().size());
+      assertTrue(rootNode.getData().isEmpty());
+      tm.commit();
+      assertTrue(rootNode.getData().isEmpty());
+   }
+
+   public void testPutData()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      assertTrue(rootNode.getData().isEmpty());
+
+      Map<Object, Object> map = new HashMap<Object, Object>();
+      map.put("k1", "v1");
+      map.put("k2", "v2");
+
+      rootNode.putAll(map);
+
+      assertEquals(2, rootNode.getData().size());
+      assertEquals("v1", rootNode.get("k1"));
+      assertEquals("v2", rootNode.get("k2"));
+
+      map.clear();
+      map.put("k3", "v3");
+
+      rootNode.putAll(map);
+      assertEquals(3, rootNode.getData().size());
+      assertEquals("v1", rootNode.get("k1"));
+      assertEquals("v2", rootNode.get("k2"));
+      assertEquals("v3", rootNode.get("k3"));
+
+      map.clear();
+      map.put("k4", "v4");
+      map.put("k5", "v5");
+
+      rootNode.replaceAll(map);
+      assertEquals(2, rootNode.getData().size());
+      assertEquals("v4", rootNode.get("k4"));
+      assertEquals("v5", rootNode.get("k5"));
+   }
+
+   public void testGetChildrenNames() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      rootNode.addChild(A).put("k", "v");
+      rootNode.addChild(B).put("k", "v");
+
+      Set<Object> childrenNames = new HashSet<Object>();
+      childrenNames.add(A.getLastElement());
+      childrenNames.add(B.getLastElement());
+
+      assertEquals(childrenNames, rootNode.getChildrenNames());
+
+      // now delete a child, within a tx
+      tm.begin();
+      rootNode.removeChild(B);
+      assertFalse(rootNode.hasChild(B));
+      childrenNames.remove(B.getLastElement());
+      assertEquals(childrenNames, rootNode.getChildrenNames());
+      tm.commit();
+      assertEquals(childrenNames, rootNode.getChildrenNames());
+   }
+
+   public void testDoubleRemovalOfData() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+
+      assert DummyTransactionManager.getInstance().getTransaction() == null;
+      cache.put("/foo/1/2/3", "item", 1);
+      assert DummyTransactionManager.getInstance().getTransaction() == null;
+      assert 1 == (Integer) cache.get("/foo/1/2/3", "item");
+      tm.begin();
+      assert 1 == (Integer) cache.get("/foo/1/2/3", "item");
+      cache.removeNode("/foo/1");
+      assertNull(cache.getNode("/foo/1"));
+      assertNull(cache.get("/foo/1", "item"));
+      cache.removeNode("/foo/1/2/3");
+      System.out.println("Cache: " + cache);
+      assertNull(cache.get("/foo/1/2/3", "item"));
+      assertNull(cache.get("/foo/1", "item"));
+      tm.commit();
+      assertFalse(cache.exists("/foo/1"));
+      assertNull(cache.get("/foo/1/2/3", "item"));
+      assertNull(cache.get("/foo/1", "item"));
+   }
+
+   public void testDoubleRemovalOfData2() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+
+      cache.put("/foo/1/2", "item", 1);
+      tm.begin();
+      assertEquals(cache.get("/foo/1", "item"), null);
+      cache.removeNode("/foo/1");
+      assertNull(cache.get("/foo/1", "item"));
+      cache.removeNode("/foo/1/2");
+      assertNull(cache.get("/foo/1", "item"));
+      tm.commit();
+      assertFalse(cache.exists("/foo/1"));
+      assertNull(cache.get("/foo/1/2", "item"));
+      assertNull(cache.get("/foo/1", "item"));
+   }
+}


Property changes on: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSupport.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeLockSupport.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSupport.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSupport.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.starobrno.api.tree;
+
+import org.jboss.starobrno.Cache;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.lock.LockManager;
+import org.jboss.starobrno.tree.Fqn;
+import org.jboss.starobrno.tree.TreeCache;
+import org.jboss.starobrno.tree.TreeStructureSupport;
+
+import javax.transaction.TransactionManager;
+
+public abstract class NodeLockSupport
+{
+   static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d"), E = Fqn.fromString("/e");
+   static final Object k = "key", vA = "valueA", vB = "valueB", vC = "valueC", vD = "valueD", vE = "valueE";
+   static final Fqn A_B = Fqn.fromRelativeFqn(A, B);
+   static final Fqn A_B_C = Fqn.fromRelativeFqn(A_B, C);
+   static final Fqn A_B_C_E = Fqn.fromRelativeFqn(A_B_C, E);
+   static final Fqn A_B_D = Fqn.fromRelativeFqn(A_B, D);
+   static final Fqn C_E = Fqn.fromRelativeFqn(C, E);
+   static final Fqn D_B = Fqn.fromRelativeFqn(D, B);
+   static final Fqn D_B_C = Fqn.fromRelativeFqn(D_B, C);
+
+   protected ThreadLocal<Cache<Object, Object>> cacheTL = new ThreadLocal<Cache<Object, Object>>();
+   protected ThreadLocal<TransactionManager> tmTL = new ThreadLocal<TransactionManager>();
+   protected ThreadLocal<TreeCache> treeCacheTL = new ThreadLocal<TreeCache>();
+
+   protected void checkLocks()
+   {
+      Cache<Object, Object> cache = cacheTL.get();
+
+      assert !TreeStructureSupport.isLocked(cache, A);
+      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
+      assert TreeStructureSupport.isLocked(cache, C);
+      assert TreeStructureSupport.isLocked(cache, A_B);
+      assert TreeStructureSupport.isLocked(cache, A_B_C);
+   }
+
+   protected void checkLocksDeep()
+   {
+      Cache<Object, Object> cache = cacheTL.get();
+
+      assert !TreeStructureSupport.isLocked(cache, A);
+      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
+      assert !TreeStructureSupport.isLocked(cache, A_B_D);
+
+      assert TreeStructureSupport.isLocked(cache, C);
+      assert TreeStructureSupport.isLocked(cache, C_E);
+      assert TreeStructureSupport.isLocked(cache, A_B);
+      assert TreeStructureSupport.isLocked(cache, A_B_C);
+      assert TreeStructureSupport.isLocked(cache, A_B_C_E);
+   }
+
+   protected void assertNoLocks()
+   {
+      Cache<Object, Object> cache = cacheTL.get();
+      LockManager lm = ((CacheSPI) cache).getLockManager();
+      for (Object key : cache.keySet()) assert !lm.isLocked(key);
+   }
+}


Property changes on: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSupport.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveAPITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeMoveAPITest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveAPITest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveAPITest.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,667 @@
+package org.jboss.starobrno.api.tree;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.NodeNotExistsException;
+import org.jboss.starobrno.Cache;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.UnitTestCacheFactory;
+import org.jboss.starobrno.api.mvcc.LockAssert;
+import org.jboss.starobrno.config.CacheLoaderConfig;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.config.parsing.XmlConfigHelper;
+import org.jboss.starobrno.config.parsing.element.LoadersElementParser;
+import org.jboss.starobrno.factories.ComponentRegistry;
+import org.jboss.starobrno.invocation.InvocationContextContainer;
+import org.jboss.starobrno.lock.LockManager;
+import org.jboss.starobrno.tree.*;
+import org.jboss.starobrno.util.TestingUtil;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.w3c.dom.Element;
+
+import javax.transaction.TransactionManager;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Excercises and tests the new move() api
+ *
+ * @author <a href="mailto:manik AT jboss DOT org">Manik Surtani</a>
+ * @since 2.0.0
+ */
+ at Test(groups = {"functional", "pessimistic"}, testName = "api.NodeMoveAPITest")
+public class NodeMoveAPITest
+{
+   protected final Log log = LogFactory.getLog(getClass());
+
+   protected static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d"), E = Fqn.fromString("/e");
+   static final Fqn A_B = Fqn.fromRelativeFqn(A, B);
+   static final Fqn A_B_C = Fqn.fromRelativeFqn(A_B, C);
+   static final Fqn A_B_C_E = Fqn.fromRelativeFqn(A_B_C, E);
+   static final Fqn A_B_D = Fqn.fromRelativeFqn(A_B, D);
+   static final Fqn C_E = Fqn.fromRelativeFqn(C, E);
+   static final Fqn D_B = Fqn.fromRelativeFqn(D, B);
+   static final Fqn D_B_C = Fqn.fromRelativeFqn(D_B, C);
+   protected static final Object k = "key", vA = "valueA", vB = "valueB", vC = "valueC", vD = "valueD", vE = "valueE";
+
+   protected ThreadLocal<TreeCache<Object, Object>> cacheTL = new ThreadLocal<TreeCache<Object, Object>>();
+   protected ThreadLocal<TransactionManager> tmTL = new ThreadLocal<TransactionManager>();
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      // start a single cache instance
+      Configuration c = new Configuration();
+      c.setFetchInMemoryState(false);
+      c.setInvocationBatchingEnabled(true);
+      CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c);
+
+      cacheTL.set(new TreeCacheImpl<Object, Object>(cache));
+      tmTL.set(cache.getTransactionManager());
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      TestingUtil.killTreeCaches(cacheTL.get());
+      cacheTL.set(null);
+   }
+
+   public void testBasicMove()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      nodeA.put(k, vA);
+      Node<Object, Object> nodeB = rootNode.addChild(B);
+      nodeB.put(k, vB);
+      Node<Object, Object> nodeC = nodeA.addChild(C);
+      nodeC.put(k, vC);
+      /*
+        /a/c
+        /b
+      */
+
+      assertTrue(rootNode.hasChild(A));
+      assertTrue(rootNode.hasChild(B));
+      assertFalse(rootNode.hasChild(C));
+      assertTrue(nodeA.hasChild(C));
+
+      // test data
+      assertEquals("" + nodeA, vA, nodeA.get(k));
+      assertEquals(vB, nodeB.get(k));
+      assertEquals(vC, nodeC.get(k));
+
+      // parentage
+      assertEquals(nodeA, nodeC.getParent());
+
+      log.info("BEFORE MOVE " + cache);
+      // move
+      cache.move(nodeC.getFqn(), nodeB.getFqn());
+
+      // re-fetch nodeC
+      nodeC = cache.getNode(Fqn.fromRelativeFqn(nodeB.getFqn(), C));
+
+      log.info("POST MOVE " + cache);
+      log.info("HC " + nodeC + " " + System.identityHashCode(nodeC));
+      Node x = cache.getRoot().getChild(Fqn.fromString("b/c"));
+      log.info("HC " + x + " " + System.identityHashCode(x));
+      /*
+         /a
+         /b/c
+      */
+      assertEquals("NODE C " + nodeC, "/b/c", nodeC.getFqn().toString());
+
+      assertTrue(rootNode.hasChild(A));
+      assertTrue(rootNode.hasChild(B));
+      assertFalse(rootNode.hasChild(C));
+      assertFalse(nodeA.hasChild(C));
+      assertTrue(nodeB.hasChild(C));
+
+      // test data
+      assertEquals(vA, nodeA.get(k));
+      assertEquals(vB, nodeB.get(k));
+      assertEquals(vC, nodeC.get(k));
+
+      // parentage
+      assertEquals("B is parent of C: " + nodeB, nodeB, nodeC.getParent());
+   }
+
+   @SuppressWarnings("unchecked")
+   private Node<Object, Object> genericize(Node node)
+   {
+      return (Node<Object, Object>) node;
+   }
+
+   public void testMoveWithChildren()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      nodeA.put(k, vA);
+      Node<Object, Object> nodeB = rootNode.addChild(B);
+      nodeB.put(k, vB);
+      Node<Object, Object> nodeC = nodeA.addChild(C);
+      nodeC.put(k, vC);
+      Node<Object, Object> nodeD = nodeC.addChild(D);
+      nodeD.put(k, vD);
+      Node<Object, Object> nodeE = nodeD.addChild(E);
+      nodeE.put(k, vE);
+
+      assertTrue(rootNode.hasChild(A));
+      assertTrue(rootNode.hasChild(B));
+      assertFalse(rootNode.hasChild(C));
+      assertTrue(nodeA.hasChild(C));
+      assertTrue(nodeC.hasChild(D));
+      assertTrue(nodeD.hasChild(E));
+
+      // test data
+      assertEquals(vA, nodeA.get(k));
+      assertEquals(vB, nodeB.get(k));
+      assertEquals(vC, nodeC.get(k));
+      assertEquals(vD, nodeD.get(k));
+      assertEquals(vE, nodeE.get(k));
+
+      // parentage
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(rootNode, nodeB.getParent());
+      assertEquals(nodeA, nodeC.getParent());
+      assertEquals(nodeC, nodeD.getParent());
+      assertEquals(nodeD, nodeE.getParent());
+
+      // move
+      log.info("move " + nodeC + " to " + nodeB);
+      cache.move(nodeC.getFqn(), nodeB.getFqn());
+      //System.out.println("nodeB " + nodeB);
+      //System.out.println("nodeC " + nodeC);
+
+      // child nodes will need refreshing, since existing pointers will be stale.
+      nodeC = nodeB.getChild(C);
+      nodeD = nodeC.getChild(D);
+      nodeE = nodeD.getChild(E);
+
+      assertTrue(rootNode.hasChild(A));
+      assertTrue(rootNode.hasChild(B));
+      assertFalse(rootNode.hasChild(C));
+      assertFalse(nodeA.hasChild(C));
+      assertTrue(nodeB.hasChild(C));
+      assertTrue(nodeC.hasChild(D));
+      assertTrue(nodeD.hasChild(E));
+
+      // test data
+      assertEquals(vA, nodeA.get(k));
+      assertEquals(vB, nodeB.get(k));
+      assertEquals(vC, nodeC.get(k));
+      assertEquals(vD, nodeD.get(k));
+      assertEquals(vE, nodeE.get(k));
+
+      // parentage
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(rootNode, nodeB.getParent());
+      assertEquals(nodeB, nodeC.getParent());
+      assertEquals(nodeC, nodeD.getParent());
+      assertEquals(nodeD, nodeE.getParent());
+   }
+
+   public void testTxCommit() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      Node<Object, Object> nodeB = nodeA.addChild(B);
+
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(nodeA, nodeB.getParent());
+      assertEquals(nodeA, rootNode.getChildren().iterator().next());
+      assertEquals(nodeB, nodeA.getChildren().iterator().next());
+
+      tm.begin();
+      // move node B up to hang off the root
+      cache.move(nodeB.getFqn(), Fqn.ROOT);
+
+      tm.commit();
+
+      nodeB = rootNode.getChild(B);
+
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(rootNode, nodeB.getParent());
+
+      assertTrue(rootNode.getChildren().contains(nodeA));
+      assertTrue(rootNode.getChildren().contains(nodeB));
+
+      assertTrue(nodeA.getChildren().isEmpty());
+   }
+
+   public void testTxRollback() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      Node<Object, Object> nodeB = nodeA.addChild(B);
+
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(nodeA, nodeB.getParent());
+      assertEquals(nodeA, rootNode.getChildren().iterator().next());
+      assertEquals(nodeB, nodeA.getChildren().iterator().next());
+
+
+      tm.begin();
+      // move node B up to hang off the root
+      System.out.println("Before: " + TreeStructureSupport.printTree(cache, true));
+      cache.move(nodeB.getFqn(), Fqn.ROOT);
+      System.out.println("After: " + TreeStructureSupport.printTree(cache, true));
+      tm.rollback();
+      System.out.println("Rolled back: " + TreeStructureSupport.printTree(cache, true));
+
+      nodeA = rootNode.getChild(A);
+      nodeB = nodeA.getChild(B);
+
+      // should revert
+      assertEquals(rootNode, nodeA.getParent());
+      assertEquals(nodeA, nodeB.getParent());
+      assertEquals(nodeA, rootNode.getChildren().iterator().next());
+      assertEquals(nodeB, nodeA.getChildren().iterator().next());
+   }
+
+   /*
+   public void testWithCacheloaders() throws Exception
+   {
+      doCacheLoaderTest(false, false);
+   }
+
+   public void testWithPassivation() throws Exception
+   {
+      doCacheLoaderTest(true, false);
+   }
+
+   public void testWithCacheloadersTx() throws Exception
+   {
+      doCacheLoaderTest(false, true);
+   }
+
+   public void testWithPassivationTx() throws Exception
+   {
+      doCacheLoaderTest(true, true);
+   }
+   */
+
+   /*
+protected void doCacheLoaderTest(boolean pasv, boolean useTx) throws Exception
+{
+TreeCache<Object, Object> cache = cacheTL.get();
+TransactionManager tm = tmTL.get();
+Node<Object, Object> rootNode = cache.getRoot();
+
+cache.destroy();
+cache.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig(pasv, "/", DummyInMemoryCacheLoader.class.getName(), "debug=true", false, false, false, false));
+cache.start();
+
+DummyInMemoryCacheLoader loader = (DummyInMemoryCacheLoader) cache.getCacheLoaderManager().getCacheLoader();
+
+rootNode.put("key", "value");
+
+if (!pasv)
+{
+Map m = loader.get(Fqn.ROOT);
+assertNotNull("Should not be null", m);
+assertEquals("value", m.get("key"));
+}
+
+Node<Object, Object> nodeA = rootNode.addChild(A);
+nodeA.put(k, vA);
+Node<Object, Object> nodeB = rootNode.addChild(B);
+nodeB.put(k, vB);
+Node<Object, Object> nodeC = nodeA.addChild(C);
+nodeC.put(k, vC);
+Node<Object, Object> nodeD = nodeC.addChild(D);
+nodeD.put(k, vD);
+Node<Object, Object> nodeE = nodeD.addChild(E);
+nodeE.put(k, vE);
+cache.evict(Fqn.ROOT, true);
+
+// move
+if (useTx) tm.begin();
+cache.move(nodeC.getFqn(), nodeB.getFqn());
+if (useTx) tm.commit();
+
+// after eviction, the node objects we hold are probably stale.
+nodeA = rootNode.getChild(A);
+nodeB = rootNode.getChild(B);
+nodeC = nodeB.getChild(C);
+log.info("nodeC get child B ");
+nodeD = nodeC.getChild(D);
+log.info("nodeD get child E ");
+nodeE = nodeD.getChild(E);
+
+Fqn old_C = C;
+Fqn old_D = Fqn.fromRelativeFqn(old_C, D);
+Fqn old_E = Fqn.fromRelativeFqn(old_D, E);
+
+// test data
+assertEquals(vA, nodeA.get(k));
+assertEquals(vB, nodeB.get(k));
+assertEquals(vC, nodeC.get(k));
+assertEquals(vD, nodeD.get(k));
+assertEquals(vE, nodeE.get(k));
+
+// parentage
+assertEquals(rootNode, nodeA.getParent());
+assertEquals(rootNode, nodeB.getParent());
+assertEquals(nodeB, nodeC.getParent());
+assertEquals(nodeC, nodeD.getParent());
+assertEquals(nodeD, nodeE.getParent());
+
+
+if (pasv) cache.evict(Fqn.ROOT, true);
+
+//now inspect the loader.
+assertEquals(vA, loader.get(nodeA.getFqn()).get(k));
+assertEquals(vB, loader.get(nodeB.getFqn()).get(k));
+assertEquals(vC, loader.get(nodeC.getFqn()).get(k));
+assertEquals(vD, loader.get(nodeD.getFqn()).get(k));
+assertEquals(vE, loader.get(nodeE.getFqn()).get(k));
+
+assertNull(loader.get(old_C));
+assertNull(loader.get(old_D));
+assertNull(loader.get(old_E));
+
+}
+   */
+
+   public void testLocksDeepMove() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      Node<Object, Object> nodeB = nodeA.addChild(B);
+      Node<Object, Object> nodeD = nodeB.addChild(D);
+      Node<Object, Object> nodeC = rootNode.addChild(C);
+      Node<Object, Object> nodeE = nodeC.addChild(E);
+      assertNoLocks();
+      tm.begin();
+
+      cache.move(nodeC.getFqn(), nodeB.getFqn());
+
+      checkLocksDeep();
+
+
+      tm.commit();
+
+      assertNoLocks();
+   }
+
+   public void testLocks() throws Exception
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      TransactionManager tm = tmTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      Node<Object, Object> nodeA = rootNode.addChild(A);
+      Node<Object, Object> nodeB = nodeA.addChild(B);
+      Node<Object, Object> nodeC = rootNode.addChild(C);
+      assertNoLocks();
+      tm.begin();
+
+      cache.move(nodeC.getFqn(), nodeB.getFqn());
+
+      checkLocks();
+
+      tm.commit();
+      assertNoLocks();
+   }
+
+   public void testConcurrency() throws InterruptedException
+   {
+      final TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      final int N = 3;// number of threads
+      final int loops = 1 << 6;// number of loops
+      // tests a tree structure as such:
+      // /a
+      // /b
+      // /c
+      // /d
+      // /e
+      // /x
+      // /y
+
+      // N threads constantly move /x and /y around to hang off either /a ~ /e randomly.
+
+      final Fqn FQN_A = A, FQN_B = B, FQN_C = C, FQN_D = D, FQN_E = E, FQN_X = Fqn.fromString("/x"), FQN_Y = Fqn.fromString("/y");
+
+      // set up the initial structure.
+      final Node[] NODES = {
+            rootNode.addChild(FQN_A), rootNode.addChild(FQN_B),
+            rootNode.addChild(FQN_C), rootNode.addChild(FQN_D), rootNode.addChild(FQN_E)
+      };
+
+      final Node<Object, Object> NODE_X = genericize(NODES[0]).addChild(FQN_X);
+      final Node<Object, Object> NODE_Y = genericize(NODES[1]).addChild(FQN_Y);
+
+      Thread[] movers = new Thread[N];
+      final CountDownLatch latch = new CountDownLatch(1);
+      final Random r = new Random();
+
+      for (int i = 0; i < N; i++)
+      {
+         movers[i] = new Thread("Mover-" + i)
+         {
+            public void run()
+            {
+               try
+               {
+                  latch.await();
+               }
+               catch (InterruptedException e)
+               {
+               }
+
+               for (int counter = 0; counter < loops; counter++)
+               {
+
+                  System.out.println(getName() + ": Attempt " + counter);
+                  try
+                  {
+                     cache.move(NODE_X.getFqn(), NODES[r.nextInt(NODES.length)].getFqn());
+                  }
+                  catch (NodeNotExistsException e)
+                  {
+                     // this may happen ...
+                  }
+                  TestingUtil.sleepRandom(250);
+                  try
+                  {
+                     cache.move(NODE_Y.getFqn(), NODES[r.nextInt(NODES.length)].getFqn());
+                  }
+                  catch (NodeNotExistsException e)
+                  {
+                     // this may happen ...
+                  }
+                  TestingUtil.sleepRandom(250);
+               }
+            }
+         };
+         movers[i].start();
+      }
+
+      latch.countDown();
+
+      for (Thread t : movers)
+      {
+         t.join();
+      }
+
+      assertNoLocks();
+      boolean found_x = false, found_x_again = false;
+      for (Node erased : NODES)
+      {
+         Node<Object, Object> n = genericize(erased);
+         if (!found_x)
+         {
+            found_x = n.hasChild(FQN_X);
+         }
+         else
+         {
+            found_x_again = found_x_again || n.hasChild(FQN_X);
+         }
+      }
+      boolean found_y = false, found_y_again = false;
+      for (Node erased : NODES)
+      {
+         Node<Object, Object> n = genericize(erased);
+         if (!found_y)
+         {
+            found_y = n.hasChild(FQN_Y);
+         }
+         else
+         {
+            found_y_again = found_y_again || n.hasChild(FQN_Y);
+         }
+      }
+
+      assertTrue("Should have found x", found_x);
+      assertTrue("Should have found y", found_y);
+      assertFalse("Should have only found x once", found_x_again);
+      assertFalse("Should have only found y once", found_y_again);
+   }
+
+   public void testMoveInSamePlace()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      Node<Object, Object> rootNode = cache.getRoot();
+
+      final Fqn FQN_X = Fqn.fromString("/x");
+      // set up the initial structure.
+      Node aNode = rootNode.addChild(A);
+      Node xNode = aNode.addChild(FQN_X);
+      assertEquals(aNode.getChildren().size(), 1);
+
+      System.out.println("Before: " + TreeStructureSupport.printTree(cache, true));
+
+      cache.move(xNode.getFqn(), aNode.getFqn());
+
+      System.out.println("After: " + TreeStructureSupport.printTree(cache, true));
+
+      assertEquals(aNode.getChildren().size(), 1);
+
+      assertNoLocks();
+   }
+
+   protected CacheLoaderConfig getSingleCacheLoaderConfig(boolean passivation, String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
+   {
+      String xml =
+            "      <loaders passivation=\"" + passivation + "\" shared=\"" + shared + "\">\n" +
+                  "         <preload>\n" +
+                  "            <node fqn=\"" + preload + "\"/>\n" +
+                  "         </preload>\n" +
+                  "         <loader class=\"" + cacheloaderClass + "\" async=\"" + async + "\" fetchPersistentState=\"" + fetchPersistentState + "\"\n" +
+                  "                     purgeOnStartup=\"" + purgeOnStartup + "\">\n" +
+                  "            <properties>\n" +
+                  properties +
+                  "            </properties>\n" +
+                  "         </loader>\n" +
+                  "      </loaders>";
+      Element element = XmlConfigHelper.stringToElementInCoreNS(xml);
+      LoadersElementParser elementParser = new LoadersElementParser();
+      return elementParser.parseLoadersElement(element);
+   }
+
+   protected void checkLocks()
+   {
+      TreeCache<Object, Object> tree = cacheTL.get();
+      Cache<Object, Object> cache = tree.getCache();
+      ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
+      LockManager lm = cr.getComponent(LockManager.class);
+      InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+
+//      assert !TreeStructureSupport.isLocked(cache, A);
+//      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
+
+      assert TreeStructureSupport.isLocked(cache, C);
+      assert TreeStructureSupport.isLocked(cache, A_B);
+      assert TreeStructureSupport.isLocked(cache, A_B_C);
+   }
+
+   protected void checkLocksDeep()
+   {
+      TreeCache<Object, Object> tree = cacheTL.get();
+      Cache<Object, Object> cache = tree.getCache();
+      ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
+      LockManager lm = cr.getComponent(LockManager.class);
+      InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+
+//      assert !TreeStructureSupport.isLocked(cache, A);
+//      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
+//      assert !TreeStructureSupport.isLocked(cache, A_B_D);
+
+      // /a/b, /c, /c/e, /a/b/c and /a/b/c/e should all be locked.
+      assert TreeStructureSupport.isLocked(cache, A_B);
+      assert TreeStructureSupport.isLocked(cache, C);
+      assert TreeStructureSupport.isLocked(cache, C_E);
+      assert TreeStructureSupport.isLocked(cache, A_B_C);
+      assert TreeStructureSupport.isLocked(cache, A_B_C_E);
+   }
+
+   protected void assertNoLocks()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache.getCache());
+      LockManager lm = cr.getComponent(LockManager.class);
+      InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+      LockAssert.assertNoLocks(lm, icc);
+   }
+
+   public void testNonexistentSource()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      cache.put(A_B_C, "k", "v");
+      assert "v".equals(cache.get(A_B_C, "k"));
+      assert 1 == cache.getNode(A_B).getChildren().size();
+      assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+      assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElement());
+
+      cache.move(D, A_B);
+
+      assert "v".equals(cache.get(A_B_C, "k"));
+      assert 1 == cache.getNode(A_B).getChildren().size();
+      assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+      assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElement());
+   }
+
+   public void testNonexistentTarget()
+   {
+      TreeCache<Object, Object> cache = cacheTL.get();
+      cache.put(A_B_C, "k", "v");
+      assert "v".equals(cache.get(A_B_C, "k"));
+      assert 1 == cache.getNode(A_B).getChildren().size();
+      assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+      assert null == cache.getNode(D);
+
+      System.out.println(TreeStructureSupport.printTree(cache, true));
+
+      cache.move(A_B, D);
+
+      System.out.println(TreeStructureSupport.printTree(cache, true));
+
+      assert null == cache.getNode(A_B_C);
+      assert null == cache.getNode(A_B);
+      assert null != cache.getNode(D);
+      assert null != cache.getNode(D_B);
+      assert null != cache.getNode(D_B_C);
+      assert "v".equals(cache.get(D_B_C, "k"));
+   }
+}

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTest.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.starobrno.api.tree;
+
+import org.jboss.starobrno.Cache;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.UnitTestCacheFactory;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.tree.Fqn;
+import org.jboss.starobrno.tree.Node;
+import org.jboss.starobrno.tree.TreeCache;
+import org.jboss.starobrno.tree.TreeCacheImpl;
+import org.jboss.starobrno.util.TestingUtil;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:manik AT jboss DOT org">Manik Surtani (manik AT jboss DOT org)</a>
+ */
+ at Test(groups = {"functional", "jgroups", "pessimistic"}, sequential = true, testName = "api.SyncReplTest")
+public class SyncReplTest
+{
+   private CacheSPI<Object, Object> c1, c2;
+   private TreeCache<Object, Object> cache1, cache2;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp()
+   {
+      System.out.println("*** In setUp()");
+      Configuration c = new Configuration();
+      c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+      c.setInvocationBatchingEnabled(true);
+      c.setFetchInMemoryState(false);
+
+      c1 = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c.clone());
+      c2 = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c.clone());
+
+      TestingUtil.blockUntilViewsReceived(new Cache[]{c1, c2}, 5000);
+
+      cache1 = new TreeCacheImpl<Object, Object>(c1);
+      cache2 = new TreeCacheImpl<Object, Object>(c2);
+
+      System.out.println("*** Finished setUp()");
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      TestingUtil.killCaches(c1, c2);
+      cache1 = null;
+      cache2 = null;
+   }
+
+   public void testBasicOperation()
+   {
+      assertClusterSize("Should only be 2  caches in the cluster!!!", 2);
+
+      Fqn f = Fqn.fromString("/test/data");
+      String k = "key", v = "value";
+
+      assertNull("Should be null", cache1.getRoot().getChild(f));
+      assertNull("Should be null", cache2.getRoot().getChild(f));
+
+      Node<Object, Object> node = cache1.getRoot().addChild(f);
+
+      assertNotNull("Should not be null", node);
+
+      node.put(k, v);
+
+      assertEquals(v, node.get(k));
+      assertEquals(v, cache1.get(f, k));
+      assert v.equals(cache2.get(f, k));
+   }
+
+   public void testSyncRepl()
+   {
+      assertClusterSize("Should only be 2  caches in the cluster!!!", 2);
+
+      Fqn fqn = Fqn.fromString("/JSESSIONID/1010.10.5:3000/1234567890/1");
+      cache1.getConfiguration().setSyncCommitPhase(true);
+      cache2.getConfiguration().setSyncCommitPhase(true);
+
+
+      cache1.put(fqn, "age", 38);
+      assertEquals("Value should be set", 38, cache1.get(fqn, "age"));
+      assertEquals("Value should have replicated", 38, cache2.get(fqn, "age"));
+   }
+
+   public void testPutMap()
+   {
+      assertClusterSize("Should only be 2  caches in the cluster!!!", 2);
+
+      Fqn fqn = Fqn.fromString("/JSESSIONID/10.10.10.5:3000/1234567890/1");
+      Fqn fqn1 = Fqn.fromString("/JSESSIONID/10.10.10.5:3000/1234567890/2");
+
+      Map<Object, Object> map = new HashMap<Object, Object>();
+      map.put("1", "1");
+      map.put("2", "2");
+      cache1.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache1.getRoot().addChild(fqn).putAll(map);
+      cache1.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      assertEquals("Value should be set", "1", cache1.get(fqn, "1"));
+
+      map = new HashMap<Object, Object>();
+      map.put("3", "3");
+      map.put("4", "4");
+      cache1.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      cache1.getRoot().addChild(fqn1).putAll(map);
+
+      cache1.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+      assertEquals("Value should be set", "2", cache1.get(fqn, "2"));
+   }
+
+
+   private void assertClusterSize(String message, int size)
+   {
+      assertClusterSize(message, size, cache1);
+      assertClusterSize(message, size, cache2);
+   }
+
+   private void assertClusterSize(String message, int size, TreeCache c)
+   {
+      assertEquals(message, size, c.getMembers().size());
+   }
+}

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTxTest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTxTest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTxTest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTxTest.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,117 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.starobrno.api.tree;
+
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.starobrno.Cache;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.UnitTestCacheFactory;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.tree.Fqn;
+import org.jboss.starobrno.tree.Node;
+import org.jboss.starobrno.tree.TreeCache;
+import org.jboss.starobrno.tree.TreeCacheImpl;
+import org.jboss.starobrno.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.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:manik AT jboss DOT org">Manik Surtani (manik AT jboss DOT org)</a>
+ */
+ at Test(groups = {"functional", "jgroups", "transaction", "pessimistic"}, sequential = true, testName = "api.SyncReplTxTest")
+public class SyncReplTxTest
+{
+   private List<CacheSPI<Object, Object>> flatCaches;
+   private List<TreeCache<Object, Object>> caches;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws CloneNotSupportedException
+   {
+      System.out.println("*** In setUp()");
+      caches = new ArrayList<TreeCache<Object, Object>>();
+      flatCaches = new ArrayList<CacheSPI<Object, Object>>();
+      Configuration c = new Configuration();
+      c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+      c.setFetchInMemoryState(false);
+      c.setInvocationBatchingEnabled(true);
+      c.setSyncCommitPhase(true);
+      c.setSyncRollbackPhase(true);
+      c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+
+      CacheSPI<Object, Object> cache1 = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c.clone());
+      CacheSPI<Object, Object> cache2 = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c.clone());
+
+      flatCaches.add(cache1);
+      flatCaches.add(cache2);
+
+      TestingUtil.blockUntilViewsReceived(caches.toArray(new Cache[0]), 10000);
+
+      caches.add(new TreeCacheImpl<Object, Object>(cache1));
+      caches.add(new TreeCacheImpl<Object, Object>(cache2));
+
+      System.out.println("*** Finished setUp()");
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      System.out.println("*** In tearDown()");
+      TestingUtil.killTreeCaches(caches);
+      caches = null;
+      System.out.println("*** Finished tearDown()");
+   }
+
+   private TransactionManager beginTransaction(Cache<Object, Object> cache) throws NotSupportedException, SystemException
+   {
+      TransactionManager mgr = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+      mgr.begin();
+      return mgr;
+   }
+
+   public void testBasicOperation() throws SystemException, NotSupportedException, HeuristicMixedException, HeuristicRollbackException, RollbackException
+   {
+      assertClusterSize("Should only be 2  caches in the cluster!!!", 2);
+
+      Fqn f = Fqn.fromString("/test/data");
+      String k = "key", v = "value";
+
+      assertNull("Should be null", caches.get(0).getRoot().getChild(f));
+      assertNull("Should be null", caches.get(1).getRoot().getChild(f));
+
+      Node<Object, Object> node = caches.get(0).getRoot().addChild(f);
+
+      assertNotNull("Should not be null", node);
+
+      TransactionManager tm = beginTransaction(caches.get(0).getCache());
+      node.put(k, v);
+      tm.commit();
+
+      assertEquals(v, node.get(k));
+      assertEquals(v, caches.get(0).get(f, k));
+      assertEquals("Should have replicated", v, caches.get(1).get(f, k));
+   }
+
+   private void assertClusterSize(String message, int size)
+   {
+      for (Cache<Object, Object> c : flatCaches)
+      {
+         assertClusterSize(message, size, c);
+      }
+   }
+
+   private void assertClusterSize(String message, int size, Cache<Object, Object> c)
+   {
+      assertEquals(message, size, c.getMembers().size());
+   }
+}
\ No newline at end of file

Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheAPITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/TreeCacheAPITest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheAPITest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheAPITest.java	2008-11-28 15:55:10 UTC (rev 7230)
@@ -0,0 +1,234 @@
+package org.jboss.starobrno.api.tree;
+
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.manager.CacheManager;
+import org.jboss.starobrno.tree.Fqn;
+import org.jboss.starobrno.tree.Node;
+import org.jboss.starobrno.tree.TreeCache;
+import org.jboss.starobrno.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.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests the {@link org.jboss.cache.Cache} public API at a high level
+ *
+ * @author <a href="mailto:manik AT jboss DOT org">Manik Surtani</a>
+ */
+
+ at Test(groups = {"functional", "pessimistic"}, sequential = true)
+public class TreeCacheAPITest
+{
+   private TreeCache<String, String> cache;
+   private TransactionManager tm;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      // start a single cache instance
+      Configuration c = new Configuration();
+      c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      CacheManager cm = new CacheManager(c);
+
+      cache = cm.createTreeCache(getClass().getSimpleName());
+      tm = ((CacheSPI) cache.getCache()).getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown()
+   {
+      TestingUtil.killTreeCaches(cache);
+      cache = null;
+   }
+
+   /**
+    * All cache operations should happen on a {@link Node} - I.e., you look up a {@link Node} and perform data operations
+    * on this {@link Node}.  For convenience and familiarity with JBoss Cache 1.x, we provide some helpers in {@link Cache}
+    * which dives you direct data access to nodes.
+    * <p/>
+    * This test exercises these.
+    */
+   public void testConvenienceMethods()
+   {
+      Fqn fqn = Fqn.fromString("/test/fqn");
+      String key = "key", value = "value";
+      Map<String, String> data = new HashMap<String, String>();
+      data.put(key, value);
+
+      assertNull(cache.get(fqn, key));
+
+      cache.put(fqn, key, value);
+
+      assertEquals(value, cache.get(fqn, key));
+
+      cache.remove(fqn, key);
+
+      assertNull(cache.get(fqn, key));
+
+      cache.put(fqn, data);
+
+      assertEquals(value, cache.get(fqn, key));
+   }
+
+
+   /**
+    * Another convenience method that tests node removal
+    */
+   public void testNodeConvenienceNodeRemoval()
+   {
+      // this fqn is relative, but since it is from the root it may as well be absolute
+      Fqn fqn = Fqn.fromString("/test/fqn");
+      cache.getRoot().addChild(fqn);
+      assertTrue(cache.getRoot().hasChild(fqn));
+
+      assertEquals(true, cache.removeNode(fqn));
+      assertFalse(cache.getRoot().hasChild(fqn));
+      // remove should REALLY remove though and not just mark as deleted/invalid.
+      Node n = cache.getNode(fqn);
+      assert n == null;
+
+      assertEquals(false, cache.removeNode(fqn));
+
+      // remove should REALLY remove though and not just mark as deleted/invalid.
+      n = cache.getNode(fqn);
+      assert n == null;
+
+      // Check that it's removed if it has a child
+      Fqn child = Fqn.fromString("/test/fqn/child");
+      cache.getRoot().addChild(child);
+      assertTrue(cache.getRoot().hasChild(child));
+
+      assertEquals(true, cache.removeNode(fqn));
+      assertFalse(cache.getRoot().hasChild(fqn));
+      assertEquals(false, cache.removeNode(fqn));
+   }
+
+   /**
+    * Tests basic eviction
+    */
+   public void testEvict()
+   {
+      Fqn one = Fqn.fromString("/one");
+      Fqn two = Fqn.fromString("/one/two");
+      String key = "key", value = "value";
+
+      cache.getRoot().addChild(one).put(key, value);
+      cache.getRoot().addChild(two).put(key, value);
+
+      assertTrue(cache.getRoot().hasChild(one));
+      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
+      assertTrue(cache.getRoot().hasChild(two));
+      assertFalse(cache.getRoot().getChild(two).getData().isEmpty());
+
+      // evict two
+      cache.evict(two, false);
+
+      assertTrue(cache.getRoot().hasChild(one));
+      assertTrue(cache.getRoot().getChild(one).getKeys().contains(key));
+      assertFalse(cache.getRoot().hasChild(two));
+
+      // now add 2 again...
+      cache.getRoot().addChild(two).put(key, value);
+
+      // now evict one, NOT recursive
+      cache.evict(one, false);
+
+      // one will NOT be removed, just emptied.
+      assertTrue(cache.getRoot().hasChild(one));
+      assertFalse(cache.getRoot().getChild(one).getKeys().contains(key));
+
+      // two will be unaffected
+      assertTrue(cache.getRoot().hasChild(two));
+      assertTrue(cache.getRoot().getChild(two).getKeys().contains(key));
+   }
+
+
+   /**
+    * Tests recursive eviction
+    */
+   public void testEvictRecursive()
+   {
+      Fqn one = Fqn.fromString("/one");
+      Fqn two = Fqn.fromString("/one/two");
+      String key = "key", value = "value";
+
+      cache.getRoot().addChild(one).put(key, value);
+      cache.getRoot().addChild(two).put(key, value);
+
+      assertTrue(cache.getRoot().hasChild(one));
+      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
+      assertTrue(cache.getRoot().hasChild(two));
+      assertFalse(cache.getRoot().getChild(two).getData().isEmpty());
+
+      // evict two
+      cache.evict(two, true);
+
+      assertTrue(cache.getRoot().hasChild(one));
+      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
+      assertFalse(cache.getRoot().hasChild(two));
+
+      // now add 2 again...
+      cache.getRoot().addChild(two).put(key, value);
+
+      // now evict one, recursive
+      cache.evict(one, true);
+
+      assertFalse(cache.getRoot().hasChild(one));
+      assertFalse(cache.getRoot().hasChild(two));
+   }
+
+   public void testStopClearsData() throws Exception
+   {
+      Fqn a = Fqn.fromString("/a");
+      Fqn b = Fqn.fromString("/a/b");
+      String key = "key", value = "value";
+      cache.getRoot().addChild(a).put(key, value);
+      cache.getRoot().addChild(b).put(key, value);
+      cache.getRoot().put(key, value);
+
+      assertEquals(value, cache.getRoot().get(key));
+      assertEquals(value, cache.getRoot().getChild(a).get(key));
+      assertEquals(value, cache.getRoot().getChild(b).get(key));
+
+      cache.stop();
+
+      cache.start();
+
+      assertNull(cache.getRoot().get(key));
+      assertTrue(cache.getRoot().getData().isEmpty());
+      assertTrue(cache.getRoot().getChildren().isEmpty());
+   }
+
+   public void testPhantomStructuralNodesOnRemove()
+   {
+      assert cache.getNode(Fqn.fromString("/a/b/c")) == null;
+      assert !cache.removeNode("/a/b/c");
+      assert cache.getNode(Fqn.fromString("/a/b/c")) == null;
+      assert cache.getNode(Fqn.fromString("/a/b")) == null;
+      assert cache.getNode(Fqn.fromString("/a")) == null;
+   }
+
+   public void testPhantomStructuralNodesOnRemoveTransactional() throws Exception
+   {
+      assert cache.getNode(Fqn.fromString("/a/b/c")) == null;
+      tm.begin();
+      assert !cache.removeNode("/a/b/c");
+      tm.commit();
+      assert cache.getNode(Fqn.fromString("/a/b/c")) == null;
+      assert cache.getNode(Fqn.fromString("/a/b")) == null;
+      assert cache.getNode(Fqn.fromString("/a")) == null;
+   }
+
+   public void testRpcManagerElements()
+   {
+      assertEquals("CacheMode.LOCAL cache has no address", null, cache.getLocalAddress());
+      assertEquals("CacheMode.LOCAL cache has no members list", null, cache.getMembers());
+   }
+}


Property changes on: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheAPITest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF




More information about the jbosscache-commits mailing list