Package org.jboss.cache.api.nodevalidity

Source Code of org.jboss.cache.api.nodevalidity.NodeValidityTestBase

package org.jboss.cache.api.nodevalidity;

import org.jboss.cache.Cache;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
import org.jboss.cache.NodeNotValidException;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
import org.jboss.cache.optimistic.DefaultDataVersion;
import org.jboss.cache.transaction.DummyTransactionManagerLookup;
import org.jboss.cache.util.TestingUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.Collections;

/**
* exercises the isValid() api call on node.
*
* @author <a href="mailto:manik AT jboss DOT org">Manik Surtani</a>
* @since 2.1.0
*/
@Test(groups = {"functional"})
public abstract class NodeValidityTestBase
{
   protected NodeLockingScheme nodeLockingScheme = NodeLockingScheme.PESSIMISTIC;

   // needed to attach a blockUntilViewsReceived in setup
   protected boolean clustered = true;

   // needed to test tombstones
   protected boolean invalidation = false;

   protected ThreadLocal<Cache<String, String>> observerTL = new ThreadLocal<Cache<String, String>>();
   protected ThreadLocal<Cache<String, String>> modifierTL = new ThreadLocal<Cache<String, String>>();
  
   protected static final Fqn parent = Fqn.fromString("/parent");
   protected static final Fqn child = Fqn.fromString("/parent/child");
   protected static final String K = "k", V = "v";

   protected abstract Cache<String, String> createObserver();

   protected abstract Cache<String, String> createModifier();

   protected void nodeLockingSchemeSpecificSetup(Configuration c)
   {
      c.setNodeLockingScheme(nodeLockingScheme);
      if (isOptimistic())
      {
         c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
         c.setSyncCommitPhase(true);
         c.setSyncRollbackPhase(true);
      }
   }

   protected boolean isOptimistic()
   {
      return nodeLockingScheme == NodeLockingScheme.OPTIMISTIC;
   }

   @BeforeMethod
   public void setUp()
   {
      Cache<String, String> observer = createObserver();
      Cache<String, String> modifier = createModifier();
      observerTL.set(observer);
      modifierTL.set(modifier);
      if (clustered) TestingUtil.blockUntilViewsReceived(60000, observer, modifier);
   }

   @AfterMethod
   public void tearDown()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();
      TestingUtil.killCaches(observer, modifier);
      observerTL.set(null);
      modifierTL.set(null);
   }

   public void testRemoval()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();
//      observer.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
      observer.put(parent, K, V);

      Node<String, String> obsNode = observer.getRoot().getChild(parent);

      assert obsNode.get(K).equals(V) : "Data should be in the node.";
      assert obsNode.isValid() : "Node should be valid";

      modifier.removeNode(parent);

      assert !obsNode.isValid() : "Should no longer be valid";
   }

   public void testRemovalWithChildren()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();
//      observer.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
      observer.put(child, K, V);

      Node<String, String> obsParentNode = observer.getRoot().getChild(parent);
      Node<String, String> obsChildNode = observer.getRoot().getChild(child);

      assert obsChildNode.get(K).equals(V) : "Data should be in the node.";
      assert obsChildNode.isValid() : "Node should be valid";
      assert obsParentNode.isValid() : "Node should be valid";

      modifier.removeNode(parent);

      assert !obsParentNode.isValid() : "Should no longer be valid";
      assert !obsChildNode.isValid() : "Should no longer be valid";
   }

   public void testMove()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      Fqn newParent = Fqn.fromString("/newParent/parent");

      //observer.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
      observer.put(parent, K, V);

      Node<String, String> obsNode = observer.getRoot().getChild(parent);

      assert obsNode.get(K).equals(V) : "Data should be in the node.";
      assert obsNode.isValid() : "Node should be valid";

      // new parent needs to exist first.
      modifier.getRoot().addChild(newParent);
      modifier.move(parent, newParent.getParent());

      // the old node is only marked as invalid if we use opt locking
      // with pess locking we directly move the node reference so the old ref is still valid, EVEN if the move happens
      // remotely.
      if (isOptimistic()) assert !obsNode.isValid() : "Should no longer be valid";

      assert observer.getRoot().getChild(newParent).isValid() : "Should be valid";
   }

   public void testMoveWithChildren()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      Fqn newParent = Fqn.fromString("/newParent/parent");
      Fqn newChild = Fqn.fromString("/newParent/parent/child");

//      observer.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
      observer.put(child, K, V);

      Node<String, String> obsParentNode = observer.getRoot().getChild(parent);
      Node<String, String> obsChildNode = observer.getRoot().getChild(child);

      assert obsChildNode.get(K).equals(V) : "Data should be in the node.";
      assert obsChildNode.isValid() : "Node should be valid";
      assert obsParentNode.isValid() : "Node should be valid";

      // new parent needs to exist first.
      modifier.getRoot().addChild(newParent);
      modifier.move(parent, newParent.getParent());

      // the old node is only marked as invalid if we use opt locking
      // with pess locking we directly move the node reference so the old ref is still valid.
      if (isOptimistic())
      {
         assert !obsParentNode.isValid() : "Should no longer be valid";
         assert !obsChildNode.isValid() : "Should no longer be valid";
      }

      assert observer.getRoot().getChild(newParent).isValid() : "Should be valid";
      assert observer.getRoot().getChild(newChild).isValid() : "Should be valid";
   }

   public void testEvict()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      // eviction should affect validity
      observer.put(parent, K, V);
      Node<String, String> obsNode = observer.getRoot().getChild(parent);

      assert obsNode.get(K).equals(V) : "Data should be in the node.";
      assert obsNode.isValid() : "Node should be valid";

      // eviction needs to happen on the same cache being watched
      observer.evict(parent, false);

      assert !obsNode.isValid() : "Node should not be valid";
   }

   public void testOperationsOnInvalidNode()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      observer.put(parent, K, V);
      Node<String, String> obsNode = observer.getRoot().getChild(parent);

      assert obsNode.get(K).equals(V) : "Data should be in the node.";
      assert obsNode.isValid() : "Node should be valid";

      modifier.removeNode(parent);

      assert !obsNode.isValid() : "Node should not be valid";

      // all operations on the cached node should throw a NodeNotValidException

      try
      {
         obsNode.get(K);
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.put(K, "v2");
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.remove(K);
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.clearData();
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.putAll(Collections.singletonMap(K, "v2"));
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.getKeys();
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.hasChild("Something");
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.removeChild("Something");
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.addChild(child);
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }

      try
      {
         obsNode.getChildrenNames();
         assert false : "Should fail";
      }
      catch (NodeNotValidException good)
      {
         // do nothing
      }
   }

   public void testExistenceOfTombstones()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      CacheSPI modifierImpl = (CacheSPI) modifier;
      CacheSPI observerImpl = (CacheSPI) observer;

      modifier.put(parent, K, V);
      modifier.removeNode(parent);

      if (isOptimistic() && invalidation)
      {
         // if we are using optimistic invalidation then we should see tombstones.  NOT otherwise.
         NodeSPI modifierTombstone = modifierImpl.peek(parent, true, true);
         NodeSPI observerTombstone = observerImpl.peek(parent, true, true);

         assert modifierTombstone != null : "Modifier tombstone should not be null";
         assert observerTombstone != null : "Observer tombstone should not be null";

         assert !modifierTombstone.isValid() : "Should not be valid";
         assert !observerTombstone.isValid() : "Should not be valid";

         assert ((DefaultDataVersion) modifierTombstone.getVersion()).getRawVersion() == 2 : "Tombstone should be versioned";
         assert ((DefaultDataVersion) observerTombstone.getVersion()).getRawVersion() == 2 : "Tombstone should be versioned";

      }
      else
      {
         // if we are using pess locking there should be NO tombstones, regardless of replication/invalidation!
         assert modifierImpl.peek(parent, true, true) == null : "Tombstone should not exist";
         assert observerImpl.peek(parent, true, true) == null : "Tombstone should not exist";
      }
   }

   public void testExistenceOfTombstonesWithChildren()
   {
      Cache<String, String> observer = observerTL.get();
      Cache<String, String> modifier = modifierTL.get();

      CacheSPI modifierImpl = (CacheSPI) modifier;
      CacheSPI observerImpl = (CacheSPI) observer;

      modifier.put(child, K, V);
      modifier.removeNode(parent);

      if (isOptimistic() && invalidation)
      {
         // if we are using optimistic invalidation then we should see tombstones.  NOT otherwise.
         NodeSPI modifierParentTombstone = modifierImpl.peek(parent, true, true);
         NodeSPI observerParentTombstone = observerImpl.peek(parent, true, true);
         NodeSPI modifierChildTombstone = modifierImpl.peek(child, true, true);
         NodeSPI observerChildTombstone = observerImpl.peek(child, true, true);

         assert modifierParentTombstone != null : "Modifier parent tombstone should not be null";
         assert observerParentTombstone != null : "Observer parent tombstone should not be null";
         assert modifierChildTombstone != null : "Modifier child tombstone should not be null";
         assert observerChildTombstone != null : "Observer child tombstone should not be null";

         assert !modifierParentTombstone.isValid() : "Should not be valid";
         assert !observerParentTombstone.isValid() : "Should not be valid";
         assert !modifierChildTombstone.isValid() : "Should not be valid";
         assert !observerChildTombstone.isValid() : "Should not be valid";

         assert ((DefaultDataVersion) modifierParentTombstone.getVersion()).getRawVersion() == 1 : "Tombstone should be versioned";
         assert ((DefaultDataVersion) observerParentTombstone.getVersion()).getRawVersion() == 1 : "Tombstone should be versioned";

         // note that versions on children cannot be incremented/updated since the remove operation was
         // performed on the parent.
         assert ((DefaultDataVersion) modifierChildTombstone.getVersion()).getRawVersion() == 1 : "Tombstone should be versioned";
         assert ((DefaultDataVersion) observerChildTombstone.getVersion()).getRawVersion() == 1 : "Tombstone should be versioned";

      }
      else
      {
         // if we are using pess locking there should be NO tombstones, regardless of replication/invalidation!
         assert modifierImpl.peek(parent, true, true) == null : "Tombstone should not exist";
         assert observerImpl.peek(parent, true, true) == null : "Tombstone should not exist";
         assert modifierImpl.peek(child, true, true) == null : "Tombstone should not exist";
         assert observerImpl.peek(child, true, true) == null : "Tombstone should not exist";
      }
   }
}
TOP

Related Classes of org.jboss.cache.api.nodevalidity.NodeValidityTestBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.