From jbosscache-commits at lists.jboss.org Fri Nov 28 10:55:10 2008 Content-Type: multipart/mixed; boundary="===============6346218661086193656==" MIME-Version: 1.0 From: jbosscache-commits at lists.jboss.org To: jbosscache-commits at lists.jboss.org Subject: [jbosscache-commits] JBoss Cache SVN: r7230 - core/branches/flat/src/test/java/org/jboss/starobrno/api/tree. Date: Fri, 28 Nov 2008 10:55:10 -0500 Message-ID: --===============6346218661086193656== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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/NodeAPITes= t.java core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockSu= pport.java core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveAP= ITest.java core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTe= st.java core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplTx= Test.java core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCacheA= PITest.java Log: Fixed tree related stuff Copied: core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeA= PITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/star= obrno/tree/api/NodeAPITest.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITe= st.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeAPITe= st.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 Manik Surtani + * @since 2.0.0 + */ +(a)Test(groups =3D {"functional", "pessimistic"}) +public class NodeAPITest +{ + protected ThreadLocal> cacheTL =3D new Thread= Local>(); + protected static final Fqn A =3D Fqn.fromString("/a"), B =3D Fqn.fromSt= ring("/b"), C =3D Fqn.fromString("/c"), D =3D Fqn.fromString("/d"); + protected Fqn A_B =3D Fqn.fromRelativeFqn(A, B); + protected Fqn A_C =3D Fqn.fromRelativeFqn(A, C); + protected TransactionManager tm; + + @BeforeMethod(alwaysRun =3D true) + public void setUp() throws Exception + { + // start a single cache instance + Configuration c =3D new Configuration(); + c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.cla= ss.getName()); + CacheSPI cache =3D (CacheSPI) new Un= itTestCacheFactory().createCache(c, false); + cache.getConfiguration().setInvocationBatchingEnabled(true); + cache.start(); + cacheTL.set(new TreeCacheImpl(cache)); + tm =3D cache.getTransactionManager(); + } + + @AfterMethod(alwaysRun =3D true) + public void tearDown() + { + TreeCache cache =3D cacheTL.get(); + TestingUtil.killTreeCaches(cache); + cacheTL.set(null); + } + + public void testAddingData() + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + Node nodeA =3D rootNode.addChild(A); + nodeA.put("key", "value"); + + assertEquals("value", nodeA.get("key")); + } + + public void testAddingDataTx() throws Exception + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + tm.begin(); + Node nodeA =3D rootNode.addChild(A); + nodeA.put("key", "value"); + + assertEquals("value", nodeA.get("key")); + tm.commit(); + } + + public void testOverwritingDataTx() throws Exception + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + Node nodeB =3D nodeA.addChild(B); + Node nodeC =3D nodeA.addChild(C); + Node nodeD =3D 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.getLastE= lement())); + } + + + public void testImmutabilityOfData() + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + rootNode.put("key", "value"); + Map m =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + rootNode.put("key", "value"); + Map data =3D rootNode.getData(); + Set keys =3D rootNode.getKeys(); + + assert keys.size() =3D=3D 1; + assert keys.contains("key"); + + assert data.size() =3D=3D 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() =3D=3D 1; + assert keys.contains("key"); + + assert data.size() =3D=3D 1; + assert data.containsKey("key"); + } + + public void testDefensiveCopyOfChildren() + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + Fqn childFqn =3D Fqn.fromString("/child"); + rootNode.addChild(childFqn).put("k", "v"); + Set> children =3D rootNode.getChildren(); + Set childrenNames =3D rootNode.getChildrenNames(); + + assert childrenNames.size() =3D=3D 1; + assert childrenNames.contains(childFqn.getLastElement()); + + assert children.size() =3D=3D 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() =3D=3D 1; + assert childrenNames.contains(childFqn.getLastElement()); + + assert children.size() =3D=3D 1; + assert children.iterator().next().getFqn().equals(childFqn); + } + + + public void testImmutabilityOfChildren() + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + // creates a Node with fqn /a/b/c + Node childA =3D 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).g= et("key")); + + assertNull(rootNode.getChild(Fqn.fromElements("nonexistent"))); + } + + public void testClearingData() + { + TreeCache cache =3D cacheTL.get(); + Node rootNode =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + assertTrue(rootNode.getData().isEmpty()); + + Map map =3D new HashMap(); + 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + rootNode.addChild(A).put("k", "v"); + rootNode.addChild(B).put("k", "v"); + + Set childrenNames =3D new HashSet(); + 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 cache =3D cacheTL.get(); + + assert DummyTransactionManager.getInstance().getTransaction() =3D=3D= null; + cache.put("/foo/1/2/3", "item", 1); + assert DummyTransactionManager.getInstance().getTransaction() =3D=3D= null; + assert 1 =3D=3D (Integer) cache.get("/foo/1/2/3", "item"); + tm.begin(); + assert 1 =3D=3D (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 cache =3D 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/a= pi/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/NodeL= ockSupport.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/= starobrno/tree/api/NodeLockSupport.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockS= upport.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeLockS= upport.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 =3D Fqn.fromString("/a"), B =3D Fqn.fromString("/b")= , C =3D Fqn.fromString("/c"), D =3D Fqn.fromString("/d"), E =3D Fqn.fromStr= ing("/e"); + static final Object k =3D "key", vA =3D "valueA", vB =3D "valueB", vC = =3D "valueC", vD =3D "valueD", vE =3D "valueE"; + static final Fqn A_B =3D Fqn.fromRelativeFqn(A, B); + static final Fqn A_B_C =3D Fqn.fromRelativeFqn(A_B, C); + static final Fqn A_B_C_E =3D Fqn.fromRelativeFqn(A_B_C, E); + static final Fqn A_B_D =3D Fqn.fromRelativeFqn(A_B, D); + static final Fqn C_E =3D Fqn.fromRelativeFqn(C, E); + static final Fqn D_B =3D Fqn.fromRelativeFqn(D, B); + static final Fqn D_B_C =3D Fqn.fromRelativeFqn(D_B, C); + + protected ThreadLocal> cacheTL =3D new ThreadLoca= l>(); + protected ThreadLocal tmTL =3D new ThreadLocal(); + protected ThreadLocal treeCacheTL =3D new ThreadLocal(); + + protected void checkLocks() + { + Cache cache =3D 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 cache =3D 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 cache =3D cacheTL.get(); + LockManager lm =3D ((CacheSPI) cache).getLockManager(); + for (Object key : cache.keySet()) assert !lm.isLocked(key); + } +} Property changes on: core/branches/flat/src/test/java/org/jboss/starobrno/a= pi/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/NodeM= oveAPITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/= starobrno/tree/api/NodeMoveAPITest.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveA= PITest.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/NodeMoveA= PITest.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 Manik Surtani + * @since 2.0.0 + */ +(a)Test(groups =3D {"functional", "pessimistic"}, testName =3D "api.NodeMo= veAPITest") +public class NodeMoveAPITest +{ + protected final Log log =3D LogFactory.getLog(getClass()); + + protected static final Fqn A =3D Fqn.fromString("/a"), B =3D Fqn.fromSt= ring("/b"), C =3D Fqn.fromString("/c"), D =3D Fqn.fromString("/d"), E =3D F= qn.fromString("/e"); + static final Fqn A_B =3D Fqn.fromRelativeFqn(A, B); + static final Fqn A_B_C =3D Fqn.fromRelativeFqn(A_B, C); + static final Fqn A_B_C_E =3D Fqn.fromRelativeFqn(A_B_C, E); + static final Fqn A_B_D =3D Fqn.fromRelativeFqn(A_B, D); + static final Fqn C_E =3D Fqn.fromRelativeFqn(C, E); + static final Fqn D_B =3D Fqn.fromRelativeFqn(D, B); + static final Fqn D_B_C =3D Fqn.fromRelativeFqn(D_B, C); + protected static final Object k =3D "key", vA =3D "valueA", vB =3D "val= ueB", vC =3D "valueC", vD =3D "valueD", vE =3D "valueE"; + + protected ThreadLocal> cacheTL =3D new Thread= Local>(); + protected ThreadLocal tmTL =3D new ThreadLocal(); + + @BeforeMethod(alwaysRun =3D true) + public void setUp() throws Exception + { + // start a single cache instance + Configuration c =3D new Configuration(); + c.setFetchInMemoryState(false); + c.setInvocationBatchingEnabled(true); + CacheSPI cache =3D (CacheSPI) new Un= itTestCacheFactory().createCache(c); + + cacheTL.set(new TreeCacheImpl(cache)); + tmTL.set(cache.getTransactionManager()); + } + + @AfterMethod(alwaysRun =3D true) + public void tearDown() + { + TestingUtil.killTreeCaches(cacheTL.get()); + cacheTL.set(null); + } + + public void testBasicMove() + { + TreeCache cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + nodeA.put(k, vA); + Node nodeB =3D rootNode.addChild(B); + nodeB.put(k, vB); + Node nodeC =3D 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 =3D cache.getNode(Fqn.fromRelativeFqn(nodeB.getFqn(), C)); + + log.info("POST MOVE " + cache); + log.info("HC " + nodeC + " " + System.identityHashCode(nodeC)); + Node x =3D 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 genericize(Node node) + { + return (Node) node; + } + + public void testMoveWithChildren() + { + TreeCache cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + nodeA.put(k, vA); + Node nodeB =3D rootNode.addChild(B); + nodeB.put(k, vB); + Node nodeC =3D nodeA.addChild(C); + nodeC.put(k, vC); + Node nodeD =3D nodeC.addChild(D); + nodeD.put(k, vD); + Node nodeE =3D 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 =3D nodeB.getChild(C); + nodeD =3D nodeC.getChild(D); + nodeE =3D 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 cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + Node nodeB =3D 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 =3D 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 cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + Node nodeB =3D 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 =3D rootNode.getChild(A); + nodeB =3D 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 Excep= tion +{ +TreeCache cache =3D cacheTL.get(); +TransactionManager tm =3D tmTL.get(); +Node rootNode =3D cache.getRoot(); + +cache.destroy(); +cache.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig(p= asv, "/", DummyInMemoryCacheLoader.class.getName(), "debug=3Dtrue", false, = false, false, false)); +cache.start(); + +DummyInMemoryCacheLoader loader =3D (DummyInMemoryCacheLoader) cache.getCa= cheLoaderManager().getCacheLoader(); + +rootNode.put("key", "value"); + +if (!pasv) +{ +Map m =3D loader.get(Fqn.ROOT); +assertNotNull("Should not be null", m); +assertEquals("value", m.get("key")); +} + +Node nodeA =3D rootNode.addChild(A); +nodeA.put(k, vA); +Node nodeB =3D rootNode.addChild(B); +nodeB.put(k, vB); +Node nodeC =3D nodeA.addChild(C); +nodeC.put(k, vC); +Node nodeD =3D nodeC.addChild(D); +nodeD.put(k, vD); +Node nodeE =3D 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 =3D rootNode.getChild(A); +nodeB =3D rootNode.getChild(B); +nodeC =3D nodeB.getChild(C); +log.info("nodeC get child B "); +nodeD =3D nodeC.getChild(D); +log.info("nodeD get child E "); +nodeE =3D nodeD.getChild(E); + +Fqn old_C =3D C; +Fqn old_D =3D Fqn.fromRelativeFqn(old_C, D); +Fqn old_E =3D 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 cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + Node nodeB =3D nodeA.addChild(B); + Node nodeD =3D nodeB.addChild(D); + Node nodeC =3D rootNode.addChild(C); + Node nodeE =3D nodeC.addChild(E); + assertNoLocks(); + tm.begin(); + + cache.move(nodeC.getFqn(), nodeB.getFqn()); + + checkLocksDeep(); + + + tm.commit(); + + assertNoLocks(); + } + + public void testLocks() throws Exception + { + TreeCache cache =3D cacheTL.get(); + TransactionManager tm =3D tmTL.get(); + Node rootNode =3D cache.getRoot(); + + Node nodeA =3D rootNode.addChild(A); + Node nodeB =3D nodeA.addChild(B); + Node nodeC =3D rootNode.addChild(C); + assertNoLocks(); + tm.begin(); + + cache.move(nodeC.getFqn(), nodeB.getFqn()); + + checkLocks(); + + tm.commit(); + assertNoLocks(); + } + + public void testConcurrency() throws InterruptedException + { + final TreeCache cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + final int N =3D 3;// number of threads + final int loops =3D 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 =3D A, FQN_B =3D B, FQN_C =3D C, FQN_D =3D D, FQN_E = =3D E, FQN_X =3D Fqn.fromString("/x"), FQN_Y =3D Fqn.fromString("/y"); + + // set up the initial structure. + final Node[] NODES =3D { + rootNode.addChild(FQN_A), rootNode.addChild(FQN_B), + rootNode.addChild(FQN_C), rootNode.addChild(FQN_D), rootNode.a= ddChild(FQN_E) + }; + + final Node NODE_X =3D genericize(NODES[0]).addChild(= FQN_X); + final Node NODE_Y =3D genericize(NODES[1]).addChild(= FQN_Y); + + Thread[] movers =3D new Thread[N]; + final CountDownLatch latch =3D new CountDownLatch(1); + final Random r =3D new Random(); + + for (int i =3D 0; i < N; i++) + { + movers[i] =3D new Thread("Mover-" + i) + { + public void run() + { + try + { + latch.await(); + } + catch (InterruptedException e) + { + } + + for (int counter =3D 0; counter < loops; counter++) + { + + System.out.println(getName() + ": Attempt " + counter); + try + { + cache.move(NODE_X.getFqn(), NODES[r.nextInt(NODES.len= gth)].getFqn()); + } + catch (NodeNotExistsException e) + { + // this may happen ... + } + TestingUtil.sleepRandom(250); + try + { + cache.move(NODE_Y.getFqn(), NODES[r.nextInt(NODES.len= gth)].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 =3D false, found_x_again =3D false; + for (Node erased : NODES) + { + Node n =3D genericize(erased); + if (!found_x) + { + found_x =3D n.hasChild(FQN_X); + } + else + { + found_x_again =3D found_x_again || n.hasChild(FQN_X); + } + } + boolean found_y =3D false, found_y_again =3D false; + for (Node erased : NODES) + { + Node n =3D genericize(erased); + if (!found_y) + { + found_y =3D n.hasChild(FQN_Y); + } + else + { + found_y_again =3D 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 cache =3D cacheTL.get(); + Node rootNode =3D cache.getRoot(); + + final Fqn FQN_X =3D Fqn.fromString("/x"); + // set up the initial structure. + Node aNode =3D rootNode.addChild(A); + Node xNode =3D 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 passivat= ion, String preload, String cacheloaderClass, String properties, boolean as= ync, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) = throws Exception + { + String xml =3D + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + properties + + " \n" + + " \n" + + " "; + Element element =3D XmlConfigHelper.stringToElementInCoreNS(xml); + LoadersElementParser elementParser =3D new LoadersElementParser(); + return elementParser.parseLoadersElement(element); + } + + protected void checkLocks() + { + TreeCache tree =3D cacheTL.get(); + Cache cache =3D tree.getCache(); + ComponentRegistry cr =3D TestingUtil.extractComponentRegistry(cache); + LockManager lm =3D cr.getComponent(LockManager.class); + InvocationContextContainer icc =3D cr.getComponent(InvocationContext= Container.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 tree =3D cacheTL.get(); + Cache cache =3D tree.getCache(); + ComponentRegistry cr =3D TestingUtil.extractComponentRegistry(cache); + LockManager lm =3D cr.getComponent(LockManager.class); + InvocationContextContainer icc =3D cr.getComponent(InvocationContext= Container.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 cache =3D cacheTL.get(); + ComponentRegistry cr =3D TestingUtil.extractComponentRegistry(cache.= getCache()); + LockManager lm =3D cr.getComponent(LockManager.class); + InvocationContextContainer icc =3D cr.getComponent(InvocationContext= Container.class); + LockAssert.assertNoLocks(lm, icc); + } + + public void testNonexistentSource() + { + TreeCache cache =3D cacheTL.get(); + cache.put(A_B_C, "k", "v"); + assert "v".equals(cache.get(A_B_C, "k")); + assert 1 =3D=3D cache.getNode(A_B).getChildren().size(); + assert cache.getNode(A_B).getChildrenNames().contains(C.getLastEleme= nt()); + assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElem= ent()); + + cache.move(D, A_B); + + assert "v".equals(cache.get(A_B_C, "k")); + assert 1 =3D=3D cache.getNode(A_B).getChildren().size(); + assert cache.getNode(A_B).getChildrenNames().contains(C.getLastEleme= nt()); + assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElem= ent()); + } + + public void testNonexistentTarget() + { + TreeCache cache =3D cacheTL.get(); + cache.put(A_B_C, "k", "v"); + assert "v".equals(cache.get(A_B_C, "k")); + assert 1 =3D=3D cache.getNode(A_B).getChildren().size(); + assert cache.getNode(A_B).getChildrenNames().contains(C.getLastEleme= nt()); + assert null =3D=3D cache.getNode(D); + + System.out.println(TreeStructureSupport.printTree(cache, true)); + + cache.move(A_B, D); + + System.out.println(TreeStructureSupport.printTree(cache, true)); + + assert null =3D=3D cache.getNode(A_B_C); + assert null =3D=3D cache.getNode(A_B); + assert null !=3D cache.getNode(D); + assert null !=3D cache.getNode(D_B); + assert null !=3D 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/SyncR= eplTest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/sta= robrno/tree/api/SyncReplTest.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplT= est.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplT= est.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 Manik Surtani (manik = AT jboss DOT org) + */ +(a)Test(groups =3D {"functional", "jgroups", "pessimistic"}, sequential = =3D true, testName =3D "api.SyncReplTest") +public class SyncReplTest +{ + private CacheSPI c1, c2; + private TreeCache cache1, cache2; + + @BeforeMethod(alwaysRun =3D true) + public void setUp() + { + System.out.println("*** In setUp()"); + Configuration c =3D new Configuration(); + c.setCacheMode(Configuration.CacheMode.REPL_SYNC); + c.setInvocationBatchingEnabled(true); + c.setFetchInMemoryState(false); + + c1 =3D (CacheSPI) new UnitTestCacheFactory().createCache(c.clone()); + c2 =3D (CacheSPI) new UnitTestCacheFactory().createCache(c.clone()); + + TestingUtil.blockUntilViewsReceived(new Cache[]{c1, c2}, 5000); + + cache1 =3D new TreeCacheImpl(c1); + cache2 =3D new TreeCacheImpl(c2); + + System.out.println("*** Finished setUp()"); + } + + @AfterMethod(alwaysRun =3D true) + public void tearDown() + { + TestingUtil.killCaches(c1, c2); + cache1 =3D null; + cache2 =3D null; + } + + public void testBasicOperation() + { + assertClusterSize("Should only be 2 caches in the cluster!!!", 2); + + Fqn f =3D Fqn.fromString("/test/data"); + String k =3D "key", v =3D "value"; + + assertNull("Should be null", cache1.getRoot().getChild(f)); + assertNull("Should be null", cache2.getRoot().getChild(f)); + + Node node =3D 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 =3D 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, "ag= e")); + } + + public void testPutMap() + { + assertClusterSize("Should only be 2 caches in the cluster!!!", 2); + + Fqn fqn =3D Fqn.fromString("/JSESSIONID/10.10.10.5:3000/1234567890/1= "); + Fqn fqn1 =3D Fqn.fromString("/JSESSIONID/10.10.10.5:3000/1234567890/= 2"); + + Map map =3D new HashMap(); + map.put("1", "1"); + map.put("2", "2"); + cache1.getInvocationContext().getOptionOverrides().setSuppressLockin= g(true); + cache1.getRoot().addChild(fqn).putAll(map); + cache1.getInvocationContext().getOptionOverrides().setSuppressLockin= g(true); + assertEquals("Value should be set", "1", cache1.get(fqn, "1")); + + map =3D new HashMap(); + map.put("3", "3"); + map.put("4", "4"); + cache1.getInvocationContext().getOptionOverrides().setSuppressLockin= g(true); + cache1.getRoot().addChild(fqn1).putAll(map); + + cache1.getInvocationContext().getOptionOverrides().setSuppressLockin= g(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/SyncR= eplTxTest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss/s= tarobrno/tree/api/SyncReplTxTest.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplT= xTest.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/SyncReplT= xTest.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 Manik Surtani (manik = AT jboss DOT org) + */ +(a)Test(groups =3D {"functional", "jgroups", "transaction", "pessimistic"}= , sequential =3D true, testName =3D "api.SyncReplTxTest") +public class SyncReplTxTest +{ + private List> flatCaches; + private List> caches; + + @BeforeMethod(alwaysRun =3D true) + public void setUp() throws CloneNotSupportedException + { + System.out.println("*** In setUp()"); + caches =3D new ArrayList>(); + flatCaches =3D new ArrayList>(); + Configuration c =3D new Configuration(); + c.setCacheMode(Configuration.CacheMode.REPL_SYNC); + c.setFetchInMemoryState(false); + c.setInvocationBatchingEnabled(true); + c.setSyncCommitPhase(true); + c.setSyncRollbackPhase(true); + c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.cla= ss.getName()); + + CacheSPI cache1 =3D (CacheSPI) new U= nitTestCacheFactory().createCache(c.clone()); + CacheSPI cache2 =3D (CacheSPI) new U= nitTestCacheFactory().createCache(c.clone()); + + flatCaches.add(cache1); + flatCaches.add(cache2); + + TestingUtil.blockUntilViewsReceived(caches.toArray(new Cache[0]), 10= 000); + + caches.add(new TreeCacheImpl(cache1)); + caches.add(new TreeCacheImpl(cache2)); + + System.out.println("*** Finished setUp()"); + } + + @AfterMethod(alwaysRun =3D true) + public void tearDown() + { + System.out.println("*** In tearDown()"); + TestingUtil.killTreeCaches(caches); + caches =3D null; + System.out.println("*** Finished tearDown()"); + } + + private TransactionManager beginTransaction(Cache cache= ) throws NotSupportedException, SystemException + { + TransactionManager mgr =3D cache.getConfiguration().getRuntimeConfig= ().getTransactionManager(); + mgr.begin(); + return mgr; + } + + public void testBasicOperation() throws SystemException, NotSupportedEx= ception, HeuristicMixedException, HeuristicRollbackException, RollbackExcep= tion + { + assertClusterSize("Should only be 2 caches in the cluster!!!", 2); + + Fqn f =3D Fqn.fromString("/test/data"); + String k =3D "key", v =3D "value"; + + assertNull("Should be null", caches.get(0).getRoot().getChild(f)); + assertNull("Should be null", caches.get(1).getRoot().getChild(f)); + + Node node =3D caches.get(0).getRoot().addChild(f); + + assertNotNull("Should not be null", node); + + TransactionManager tm =3D 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 c : flatCaches) + { + assertClusterSize(message, size, c); + } + } + + private void assertClusterSize(String message, int size, Cache 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/TreeC= acheAPITest.java (from rev 7228, core/branches/flat/src/test/java/org/jboss= /starobrno/tree/api/TreeCacheAPITest.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCache= APITest.java (rev 0) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/tree/TreeCache= APITest.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 Manik Surtani + */ + +(a)Test(groups =3D {"functional", "pessimistic"}, sequential =3D true) +public class TreeCacheAPITest +{ + private TreeCache cache; + private TransactionManager tm; + + @BeforeMethod(alwaysRun =3D true) + public void setUp() throws Exception + { + // start a single cache instance + Configuration c =3D new Configuration(); + c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.cla= ss.getName()); + CacheManager cm =3D new CacheManager(c); + + cache =3D cm.createTreeCache(getClass().getSimpleName()); + tm =3D ((CacheSPI) cache.getCache()).getTransactionManager(); + } + + @AfterMethod(alwaysRun =3D true) + public void tearDown() + { + TestingUtil.killTreeCaches(cache); + cache =3D null; + } + + /** + * All cache operations should happen on a {@link Node} - I.e., you loo= k up a {@link Node} and perform data operations + * on this {@link Node}. For convenience and familiarity with JBoss Ca= che 1.x, we provide some helpers in {@link Cache} + * which dives you direct data access to nodes. + *

+ * This test exercises these. + */ + public void testConvenienceMethods() + { + Fqn fqn =3D Fqn.fromString("/test/fqn"); + String key =3D "key", value =3D "value"; + Map data =3D new HashMap(); + 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 wel= l be absolute + Fqn fqn =3D 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/i= nvalid. + Node n =3D cache.getNode(fqn); + assert n =3D=3D null; + + assertEquals(false, cache.removeNode(fqn)); + + // remove should REALLY remove though and not just mark as deleted/i= nvalid. + n =3D cache.getNode(fqn); + assert n =3D=3D null; + + // Check that it's removed if it has a child + Fqn child =3D 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 =3D Fqn.fromString("/one"); + Fqn two =3D Fqn.fromString("/one/two"); + String key =3D "key", value =3D "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 =3D Fqn.fromString("/one"); + Fqn two =3D Fqn.fromString("/one/two"); + String key =3D "key", value =3D "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 =3D Fqn.fromString("/a"); + Fqn b =3D Fqn.fromString("/a/b"); + String key =3D "key", value =3D "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")) =3D=3D null; + assert !cache.removeNode("/a/b/c"); + assert cache.getNode(Fqn.fromString("/a/b/c")) =3D=3D null; + assert cache.getNode(Fqn.fromString("/a/b")) =3D=3D null; + assert cache.getNode(Fqn.fromString("/a")) =3D=3D null; + } + + public void testPhantomStructuralNodesOnRemoveTransactional() throws Ex= ception + { + assert cache.getNode(Fqn.fromString("/a/b/c")) =3D=3D null; + tm.begin(); + assert !cache.removeNode("/a/b/c"); + tm.commit(); + assert cache.getNode(Fqn.fromString("/a/b/c")) =3D=3D null; + assert cache.getNode(Fqn.fromString("/a/b")) =3D=3D null; + assert cache.getNode(Fqn.fromString("/a")) =3D=3D null; + } + + public void testRpcManagerElements() + { + assertEquals("CacheMode.LOCAL cache has no address", null, cache.get= LocalAddress()); + assertEquals("CacheMode.LOCAL cache has no members list", null, cach= e.getMembers()); + } +} Property changes on: core/branches/flat/src/test/java/org/jboss/starobrno/a= pi/tree/TreeCacheAPITest.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF --===============6346218661086193656==--