Author: bstansberry(a)jboss.com
Date: 2007-09-17 23:26:48 -0400 (Mon, 17 Sep 2007)
New Revision: 4482
Added:
core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
Log:
[JBCACHE-1178] Option to set lock timeout
Added: core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java 2007-09-18
03:26:48 UTC (rev 4482)
@@ -0,0 +1,371 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.cache.options;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.fail;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheImpl;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.TimeoutException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Test functionality of {@link Option#setLockAcquisitionTimeout(int)}.
+ *
+ * @author Brian Stansberry
+ */
+@Test(groups = {"functional"})
+public class LockAcquisitionTimeoutTest
+{
+ private static final Log log = LogFactory.getLog(LockAcquisitionTimeoutTest.class);
+
+ private static final Fqn FQNA = Fqn.fromString("/A");
+ private static final Fqn FQNB = Fqn.fromString("/B");
+ private static final String KEY = "key";
+ private static final String VALUE1 = "value1";
+ private static final String VALUE2 = "value2";
+
+ private CacheImpl<Object, Object> cache;
+ private Option option;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception
+ {
+ cache = (CacheImpl<Object,
Object>)DefaultCacheFactory.getInstance().createCache(false);
+ Configuration c = new Configuration();
+ cache.setConfiguration(c);
+ c.setCacheMode("REPL_SYNC");
+
c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+
+ cache.start();
+
+ option = new Option();
+ option.setLockAcquisitionTimeout(0);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ if (cache != null)
+ {
+ cache.stop();
+ cache = null;
+ }
+ }
+
+ /**
+ * Confirms that doing a put with a lockAcquisitionTime option set
+ * does the put as expected. There is no other thread or tx contesting
+ * the lock the put needs, so this is just a simple test that the option
+ * doesn't somehow screw up the put.
+ *
+ * @throws Exception
+ */
+ public void testSimplePut() throws Exception
+ {
+ log.info("++++ testSimplePut() ++++");
+ simplePutTest(false);
+ }
+
+ /**
+ * Confirms that doing a put with a lockAcquisitionTime option set
+ * does the put as expected when executed within a transaction. There is no
+ * other thread or tx contesting the lock the put needs, so this is just a
+ * simple test that the option doesn't somehow screw up the put.
+ *
+ * @throws Exception
+ */
+ public void testSimplePutWithTx() throws Exception
+ {
+ log.info("++++ testSimplePutWithTx() ++++");
+ simplePutTest(true);
+ }
+
+ private void simplePutTest(boolean useTx) throws Exception
+ {
+ TransactionManager tm = useTx ? cache.getTransactionManager() : null;
+ LowTimeoutSetter setter = new LowTimeoutSetter(tm);
+ setter.start();
+
+ setter.join(2000);
+ if (!setter.finished)
+ {
+ setter.interrupt();
+ fail("Puts failed to complete in a timely manner");
+ }
+
+ assertNull("LowTimeoutSetter saw no TimeoutException", setter.te);
+ assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
+ assertEquals("Cache correct for " + FQNA, VALUE2, cache.get(FQNA, KEY));
+ assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
+ }
+
+ /**
+ * Confirms that a put with a lockAcquisitionTimeout option set to zero
+ * fails promptly in the presence of a lock on the target node.
+ *
+ * @throws Exception
+ */
+ public void testContestedPut() throws Exception
+ {
+ log.info("++++ testContestedPut() ++++");
+ contestedPutTest(false);
+ }
+
+ /**
+ * Confirms that a put with a lockAcquisitionTimeout option set to zero
+ * is ignored if executed within a transaction.
+ *
+ * @throws Exception
+ */
+ public void testContestedPutWithTx() throws Exception
+ {
+ log.info("++++ testContestedPutWithTx() ++++");
+ contestedPutTest(true);
+ }
+
+ private void contestedPutTest(boolean tx) throws Exception
+ {
+ TransactionManager mgr = cache.getTransactionManager();
+ mgr.begin();
+
+ LowTimeoutSetter setter = null;
+ try
+ {
+ // Put a WL on /A
+ cache.put(FQNA, KEY, VALUE1);
+
+ // Launch a thread that tries to write to /A
+ setter = new LowTimeoutSetter(tx ? mgr : null);
+ setter.start();
+
+ setter.join(2000);
+ if (!setter.finished)
+ {
+ setter.interrupt();
+ fail("Puts failed to complete in a timely manner");
+ }
+ }
+ finally
+ {
+ // always commit the tx
+ mgr.commit();
+ }
+
+ assertNotNull("LowTimeoutSetter saw TimeoutException", setter.te);
+ assertNull("LowTimeoutSetter saw no misc Exception", setter.failure);
+ assertEquals("Cache correct for " + FQNA, VALUE1, cache.get(FQNA, KEY));
+ assertEquals("Cache correct for " + FQNB, VALUE2, cache.get(FQNB, KEY));
+
+ }
+
+ public void testSimpleRead() throws Exception
+ {
+ log.info("++++++ testSimpleRead() ++++++");
+ simpleReadTest(false);
+ }
+
+ public void testSimpleReadWithTx() throws Exception
+ {
+ log.info("++++++ testSimpleReadWithTx() ++++++");
+ simpleReadTest(true);
+ }
+
+ private void simpleReadTest(boolean useTx) throws Exception
+ {
+ TransactionManager tm = useTx ? cache.getTransactionManager() : null;
+ LowTimeoutReader reader = new LowTimeoutReader(tm);
+
+ cache.put(FQNA, KEY, VALUE1);
+
+ reader.start();
+
+ reader.join(2000);
+ if (!reader.finished)
+ {
+ reader.interrupt();
+ fail("Read failed to complete in a timely manner");
+ }
+
+ assertNull("LowTimeoutSetter saw no TimeoutException", reader.te);
+ assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
+ assertEquals("LowTimeoutSetter correct for " + FQNA, VALUE1,
reader.value);
+
+ }
+
+ public void testContestedRead() throws Exception
+ {
+ log.info("++++++ testContestedRead() ++++++");
+ contestedReadTest(false);
+ }
+
+ public void testContestedReadWithTx() throws Exception
+ {
+ log.info("++++++ testContestedReadWithTx() ++++++");
+ contestedReadTest(true);
+ }
+
+ private void contestedReadTest(boolean tx) throws Exception
+ {
+ TransactionManager mgr = cache.getTransactionManager();
+ mgr.begin();
+
+ LowTimeoutReader reader = null;
+ try
+ {
+ // Put a WL on /A
+ cache.put(FQNA, KEY, VALUE1);
+
+ // Launch a thread that tries to read from /A
+ reader = new LowTimeoutReader(tx ? mgr : null);
+ reader.start();
+
+ reader.join(2000);
+ if (!reader.finished)
+ {
+ reader.interrupt();
+ fail("Read failed to complete in a timely manner");
+ }
+ }
+ finally
+ {
+ // always commit the tx
+ mgr.commit();
+ }
+
+ assertNotNull("LowTimeoutSetter saw TimeoutException", reader.te);
+ assertNull("LowTimeoutSetter saw no misc Exception", reader.failure);
+ assertNull("LowTimeoutSetter unable to read " + FQNA, reader.value);
+
+ }
+
+ class LowTimeoutSetter extends Thread
+ {
+ TransactionManager tm;
+ TimeoutException te;
+ Throwable failure;
+ boolean finished;
+
+ LowTimeoutSetter(TransactionManager tm)
+ {
+ this.tm = tm;
+ }
+
+ public void run()
+ {
+ try
+ {
+ Transaction tx = null;
+
+ try
+ {
+ if (tm != null)
+ {
+ tm.begin();
+ tx = tm.getTransaction();
+ }
+
+ cache.put(FQNB, KEY, VALUE2);
+
+ cache.getInvocationContext().setOptionOverrides(option);
+ cache.put(FQNA, KEY, VALUE2);
+ }
+ catch (TimeoutException te)
+ {
+ this.te = te;
+ }
+ catch (Exception e)
+ {
+ if (tx != null)
+ tx.setRollbackOnly();
+ throw e;
+ }
+ finally
+ {
+ if (tx != null)
+ {
+ tx.commit();
+ }
+ finished = true;
+ }
+ }
+ catch (Throwable t)
+ {
+ failure = t;
+ }
+ }
+ }
+
+ class LowTimeoutReader extends Thread
+ {
+ TransactionManager tm;
+ TimeoutException te;
+ Throwable failure;
+ Object value;
+ boolean finished;
+
+ LowTimeoutReader(TransactionManager tm)
+ {
+ this.tm = tm;
+ }
+
+ public void run()
+ {
+ try
+ {
+ Transaction tx = null;
+
+ try
+ {
+ if (tm != null)
+ {
+ tm.begin();
+ tx = tm.getTransaction();
+ }
+
+ cache.getInvocationContext().setOptionOverrides(option);
+ value = cache.get(FQNA, KEY);
+ }
+ catch (TimeoutException te)
+ {
+ this.te = te;
+ }
+ catch (Exception e)
+ {
+ if (tx != null)
+ tx.setRollbackOnly();
+ throw e;
+ }
+ finally
+ {
+ if (tx != null)
+ {
+ tx.commit();
+ }
+ finished = true;
+ }
+ }
+ catch (Throwable t)
+ {
+ failure = t;
+ }
+ }
+ }
+}
Property changes on:
core/trunk/src/test/java/org/jboss/cache/options/LockAcquisitionTimeoutTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native