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