JBoss Cache SVN: r7230 - core/branches/flat/src/test/java/org/jboss/starobrno/api/tree.
by jbosscache-commits@lists.jboss.org
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
16 years
JBoss Cache SVN: r7229 - in core/branches/flat/src: test/java/org/jboss/starobrno and 2 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-11-28 10:54:45 -0500 (Fri, 28 Nov 2008)
New Revision: 7229
Added:
core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/
core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeReplicatedMoveTest.java
Removed:
core/branches/flat/src/test/java/org/jboss/starobrno/tree/
Modified:
core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java
core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java
Log:
Fixed tree related stuff
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java 2008-11-28 04:54:27 UTC (rev 7228)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java 2008-11-28 15:54:45 UTC (rev 7229)
@@ -22,6 +22,7 @@
package org.jboss.starobrno.tree;
import org.jboss.starobrno.Cache;
+import org.jboss.starobrno.atomic.AtomicMap;
import org.jboss.starobrno.util.Immutables;
import org.jboss.starobrno.util.Util;
@@ -107,9 +108,9 @@
{
Fqn absoluteChildFqn = Fqn.fromRelativeFqn(fqn, f);
NodeImpl child = new NodeImpl(absoluteChildFqn, cache);
- Map<Object, Fqn> s = getStructure();
+ AtomicMap<Object, Fqn> s = getStructure();
s.put(f.getLastElement(), absoluteChildFqn);
- updateStructure(s);
+// updateStructure(s);
createNodeInCache(absoluteChildFqn);
return child;
}
@@ -129,7 +130,7 @@
startAtomic();
try
{
- Map<Object, Fqn> s = getStructure();
+ AtomicMap<Object, Fqn> s = getStructure();
Fqn childFqn = s.remove(childName);
if (childFqn != null)
{
@@ -137,7 +138,7 @@
child.removeChildren();
cache.remove(new NodeKey(childFqn, NodeKey.Type.DATA));
cache.remove(new NodeKey(childFqn, NodeKey.Type.STRUCTURE));
- updateStructure(s);
+// updateStructure(s);
return true;
}
@@ -186,10 +187,7 @@
startAtomic();
try
{
- Map data = getDataInternal();
- Object result = data.put(key, value);
- putAll(data);
- return (V) result;
+ return getDataInternal().put(key, value);
}
finally
{
@@ -202,15 +200,10 @@
startAtomic();
try
{
- Map data = getData();
- Object result = null;
- if (!data.containsKey(key))
- {
- result = data.put(key, value);
- putAll(data);
- }
+ AtomicMap<K, V> data = getDataInternal();
+ if (!data.containsKey(key)) return data.put(key, value);
- return (V) result;
+ return null;
}
finally
{
@@ -223,8 +216,11 @@
startAtomic();
try
{
- Map<K, V> data = getDataInternal();
- return data.put(key, value);
+ AtomicMap<K, V> map = getDataInternal();
+ if (map.containsKey(key))
+ return map.put(key, value);
+ else
+ return null;
}
finally
{
@@ -237,8 +233,8 @@
startAtomic();
try
{
- Map data = getData();
- V old = (V) data.get(key);
+ AtomicMap<K, V> data = getDataInternal();
+ V old = data.get(key);
if (Util.safeEquals(oldValue, old))
{
data.put(key, newValue);
@@ -257,8 +253,7 @@
startAtomic();
try
{
- Map data = getDataInternal();
- data.putAll(map);
+ getDataInternal().putAll(map);
}
finally
{
@@ -271,7 +266,7 @@
startAtomic();
try
{
- Map data = getDataInternal();
+ AtomicMap<K, V> data = getDataInternal();
data.clear();
data.putAll(map);
}
@@ -291,8 +286,7 @@
startAtomic();
try
{
- Map<K, V> data = getDataInternal();
- return data.remove(key);
+ return getDataInternal().remove(key);
}
finally
{
@@ -362,19 +356,19 @@
}
}
- Map<K, V> getDataInternal()
+ AtomicMap<K, V> getDataInternal()
{
- return (Map<K, V>) atomicMapCache.getAtomicMap(dataKey);
+ return (AtomicMap<K, V>) atomicMapCache.getAtomicMap(dataKey);
}
- void updateStructure(Map<Object, Fqn> s)
- {
- cache.put(structureKey, s);
- }
+// void updateStructure(FastCopyHashMap<Object, Fqn> s)
+// {
+// cache.put(structureKey, s.clone());
+// }
- Map<Object, Fqn> getStructure()
+ AtomicMap<Object, Fqn> getStructure()
{
- return (Map<Object, Fqn>) cache.get(structureKey);
+ return atomicMapCache.getAtomicMap(structureKey, Object.class, Fqn.class);
}
public boolean equals(Object o)
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java 2008-11-28 04:54:27 UTC (rev 7228)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java 2008-11-28 15:54:45 UTC (rev 7229)
@@ -23,12 +23,10 @@
import org.jboss.starobrno.Cache;
import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.atomic.AtomicMap;
import org.jboss.starobrno.atomic.AtomicMapCache;
import org.jboss.starobrno.batch.AutoBatchSupport;
-import java.util.HashMap;
-import java.util.Map;
-
public class TreeStructureSupport extends AutoBatchSupport
{
AtomicMapCache atomicMapCache;
@@ -61,15 +59,16 @@
if (!fqn.isRoot())
{
if (!exists(parent)) createNodeInCache(parent);
- Map<Object, Fqn> parentStructure = getStructure(parent);
+ AtomicMap<Object, Fqn> parentStructure = getStructure(parent);
parentStructure.put(fqn.getLastElement(), fqn);
- updateStructure(parent, parentStructure);
+// updateStructure(parent, parentStructure);
}
NodeKey dataKey = new NodeKey(fqn, NodeKey.Type.DATA);
NodeKey structureKey = new NodeKey(fqn, NodeKey.Type.STRUCTURE);
if (cache.containsKey(dataKey) && cache.containsKey(structureKey)) return;
- Map<Object, Fqn> structure = new HashMap<Object, Fqn>();
- cache.put(structureKey, structure);
+// FastCopyHashMap<Object, Fqn> structure = new FastCopyHashMap<Object, Fqn>();
+// cache.put(structureKey, structure);
+ atomicMapCache.getAtomicMap(structureKey);
atomicMapCache.getAtomicMap(dataKey);
}
finally
@@ -78,15 +77,15 @@
}
}
- Map<Object, Fqn> getStructure(Fqn fqn)
+ AtomicMap<Object, Fqn> getStructure(Fqn fqn)
{
- return (Map<Object, Fqn>) cache.get(new NodeKey(fqn, NodeKey.Type.STRUCTURE));
+ return atomicMapCache.getAtomicMap(new NodeKey(fqn, NodeKey.Type.STRUCTURE), Object.class, Fqn.class);
}
- void updateStructure(Fqn fqn, Map<Object, Fqn> structure)
- {
- cache.put(new NodeKey(fqn, NodeKey.Type.STRUCTURE), structure);
- }
+// void updateStructure(Fqn fqn, FastCopyHashMap<Object, Fqn> structure)
+// {
+// cache.put(new NodeKey(fqn, NodeKey.Type.STRUCTURE), structure.clone());
+// }
public static boolean isLocked(Cache c, Fqn fqn)
{
@@ -97,6 +96,7 @@
/**
* Visual representation of a tree
+ *
* @param cache cache to dump
* @return String rep
*/
@@ -108,7 +108,7 @@
// walk tree
sb.append("+ ").append(Fqn.SEPARATOR);
- if (details) sb.append(" ").append(cache.getRoot().getData());
+ if (details) sb.append(" ").append(cache.getRoot().getData());
sb.append("\n");
addChildren(cache.getRoot(), 1, sb, details);
return sb.toString();
@@ -116,14 +116,14 @@
private static void addChildren(Node<?, ?> node, int depth, StringBuilder sb, boolean details)
{
- for (Node<?, ?> child: node.getChildren())
+ for (Node<?, ?> child : node.getChildren())
{
- for (int i=0; i<depth; i++) sb.append(" "); // indentations
+ for (int i = 0; i < depth; i++) sb.append(" "); // indentations
sb.append("+ ");
sb.append(child.getFqn().getLastElementAsString()).append(Fqn.SEPARATOR);
if (details) sb.append(" ").append(child.getData());
sb.append("\n");
addChildren(child, depth + 1, sb, details);
- }
+ }
}
}
Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeReplicatedMoveTest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeReplicatedMoveTest.java)
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeReplicatedMoveTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeReplicatedMoveTest.java 2008-11-28 15:54:45 UTC (rev 7229)
@@ -0,0 +1,160 @@
+/*
+ * 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.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.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+@Test(groups = {"functional", "jgroups", "pessimistic"}, testName = "api.NodeReplicatedMoveTest")
+public class NodeReplicatedMoveTest
+{
+ private class NodeReplicatedMoveTestTL
+ {
+ protected TreeCache<Object, Object> cache1;
+ protected TreeCache<Object, Object> cache2;
+ protected TransactionManager tm;
+ }
+
+ protected ThreadLocal<NodeReplicatedMoveTestTL> threadLocal = new ThreadLocal<NodeReplicatedMoveTestTL>();
+
+ protected static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d"), E = Fqn.fromString("/e");
+ protected static final Object k = "key", vA = "valueA", vB = "valueB", vC = "valueC", vD = "valueD", vE = "valueE";
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = new NodeReplicatedMoveTestTL();
+ threadLocal.set(tl);
+ Configuration c = new Configuration();
+ c.setInvocationBatchingEnabled(true);
+ c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ c.setSyncCommitPhase(true);
+ c.setSyncRollbackPhase(true);
+ // start a single cache instance
+ tl.cache1 = new TreeCacheImpl<Object, Object>(new UnitTestCacheFactory<Object, Object>().createCache(c.clone()));
+ tl.cache2 = new TreeCacheImpl<Object, Object>(new UnitTestCacheFactory<Object, Object>().createCache(c.clone()));
+ tl.tm = tl.cache1.getConfiguration().getRuntimeConfig().getTransactionManager();
+
+ TestingUtil.blockUntilViewsReceived(10000, tl.cache1.getCache(), tl.cache2.getCache());
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ if (tl != null)
+ {
+ TestingUtil.killTreeCaches(tl.cache1, tl.cache2);
+ threadLocal.set(null);
+ }
+ }
+
+
+ public void testReplicatability()
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(B).get(k));
+ }
+
+ public void testReplTxCommit() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+ Fqn A_B = Fqn.fromRelativeFqn(A, B);
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.tm.begin();
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.get(A, k));
+ assertNull(tl.cache1.get(A_B, k));
+ assertEquals(vB, tl.cache1.get(B, k));
+ tl.tm.commit();
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(B).get(k));
+
+ }
+
+ public void testReplTxRollback() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.tm.begin();
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.get(A, k));
+ assertEquals(vB, tl.cache1.get(B, k));
+
+ tl.tm.rollback();
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+ }
+}
16 years
JBoss Cache SVN: r7228 - enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/es-ES.
by jbosscache-commits@lists.jboss.org
Author: mospina
Date: 2008-11-27 23:54:27 -0500 (Thu, 27 Nov 2008)
New Revision: 7228
Modified:
enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/es-ES/Jbossaop.po
Log:
New revision
Modified: enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/es-ES/Jbossaop.po
===================================================================
--- enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/es-ES/Jbossaop.po 2008-11-28 03:39:39 UTC (rev 7227)
+++ enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/es-ES/Jbossaop.po 2008-11-28 04:54:27 UTC (rev 7228)
@@ -8,7 +8,7 @@
"Project-Id-Version: Jbossaop\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2008-09-21 04:57+0000\n"
-"PO-Revision-Date: 2008-11-20 13:12+1000\n"
+"PO-Revision-Date: 2008-11-28 11:09+1000\n"
"Last-Translator: Angela Garcia\n"
"Language-Team: <en(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -157,7 +157,7 @@
"crosscutting concerns, and a programmatic construct -- a programming "
"language or a set of tags -- to specify how you want to apply those snippets "
"of code."
-msgstr "En pocas palabras, todos los marcos de trabajo AOP definen dos cosas: una manrera de implementar asuntos con múltiple puntos de corte y una construcción programática -- un lenguaje de programación o un grupo de etiquetas -- para especificar la manera en que quiere aplicar esos pedazos de código. "
+msgstr "En pocas palabras, todos los marcos de trabajo AOP definen dos cosas: una manera de implementar asuntos con múltiple puntos de corte y una construcción programática -- un lenguaje de programación o un grupo de etiquetas -- para especificar la manera en que quiere aplicar esos pedazos de código. "
#. Tag: para
#: Jbossaop.xml:33
16 years
JBoss Cache SVN: r7227 - in core/branches/flat/src: test/java/org/jboss/starobrno/api and 4 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-11-27 22:39:39 -0500 (Thu, 27 Nov 2008)
New Revision: 7227
Added:
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeMoveAPITest.java
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeReplicatedMoveTest.java
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTest.java
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTxTest.java
Modified:
core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java
core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCache.java
core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCacheImpl.java
core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java
core/branches/flat/src/test/java/org/jboss/starobrno/api/CacheAPITest.java
core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_committed/CacheAPIMVCCTest.java
core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/repeatable_read/CacheAPIMVCCTest.java
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeAPITest.java
core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/TreeCacheAPITest.java
core/branches/flat/src/test/java/org/jboss/starobrno/util/TestingUtil.java
Log:
Tree related stuff, move impl, etc
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/NodeImpl.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -393,4 +393,12 @@
{
return (fqn != null ? fqn.hashCode() : 0);
}
+
+ @Override
+ public String toString()
+ {
+ return "NodeImpl{" +
+ "fqn=" + fqn +
+ '}';
+ }
}
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCache.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCache.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCache.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -500,7 +500,7 @@
Configuration getConfiguration();
- Cache getCache();
+ Cache<K, V> getCache();
boolean exists(String fqn);
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCacheImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCacheImpl.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeCacheImpl.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -192,7 +192,45 @@
public void move(Fqn nodeToMove, Fqn newParent) throws NodeNotExistsException
{
- //TODO: Autogenerated. Implement me properly
+ if (nodeToMove == null || newParent == null) throw new NullPointerException("Cannot accept null parameters!");
+
+ if (nodeToMove.getParent().equals(newParent))
+ {
+ // moving onto self! Do nothing!
+ return;
+ }
+
+ // Depth first. Lets start with getting the node we want.
+ startAtomic();
+ try
+ {
+ Node node = getNode(nodeToMove);
+ if (node == null) return; // nothing to do here!
+ if (!exists(newParent))
+ {
+ // then we need to silently create the new parent
+ createNodeInCache(newParent);
+ }
+
+ // create an empty node for this new parent
+ Fqn newFqn = Fqn.fromRelativeElements(newParent, nodeToMove.getLastElement());
+ createNodeInCache(newFqn);
+ Node newNode = getNode(newFqn);
+ Map oldData = node.getData();
+ if (oldData != null && !oldData.isEmpty()) newNode.putAll(oldData);
+ for (Object child : node.getChildrenNames())
+ {
+ // move kids
+ Fqn oldChildFqn = Fqn.fromRelativeElements(nodeToMove, child);
+ move(oldChildFqn, newFqn);
+ }
+
+ removeNode(nodeToMove);
+ }
+ finally
+ {
+ endAtomic();
+ }
}
public void move(String nodeToMove, String newParent) throws NodeNotExistsException
Modified: core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/tree/TreeStructureSupport.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -94,4 +94,36 @@
return lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.STRUCTURE)) &&
lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.DATA));
}
+
+ /**
+ * Visual representation of a tree
+ * @param cache cache to dump
+ * @return String rep
+ */
+ public static String printTree(TreeCache<?, ?> cache, boolean details)
+ {
+ StringBuilder sb = new StringBuilder();
+// sb.append("Raw keys: " + cache.getCache().keySet());
+ sb.append("\n\n");
+
+ // walk tree
+ sb.append("+ ").append(Fqn.SEPARATOR);
+ if (details) sb.append(" ").append(cache.getRoot().getData());
+ sb.append("\n");
+ addChildren(cache.getRoot(), 1, sb, details);
+ return sb.toString();
+ }
+
+ private static void addChildren(Node<?, ?> node, int depth, StringBuilder sb, boolean details)
+ {
+ for (Node<?, ?> child: node.getChildren())
+ {
+ for (int i=0; i<depth; i++) sb.append(" "); // indentations
+ sb.append("+ ");
+ sb.append(child.getFqn().getLastElementAsString()).append(Fqn.SEPARATOR);
+ if (details) sb.append(" ").append(child.getData());
+ sb.append("\n");
+ addChildren(child, depth + 1, sb, details);
+ }
+ }
}
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/api/CacheAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/CacheAPITest.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/CacheAPITest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -1,8 +1,11 @@
package org.jboss.starobrno.api;
import org.jboss.cache.CacheFactory;
-import org.jboss.cache.transaction.GenericTransactionManagerLookup;
+import org.jboss.cache.lock.IsolationLevel;
+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.config.ConfigurationException;
import org.jboss.starobrno.util.TestingUtil;
@@ -14,7 +17,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.jboss.starobrno.UnitTestCacheFactory;
/**
* Tests the {@link org.jboss.cache.Cache} public API at a high level
@@ -23,7 +25,7 @@
*/
@Test(groups = {"functional", "pessimistic"})
-public class CacheAPITest
+public abstract class CacheAPITest
{
private ThreadLocal<CacheSPI<String, String>> cacheTL = new ThreadLocal<CacheSPI<String, String>>();
@@ -31,19 +33,16 @@
public void setUp() throws Exception
{
// start a single cache instance
+ Configuration c = new Configuration();
+ c.setIsolationLevel(getIsolationLevel());
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
CacheFactory<String, String> cf = new UnitTestCacheFactory<String, String>();
- CacheSPI<String, String> cache = (CacheSPI<String, String>) cf.createCache("configs/local-tx.xml", false);
- cache.getConfiguration().setEvictionConfig(null);
- configure(cache.getConfiguration());
- cache.start();
+ CacheSPI<String, String> cache = (CacheSPI<String, String>) cf.createCache(c.clone());
cacheTL.set(cache);
}
- protected void configure(Configuration c)
- {
- }
+ protected abstract IsolationLevel getIsolationLevel();
-
@AfterMethod(alwaysRun = true)
public void tearDown()
{
@@ -60,7 +59,7 @@
CacheSPI<String, String> cache = cacheTL.get();
Configuration c = cache.getConfiguration();
assertEquals(Configuration.CacheMode.LOCAL, c.getCacheMode());
- assertEquals(GenericTransactionManagerLookup.class.getName(), c.getTransactionManagerLookupClass());
+ assertEquals(DummyTransactionManagerLookup.class.getName(), c.getTransactionManagerLookupClass());
// note that certain values should be immutable. E.g., CacheMode cannot be changed on the fly.
try
@@ -80,7 +79,7 @@
public void testGetMembersInLocalMode()
{
CacheSPI<String, String> cache = cacheTL.get();
- assert cache.getRPCManager() == null : "Cache members should be null if running in LOCAL mode";
+ assert cache.getRPCManager().getLocalAddress() == null : "Cache members should be null if running in LOCAL mode";
}
/**
@@ -155,4 +154,73 @@
assert !cache.containsKey(key);
assert cache.isEmpty();
}
+
+ public void testRollbackAfterPut() throws Exception
+ {
+ CacheSPI<String, String> cache = cacheTL.get();
+ String key = "key", value = "value";
+ cache.put(key, value);
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+
+ DummyTransactionManager.getInstance().begin();
+ cache.put("key2", "value2");
+ assert cache.get("key2").equals("value2");
+ DummyTransactionManager.getInstance().rollback();
+
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+ }
+
+ public void testRollbackAfterOverwrite() throws Exception
+ {
+ CacheSPI<String, String> cache = cacheTL.get();
+ String key = "key", value = "value";
+ cache.put(key, value);
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+
+ DummyTransactionManager.getInstance().begin();
+ cache.put(key, "value2");
+ assert cache.get(key).equals("value2");
+ assert 1 == cache.size();
+ DummyTransactionManager.getInstance().rollback();
+
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+ }
+
+ public void testRollbackAfterRemove() throws Exception
+ {
+ CacheSPI<String, String> cache = cacheTL.get();
+ String key = "key", value = "value";
+ cache.put(key, value);
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+
+ DummyTransactionManager.getInstance().begin();
+ cache.remove(key);
+ assert cache.get(key) == null;
+ DummyTransactionManager.getInstance().rollback();
+
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+ }
+
+ public void testRollbackAfterClear() throws Exception
+ {
+ CacheSPI<String, String> cache = cacheTL.get();
+ String key = "key", value = "value";
+ cache.put(key, value);
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+
+ DummyTransactionManager.getInstance().begin();
+ cache.clear();
+ assert cache.get(key) == null;
+ DummyTransactionManager.getInstance().rollback();
+
+ assert cache.get(key).equals(value);
+ assert 1 == cache.size();
+ }
}
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_committed/CacheAPIMVCCTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_committed/CacheAPIMVCCTest.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_committed/CacheAPIMVCCTest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -2,7 +2,6 @@
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.starobrno.api.CacheAPITest;
-import org.jboss.starobrno.config.Configuration;
import org.testng.annotations.Test;
/**
@@ -12,9 +11,8 @@
public class CacheAPIMVCCTest extends CacheAPITest
{
@Override
- protected void configure(Configuration c)
+ protected IsolationLevel getIsolationLevel()
{
- super.configure(c);
- c.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+ return IsolationLevel.READ_COMMITTED;
}
}
\ No newline at end of file
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/repeatable_read/CacheAPIMVCCTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/repeatable_read/CacheAPIMVCCTest.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/repeatable_read/CacheAPIMVCCTest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -2,7 +2,6 @@
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.starobrno.api.CacheAPITest;
-import org.jboss.starobrno.config.Configuration;
import org.testng.annotations.Test;
/**
@@ -12,9 +11,8 @@
public class CacheAPIMVCCTest extends CacheAPITest
{
@Override
- protected void configure(Configuration c)
+ protected IsolationLevel getIsolationLevel()
{
- super.configure(c);
- c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
+ return IsolationLevel.READ_COMMITTED;
}
}
\ No newline at end of file
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeAPITest.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeAPITest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -53,7 +53,7 @@
public void tearDown()
{
TreeCache<Object, Object> cache = cacheTL.get();
- TestingUtil.killCaches(cache.getCache());
+ TestingUtil.killTreeCaches(cache);
cacheTL.set(null);
}
Added: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeMoveAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeMoveAPITest.java (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeMoveAPITest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -0,0 +1,667 @@
+package org.jboss.starobrno.tree.api;
+
+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"));
+ }
+}
Added: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeReplicatedMoveTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeReplicatedMoveTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/NodeReplicatedMoveTest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -0,0 +1,159 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.starobrno.tree.api;
+
+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.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+@Test(groups = {"functional", "jgroups", "pessimistic"}, testName = "api.NodeReplicatedMoveTest")
+public class NodeReplicatedMoveTest
+{
+ private class NodeReplicatedMoveTestTL
+ {
+ protected TreeCache<Object, Object> cache1;
+ protected TreeCache<Object, Object> cache2;
+ protected TransactionManager tm;
+ }
+
+ protected ThreadLocal<NodeReplicatedMoveTestTL> threadLocal = new ThreadLocal<NodeReplicatedMoveTestTL>();
+
+ protected static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d"), E = Fqn.fromString("/e");
+ protected static final Object k = "key", vA = "valueA", vB = "valueB", vC = "valueC", vD = "valueD", vE = "valueE";
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = new NodeReplicatedMoveTestTL();
+ threadLocal.set(tl);
+ Configuration c = new Configuration();
+ c.setInvocationBatchingEnabled(true);
+ c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ c.setSyncCommitPhase(true);
+ c.setSyncRollbackPhase(true);
+ // start a single cache instance
+ tl.cache1 = new TreeCacheImpl<Object, Object>(new UnitTestCacheFactory<Object, Object>().createCache(c.clone()));
+ tl.cache2 = new TreeCacheImpl<Object, Object>(new UnitTestCacheFactory<Object, Object>().createCache(c.clone()));
+ tl.tm = tl.cache1.getConfiguration().getRuntimeConfig().getTransactionManager();
+
+ TestingUtil.blockUntilViewsReceived(10000, tl.cache1.getCache(), tl.cache2.getCache());
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ if (tl != null)
+ {
+ TestingUtil.killTreeCaches(tl.cache1, tl.cache2);
+ threadLocal.set(null);
+ }
+ }
+
+
+
+ public void testReplicatability()
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(B).get(k));
+ }
+
+ public void testReplTxCommit() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+ Fqn A_B = Fqn.fromRelativeFqn(A, B);
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.tm.begin();
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.get(A, k));
+ assertNull(tl.cache1.get(A_B, k));
+ assertEquals(vB, tl.cache1.get(B, k));
+ tl.tm.commit();
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(B).get(k));
+
+ }
+
+ public void testReplTxRollback() throws Exception
+ {
+ NodeReplicatedMoveTestTL tl = threadLocal.get();
+ Node<Object, Object> rootNode = tl.cache1.getRoot();
+ Node<Object, Object> nodeA = rootNode.addChild(A);
+ Node<Object, Object> nodeB = nodeA.addChild(B);
+
+ nodeA.put(k, vA);
+ nodeB.put(k, vB);
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+
+ // now move...
+ tl.tm.begin();
+ tl.cache1.move(nodeB.getFqn(), Fqn.ROOT);
+
+ assertEquals(vA, tl.cache1.get(A, k));
+ assertEquals(vB, tl.cache1.get(B, k));
+
+ tl.tm.rollback();
+
+ assertEquals(vA, tl.cache1.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache1.getRoot().getChild(A).getChild(B).get(k));
+ assertEquals(vA, tl.cache2.getRoot().getChild(A).get(k));
+ assertEquals(vB, tl.cache2.getRoot().getChild(A).getChild(B).get(k));
+ }
+}
Added: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -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.tree.api;
+
+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());
+ }
+}
Added: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTxTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTxTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/SyncReplTxTest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -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.tree.api;
+
+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
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/TreeCacheAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/TreeCacheAPITest.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/tree/api/TreeCacheAPITest.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -44,7 +44,7 @@
@AfterMethod(alwaysRun = true)
public void tearDown()
{
- if (cache != null) TestingUtil.killCaches(cache.getCache());
+ TestingUtil.killTreeCaches(cache);
cache = null;
}
Modified: core/branches/flat/src/test/java/org/jboss/starobrno/util/TestingUtil.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/util/TestingUtil.java 2008-11-28 01:42:18 UTC (rev 7226)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/util/TestingUtil.java 2008-11-28 03:39:39 UTC (rev 7227)
@@ -17,12 +17,14 @@
import org.jboss.starobrno.interceptors.InterceptorChain;
import org.jboss.starobrno.interceptors.base.CommandInterceptor;
import org.jboss.starobrno.lock.LockManager;
+import org.jboss.starobrno.tree.TreeCache;
import org.jgroups.JChannel;
import javax.transaction.TransactionManager;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Random;
@@ -412,6 +414,24 @@
f.delete();
}
+ public static void killTreeCaches(Collection treeCaches)
+ {
+ if (treeCaches != null) killTreeCaches((TreeCache[]) treeCaches.toArray(new TreeCache[]{}));
+ }
+
+ public static void killCaches(Collection caches)
+ {
+ if (caches != null) killCaches((Cache[]) caches.toArray(new Cache[]{}));
+ }
+
+ public static void killTreeCaches(TreeCache... treeCaches)
+ {
+ for (TreeCache tc: treeCaches)
+ {
+ if (tc != null) killCaches(tc.getCache());
+ }
+ }
+
/**
* Kills a cache - stops it, clears any data in any cache loaders, and rolls back any associated txs
*/
16 years