Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 199   Methods: 12
NCLOC: 153   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
ConcurrentTransactionTest.java 75% 93.8% 100% 93.8%
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.optimistic;
 8   
 9    import org.jboss.cache.CacheSPI;
 10    import org.jboss.cache.Fqn;
 11    import org.jboss.cache.NodeSPI;
 12   
 13    import javax.transaction.Transaction;
 14    import javax.transaction.TransactionManager;
 15    import java.util.LinkedList;
 16    import java.util.List;
 17    import java.util.concurrent.CountDownLatch;
 18   
 19    /**
 20    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 21    */
 22    public class ConcurrentTransactionTest extends AbstractOptimisticTestCase
 23    {
 24    private CacheSPI cache;
 25   
 26  5 public ConcurrentTransactionTest(String name)
 27    {
 28  5 super(name);
 29    }
 30   
 31  5 protected void setUp()
 32    {
 33  5 try
 34    {
 35  5 cache = createCacheUnstarted();
 36  5 cache.getConfiguration().setUseRegionBasedMarshalling(true);
 37  5 cache.start();
 38    }
 39    catch (Exception e)
 40    {
 41  0 e.printStackTrace();
 42    }
 43    }
 44   
 45  5 protected void tearDown()
 46    {
 47  5 if (cache != null)
 48    {
 49  5 cache.stop();
 50  5 cache = null;
 51    }
 52    }
 53   
 54  1 public void testConcurrentTransactions() throws Exception
 55    {
 56  1 TransactionManager tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
 57  1 Fqn abcd = Fqn.fromString("/a/b/c/d");
 58  1 Fqn abce = Fqn.fromString("/a/b/c/e");
 59  1 Fqn abcf = Fqn.fromString("/a/b/c/f");
 60  1 Fqn abcg = Fqn.fromString("/a/b/c/g");
 61  1 Fqn abxy = Fqn.fromString("/a/b/x/y");
 62  1 cache.put(abcd, key, value);
 63   
 64  1 assertEquals(value, cache.get(abcd, key));
 65   
 66  1 tm.begin();
 67  1 Transaction tx = tm.getTransaction();
 68   
 69  1 cache.put(abxy, key, value);
 70  1 tm.suspend();
 71   
 72    // a number of random puts in unrelated sub nodes.
 73  1 cache.put(abcd, key, value + value);
 74  1 cache.put(abce, key, value);
 75  1 cache.put(abcf, key, value);
 76  1 cache.put(abcg, key, value);
 77   
 78  1 assertEquals(value + value, cache.get(abcd, key));
 79  1 assertEquals(value, cache.get(abce, key));
 80  1 assertEquals(value, cache.get(abcf, key));
 81  1 assertEquals(value, cache.get(abcg, key));
 82   
 83  1 tm.resume(tx);
 84  1 tx.commit();
 85   
 86  1 assertEquals(value, cache.get(abxy, key));
 87   
 88  1 NodeSPI n = cache.getRoot();
 89  1 System.out.println(n.getVersion());
 90    }
 91   
 92  1 public void testConcurrentCreationTestWithEmptyCache() throws Exception
 93    {
 94  1 doConcurrentCreationTest(false);
 95    }
 96   
 97  1 public void testConcurrentCreationTestWithEmptyCacheActivated() throws Exception
 98    {
 99  1 cache.put(Fqn.fromString("/parent"), null);
 100  1 cache.getRegion(Fqn.fromString("/parent"), true).activate();
 101  1 assertNotNull(cache.peek(Fqn.fromString("/parent"), false));
 102  1 doConcurrentCreationTest(false);
 103    }
 104   
 105  1 public void testConcurrentCreationTestWithPopulatedCache() throws Exception
 106    {
 107  1 doConcurrentCreationTest(true);
 108    }
 109   
 110  1 public void testConcurrentReadAndRemove() throws Exception
 111    {
 112  1 final List exceptions = new LinkedList();
 113  1 final CountDownLatch readerLatch = new CountDownLatch(1);
 114  1 final CountDownLatch readerFinishedLatch = new CountDownLatch(1);
 115  1 final Fqn fqn = Fqn.fromString("/parent/child");
 116   
 117  1 cache.put(fqn, "k", "v");
 118   
 119    class Reader extends Thread
 120    {
 121  1 public void run()
 122    {
 123  1 try
 124    {
 125  1 cache.getTransactionManager().begin();
 126  1 cache.get(fqn, "k"); // read
 127  1 readerFinishedLatch.countDown();
 128  1 readerLatch.await(); // wait
 129  1 cache.getTransactionManager().commit();
 130    }
 131    catch (Exception e)
 132    {
 133  0 e.printStackTrace();
 134  0 exceptions.add(e);
 135   
 136    }
 137    }
 138    }
 139   
 140  1 Thread reader = new Reader();
 141   
 142  1 reader.start();
 143  1 readerFinishedLatch.await();
 144  1 cache.removeNode(fqn.getParent());
 145  1 assertNull(cache.peek(fqn.getParent(), false));
 146  1 readerLatch.countDown();
 147  1 reader.join();
 148   
 149  1 assertTrue("Should not have caught any exceptions!!", exceptions.isEmpty());
 150    }
 151   
 152   
 153  3 private void doConcurrentCreationTest(boolean prepopulateParent) throws Exception
 154    {
 155  1 if (prepopulateParent) cache.put(Fqn.fromString("/parent/dummy"), "k", "v");
 156   
 157  3 final List exceptions = new LinkedList();
 158  3 final CountDownLatch latch = new CountDownLatch(1);
 159   
 160    class ConcurrentCreator extends Thread
 161    {
 162    private String name;
 163   
 164  6 public ConcurrentCreator(String name)
 165    {
 166  6 this.name = name;
 167    }
 168   
 169  6 public void run()
 170    {
 171  6 try
 172    {
 173  6 cache.getTransactionManager().begin();
 174  6 cache.put(Fqn.fromString("/parent/child" + name), "key", "value");
 175  6 latch.await();
 176  6 cache.getTransactionManager().commit();
 177    }
 178    catch (Exception e)
 179    {
 180  0 e.printStackTrace();
 181  0 exceptions.add(e);
 182    }
 183    }
 184    }
 185   
 186  3 Thread one = new ConcurrentCreator("one");
 187  3 Thread two = new ConcurrentCreator("two");
 188   
 189  3 one.start();
 190  3 two.start();
 191   
 192  3 latch.countDown();
 193   
 194  3 one.join();
 195  3 two.join();
 196   
 197  3 assertTrue("Should not have caught any exceptions!!", exceptions.isEmpty());
 198    }
 199    }