Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 234   Methods: 7
NCLOC: 162   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IsolationLevelReadCommittedNodeCreationRollbackTest.java 12.5% 82.2% 100% 77.3%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.transaction;
 8   
 9    import junit.framework.AssertionFailedError;
 10    import junit.framework.Test;
 11    import junit.framework.TestCase;
 12    import junit.framework.TestSuite;
 13    import org.jboss.cache.CacheImpl;
 14    import org.jboss.cache.DefaultCacheFactory;
 15    import org.jboss.cache.Fqn;
 16    import org.jboss.cache.config.Configuration;
 17    import org.jboss.cache.lock.IsolationLevel;
 18    import org.jboss.cache.lock.TimeoutException;
 19   
 20    import javax.transaction.NotSupportedException;
 21    import javax.transaction.SystemException;
 22    import javax.transaction.Transaction;
 23    import java.util.concurrent.CountDownLatch;
 24    import java.util.concurrent.TimeUnit;
 25   
 26    /**
 27    * Tests READ_COMMITED isolation level.
 28    *
 29    * @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
 30    * @version $Id: IsolationLevelReadCommittedNodeCreationRollbackTest.java,v 1.7 2007/02/07 22:06:43 genman Exp $
 31    */
 32   
 33    public class IsolationLevelReadCommittedNodeCreationRollbackTest extends TestCase
 34    {
 35   
 36    private CacheImpl cache = null;
 37    private final Fqn FQN = Fqn.fromString("/a/b/c");
 38    private final String KEY = "key";
 39    private final String VALUE = "value";
 40   
 41    private volatile boolean writerFailed;
 42    private volatile boolean readerFailed;
 43    private volatile AssertionFailedError writerError;
 44    private volatile AssertionFailedError readerError;
 45   
 46  1 protected void setUp() throws Exception
 47    {
 48  1 super.setUp();
 49   
 50  1 writerFailed = false;
 51  1 readerFailed = false;
 52   
 53  1 writerError = null;
 54  1 readerError = null;
 55   
 56  1 cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 57  1 cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
 58  1 cache.getConfiguration().setIsolationLevel(IsolationLevel.READ_COMMITTED);
 59  1 cache.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
 60  1 cache.start();
 61    }
 62   
 63   
 64  1 protected void tearDown() throws Exception
 65    {
 66  1 super.tearDown();
 67   
 68  1 cache.stop();
 69  1 cache.destroy();
 70  1 cache = null;
 71    }
 72   
 73   
 74  1 public void testNodeCreationRollback() throws Exception
 75    {
 76  1 final CountDownLatch secondCanWrite = new CountDownLatch(1);
 77  1 final CountDownLatch secondCanRead = new CountDownLatch(1);
 78  1 final CountDownLatch secondDone = new CountDownLatch(1);
 79  1 final CountDownLatch firstCanRollback = new CountDownLatch(1);
 80  1 final CountDownLatch firstDone = new CountDownLatch(1);
 81   
 82  1 final Fqn PARENT = Fqn.fromString("/a");
 83   
 84    // start a first thread and a transaction
 85   
 86  1 Thread firstThread = new Thread(new Runnable()
 87    {
 88  1 public void run()
 89    {
 90  1 try
 91    {
 92  1 Transaction tx = startTransaction();
 93   
 94  1 System.out.println("Writing /a/1");
 95   
 96    // Create an empty parent node and a node with data
 97  1 Fqn a1 = new Fqn(PARENT, "1");
 98  1 cache.put(a1, KEY, VALUE);
 99   
 100    // notify the second thread it can write
 101  1 secondCanWrite.countDown();
 102   
 103    // wait until the second thread writes and allows me to rollback or until I timeout
 104  1 firstCanRollback.await(3000, TimeUnit.MILLISECONDS);
 105   
 106  1 System.out.println("rolling back");
 107   
 108  1 tx.rollback();
 109   
 110  1 assertNull("a1 empty", cache.get(a1, KEY));
 111   
 112    // notify the reading thread
 113  1 secondCanRead.countDown();
 114    }
 115    catch (AssertionFailedError e)
 116    {
 117  0 writerError = e;
 118    }
 119    catch (Throwable t)
 120    {
 121  0 t.printStackTrace();
 122  0 writerFailed = true;
 123    }
 124    finally
 125    {
 126  1 System.out.println("first thread exits");
 127  1 secondCanWrite.countDown();
 128  1 secondCanRead.countDown();
 129  1 firstDone.countDown();
 130    }
 131    }
 132    }, "FIRST");
 133  1 firstThread.start();
 134   
 135    // start a second thread; no transaction is necessary here
 136   
 137  1 Thread secondThread = new Thread(new Runnable()
 138    {
 139  1 public void run()
 140    {
 141  1 try
 142    {
 143    // wait until the first thread has created PARENT and a child
 144  1 secondCanWrite.await();
 145   
 146  1 System.out.println("writing a2");
 147   
 148    // create a second child under parent
 149  1 Fqn a2 = new Fqn(PARENT, "2");
 150  1 try
 151    {
 152  1 cache.put(a2, KEY, VALUE);
 153    }
 154    catch (TimeoutException good)
 155    {
 156    // first thread locked us out of parent
 157  0 System.out.println("Prevented from writing a2 -- " +
 158    good.getLocalizedMessage());
 159  0 return;
 160    }
 161   
 162    // let the first thread know it can rollback
 163  1 firstCanRollback.countDown();
 164   
 165    // wait until the first thread rolls back.
 166  1 secondCanRead.await();
 167   
 168    // I should still see the value I put
 169  1 assertEquals("Known issue JBCACHE-407 -- write lock not acquired on " +
 170    "creation of an empty node", VALUE, cache.get(a2, KEY));
 171    }
 172    catch (AssertionFailedError e)
 173    {
 174  1 readerError = e;
 175    }
 176    catch (Throwable t)
 177    {
 178  0 t.printStackTrace();
 179  0 readerFailed = true;
 180    }
 181    finally
 182    {
 183  1 System.out.println("second thread exits");
 184  1 firstCanRollback.countDown();
 185  1 secondDone.countDown();
 186    }
 187    }
 188    }, "SECOND");
 189  1 secondThread.start();
 190   
 191    // wait for both threads to finish
 192  1 secondDone.await();
 193  1 firstDone.await();
 194   
 195    // If any assertion failed, throw on the AssertionFailedError
 196  1 if (readerError != null)
 197    {
 198  1 throw readerError;
 199    }
 200   
 201  0 if (writerError != null)
 202    {
 203  0 throw writerError;
 204    }
 205   
 206  0 if (readerFailed)
 207    {
 208  0 fail("The second thread exited incorrectly. Watch the log for previous stack traces");
 209    }
 210   
 211  0 if (writerFailed)
 212    {
 213  0 fail("The first thread exited incorrectly. Watch the log for previous stack traces");
 214    }
 215    }
 216   
 217   
 218  1 private Transaction startTransaction() throws SystemException, NotSupportedException
 219    {
 220  1 DummyTransactionManager mgr = DummyTransactionManager.getInstance();
 221  1 mgr.begin();
 222  1 return mgr.getTransaction();
 223    }
 224   
 225   
 226  1 public static Test suite()
 227    {
 228   
 229  1 return new TestSuite(IsolationLevelReadCommittedNodeCreationRollbackTest.class);
 230   
 231    }
 232   
 233   
 234    }