Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 166   Methods: 6
NCLOC: 112   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IsolationLevelRepeatableReadTest.java 50% 88.9% 100% 87.3%
coverage coverage
 1    package org.jboss.cache.transaction;
 2   
 3    import junit.framework.AssertionFailedError;
 4    import junit.framework.Test;
 5    import junit.framework.TestCase;
 6    import junit.framework.TestSuite;
 7    import org.jboss.cache.CacheImpl;
 8    import org.jboss.cache.DefaultCacheFactory;
 9    import org.jboss.cache.Fqn;
 10    import org.jboss.cache.lock.IsolationLevel;
 11    import org.jboss.cache.lock.TimeoutException;
 12   
 13    import javax.transaction.NotSupportedException;
 14    import javax.transaction.SystemException;
 15    import javax.transaction.Transaction;
 16    import java.util.concurrent.CountDownLatch;
 17   
 18    /**
 19    * Tests READ_COMMITED isolation level.
 20    *
 21    * @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
 22    * @version $Id: IsolationLevelRepeatableReadTest.java,v 1.6 2007/02/07 22:06:43 genman Exp $
 23    */
 24   
 25    public class IsolationLevelRepeatableReadTest extends TestCase
 26    {
 27   
 28    private CacheImpl cache = null;
 29    private final Fqn FQN = Fqn.fromString("/a");
 30    private final String KEY = "key";
 31    private final String VALUE = "value";
 32   
 33    private volatile boolean writerFailed;
 34    private volatile AssertionFailedError writerError;
 35   
 36  1 protected void setUp() throws Exception
 37    {
 38  1 super.setUp();
 39   
 40  1 writerFailed = false;
 41  1 writerError = null;
 42   
 43  1 cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 44  1 cache.getConfiguration().setCacheMode("LOCAL");
 45  1 cache.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_READ);
 46  1 cache.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
 47  1 cache.getConfiguration().setLockAcquisitionTimeout(1000);
 48  1 cache.start();
 49    }
 50   
 51   
 52  1 protected void tearDown() throws Exception
 53    {
 54  1 super.tearDown();
 55  1 cache.stop();
 56    }
 57   
 58    /**
 59    * Test creates a cache node then starts a separate thread that removes
 60    * the node inside a tx. Test confirms that the removal cannot be seen
 61    * before the test commits.
 62    *
 63    * @throws Exception
 64    */
 65  1 public void testNodeRemoved() throws Exception
 66    {
 67  1 final CountDownLatch readerCanRead = new CountDownLatch(1);
 68  1 final CountDownLatch readerDone = new CountDownLatch(1);
 69  1 final CountDownLatch writerDone = new CountDownLatch(1);
 70   
 71  1 cache.put(FQN, KEY, VALUE);
 72  1 assertEquals(VALUE, cache.get(FQN, KEY));
 73   
 74    // start a writer thread and a transaction
 75   
 76  1 Thread writerThread = new Thread(new Runnable()
 77    {
 78  1 public void run()
 79    {
 80  1 try
 81    {
 82  1 Transaction tx = startTransaction();
 83   
 84    // change VALUE in a transaction
 85  1 cache.remove(FQN);
 86   
 87    // notify the reading thread
 88  1 readerCanRead.countDown();
 89   
 90  1 readerDone.await();
 91   
 92  1 tx.commit();
 93    }
 94    catch (AssertionFailedError e)
 95    {
 96  0 writerError = e;
 97    }
 98    catch (Throwable t)
 99    {
 100  0 t.printStackTrace();
 101  0 writerFailed = true;
 102    }
 103    finally
 104    {
 105  1 System.out.println("writer thread exits");
 106  1 readerCanRead.countDown();
 107  1 writerDone.countDown();
 108    }
 109    }
 110    }, "WRITER");
 111  1 writerThread.start();
 112   
 113  1 try
 114    {
 115    // wait until the writer thread changes the value in a transaction,
 116    // but it did not yet commit or roll back.
 117  1 readerCanRead.await();
 118   
 119    // I shouldn't be able to see the "dirty" value
 120  1 assertEquals("2nd thread cannot see uncommitted changes",
 121    VALUE, cache.get(FQN, KEY));
 122    }
 123    catch (TimeoutException t)
 124    {
 125    // ignore, this is good
 126    }
 127    finally
 128    {
 129  1 System.out.println("reader thread exits");
 130  1 readerDone.countDown();
 131    }
 132   
 133    // wait for the writer to finish
 134  1 writerDone.await();
 135   
 136  1 assertNull("Node was not removed", cache.get(FQN));
 137   
 138    // If any assertion failed, throw on the AssertionFailedError
 139   
 140  1 if (writerError != null)
 141    {
 142  0 throw writerError;
 143    }
 144   
 145  1 if (writerFailed)
 146    {
 147  0 fail("The writer thread exited incorrectly. Watch the log for previous stack traces");
 148    }
 149   
 150    }
 151   
 152  1 private Transaction startTransaction() throws SystemException, NotSupportedException
 153    {
 154  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 155  1 mgr.begin();
 156  1 return mgr.getTransaction();
 157    }
 158   
 159  1 public static Test suite()
 160    {
 161   
 162  1 return new TestSuite(IsolationLevelRepeatableReadTest.class);
 163   
 164    }
 165   
 166    }