Clover coverage report -
Coverage timestamp: Wed Jan 31 2007 15:38:53 EST
file stats: LOC: 271   Methods: 15
NCLOC: 213   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
LocalConcurrentTest.java 81.8% 91.3% 100% 90.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   
 8    package org.jboss.cache.pojo.region;
 9   
 10    import junit.framework.TestCase;
 11    import junit.framework.Test;
 12    import junit.framework.TestSuite;
 13    import org.jboss.cache.pojo.*;
 14    import org.jboss.cache.pojo.test.Person;
 15    import org.jboss.cache.pojo.test.Address;
 16    import org.jboss.cache.transaction.DummyTransactionManager;
 17    import org.jboss.cache.lock.UpgradeException;
 18    import org.jboss.cache.Fqn;
 19   
 20    import javax.transaction.UserTransaction;
 21    import javax.naming.Context;
 22    import javax.naming.InitialContext;
 23    import java.util.Properties;
 24    import java.util.ArrayList;
 25    import java.util.Random;
 26   
 27    /**
 28    * Local concurrent test for PojoCache. Test attach and detach under load
 29    * and concurrency.
 30    *
 31    * @version $Revision: 1.1 $
 32    * @author<a href="mailto:bwang@jboss.org">Ben Wang</a> December 2004
 33    */
 34    public class LocalConcurrentTest extends TestCase
 35    {
 36    static PojoCache cache_;
 37    Properties p_;
 38    String oldFactory_ = null;
 39    final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory";
 40    static ArrayList nodeList_;
 41    static final int depth_ = 2;
 42    static final int children_ = 2;
 43    static final int MAX_LOOP = 100;
 44    static final int SLEEP_TIME = 50;
 45    static Exception thread_ex = null;
 46    UserTransaction tx_ = null;
 47   
 48  2 public LocalConcurrentTest(String name)
 49    {
 50  2 super(name);
 51    }
 52   
 53  2 public void setUp() throws Exception
 54    {
 55  2 super.setUp();
 56  2 oldFactory_ = 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  2 p_ = new Properties();
 62  2 p_.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
 63    }
 64   
 65  2 tx_ = (UserTransaction) new InitialContext(p_).lookup("UserTransaction");
 66   
 67  2 initCaches();
 68  2 nodeList_ = nodeGen(depth_, children_);
 69   
 70  2 log("LocalConcurrentTestCase: cacheMode=TRANSIENT, one cache");
 71    }
 72   
 73  2 public void tearDown() throws Exception
 74    {
 75  2 super.tearDown();
 76  2 thread_ex = null;
 77  2 DummyTransactionManager.destroy();
 78  2 destroyCaches();
 79   
 80  2 if (oldFactory_ != null)
 81    {
 82  0 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, oldFactory_);
 83  0 oldFactory_ = null;
 84    }
 85   
 86    }
 87   
 88  2 void initCaches() throws Exception
 89    {
 90  2 boolean toStart = false;
 91  2 cache_ = PojoCacheFactory.createCache("META-INF/local-service.xml", toStart);
 92  2 cache_.start();
 93    }
 94   
 95  2 void destroyCaches() throws Exception
 96    {
 97  2 cache_.stop();
 98  2 cache_ = null;
 99    }
 100   
 101  2 public void testAll_RWLock() throws Exception
 102    {
 103  2 try
 104    {
 105  2 all();
 106    } catch (UpgradeException ue)
 107    {
 108  0 log("Upgrade exception. Can ingore for repeatable read. " + ue);
 109    } catch (Exception ex)
 110    {
 111  0 log("Exception: " + ex);
 112  0 throw ex;
 113    }
 114    }
 115   
 116  2 private void all() throws Exception
 117    {
 118  2 RunThread t1 = new RunThread(1, "t1");
 119  2 RunThread t2 = new RunThread(2, "t2");
 120  2 RunThread t3 = new RunThread(3, "t3");
 121  2 RunThread t4 = new RunThread(4, "t4");
 122   
 123  2 t1.start();
 124  2 TestingUtil.sleepThread(100);
 125  2 t2.start();
 126  2 TestingUtil.sleepThread(100);
 127  2 t3.start();
 128  2 TestingUtil.sleepThread(100);
 129  2 t4.start();
 130   
 131  2 t1.join(60000); // wait for 20 secs
 132  2 t2.join(60000); // wait for 20 secs
 133  2 t3.join(60000); // wait for 20 secs
 134  2 t4.join(60000); // wait for 20 secs
 135   
 136  2 if (thread_ex != null)
 137  0 throw thread_ex;
 138    }
 139   
 140    class RunThread extends Thread
 141    {
 142    final int seed_;
 143    Random random_;
 144    Person person_;
 145   
 146  8 public RunThread(int seed, String threadName)
 147    {
 148  8 super(threadName);
 149  8 seed_ = seed;
 150  8 random_ = new Random(seed);
 151    }
 152   
 153  800 private void createPerson()
 154    {
 155  800 person_ = new Person();
 156  800 person_.setName("Ben");
 157  800 person_.setAge(18);
 158  800 ArrayList<String> lang = new ArrayList<String>();
 159  800 lang.add("English");
 160  800 lang.add("French");
 161  800 lang.add("Mandarin");
 162  800 person_.setLanguages(lang);
 163  800 Address addr = new Address();
 164  800 addr.setZip(95123);
 165  800 addr.setStreet("Almeria");
 166  800 addr.setCity("San Jose");
 167  800 person_.setAddress(addr);
 168    }
 169   
 170  8 public void run()
 171    {
 172  8 try
 173    {
 174  8 cache_.getCache().getRegion(Fqn.fromString(Thread.currentThread().getName()), true);
 175  8 _run();
 176    }
 177    catch (Exception e)
 178    {
 179  0 thread_ex = e;
 180    }
 181    }
 182   
 183    /**
 184    */
 185  8 public void _run() throws Exception
 186    {
 187  8 for (int loop = 0; loop < MAX_LOOP; loop++)
 188    {
 189  800 createPerson(); // create a new person instance every loop.
 190  800 op1();
 191    }
 192    }
 193   
 194    // Operation 1
 195  800 private void op1()
 196    {
 197  800 int i = random_.nextInt(nodeList_.size() - 1);
 198  116 if (i == 0) return; // it is meaningless to test root
 199  684 String node = (String) nodeList_.get(i) + "/aop";
 200  684 cache_.attach(node, person_);
 201  684 TestingUtil.sleepThread(random_.nextInt(SLEEP_TIME)); // sleep for max 200 millis
 202  684 TestingUtil.sleepThread(random_.nextInt(SLEEP_TIME)); // sleep for max 200 millis
 203  684 cache_.detach(node);
 204    }
 205    }
 206   
 207    /**
 208    * Generate the tree nodes quasi-exponentially. I.e., depth is the level
 209    * of the hierarchy and children is the number of children under each node.
 210    * This strucutre is used to add, get, and remove for each node.
 211    */
 212  2 private ArrayList nodeGen(int depth, int children)
 213    {
 214  2 ArrayList<String> strList = new ArrayList<String>();
 215  2 ArrayList<String> oldList = new ArrayList<String>();
 216  2 ArrayList<String> newList = new ArrayList<String>();
 217   
 218    // Skip root node
 219  2 String str = Thread.currentThread().getName();
 220  2 oldList.add(str);
 221  2 newList.add(str);
 222  2 strList.add(str);
 223   
 224  2 while (depth > 0)
 225    {
 226    // Trying to produce node name at this depth.
 227  4 newList = new ArrayList<String>();
 228  4 for (int i = 0; i < oldList.size(); i++)
 229    {
 230  6 for (int j = 0; j < children; j++)
 231    {
 232  12 String tmp = (String) oldList.get(i);
 233  12 tmp += Integer.toString(j);
 234  12 if (depth != 1)
 235    {
 236  4 tmp += "/";
 237    }
 238   
 239  12 newList.add(tmp);
 240    }
 241    }
 242  4 strList.addAll(newList);
 243  4 oldList = newList;
 244  4 depth--;
 245    }
 246   
 247    // let's prune out root node
 248  2 for (int i = 0; i < strList.size(); i++)
 249    {
 250  14 if (strList.get(i).equals("/"))
 251    {
 252  0 strList.remove(i);
 253  0 break;
 254    }
 255    }
 256  2 log("Nodes generated: " + strList.size());
 257  2 return strList;
 258    }
 259   
 260  2 public static Test suite() throws Exception
 261    {
 262  2 return new TestSuite(org.jboss.cache.pojo.region.LocalConcurrentTest.class);
 263    }
 264   
 265  4 private static void log(String str)
 266    {
 267  4 System.out.println("Thread: " + Thread.currentThread() + ": " + str);
 268    // System.out.println(str);
 269    }
 270   
 271    }