Clover coverage report -
Coverage timestamp: Wed Jan 31 2007 15:38:53 EST
file stats: LOC: 382   Methods: 24
NCLOC: 301   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
SingletonStoreCacheLoaderTest.java 87.5% 98.3% 95.8% 97.5%
coverage coverage
 1    /*
 2    * JBoss, the OpenSource J2EE webOS
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.loader;
 8   
 9    import org.apache.commons.logging.Log;
 10    import org.apache.commons.logging.LogFactory;
 11    import org.jboss.cache.CacheImpl;
 12    import org.jboss.cache.CacheSPI;
 13    import org.jboss.cache.DefaultCacheFactory;
 14    import org.jboss.cache.Fqn;
 15    import org.jboss.cache.config.CacheLoaderConfig;
 16    import org.jboss.cache.config.Configuration;
 17    import org.jboss.cache.factories.XmlConfigurationParser;
 18    import org.jboss.cache.xml.XmlHelper;
 19    import org.w3c.dom.Element;
 20   
 21    /**
 22    * Unit test class for SingletonStoreCacheLoader
 23    *
 24    * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
 25    */
 26    public class SingletonStoreCacheLoaderTest extends AbstractCacheLoaderTestBase
 27    {
 28    private CacheSPI cache1, cache2, cache3;
 29    private static final Log log = LogFactory.getLog(SingletonStoreCacheLoaderTest.class);
 30   
 31  3 protected void setUp() throws Exception
 32    {
 33  3 log.info("*** test:" + getName() + " ***");
 34   
 35  3 cache1 = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 36  3 cache2 = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 37  3 cache3 = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 38   
 39  3 cache1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
 40  3 cache2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
 41  3 cache3.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
 42    }
 43   
 44  1 public void testPutCacheLoaderWithNoPush() throws Exception
 45    {
 46  1 initSingletonNonPushCache(cache1);
 47  1 initSingletonNonPushCache(cache2);
 48  1 initSingletonNonPushCache(cache3);
 49   
 50  1 createCaches();
 51  1 statCaches();
 52   
 53  1 cache1.put(fqn("/test1"), "key", "value");
 54  1 cache2.put(fqn("/test2"), "key", "value");
 55  1 cache3.put(fqn("/test3"), "key", "value");
 56   
 57  1 CacheLoader cl1 = getDelegatingCacheLoader(cache1);
 58  1 CacheLoader cl2 = getDelegatingCacheLoader(cache2);
 59  1 CacheLoader cl3 = getDelegatingCacheLoader(cache3);
 60   
 61  1 assertTrue("/test1 should have been entered in cl1", cl1.exists(fqn("/test1")));
 62  1 assertTrue("/test2 should have been entered in cl1", cl1.exists(fqn("/test2")));
 63  1 assertTrue("/test3 should have been entered in cl1", cl1.exists(fqn("/test3")));
 64   
 65  1 assertFalse("/test1 should not be in cl2", cl2.exists(fqn("/test1")));
 66  1 assertFalse("/test2 should not be in cl2", cl2.exists(fqn("/test2")));
 67  1 assertFalse("/test3 should not be in cl2", cl2.exists(fqn("/test3")));
 68   
 69  1 assertFalse("/test1 should not be in cl3", cl3.exists(fqn("/test1")));
 70  1 assertFalse("/test2 should not be in cl3", cl3.exists(fqn("/test2")));
 71  1 assertFalse("/test3 should not be in cl3", cl3.exists(fqn("/test3")));
 72   
 73  1 stopCache1();
 74   
 75  1 cache2.put(fqn("/test4"), "key", "value");
 76  1 cache3.put(fqn("/test5"), "key", "value");
 77   
 78  1 assertTrue("/test4 should have been entered in cl2", cl2.exists(fqn("/test4")));
 79  1 assertTrue("/test5 should have been entered in cl2", cl2.exists(fqn("/test5")));
 80   
 81  1 assertFalse("/test4 should not be in cl3", cl3.exists(fqn("/test4")));
 82  1 assertFalse("/test5 should not be in cl3", cl3.exists(fqn("/test5")));
 83   
 84  1 stopCache2();
 85   
 86  1 cache3.put(fqn("/test6"), "key", "value");
 87  1 assertTrue("/test5 should have been entered in cl3", cl3.exists(Fqn.fromString("/test6")));
 88    }
 89   
 90  1 public void testPutCacheLoaderWithPush() throws Exception
 91    {
 92  1 initSingletonWithPushCache(cache1);
 93  1 initSingletonWithPushCache(cache2);
 94  1 initSingletonWithPushCache(cache3);
 95   
 96  1 createCaches();
 97  1 statCaches();
 98   
 99  1 cache1.put(fqn("/a"), "a-key", "a-value");
 100  1 cache1.put(fqn("/a"), "aa-key", "aa-value");
 101  1 cache1.put(fqn("/a/b"), "b-key", "b-value");
 102  1 cache1.put(fqn("/a/b"), "bb-key", "bb-value");
 103  1 cache1.put(fqn("/a/b/c"), "c-key", "c-value");
 104  1 cache1.put(fqn("/a/b/d"), "d-key", "d-value");
 105  1 cache1.put(fqn("/e"), "e-key", "e-value");
 106  1 cache1.put(fqn("/e/f/g"), "g-key", "g-value");
 107   
 108  1 CacheLoader cl1 = getDelegatingCacheLoader(cache1);
 109  1 CacheLoader cl2 = getDelegatingCacheLoader(cache2);
 110  1 CacheLoader cl3 = getDelegatingCacheLoader(cache3);
 111   
 112  1 assertTrue(cl1.get(fqn("/a")).containsKey("a-key"));
 113  1 assertTrue(cl1.get(fqn("/a")).containsKey("aa-key"));
 114  1 assertTrue(cl1.get(fqn("/a/b")).containsKey("b-key"));
 115  1 assertTrue(cl1.get(fqn("/a/b")).containsKey("bb-key"));
 116  1 assertTrue(cl1.get(fqn("/a/b/c")).containsKey("c-key"));
 117  1 assertTrue(cl1.get(fqn("/a/b/d")).containsKey("d-key"));
 118  1 assertTrue(cl1.get(fqn("/e")).containsKey("e-key"));
 119  1 assertTrue(cl1.get(fqn("/e/f/g")).containsKey("g-key"));
 120   
 121  1 assertFalse(cl2.exists(fqn("/a")));
 122  1 assertFalse(cl2.exists(fqn("/a")));
 123  1 assertFalse(cl2.exists(fqn("/a/b")));
 124  1 assertFalse(cl2.exists(fqn("/a/b")));
 125  1 assertFalse(cl2.exists(fqn("/a/b/c")));
 126  1 assertFalse(cl2.exists(fqn("/a/b/d")));
 127  1 assertFalse(cl2.exists(fqn("/e")));
 128  1 assertFalse(cl2.exists(fqn("/e/f/g")));
 129   
 130  1 assertFalse(cl3.exists(fqn("/a")));
 131  1 assertFalse(cl3.exists(fqn("/a")));
 132  1 assertFalse(cl3.exists(fqn("/a/b")));
 133  1 assertFalse(cl3.exists(fqn("/a/b")));
 134  1 assertFalse(cl3.exists(fqn("/a/b/c")));
 135  1 assertFalse(cl3.exists(fqn("/a/b/d")));
 136  1 assertFalse(cl3.exists(fqn("/e")));
 137  1 assertFalse(cl3.exists(fqn("/e/f/g")));
 138   
 139  1 stopCache1();
 140  1 Thread.sleep(1000);
 141   
 142  1 SingletonStoreCacheLoader scl2 = (SingletonStoreCacheLoader) cache2.getCacheLoaderManager().getCacheLoader();
 143  1 joinPushThread(scl2.getPushStateThread());
 144   
 145  1 assertTrue(cl2.get(fqn("/a")).containsKey("a-key"));
 146  1 assertTrue(cl2.get(fqn("/a")).containsKey("aa-key"));
 147  1 assertTrue(cl2.get(fqn("/a/b")).containsKey("b-key"));
 148  1 assertTrue(cl2.get(fqn("/a/b")).containsKey("bb-key"));
 149  1 assertTrue(cl2.get(fqn("/a/b/c")).containsKey("c-key"));
 150  1 assertTrue(cl2.get(fqn("/a/b/d")).containsKey("d-key"));
 151  1 assertTrue(cl2.get(fqn("/e")).containsKey("e-key"));
 152  1 assertTrue(cl2.get(fqn("/e/f/g")).containsKey("g-key"));
 153   
 154  1 cache2.put(fqn("/e/f/h"), "h-key", "h-value");
 155  1 cache3.put(fqn("/i"), "i-key", "i-value");
 156   
 157  1 assertTrue(cl2.get(fqn("/e/f/h")).containsKey("h-key"));
 158  1 assertTrue(cl2.get(fqn("/i")).containsKey("i-key"));
 159   
 160  1 assertFalse(cl3.exists(fqn("/a")));
 161  1 assertFalse(cl3.exists(fqn("/a")));
 162  1 assertFalse(cl3.exists(fqn("/a/b")));
 163  1 assertFalse(cl3.exists(fqn("/a/b")));
 164  1 assertFalse(cl3.exists(fqn("/a/b/c")));
 165  1 assertFalse(cl3.exists(fqn("/a/b/d")));
 166  1 assertFalse(cl3.exists(fqn("/e")));
 167  1 assertFalse(cl3.exists(fqn("/e/f/g")));
 168  1 assertFalse(cl3.exists(fqn("/e/f/h")));
 169  1 assertFalse(cl3.exists(fqn("/i")));
 170   
 171  1 stopCache2();
 172  1 Thread.sleep(1000);
 173   
 174  1 SingletonStoreCacheLoader scl3 = (SingletonStoreCacheLoader) cache3.getCacheLoaderManager().getCacheLoader();
 175  1 joinPushThread(scl3.getPushStateThread());
 176   
 177  1 assertTrue(cl3.get(fqn("/a")).containsKey("a-key"));
 178  1 assertTrue(cl3.get(fqn("/a")).containsKey("aa-key"));
 179  1 assertTrue(cl3.get(fqn("/a/b")).containsKey("b-key"));
 180  1 assertTrue(cl3.get(fqn("/a/b")).containsKey("bb-key"));
 181  1 assertTrue(cl3.get(fqn("/a/b/c")).containsKey("c-key"));
 182  1 assertTrue(cl3.get(fqn("/a/b/d")).containsKey("d-key"));
 183  1 assertTrue(cl3.get(fqn("/e")).containsKey("e-key"));
 184  1 assertTrue(cl3.get(fqn("/e/f/g")).containsKey("g-key"));
 185  1 assertTrue(cl3.get(fqn("/e/f/h")).containsKey("h-key"));
 186  1 assertTrue(cl3.get(fqn("/i")).containsKey("i-key"));
 187   
 188  1 cache3.put(fqn("/a"), "aaa-key", "aaa-value");
 189   
 190  1 assertTrue(cl3.get(fqn("/a")).containsKey("aaa-key"));
 191   
 192  1 stopCache3();
 193    }
 194   
 195  1 public void testAvoidConcurrentStatePush() throws InterruptedException
 196    {
 197  1 MockSingletonStoreCacheLoader mscl = new MockSingletonStoreCacheLoader(null, true, 3000);
 198   
 199  1 Thread t1 = new Thread(createActiveStatusChanger(mscl));
 200  1 Thread t2 = new Thread(createActiveStatusChanger(mscl));
 201   
 202  1 t1.start();
 203  1 Thread.sleep(1000);
 204  1 t2.start();
 205   
 206  1 t1.join();
 207  1 t2.join();
 208   
 209  1 assertEquals(1, mscl.getNumberCreatedThreads());
 210    }
 211   
 212  2 private void createCaches() throws Exception
 213    {
 214  2 cache1.create();
 215  2 cache2.create();
 216  2 cache3.create();
 217    }
 218   
 219  2 private void statCaches() throws Exception
 220    {
 221  2 cache1.start();
 222  2 cache2.start();
 223  2 cache3.start();
 224    }
 225   
 226  2 private void joinPushThread(Thread pushThread) throws InterruptedException
 227    {
 228  2 if (pushThread != null)
 229    {
 230  2 pushThread.join();
 231    }
 232    }
 233   
 234  2 private Runnable createActiveStatusChanger(SingletonStoreCacheLoader mscl)
 235    {
 236  2 return new ActiveStatusModifier(mscl);
 237    }
 238   
 239  6 protected CacheLoaderConfig getSingletonStoreCacheLoaderConfig(String cacheloaderClass, boolean singleton,
 240    boolean pushStateWhenCoordinator) throws Exception
 241    {
 242  6 String xml = "<config>\n" +
 243    "<passivation>false</passivation>\n" +
 244    "<preload></preload>\n" +
 245    "<cacheloader>\n" +
 246    "<class>" + cacheloaderClass + "</class>\n" +
 247    "<properties></properties>\n" +
 248    // "<async>false</async>\n" +
 249    // "<shared>false</shared>\n" +
 250    // "<fetchPersistentState>false</fetchPersistentState>\n" +
 251    // "<purgeOnStartup>false</purgeOnStartup>\n" +
 252    "<singletonStore pushStateWhenCoordinator=\"" + pushStateWhenCoordinator + "\">" + singleton + "</singletonStore>\n" +
 253    "</cacheloader>\n" +
 254    "</config>";
 255  6 Element element = XmlHelper.stringToElement(xml);
 256  6 return XmlConfigurationParser.parseCacheLoaderConfig(element);
 257    }
 258   
 259  3 private void initSingletonNonPushCache(CacheSPI cache) throws Exception
 260    {
 261  3 cache.getConfiguration().setCacheLoaderConfig(getSingletonStoreCacheLoaderConfig(
 262    DummyInMemoryCacheLoader.class.getName(), true, false));
 263    }
 264   
 265  3 private void initSingletonWithPushCache(CacheSPI cache) throws Exception
 266    {
 267  3 cache.getConfiguration().setCacheLoaderConfig(getSingletonStoreCacheLoaderConfig(
 268    DummyInMemoryCacheLoader.class.getName(), true, true));
 269    }
 270   
 271  6 private CacheLoader getDelegatingCacheLoader(CacheSPI cache)
 272    {
 273  6 AbstractDelegatingCacheLoader acl = (AbstractDelegatingCacheLoader) cache.getCacheLoaderManager().getCacheLoader();
 274  6 return acl.getCacheLoader();
 275    }
 276   
 277  85 private Fqn fqn(String fqn)
 278    {
 279  85 return Fqn.fromString(fqn);
 280    }
 281   
 282  5 private void stopCache1()
 283    {
 284  5 if (cache1 != null)
 285    {
 286  3 cache1.stop();
 287    }
 288   
 289  5 cache1 = null;
 290    }
 291   
 292  5 private void stopCache2()
 293    {
 294  5 if (cache2 != null)
 295    {
 296  3 cache2.stop();
 297    }
 298   
 299  5 cache2 = null;
 300    }
 301   
 302  4 private void stopCache3()
 303    {
 304  4 if (cache3 != null)
 305    {
 306  3 cache3.stop();
 307    }
 308   
 309  4 cache3 = null;
 310    }
 311   
 312  3 protected void tearDown()
 313    {
 314  3 stopCache1();
 315  3 stopCache2();
 316  3 stopCache3();
 317    }
 318   
 319    class MockSingletonStoreCacheLoader extends SingletonStoreCacheLoader
 320    {
 321    private int numberCreatedThreads = 0;
 322    private long busyPeriod;
 323   
 324  1 public MockSingletonStoreCacheLoader(CacheLoader loader, boolean pushConfiguration, long busyPeriodTime)
 325    {
 326  1 super(loader, pushConfiguration);
 327  1 busyPeriod = busyPeriodTime;
 328    }
 329   
 330  1 public int getNumberCreatedThreads()
 331    {
 332  1 return numberCreatedThreads;
 333    }
 334   
 335  0 public void setNumberCreatedThreads(int numberCreatedThreads)
 336    {
 337  0 this.numberCreatedThreads = numberCreatedThreads;
 338    }
 339   
 340  1 protected Thread createPushStateThread()
 341    {
 342  1 return new Thread(new Runnable()
 343    {
 344  1 public void run()
 345    {
 346  1 numberCreatedThreads++;
 347  1 try
 348    {
 349  1 Thread.sleep(busyPeriod);
 350    }
 351    catch (InterruptedException e)
 352    {
 353  0 fail("ActiveStatusModifier interrupted");
 354    }
 355    }
 356    });
 357    }
 358    }
 359   
 360    class ActiveStatusModifier implements Runnable
 361    {
 362    private SingletonStoreCacheLoader scl;
 363   
 364  2 public ActiveStatusModifier(SingletonStoreCacheLoader singleton)
 365    {
 366  2 scl = singleton;
 367    }
 368   
 369  2 public void run()
 370    {
 371  2 scl.activeStatusChanged(true);
 372  2 try
 373    {
 374  2 scl.getPushStateThread().join();
 375    }
 376    catch (InterruptedException e)
 377    {
 378  0 throw new RuntimeException(e);
 379    }
 380    }
 381    }
 382    }