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