package org.jboss.cache;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.transaction.DummyTransactionManager;

import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;

/**
 * Tests restart (stop-destroy-create-start) of TreeCache
 * @author Bela Ban
 * @version $Id: LifeCycleTest.java 3090 2006-12-05 15:27:52Z msurtani $
 */
public class LifeCycleTest extends TestCase {

    private static Log log = LogFactory.getLog(LifeCycleTest.class);

   public void testLocalRestartNoTransactions() throws Exception {
      TreeCache cache=createCache(TreeCache.LOCAL);
      cache.createService();
      cache.startService();

      cache.put("/a/b/c", null);
      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());

      System.out.println("cache locks before restart:\n" + cache.printLockInfo());
      restartCache(cache);
      System.out.println("cache locks after restart:\n" + cache.printLockInfo());

      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());
   }


   public void testLocalRestartWithTransactions() throws Exception {
      TreeCache cache=createCache(TreeCache.LOCAL);
      cache.createService();
      cache.startService();

      Transaction tx=beginTransaction();

      cache.put("/a/b/c", null);
      log.debug("cache locks before restart:\n" + cache.printLockInfo());
      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(4, cache.getNumberOfLocksHeld());

      restartCache(cache);
      log.debug("cache locks after restart:\n" + cache.printLockInfo());

      assertEquals(4, cache.getNumberOfLocksHeld());
      assertTrue(cache.getNumberOfNodes() > 0);

      tx.rollback();
      assertEquals(0, cache.getNumberOfLocksHeld());
   }

   public void testStartNoCreate() throws Exception {
      TreeCache cache=createCache(TreeCache.LOCAL);
      cache.start();

      cache.put("/a/b/c", null);
      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());

      System.out.println("cache locks before restart:\n" + cache.printLockInfo());
      restartCache(cache);
      System.out.println("cache locks after restart:\n" + cache.printLockInfo());

      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());
   }

   public void testReStartNoCreate() throws Exception {
      TreeCache cache=createCache(TreeCache.LOCAL);
      cache.start();
      cache.stop();
      cache.start();

      cache.put("/a/b/c", null);
      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());

      System.out.println("cache locks before restart:\n" + cache.printLockInfo());
      restartCache(cache);
      System.out.println("cache locks after restart:\n" + cache.printLockInfo());

      assertTrue(cache.getNumberOfNodes() > 0);
      assertEquals(0, cache.getNumberOfLocksHeld());
   }

   TreeCache createCache(int cache_mode) throws Exception {
      TreeCache retval=new TreeCache();
      retval.setCacheMode(cache_mode);
      retval.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      return retval;
   }


   Transaction beginTransaction() throws SystemException, NotSupportedException {
      DummyTransactionManager mgr=DummyTransactionManager.getInstance();
      mgr.begin();
      Transaction tx=mgr.getTransaction();
      return tx;
   }


   void startCache(TreeCache c) throws Exception {
      c.createService();
      c.startService();
   }

   void stopCache(TreeCache c) {
      c.stopService();
      c.destroyService();
   }

   void restartCache(TreeCache c) throws Exception {
      stopCache(c);
      startCache(c);
   }


   public static Test suite() {
      return new TestSuite(LifeCycleTest.class);
   }

   public static void main(String[] args) {
      junit.textui.TestRunner.run(suite());
   }

}
