Author: manik.surtani(a)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
+ */
+@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
+ */
+@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>
+ */
+@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>
+ */
+@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>
+ */
+
+@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