Clover coverage report -
Coverage timestamp: Wed Jan 31 2007 15:38:53 EST
file stats: LOC: 257   Methods: 14
NCLOC: 213   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
ConcurrentTransactionalTest.java 37.5% 68.2% 85.7% 64.3%
coverage coverage
 1    /*
 2    *
 3    * JBoss, the OpenSource J2EE webOS
 4    *
 5    * Distributable under LGPL license.
 6    * See terms of license at gnu.org.
 7    */
 8    package org.jboss.cache.transaction;
 9   
 10    import junit.framework.Test;
 11    import junit.framework.TestCase;
 12    import junit.framework.TestSuite;
 13    import org.apache.commons.logging.Log;
 14    import org.apache.commons.logging.LogFactory;
 15    import org.jboss.cache.CacheImpl;
 16    import org.jboss.cache.DefaultCacheFactory;
 17    import org.jboss.cache.config.Configuration;
 18    import org.jboss.cache.factories.XmlConfigurationParser;
 19    import org.jboss.cache.lock.IsolationLevel;
 20   
 21    import javax.naming.Context;
 22    import javax.naming.InitialContext;
 23    import javax.naming.NamingException;
 24    import javax.transaction.UserTransaction;
 25    import java.util.Collections;
 26    import java.util.Iterator;
 27    import java.util.LinkedList;
 28    import java.util.List;
 29    import java.util.Properties;
 30    import java.util.Set;
 31   
 32    /**
 33    * Unit test for local CacheImpl. Use locking and multiple threads to test
 34    * concurrent access to the tree.
 35    *
 36    * @version $Id: ConcurrentTransactionalTest.java,v 1.8 2007/01/11 13:49:06 msurtani Exp $
 37    */
 38    public class ConcurrentTransactionalTest extends TestCase
 39    {
 40    CacheImpl cache;
 41    private Log logger_ = LogFactory.getLog(ConcurrentTransactionalTest.class);
 42    static Throwable thread_ex = null;
 43    final int NUM = 10000;
 44    static Properties p = null;
 45    String old_factory = null;
 46    final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory";
 47   
 48  2 public ConcurrentTransactionalTest(String name)
 49    {
 50  2 super(name);
 51    }
 52   
 53  2 public void setUp() throws Exception
 54    {
 55  2 super.setUp();
 56  2 old_factory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
 57  2 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
 58  2 DummyTransactionManager.getInstance();
 59  2 if (p == null)
 60    {
 61  1 p = new Properties();
 62  1 p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
 63    }
 64    }
 65   
 66  2 private void createCache(IsolationLevel level) throws Exception
 67    {
 68  2 cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 69  2 cache.setConfiguration(new XmlConfigurationParser().parseFile("META-INF/local-service.xml"));
 70   
 71  2 cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
 72  2 cache.getConfiguration().setIsolationLevel(level);
 73  2 cache.start();
 74  2 cache.put("/a/b/c", null);
 75    }
 76   
 77  4 private UserTransaction getTransaction()
 78    {
 79  4 UserTransaction tx = null;
 80  4 try
 81    {
 82  4 tx = (UserTransaction) new InitialContext(p).lookup("UserTransaction");
 83    }
 84    catch (NamingException e)
 85    {
 86  0 e.printStackTrace();
 87    }
 88   
 89  4 if (tx == null)
 90    {
 91  0 throw new RuntimeException("Tx is null");
 92    }
 93   
 94  4 return tx;
 95    }
 96   
 97  2 public void tearDown() throws Exception
 98    {
 99  2 super.tearDown();
 100  2 cache.stop();
 101  2 thread_ex = null;
 102  2 DummyTransactionManager.destroy();
 103  2 if (old_factory != null)
 104    {
 105  1 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory);
 106  1 old_factory = null;
 107    }
 108    }
 109   
 110  1 public void testConcurrentAccessWithRWLock() throws Throwable
 111    {
 112  1 createCache(IsolationLevel.REPEATABLE_READ);
 113  1 work_();
 114    }
 115   
 116  1 public void testConcurrentAccessWithExclusiveLock() throws Throwable
 117    {
 118  1 createCache(IsolationLevel.SERIALIZABLE);
 119  1 work_();
 120    }
 121   
 122  2 private void work_() throws Throwable
 123    {
 124  2 Updater one, two;
 125  2 try
 126    {
 127  2 one = new Updater("Thread one");
 128  2 two = new Updater("Thread two");
 129  2 long current = System.currentTimeMillis();
 130  2 one.start();
 131  2 two.start();
 132  2 one.join();
 133  2 two.join();
 134  2 if (thread_ex != null)
 135    {
 136  0 throw thread_ex;
 137    }
 138   
 139  2 long now = System.currentTimeMillis();
 140  2 log("*** Time elapsed: " + (now - current));
 141   
 142  2 System.out.println("cache content: " + cache.toString());
 143  2 Set keys = cache.getKeys("/a/b/c");
 144  2 System.out.println("number of keys=" + keys.size());
 145   
 146  2 if (keys.size() != NUM)
 147    {
 148  0 scanForNullValues(keys);
 149   
 150  0 try
 151    {
 152  0 System.out.println("size=" + keys.size());
 153  0 List l = new LinkedList(keys);
 154  0 Collections.sort(l);
 155  0 System.out.println("keys: " + l);
 156  0 for (int i = 0; i < NUM; i++)
 157    {
 158  0 if (!l.contains(new Integer(i)))
 159    {
 160  0 System.out.println("missing: " + i);
 161    }
 162    }
 163   
 164  0 LinkedList duplicates = new LinkedList();
 165  0 for (Iterator it = l.iterator(); it.hasNext();)
 166    {
 167  0 Integer integer = (Integer) it.next();
 168  0 if (duplicates.contains(integer))
 169    {
 170  0 System.out.println(integer + " is a duplicate");
 171    }
 172    else
 173    {
 174  0 duplicates.add(integer);
 175    }
 176    }
 177    }
 178    catch (Exception e1)
 179    {
 180  0 e1.printStackTrace();
 181    }
 182    }
 183   
 184  2 assertEquals(NUM, keys.size());
 185  2 log("lock info:\n" + cache.printLockInfo());
 186   
 187    }
 188    catch (Exception e)
 189    {
 190  0 e.printStackTrace();
 191  0 fail(e.toString());
 192    }
 193    }
 194   
 195  0 private void scanForNullValues(Set keys)
 196    {
 197  0 for (Iterator it = keys.iterator(); it.hasNext();)
 198    {
 199  0 Object o = it.next();
 200  0 if (o == null)
 201    {
 202  0 System.err.println("found a null value in keys");
 203    }
 204    }
 205    }
 206   
 207  40008 void log(String msg)
 208    {
 209  40008 logger_.debug(" [" + Thread.currentThread() + "]: " + msg);
 210    }
 211   
 212   
 213    class Updater extends Thread
 214    {
 215    String val = null;
 216    UserTransaction tx;
 217   
 218  4 Updater(String name)
 219    {
 220  4 this.val = name;
 221    }
 222   
 223  4 public void run()
 224    {
 225  4 try
 226    {
 227  4 log("adding data");
 228  4 tx = getTransaction();
 229  4 for (int i = 0; i < NUM; i++)
 230    {
 231  40000 log("adding data i=" + i);
 232  40000 tx.begin();
 233  40000 cache.put("/a/b/c", i, val);
 234  40000 tx.commit();
 235  40000 yield();
 236    }
 237    }
 238    catch (Throwable t)
 239    {
 240  0 t.printStackTrace();
 241  0 thread_ex = t;
 242    }
 243    }
 244    }
 245   
 246  1 public static Test suite()
 247    {
 248  1 return new TestSuite(ConcurrentTransactionalTest.class);
 249    }
 250   
 251  0 public static void main(String[] args)
 252    {
 253  0 junit.textui.TestRunner.run(suite());
 254    }
 255   
 256   
 257    }