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