/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.tests;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.transaction.DummyTransactionManager;

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

/**
 * Simple functional tests for TreeCache
 * @author Bela Ban
 * @version $Id: TreeCacheFunctionalTest.java,v 1.2.2.2 2005/04/06 21:07:05 starksm Exp $
 */
public class TreeCacheFunctionalTest extends TestCase {
   TreeCache cache=null;
   Transaction tx=null;
   final Fqn FQN=Fqn.fromString("/myNode");
   final String KEY="key";
   final String VALUE="value";
   Exception ex;


   protected void setUp() throws Exception {
      super.setUp();
      ex=null;
   }

   protected void tearDown() throws Exception {
      super.tearDown();
      if(cache != null) {
         cache.stopService();
         cache.destroyService();
         cache=null;
      }
      if(ex != null)
         throw ex;
   }


   public void testFailFastPut() throws Exception {
      cache=new TreeCache();
      cache.setCacheMode(TreeCache.LOCAL);
      cache.startService();
      cache.put(FQN, KEY, VALUE);
      cache.putFailFast(Fqn.fromString("/a/b/c"), KEY, VALUE, 0);
      cache.putFailFast(Fqn.fromString("/a/b/c"), KEY, VALUE, 100);
      cache.putFailFast(Fqn.fromString("/1/2/3"), KEY, VALUE, 100);
      cache.putFailFast(Fqn.fromString("/1/2/3"), KEY, VALUE, 0);
      System.out.println("cache: " + cache.printLockInfo());
   }


   public void testFailFastWith2Transactions() throws Exception, NotSupportedException {
      cache=new TreeCache();
      cache.setCacheMode(TreeCache.LOCAL);
      cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.startService();
      tx=startTransaction();
      cache.put("/a/b/c", KEY, VALUE);

      class Loser extends Thread {
         public void run() {
            Transaction trans=null;
            try {
               trans=startTransaction();
               cache.putFailFast(Fqn.fromString("/a/b/c"), KEY, VALUE, 500);
               fail("this should fail as /a/b/c is held by another thread");
            }
            catch(TimeoutException timeoutEx) {
               System.out.println("got TimeoutException (as expected)");
            }
            catch(Exception e) {
               ex=e;
            }
         }
      }

      System.out.println("locks before loser: " + cache.printLockInfo());
      Loser loser=new Loser();
      loser.start();
      loser.join();
      tx.commit();
   }


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



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

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

}