Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 363   Methods: 14
NCLOC: 281   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ClusteredCacheLoaderTest.java 90.6% 95.5% 100% 95%
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.loader;
 8   
 9    import junit.framework.Assert;
 10    import org.apache.commons.logging.Log;
 11    import org.apache.commons.logging.LogFactory;
 12    import org.jboss.cache.CacheImpl;
 13    import org.jboss.cache.DefaultCacheFactory;
 14    import org.jboss.cache.Fqn;
 15    import org.jboss.cache.Region;
 16    import org.jboss.cache.config.Configuration;
 17    import org.jboss.cache.lock.TimeoutException;
 18   
 19    import java.util.ArrayList;
 20    import java.util.List;
 21    import java.util.Map;
 22    import java.util.Random;
 23    import java.util.Set;
 24    import java.util.concurrent.CopyOnWriteArraySet;
 25    import java.util.concurrent.CountDownLatch;
 26   
 27    /**
 28    * Tests ClusteredCacheLoader
 29    *
 30    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 31    */
 32    public class ClusteredCacheLoaderTest extends AbstractCacheLoaderTestBase
 33    {
 34    private static Log log = LogFactory.getLog(ClusteredCacheLoaderTest.class);
 35    private CacheImpl cache1, cache2;
 36    private CacheLoader loader1, loader2;
 37    private Fqn fqn = Fqn.fromString("/a");
 38    private String key = "key";
 39   
 40    protected boolean useRegionBasedMarshalling = false;
 41   
 42   
 43  12 protected void setUp() throws Exception
 44    {
 45  0 if (cache1 != null || cache2 != null) tearDown();
 46  12 cache1 = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 47  12 cache2 = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 48   
 49  12 cache1.getConfiguration().setClusterName("CCL-Test");
 50  12 cache1.getConfiguration().setStateRetrievalTimeout(2000);
 51  12 cache2.getConfiguration().setClusterName("CCL-Test");
 52  12 cache2.getConfiguration().setStateRetrievalTimeout(2000);
 53  12 cache1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
 54  12 cache2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
 55   
 56  12 cache1.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.ClusteredCacheLoader", "timeout=500", false, false, false));
 57  12 cache2.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.ClusteredCacheLoader", "timeout=500", false, false, false));
 58   
 59  12 cache1.getConfiguration().setUseRegionBasedMarshalling(useRegionBasedMarshalling);
 60  12 cache2.getConfiguration().setUseRegionBasedMarshalling(useRegionBasedMarshalling);
 61   
 62  12 if (useRegionBasedMarshalling)
 63    {
 64  6 cache1.getRegionManager().getRegion(fqn, Region.Type.MARSHALLING, true).registerContextClassLoader(this.getClass().getClassLoader());
 65  6 cache2.getRegionManager().getRegion(fqn, Region.Type.MARSHALLING, true).registerContextClassLoader(this.getClass().getClassLoader());
 66    }
 67   
 68  12 cache1.start();
 69  12 cache2.start();
 70   
 71  12 loader1 = cache1.getCacheLoaderManager().getCacheLoader();
 72  12 loader2 = cache2.getCacheLoaderManager().getCacheLoader();
 73    }
 74   
 75  12 protected void tearDown()
 76    {
 77  12 System.out.println("***** TEARING DOWN ***** ");
 78  12 if (cache1 != null)
 79    {
 80  12 cache1.stop();
 81  12 cache1 = null;
 82  12 loader1 = null;
 83    }
 84   
 85  12 if (cache2 != null)
 86    {
 87  12 cache2.stop();
 88  12 cache2 = null;
 89  12 loader2 = null;
 90    }
 91    }
 92   
 93  2 public void testGetKeyValue() throws Exception
 94    {
 95  2 cache1.put(fqn, key, "value");
 96   
 97  2 log.info("Finished put");
 98    // test that this has propagated.
 99  2 Assert.assertEquals("value", loader1.get(fqn).get(key));
 100  2 Assert.assertEquals("value", loader2.get(fqn).get(key));
 101   
 102  2 cache1.evict(fqn);
 103   
 104    // now cache 1 should not have this but cache 2 should.
 105    // loader1 looks at cache2 while loader2 looks at cache1
 106  2 Assert.assertEquals("value", loader1.get(fqn).get(key));
 107  2 Assert.assertNull("Expecting null", loader2.get(fqn));
 108    // // calling a get on cache1 should cause the loader to retrieve the node from cache2
 109  2 Assert.assertEquals("value", cache1.get(fqn, key));
 110    // // and now loader2 should see it
 111    // Assert.assertEquals("value", loader2.get(fqn).get(key));
 112    }
 113   
 114  2 public void testGet() throws Exception
 115    {
 116  2 cache1.put(fqn, key, "value");
 117   
 118    // test that this has propagated.
 119  2 Map map = loader1.get(fqn);
 120  2 Assert.assertTrue("Should contain key", map.containsKey(key));
 121  2 Assert.assertEquals("value", map.get(key));
 122  2 Assert.assertEquals(1, map.size());
 123   
 124  2 map = loader2.get(fqn);
 125  2 Assert.assertTrue("Should contain key", map.containsKey(key));
 126  2 Assert.assertEquals("value", map.get(key));
 127  2 Assert.assertEquals(1, map.size());
 128   
 129  2 cache1.evict(fqn);
 130   
 131    // now cache 1 should not have this but cache 2 should.
 132    // loader1 looks at cache2 while loader2 looks at cache1
 133  2 map = loader1.get(fqn);
 134  2 Assert.assertTrue(map.containsKey(key));
 135  2 Assert.assertEquals("value", map.get(key));
 136  2 Assert.assertEquals(1, map.size());
 137   
 138  2 Assert.assertNull("Expecting null", loader2.get(fqn));
 139  2 map = loader2.get(fqn);
 140  2 Assert.assertNull("Should be null", map);
 141   
 142    // calling a get on cache1 should cause the loader to retrieve the node from cache2
 143  2 Assert.assertEquals("value", cache1.get(fqn, key));
 144    // and now loader2 should see it
 145  2 map = loader2.get(fqn);
 146  2 Assert.assertTrue(map.containsKey(key));
 147  2 Assert.assertEquals("value", map.get(key));
 148  2 Assert.assertEquals(1, map.size());
 149    }
 150   
 151  2 public void testGetChildrenNames() throws Exception
 152    {
 153  2 cache1.put(fqn, key, "value");
 154  2 Fqn child1 = new Fqn(fqn, "child1");
 155  2 Fqn child2 = new Fqn(fqn, "child2");
 156  2 Fqn child3 = new Fqn(fqn, "child3");
 157  2 cache1.put(child1, key, "value");
 158  2 cache1.put(child2, key, "value");
 159  2 cache1.put(child3, key, "value");
 160   
 161    // test that this has propagated.
 162  2 Set childNames = loader1.getChildrenNames(fqn);
 163  2 Assert.assertEquals(3, childNames.size());
 164  2 childNames = loader2.getChildrenNames(fqn);
 165  2 Assert.assertEquals(3, childNames.size());
 166   
 167  2 cache1.evict(child1);
 168  2 cache1.evict(child2);
 169  2 cache1.evict(child3);
 170  2 cache1.evict(fqn);
 171   
 172    // now cache 1 should not have this but cache 2 should.
 173    // loader1 looks at cache2 while loader2 looks at cache1
 174  2 childNames = loader1.getChildrenNames(fqn);
 175  2 Assert.assertEquals(3, childNames.size());
 176   
 177  2 childNames = loader2.getChildrenNames(fqn);
 178  2 Assert.assertNull("should be null", childNames);
 179    // calling a get on cache1 should cause the loader to retrieve the node from cache2
 180  2 Assert.assertEquals("value", cache1.get(fqn, key));
 181    // load up children
 182  2 Assert.assertEquals("value", cache1.get(child1, key));
 183  2 Assert.assertEquals("value", cache1.get(child2, key));
 184  2 Assert.assertEquals("value", cache1.get(child3, key));
 185    // and now loader2 should see it
 186  2 childNames = loader2.getChildrenNames(fqn);
 187  2 Assert.assertEquals(3, childNames.size());
 188    }
 189   
 190  2 public void testExists() throws Exception
 191    {
 192  2 cache1.put(fqn, key, "value");
 193   
 194    // test that this has propagated.
 195  2 Assert.assertTrue("should exist", loader1.exists(fqn));
 196  2 Assert.assertTrue("should exist", loader2.exists(fqn));
 197   
 198  2 cache1.evict(fqn);
 199   
 200    // now cache 1 should not have this but cache 2 should.
 201    // loader1 looks at cache2 while loader2 looks at cache1
 202  2 Assert.assertTrue("should exist", loader1.exists(fqn));
 203  2 Assert.assertTrue("should not exist", !loader2.exists(fqn));
 204    // calling a get on cache1 should cause the loader to retrieve the node from cache2
 205  2 Assert.assertEquals("value", cache1.get(fqn, key));
 206    // and now loader2 should see it
 207  2 Assert.assertTrue("should exist", loader2.exists(fqn));
 208    }
 209   
 210  2 public void testCacheLoaderThreadSafety() throws Exception
 211    {
 212  2 threadSafetyTest(true);
 213    }
 214   
 215  2 public void testCacheLoaderThreadSafetyMultipleFqns() throws Exception
 216    {
 217  2 threadSafetyTest(false);
 218    }
 219   
 220  4 protected void threadSafetyTest(final boolean singleFqn) throws Exception
 221    {
 222  4 final CountDownLatch latch = new CountDownLatch(1);
 223  4 final Fqn fqn = Fqn.fromString("/a/b/c");
 224  4 final List<Fqn> fqns = new ArrayList<Fqn>(30);
 225  4 final Random r = new Random();
 226  4 if (!singleFqn)
 227    {
 228  2 for (int i = 0; i < 30; i++)
 229    {
 230  60 Fqn f = Fqn.fromString("/a/b/c/" + i);
 231  60 fqns.add(f);
 232  60 cache2.put(f, "k", "v");
 233  60 cache1.evict(f);
 234    }
 235    }
 236    else
 237    {
 238  2 cache2.put(fqn, "k", "v");
 239  2 cache1.evict(fqn);
 240    }
 241  4 final int loops = 10000;
 242  4 final Set<Exception> exceptions = new CopyOnWriteArraySet<Exception>();
 243   
 244  4 Thread evictor = new Thread("Evictor")
 245    {
 246  4 public void run()
 247    {
 248  4 try
 249    {
 250  4 latch.await();
 251  4 for (int i = 0; i < loops; i++)
 252    {
 253  30217 Fqn f = singleFqn ? fqn : fqns.get(r.nextInt(fqns.size()));
 254  30217 cache1.evict(f);
 255    }
 256    }
 257    catch (TimeoutException te)
 258    {
 259    // doesn't matter if we hit these on occasion
 260    }
 261    catch (Exception e)
 262    {
 263  0 exceptions.add(e);
 264    }
 265    }
 266    };
 267   
 268  4 evictor.start();
 269   
 270  4 Thread writer = new Thread("Writer")
 271    {
 272  4 public void run()
 273    {
 274  4 try
 275    {
 276  4 latch.await();
 277  4 for (int i = 0; i < loops; i++)
 278    {
 279  40000 Fqn f = singleFqn ? fqn : fqns.get(r.nextInt(fqns.size()));
 280  40000 cache2.put(f, "k", "v");
 281    }
 282    }
 283    catch (Exception e)
 284    {
 285  0 exceptions.add(e);
 286    }
 287    }
 288    };
 289   
 290  4 writer.start();
 291   
 292   
 293  4 Thread reader1 = new Thread("Reader-1")
 294    {
 295  4 public void run()
 296    {
 297  4 try
 298    {
 299  4 latch.await();
 300  4 for (int i = 0; i < loops; i++)
 301    {
 302  40000 loader1.get(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())));
 303    }
 304    }
 305    catch (Exception e)
 306    {
 307  0 exceptions.add(e);
 308    }
 309    }
 310    };
 311  4 reader1.start();
 312   
 313  4 Thread reader2 = new Thread("Reader-2")
 314    {
 315  4 public void run()
 316    {
 317  4 try
 318    {
 319  4 latch.await();
 320  4 for (int i = 0; i < loops; i++)
 321    {
 322  40000 loader1.getChildrenNames(singleFqn ? fqn.getParent() : fqns.get(r.nextInt(fqns.size())).getParent());
 323    }
 324    }
 325    catch (Exception e)
 326    {
 327  0 exceptions.add(e);
 328    }
 329    }
 330    };
 331  4 reader2.start();
 332   
 333  4 Thread reader3 = new Thread("Reader-3")
 334    {
 335  4 public void run()
 336    {
 337  4 try
 338    {
 339  4 latch.await();
 340  4 for (int i = 0; i < loops; i++)
 341    {
 342  40000 loader1.getChildrenNames(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())));
 343    }
 344    }
 345    catch (Exception e)
 346    {
 347  0 exceptions.add(e);
 348    }
 349    }
 350    };
 351  4 reader3.start();
 352   
 353  4 latch.countDown();
 354  4 reader1.join();
 355  4 reader2.join();
 356  4 reader3.join();
 357  4 evictor.join();
 358  4 writer.join();
 359   
 360  0 for (Exception e : exceptions) throw e;
 361    }
 362   
 363    }