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