[jbosscache-commits] JBoss Cache SVN: r5835 - in core/trunk/src: main/java/org/jboss/cache/commands/write and 4 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue May 13 18:04:28 EDT 2008


Author: mircea.markus
Date: 2008-05-13 18:04:27 -0400 (Tue, 13 May 2008)
New Revision: 5835

Added:
   core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java
   core/trunk/src/test/java/org/jboss/cache/mock/
   core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/DataContainer.java
   core/trunk/src/main/java/org/jboss/cache/Node.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticCreateIfNotExistsInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
Log:
JBCACHE-1338 - added unit test for DataContainer

Modified: core/trunk/src/main/java/org/jboss/cache/DataContainer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/DataContainer.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/DataContainer.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -52,11 +52,10 @@
    {
       this.configuration = configuration;
       this.nodeFactory = nodeFactory;
-      createRootNode();
    }
 
    @Start(priority = 12)
-   private void createRootNode()
+   public void createRootNode()
    {
       // create a new root temporarily.
       NodeSPI tempRoot = nodeFactory.createRootDataNode();
@@ -120,7 +119,7 @@
    {
       try
       {
-         return peek(fqn, null);
+         return peekVersioned(fqn, null);
       }
       catch (CacheException e)
       {
@@ -138,13 +137,13 @@
     * @param version version of the node to find
     * @return a node, if found, or null if not.
     */
-   public NodeSPI peek(Fqn fqn, DataVersion version)
+   public NodeSPI peekVersioned(Fqn fqn, DataVersion version)
    {
-      return peek(fqn, version, false);
+      return peekVersioned(fqn, version, false);
    }
 
    /**
-    * Similar to {@link #peek(Fqn, org.jboss.cache.optimistic.DataVersion)} except that it throws a {@link org.jboss.cache.NodeNotExistsException}
+    * Similar to {@link #peekVersioned(Fqn, org.jboss.cache.optimistic.DataVersion)} except that it throws a {@link org.jboss.cache.NodeNotExistsException}
     * if the node cannot be found.
     *
     * @param gtx            global transaction
@@ -154,7 +153,7 @@
     */
    public NodeSPI peekStrict(GlobalTransaction gtx, Fqn fqn, boolean includeInvalid)
    {
-      NodeSPI n = peek(fqn, null, includeInvalid);
+      NodeSPI n = peekVersioned(fqn, null, includeInvalid);
       if (n == null)
       {
          StringBuilder builder = new StringBuilder();
@@ -176,7 +175,7 @@
     * @param includeInvalidNodes if true, invalid nodes are considered
     * @return the node, if found, or null otherwise.
     */
-   public NodeSPI peek(Fqn fqn, DataVersion version, boolean includeInvalidNodes)
+   public NodeSPI peekVersioned(Fqn fqn, DataVersion version, boolean includeInvalidNodes)
    {
       if (fqn == null) return null;
 
@@ -311,7 +310,17 @@
             result.add(fqn);
             return result;
          }
-         buildNodesForEviction(node, result);
+         if (fqn.isRoot())
+         {
+            for (Object childName : node.getChildrenNamesDirect())
+            {
+               if (!node.isResident()) result.add(Fqn.fromRelativeElements(fqn, childName));
+            }
+         }
+         else if (!node.isResident())
+         {
+            result.add(fqn);
+         }
       }
       return result;
    }
@@ -322,27 +331,11 @@
       {
          recursiveAddEvictionNodes(child, result);
       }
-      buildNodesForEviction(node, result);
-   }
-
-   private void buildNodesForEviction(NodeSPI node, List<Fqn> nodes)
-   {
-      if (node == null || node.isResident())
-      {
-         return;
-      }
       Fqn fqn = node.getFqn();
-      if (fqn.isRoot())
+      if (node != null && !fqn.isRoot() && !node.isResident())
       {
-         for (Object childName : node.getChildrenNamesDirect())
-         {
-            if (!node.isResident()) nodes.add(Fqn.fromRelativeElements(fqn, childName));
-         }
+         result.add(fqn);
       }
-      else
-      {
-         nodes.add(fqn);
-      }
    }
 
    @Override
@@ -518,7 +511,6 @@
          return false;
       }
 
-
       if (trace) log.trace("Performing a real remove for node " + f + ", marked for removal.");
       if (skipMarkerCheck || n.isDeleted())
       {
@@ -526,13 +518,14 @@
          {
             // do not actually delete; just remove deletion marker
             n.markAsDeleted(true);
-            // but now remove all children, since the call has been to remove("/")
-            n.removeChildrenDirect();
 
             // mark the node to be removed (and all children) as invalid so anyone holding a direct reference to it will
             // be aware that it is no longer valid.
             n.setValid(false, true);
             n.setValid(true, false);
+
+            // but now remove all children, since the call has been to remove("/")
+            n.removeChildrenDirect();
             return true;
          }
          else
@@ -575,8 +568,7 @@
       }
       else
       {
-         if (trace)
-            log.trace("removing NODE as it is a leaf: evict(" + fqn + ")");
+         if (trace) log.trace("removing NODE as it is a leaf: evict(" + fqn + ")");
          removeNode(fqn);
          return true;
       }
@@ -584,9 +576,10 @@
 
    private void removeNode(Fqn fqn)
    {
-      NodeSPI targetNode = peek(fqn, null, true);
+      NodeSPI targetNode = peekVersioned(fqn, null, true);
       if (targetNode == null) return;
       NodeSPI parentNode = targetNode.getParent();
+      targetNode.setValid(false, false);
       if (parentNode != null)
       {
          parentNode.removeChildDirect(fqn.getLastElement());
@@ -596,7 +589,7 @@
 
    protected void removeData(Fqn fqn)
    {
-      NodeSPI n = peek(fqn, null);
+      NodeSPI n = peekVersioned(fqn, null);
       if (n == null)
       {
          log.warn("node " + fqn + " not found");
@@ -647,30 +640,4 @@
       }
       return new Object[]{result, n};
    }
-
-   public void createNodesLocally(Fqn<?> fqn, Map<?, ?> data) throws CacheException
-   {
-      int treeNodeSize;
-      if ((treeNodeSize = fqn.size()) == 0) return;
-      NodeSPI n = root;
-      for (int i = 0; i < treeNodeSize; i++)
-      {
-         Object childName = fqn.get(i);
-         NodeSPI childNode = n.addChildDirect(Fqn.fromElements(childName));
-         if (childNode == null)
-         {
-            if (trace)
-            {
-               log.trace("failed to find or create child " + childName + " of node " + n.getFqn());
-            }
-            return;
-         }
-         if (i == treeNodeSize - 1)
-         {
-            // set data
-            childNode.putAllDirect(data);
-         }
-         n = childNode;
-      }
-   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/Node.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Node.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/Node.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -182,7 +182,7 @@
     * <pre>
     * if (node.get(key).equals(oldValue))
     * {
-    *     node.putAll(key, newValue);
+    *     node.put(key, newValue);
     *     return true;
     * }
     * else

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -140,7 +140,7 @@
    {
       // Find the node. This will lock it (if <tt>locking</tt> is true) and
       // add the temporarily created parent nodes to the TX's node list if tx != null)
-      NodeSPI n = dataContainer.peek(fqn, dataVersion);
+      NodeSPI n = dataContainer.peekVersioned(fqn, dataVersion);
       if (n == null)
       {
          log.warn("node " + fqn + " not found");

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -80,7 +80,7 @@
    {
       if (trace) log.trace("rollback(" + globalTransaction + ", " + fqn + ", " + data + ")");
 
-      NodeSPI n = dataContainer.peek(fqn, null, true);
+      NodeSPI n = dataContainer.peekVersioned(fqn, null, true);
       if (n != null)
       {
          n.clearDataDirect();

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveDataCommand.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveDataCommand.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -55,7 +55,7 @@
    public Object perform(InvocationContext ctx)
    {
       if (trace) log.trace("perform(" + globalTransaction + ", \"" + fqn + "\")");
-      NodeSPI targetNode = dataContainer.peek(fqn, dataVersion);
+      NodeSPI targetNode = dataContainer.peekVersioned(fqn, dataVersion);
       if (targetNode == null)
       {
          log.warn("node " + fqn + " not found");

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -59,7 +59,7 @@
          log.trace("perform(" + globalTransaction + ", \"" + fqn + "\", undo=" + createUndoOps + ")");
 
       // Find the node. This will add the temporarily created parent nodes to the TX's node list if globalTransaction != null)
-      targetNode = dataContainer.peek(fqn, dataVersion, true);
+      targetNode = dataContainer.peekVersioned(fqn, dataVersion, true);
       if (targetNode == null)
       {
          if (trace) log.trace("node " + fqn + " not found");

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -263,7 +263,7 @@
       {
          loader.removeData(command.getFqn());
          // if we are erasing all the data then consider this node loaded
-         NodeSPI n = dataContainer.peek(command.getFqn(), false, false);//cache.peek(fqn, false);
+         NodeSPI n = dataContainer.peek(command.getFqn(), false, false);
          n.setDataLoaded(true);
          return returnValue;
       }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -231,7 +231,7 @@
          return;
       }
 
-      NodeSPI<?, ?> nodeSPI = dataContainer.peek(event.getFqn(), false, false);//cache.peek(event.getFqn(), false);
+      NodeSPI<?, ?> nodeSPI = dataContainer.peek(event.getFqn(), false, false);
       //we do not trigger eviction events for resident nodes
       if (nodeSPI != null && nodeSPI.isResident())
       {

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticCreateIfNotExistsInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticCreateIfNotExistsInterceptor.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticCreateIfNotExistsInterceptor.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -103,7 +103,6 @@
     */
    private void createNode(InvocationContext ctx, Fqn targetFqn, boolean suppressNotification) throws CacheException
    {
-//      if (cache.peek(targetFqn, false) != null) return;
       if (dataContainer.peek(targetFqn, false, false) != null) return;
       // we do nothing if targetFqn is null
       if (targetFqn == null) return;

Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java	2008-05-13 14:10:18 UTC (rev 5834)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -226,8 +226,6 @@
             return true;// we're doing a remove and we've reached the PARENT node of the target to be removed.
          }
          if (!isTargetNode && dataContainer.peek(targetFqn.getAncestor(currentNodeIndex + 2), false, false) == null)
-         //if (!isTargetNode && cache.peek(targetFqn.getAncestor(currentNodeIndex + 2), false) == null)
-         //if (!isTargetNode && cache.peek(new Fqn(currentNode.getFqn(), targetFqn.get(currentNodeIndex + 1)), false) == null)
          {
             return createIfNotExists;// we're at a node in the tree, not yet at the target node, and we need to create the next node.  So we need a WL here.
          }

Added: core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -0,0 +1,332 @@
+package org.jboss.cache;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.marshall.NodeData;
+import org.jboss.cache.mock.NodeSpiMock;
+import org.jboss.cache.optimistic.DataVersion;
+import org.jboss.cache.optimistic.DefaultDataVersion;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests functionality from DataContainer.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class DataContainerTest
+{
+   private DataContainer container;
+
+   //node structure on which all tests are being run.
+   private NodeSpiMock root;
+   private Fqn a = Fqn.fromString("/a");
+   private NodeSpiMock aNode;
+   private Fqn ab = Fqn.fromString("/a/b");
+   private NodeSpiMock abNode;
+   private Fqn abc = Fqn.fromString("/a/b/c");
+   private NodeSpiMock abcNode;
+   private Fqn ad = Fqn.fromString("/a/d");
+   private NodeSpiMock adNode;
+   private Fqn ade = Fqn.fromString("/a/d/e");
+   private NodeSpiMock adeNode;
+   private Fqn adf = Fqn.fromString("/a/d/f");
+   private NodeSpiMock adfNode;
+   private Fqn adfh = Fqn.fromString("/a/d/f/h");
+   private NodeSpiMock adfhNode;
+   private Fqn adfg = Fqn.fromString("/a/d/f/g");
+   private NodeSpiMock adfgNode;
+   private Fqn notExistent = Fqn.fromString("aaa" + System.currentTimeMillis());
+   //end of node structure.
+
+   @BeforeMethod
+   public void setUp()
+   {
+      root = new NodeSpiMock(Fqn.ROOT);
+      container = new DataContainer();
+      container.setRoot(root);
+      aNode = (NodeSpiMock) root.addChild(a);
+      abNode = (NodeSpiMock) root.addChild(ab);
+      abcNode = (NodeSpiMock) root.addChild(abc);
+      adNode = (NodeSpiMock) root.addChild(ad);
+      adeNode = (NodeSpiMock) root.addChild(ade);
+      adfNode = (NodeSpiMock) root.addChild(adf);
+      adfhNode = (NodeSpiMock) root.addChild(adfh);
+      adfgNode = (NodeSpiMock) root.addChild(adfg);
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#peek(Fqn, boolean, boolean)} method
+    */
+   public void testPeekNodesSimple()
+   {
+      assert root == container.peek(Fqn.ROOT, true, true);
+      assert adfgNode == container.peek(adfg, false, false);
+      assert adfgNode == container.peek(adfg, false, true);
+      assert adfgNode == container.peek(adfg, true, true);
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#peek(Fqn, boolean, boolean)} for invalid nodes.
+    */
+   public void testPeekInvalidNodes()
+   {
+      adfgNode.setValid(false, false);
+      assert null == container.peek(adfg, true, false);
+      assert adfgNode == container.peek(adfg, true, true);
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#peek(Fqn, boolean, boolean)} method for deleted nodes.
+    */
+   public void testPeekDeletedNodes()
+   {
+      adfgNode.markAsDeleted(true);
+      assert null == container.peek(adfg, false, false);
+      assert adfgNode == container.peek(adfg, true, false);
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#peekVersioned(Fqn, org.jboss.cache.optimistic.DataVersion, boolean)} method.
+    */
+   public void testPeekVersioned()
+   {
+      assert adfgNode == container.peekVersioned(adfg, null, true) : "if data version is null this returns same value as peek(boolean, boolean)";
+
+      //test pessimistic loking
+      Configuration config = new Configuration();
+      config.setNodeLockingOptimistic(false);
+      DataVersion dataVersion = new DefaultDataVersion(2);
+      container.injectDependencies(config, null);
+      assert adfgNode == container.peekVersioned(adfg, dataVersion, true) : "if NOT opt locking same value as peek(boolean, boolean) expected";
+
+      //test optimistic locking with same version
+      config.setNodeLockingOptimistic(true);
+      DataVersion adfgDataVersion = new DefaultDataVersion(2);
+      adfgNode.setVersion(adfgDataVersion);
+      assert adfgNode == container.peekVersioned(adfg, adfgDataVersion, true) : "same version, expcting node to be returned";
+
+      //test optimistic locking with a an older
+      try
+      {
+         container.peekVersioned(adfg, new DefaultDataVersion(1), true);
+         assert false : "exception expected as version changed.";
+      } catch (CacheException e)
+      {
+         //expected
+      }
+   }
+
+   /**
+    * tests {@link DataContainer#peekStrict(org.jboss.cache.transaction.GlobalTransaction, Fqn, boolean)}.
+    */
+   public void testPeekStrict()
+   {
+      assert adfgNode == container.peekStrict(null, adfg, true) : "if data version is null this returns same value as peek(boolean, boolean)";
+
+      try
+      {
+         container.peekStrict(null, notExistent, true);
+         assert false : "excpetion expected as node does not exist";
+      } catch (Exception e)
+      {
+         //expected
+      }
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#exists(Fqn)}
+    */
+   public void testsExists()
+   {
+      assert container.exists(ab) : "ab exists";
+      abNode.markAsDeleted(true);
+      assert !container.exists(ab) : "ab marked as deleted";
+      assert container.exists(ad);
+      adNode.setValid(false, false);
+      assert !container.exists(ade) : "its parent was marked as invalid";
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#hasChildren(Fqn)}
+    */
+   public void testHasChildren()
+   {
+      assert container.hasChildren(ad) : " ade is a child of ad";
+      assert !container.hasChildren(notExistent) : " this one does not exist";
+      assert !container.hasChildren(adfg) : "this one exists but does not have children";
+      adNode.setValid(false, false);
+      assert !container.hasChildren(ad) : "ad exists and has children but is invalid";
+   }
+
+   /**
+    * test {@link DataContainer#buildNodeData(java.util.List, NodeSPI)}
+    */
+   public void testBuildNodeData()
+   {
+      abNode.put("ab", "ab");
+      abcNode.put("abc", "abc");
+      List<NodeData> result = new ArrayList<NodeData>();
+      container.buildNodeData(result, abNode);
+      assert result.size() == 2;
+      assert result.contains(new NodeData(ab, abNode.getData()));
+      assert result.contains(new NodeData(abc, abcNode.getData()));
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#getNodesForEviction(Fqn, boolean)} in a nonrecursive scenario.
+    */
+   public void testGetNodesForEvictionNonrecursive()
+   {
+      //check for root first
+      List<Fqn> result = container.getNodesForEviction(Fqn.ROOT, false);
+      assert result.size() == 1 : "for root the direct children are considered for eviction";
+      assert result.contains(a);
+
+      //check normal
+      result = container.getNodesForEviction(ad, false);
+      assert result.size() == 1 : "one child expected";
+      assert result.contains(ad);
+
+      //check resident scenario
+      adNode.setResident(true);
+      result = container.getNodesForEviction(ad, false);
+      assert result.size() == 0 : "no children expected";
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#getNodesForEviction(Fqn, boolean)} in a recursive scenario.
+    */
+   public void testGetNodesForEvictionRecursive()
+   {
+      //check for root first
+      List<Fqn> result = container.getNodesForEviction(Fqn.ROOT, true);
+      assert result.size() == 8 : "all children are considered for eviction";
+
+      //check normal
+      result = container.getNodesForEviction(ad, true);
+      assert result.size() == 5 : "five childrens expected";
+      assert result.contains(ad);
+      assert result.contains(ade);
+      assert result.contains(adf);
+      assert result.contains(adfh);
+      assert result.contains(adfg);
+
+      //check resident scenario
+      adNode.setResident(true);
+      result = container.getNodesForEviction(ad, true);
+      assert result.size() == 4 : "only children expected";
+      assert result.contains(ade);
+      assert result.contains(adf);
+      assert result.contains(adfh);
+      assert result.contains(adfg);
+   }
+
+   /**
+    * tests {@link DataContainer#getNumberOfNodes()}
+    */
+   public void testGetNumberOfNodes()
+   {
+      assert container.getNumberOfNodes() == 8 : "eoght nodes expected";
+   }
+
+   /**
+    * tests {@link DataContainer#removeFromDataStructure(Fqn, boolean)} having skipMarkerCheck set to false.
+    */
+   public void removeFromDataStructureNoSkip1()
+   {
+      //check inexisten node
+      assert !container.removeFromDataStructure(notExistent, false);
+
+      //check root - all the subnodes should be deleted and marked as invalid, but the root itself
+      root.markAsDeleted(true);
+      assert container.removeFromDataStructure(Fqn.ROOT, false);
+      assert !aNode.isValid();
+      assert !abNode.isValid();
+      assert !abcNode.isValid();
+      assert !adNode.isValid();
+      assert !adeNode.isValid();
+      assert !adfNode.isValid();
+      assert !adfgNode.isValid();
+      assert !adfhNode.isValid();
+      assert root.isValid();
+   }
+
+   /**
+    * tests {@link DataContainer#removeFromDataStructure(Fqn, boolean)} having skipMarkerCheck set to false.
+    */
+   public void removeFromDataStructureNoSkip2()
+   {
+      //check root - all the subnodes should be deleted and marked as invalid, but the root itself
+      root.markAsDeleted(false);
+      assert !container.removeFromDataStructure(Fqn.ROOT, false);
+
+      //check a normal node
+      adNode.markAsDeleted(true);
+      assert container.removeFromDataStructure(ad, false);
+      assert !adeNode.isValid();
+      assert !adfNode.isValid();
+      assert !adfhNode.isValid();
+      assert !adfhNode.isValid();
+   }
+
+   /**
+    * tests {@link DataContainer#removeFromDataStructure(Fqn, boolean)} having skipMarkerCheck set to true.
+    */
+   public void removeFromDataStructureWithSkip()
+   {
+      //check inexisten node
+      assert !container.removeFromDataStructure(notExistent, false);
+
+      //check root - all the subnodes should be deleted and marked as invalid, but the root itself
+      assert container.removeFromDataStructure(Fqn.ROOT, true);
+      assert !aNode.isValid();
+      assert !abNode.isValid();
+      assert !abcNode.isValid();
+      assert !adNode.isValid();
+      assert !adeNode.isValid();
+      assert !adfNode.isValid();
+      assert !adfgNode.isValid();
+      assert !adfhNode.isValid();
+      assert root.isValid();
+   }
+
+   /**
+    * tests {@link org.jboss.cache.DataContainer#evict(Fqn)}
+    */
+   public void testEvict()
+   {
+      //tests eviction of leaf nodes
+      assert container.evict(abc);
+      assert !abcNode.isValid();
+      assert !abNode.hasChild("c");
+
+      //test eviction of intermediate nodes
+      adNode.put("key", "value");
+      assert !container.evict(ad);
+      assert adNode.isValid();
+      assert adNode.getData().isEmpty();
+      assert aNode.hasChild("d");
+      assert adNode.hasChild("e");
+   }
+
+   /**
+    *  test {@link org.jboss.cache.DataContainer#createNodes(Fqn)}
+    */
+   public void testCreateNodes()
+   {
+      Object[] objects = container.createNodes(Fqn.fromString("/a/x/y/z"));
+      List result = (List) objects[0];
+      assert result.size() == 3;
+      assert ((NodeSPI)result.get(0)).getFqn().equals(Fqn.fromString("/a/x"));
+      assert ((NodeSPI)result.get(1)).getFqn().equals(Fqn.fromString("/a/x/y"));
+      assert ((NodeSPI)result.get(2)).getFqn().equals(Fqn.fromString("/a/x/y/z"));
+      NodeSPI target = (NodeSPI) objects[1];
+      assert target != null;
+      assert target.getFqn().toString().equals("/a/x/y/z");
+   }
+}

Added: core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java	2008-05-13 22:04:27 UTC (rev 5835)
@@ -0,0 +1,424 @@
+package org.jboss.cache.mock;
+
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.optimistic.DataVersion;
+import org.jboss.cache.lock.NodeLock;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.*;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+public class NodeSpiMock implements NodeSPI
+{
+
+   boolean isChildrenLoaded;
+   boolean isDataLoaded;
+   Map<Object, NodeSpiMock> children = new HashMap<Object, NodeSpiMock>();
+   boolean isDeleted = false;
+   boolean isValid = true;
+   DataVersion version = null;
+   Map data = new HashMap();
+   NodeSpiMock parent;
+   Fqn fqn;
+   private boolean isResident = false;
+
+   public NodeSpiMock(Fqn fqn)
+   {
+      this.fqn = fqn;
+   }
+
+   public boolean isChildrenLoaded()
+   {
+      return isChildrenLoaded;
+   }
+
+   public void setChildrenLoaded(boolean loaded)
+   {
+      this.isChildrenLoaded = loaded;
+   }
+
+   public boolean isDataLoaded()
+   {
+      return isDataLoaded;
+   }
+
+   public void setDataLoaded(boolean dataLoaded)
+   {
+      this.isDataLoaded = dataLoaded;
+   }
+
+   public Map getChildrenMapDirect()
+   {
+      return children;
+   }
+
+   public void setChildrenMapDirect(Map children)
+   {
+      this.children = new HashMap(children);
+   }
+
+   public NodeSPI getOrCreateChild(Object name, GlobalTransaction tx)
+   {
+      if (children.containsKey(name)) return children.get(name);
+      NodeSpiMock child = newChild(name);
+      return child;
+   }
+
+   private NodeSpiMock newChild(Object name)
+   {
+      NodeSpiMock child = new NodeSpiMock(Fqn.fromRelativeElements(fqn, name));
+      child.parent = this;
+      children.put(name, child);
+      return child;
+   }
+
+   public NodeLock getLock()
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public void setFqn(Fqn f)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public boolean isDeleted()
+   {
+      return isDeleted;
+   }
+
+   public void markAsDeleted(boolean marker)
+   {
+      this.isDeleted = marker;
+   }
+
+   public void markAsDeleted(boolean marker, boolean recursive)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public void addChild(Object nodeName, Node nodeToAdd)
+   {
+      children.put(nodeName, (NodeSpiMock) nodeToAdd);
+      ((NodeSpiMock) nodeToAdd).parent = this;
+      ((NodeSpiMock) nodeToAdd).fqn = Fqn.fromRelativeElements(fqn, nodeName);
+   }
+
+   public void printDetails(StringBuffer sb, int indent)
+   {
+      //skip
+   }
+
+   public void print(StringBuffer sb, int indent)
+   {
+      //skip
+   }
+
+   public void setVersion(DataVersion version)
+   {
+      this.version = version;
+   }
+
+   public DataVersion getVersion()
+   {
+      return version;
+   }
+
+   public Set getChildrenDirect()
+   {
+      return new HashSet(children.values());
+   }
+
+   public void removeChildrenDirect()
+   {
+      children.clear();
+   }
+
+   public Set getChildrenDirect(boolean includeMarkedAsDeleted)
+   {
+      Set result = new HashSet();
+      for (NodeSpiMock child : children.values())
+      {
+         if (!includeMarkedAsDeleted && child.isDeleted()) continue;
+         result.add(child);
+      }
+      return result;
+   }
+
+   public NodeSPI getChildDirect(Object childName)
+   {
+      return children.get(childName);
+   }
+
+   public NodeSPI addChildDirect(Fqn childName)
+   {
+      if (childName.size() == 0) return this;
+      Object directChildName = childName.get(0);
+      NodeSpiMock directChild = children.get(directChildName);
+      Fqn subFqn = childName.getSubFqn(1, childName.size());
+      if(directChild == null)
+      {
+         directChild = newChild(directChildName);
+      }
+      return directChild.addChildDirect(subFqn);
+   }
+
+   public NodeSPI addChildDirect(Fqn f, boolean notify)
+   {
+      return addChildDirect(f);
+   }
+
+   public NodeSPI addChildDirect(Object childName, boolean notify)
+   {
+      return newChild(childName);
+   }
+
+   public void addChildDirect(NodeSPI child)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public NodeSPI getChildDirect(Fqn childName)
+   {
+      return children.get(childName.getLastElement());
+   }
+
+   public boolean removeChildDirect(Fqn fqn)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public boolean removeChildDirect(Object childName)
+   {
+      return children.remove(childName) != null;
+   }
+
+   public Object removeDirect(Object key)
+   {
+      return data.remove(key);
+   }
+
+   public Object putDirect(Object key, Object value)
+   {
+      return data.put(key, value);
+   }
+
+   public void putAllDirect(Map data)
+   {
+      data.putAll(data);
+   }
+
+   public Map getDataDirect()
+   {
+      return data;
+   }
+
+   public Object getDirect(Object key)
+   {
+      return data.get(key);
+   }
+
+   public void clearDataDirect()
+   {
+      data.clear();
+   }
+
+   public Set getKeysDirect()
+   {
+      return data.keySet();
+   }
+
+   public Set getChildrenNamesDirect()
+   {
+      return new HashSet(children.keySet());
+   }
+
+   public CacheSPI getCache()
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public NodeSPI getParent()
+   {
+      return parent;
+   }
+
+   public boolean hasChildrenDirect()
+   {
+      return !children.isEmpty();
+   }
+
+   public Map getInternalState(boolean onlyInternalState)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public void setInternalState(Map state)
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   public void setValid(boolean valid, boolean recursive)
+   {
+      this.isValid = valid;
+      if (recursive)
+      {
+         for (NodeSpiMock child : children.values())
+         {
+            child.setValid(valid, true);
+            child.isValid = valid;
+         }
+      }
+   }
+
+   public Set getChildren()
+   {
+      return getChildrenDirect();
+   }
+
+   public Set getChildrenNames()
+   {
+      return getChildrenNamesDirect();
+   }
+
+   public Map getData()
+   {
+      return getDataDirect();
+   }
+
+   public Set getKeys()
+   {
+      return getKeysDirect();
+   }
+
+   public Fqn getFqn()
+   {
+      return fqn;
+   }
+
+   public Node addChild(Fqn f)
+   {
+      return addChildDirect(f);
+   }
+
+   public boolean removeChild(Fqn f)
+   {
+      return removeChildDirect(f);
+   }
+
+   public boolean removeChild(Object childName)
+   {
+      return removeChildDirect(childName);
+   }
+
+   public Node getChild(Fqn f)
+   {
+      return getChildDirect(f);
+   }
+
+   public Node getChild(Object name)
+   {
+      return getChildDirect(name);
+   }
+
+   public Object put(Object key, Object value)
+   {
+      return putDirect(key, value);
+   }
+
+   public Object putIfAbsent(Object key, Object value)
+   {
+      if (data.containsKey(key)) return data.get(key);
+      return data.put(key, value);
+   }
+
+   public Object replace(Object key, Object value)
+   {
+      return data.put(key, value);
+   }
+
+   public boolean replace(Object key, Object oldValue, Object newValue)
+   {
+      if (data.get(key).equals(oldValue))
+      {
+         data.put(key, newValue);
+         return true;
+      } else
+         return false;
+   }
+
+   public void putAll(Map map)
+   {
+      putAllDirect(data);
+   }
+
+   public void replaceAll(Map map)
+   {
+      data = map;  
+   }
+
+   public Object get(Object key)
+   {
+      return getDirect(key);
+   }
+
+   public Object remove(Object key)
+   {
+      return removeDirect(key);
+   }
+
+   public void clearData()
+   {
+      clearDataDirect();
+   }
+
+   public int dataSize()
+   {
+      return data.size();
+   }
+
+   public boolean hasChild(Fqn f)
+   {
+      NodeSpiMock directChild = children.get(fqn.getLastElement());
+      return directChild != null && (fqn.size() == 1 || directChild.hasChild(f.getSubFqn(1, f.size())));
+   }
+
+   public boolean hasChild(Object o)
+   {
+      return children.containsKey(o);
+   }
+
+   public boolean isValid()
+   {
+      return isValid;
+   }
+
+   public boolean isResident()
+   {
+      return isResident;
+   }
+
+   public void setResident(boolean resident)
+   {
+      this.isResident = resident;
+   }
+
+   public boolean isLockForChildInsertRemove()
+   {
+      return false;
+   }
+
+   public void setLockForChildInsertRemove(boolean lockForChildInsertRemove)
+   {
+   }
+
+   public void releaseObjectReferences(boolean recursive)
+   {
+   }
+}




More information about the jbosscache-commits mailing list