package org.jboss.cache.lock;

import junit.framework.TestCase;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.DummyTransactionManagerLookup;
import org.jboss.cache.Node;

import javax.transaction.TransactionManager;

/**
 * basic locking test
 *
 * @author <a href="mailto:manik@jboss.org">Manik Surtani</a>
 * @since 2.0.0
 */
public class PessimisticLockTest extends TestCase
{
   private TreeCache cache;
   private TransactionManager tm;
   private Fqn fqn = Fqn.fromString("/a/b/c");

   protected void setUp() throws Exception
   {
      cache = new TreeCache();
      cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
      cache.start();
      tm = cache.getTransactionManager();
   }

   protected void tearDown()
   {
      cache.stop();
   }

   public void testPut() throws Exception
   {
      cache.put(fqn, "k", "v");

      tm.begin();
      cache.put(fqn, "k2", "v2");
      Node n = cache.get(fqn);

      assertFalse(n.getLock().isReadLocked());
      assertTrue(n.getLock().isWriteLocked());
      assertTrue(n.getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getLock().isWriteLocked());
      assertTrue(n.getParent().getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getParent().getLock().isWriteLocked());

      tm.commit();
   }

   public void testGet() throws Exception
   {
      cache.put(fqn, "k", "v");

      tm.begin();
      cache.get(fqn, "k2");
      Node n = cache.get(fqn);

      assertTrue(n.getLock().isReadLocked());
      assertFalse(n.getLock().isWriteLocked());
      assertTrue(n.getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getLock().isWriteLocked());
      assertTrue(n.getParent().getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getParent().getLock().isWriteLocked());

      tm.commit();
   }

   public void testRemove() throws Exception
   {
      cache.put(fqn, "k", "v");
      tm.begin();
      cache.remove(fqn, "k2");
      Node n = cache.get(fqn);

      assertFalse(n.getLock().isReadLocked());
      assertTrue(n.getLock().isWriteLocked());
      assertTrue(n.getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getLock().isWriteLocked());
      assertTrue(n.getParent().getParent().getLock().isReadLocked());
      assertFalse(n.getParent().getParent().getLock().isWriteLocked());

      tm.commit();

   }
}
