Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 2,230   Methods: 87
NCLOC: 1,760   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
CacheLoaderTestsBase.java 84.6% 97.3% 98.9% 96.9%
coverage coverage
 1    package org.jboss.cache.loader;
 2   
 3    import org.apache.commons.logging.Log;
 4    import org.apache.commons.logging.LogFactory;
 5    import org.jboss.cache.CacheException;
 6    import org.jboss.cache.CacheImpl;
 7    import org.jboss.cache.DefaultCacheFactory;
 8    import org.jboss.cache.Fqn;
 9    import org.jboss.cache.Modification;
 10    import org.jboss.cache.Node;
 11    import org.jboss.cache.buddyreplication.BuddyManager;
 12    import org.jboss.cache.config.Configuration;
 13    import org.jboss.cache.statetransfer.StateTransferManager;
 14    import org.jboss.cache.transaction.DummyTransactionManager;
 15    import org.jboss.util.stream.MarshalledValueInputStream;
 16    import org.jboss.util.stream.MarshalledValueOutputStream;
 17   
 18    import javax.transaction.Transaction;
 19    import javax.transaction.TransactionManager;
 20    import java.io.ByteArrayInputStream;
 21    import java.io.ByteArrayOutputStream;
 22    import java.io.File;
 23    import java.io.Serializable;
 24    import java.util.ArrayList;
 25    import java.util.HashMap;
 26    import java.util.List;
 27    import java.util.Map;
 28    import java.util.Random;
 29    import java.util.Set;
 30    import java.util.concurrent.CopyOnWriteArraySet;
 31    import java.util.concurrent.CountDownLatch;
 32   
 33    /**
 34    * Commons tests for all CacheLoaders
 35    *
 36    * @author Bela Ban
 37    * @version $Id: CacheLoaderTestsBase.java,v 1.53 2007/06/19 19:45:26 msurtani Exp $
 38    */
 39    abstract public class CacheLoaderTestsBase extends AbstractCacheLoaderTestBase
 40    {
 41   
 42    private static final Log log = LogFactory.getLog(CacheLoaderTestsBase.class);
 43    CacheImpl cache;
 44    CacheLoader loader = null;
 45    private Transaction tx = null;
 46    static final Fqn FQN = new Fqn("key");
 47    private static final Fqn SUBTREE_FQN = new Fqn(FQN, "subtree");
 48   
 49    private static final Fqn BUDDY_BASE = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, "test");
 50   
 51    private static final Fqn BUDDY_PLUS_FQN = new Fqn(BUDDY_BASE, FQN);
 52   
 53    private static final Fqn BUDDY_PLUS_SUBTREE_FQN = new Fqn(BUDDY_BASE, SUBTREE_FQN);
 54   
 55   
 56  126 public CacheLoaderTestsBase(String name)
 57    {
 58  126 super(name);
 59    }
 60   
 61  493 public CacheLoaderTestsBase()
 62    {
 63  493 super();
 64    }
 65   
 66  619 protected void setUp() throws Exception
 67    {
 68  619 super.setUp();
 69  619 log.debug("\nTest " + getName() + "\n");
 70  619 cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 71  619 Configuration c = new Configuration();
 72  619 cache.setConfiguration(c);
 73  619 c.setCacheMode(Configuration.CacheMode.LOCAL);
 74  619 c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
 75  619 configureCache();
 76  619 cache.start();
 77  619 loader = cache.getCacheLoaderManager().getCacheLoader();
 78    }
 79   
 80    abstract protected void configureCache() throws Exception;
 81   
 82   
 83  619 protected void tearDown() throws Exception
 84    {
 85  619 super.tearDown();
 86  619 if (tx != null)
 87    {
 88  60 try
 89    {
 90  60 tx.commit();
 91    }
 92    catch (Throwable e)
 93    {
 94  0 e.printStackTrace();
 95    }
 96    }
 97  619 cleanup();
 98  619 try
 99    {
 100  619 cache.remove("/");
 101    }
 102    catch (Exception e)
 103    {
 104    // do nothing
 105    }
 106   
 107  619 try
 108    {
 109  619 loader.remove(Fqn.ROOT);
 110    }
 111    catch (Exception e)
 112    {
 113    // do nothing
 114    }
 115   
 116  619 cache.stop();
 117  619 cache.destroy();
 118    }
 119   
 120  619 protected void cleanup()
 121    {
 122    // to be overridden
 123    }
 124   
 125  1593 protected void addDelay()
 126    {
 127    // returns immediately in this case. Subclasses may override where a delay is needed.
 128    }
 129   
 130  0 private void clean(File dir)
 131    {
 132  0 File[] files = dir.listFiles();
 133  0 if (files != null)
 134    {
 135  0 for (File file : files)
 136    {
 137  0 if (file.isDirectory())
 138    {
 139  0 clean(file);
 140    }
 141    else
 142    {
 143  0 if (!file.delete()) file.deleteOnExit();
 144    }
 145    }
 146    }
 147    }
 148   
 149   
 150  10 public void testPrint() throws CacheException
 151    {
 152  10 final Fqn NODE = Fqn.fromString("/test");
 153  10 final String KEY = "key";
 154  10 cache.put(NODE, KEY, 10);
 155  10 cache.evict(NODE);
 156  10 addDelay();
 157  10 String ret = cache.print(NODE);
 158  10 assertNotNull(ret);
 159    }
 160   
 161  10 public void testPut() throws CacheException
 162    {
 163  10 final String NODE = "/test";
 164  10 final String KEY = "key";
 165  10 Object retval;
 166  10 cache.remove(NODE);
 167  10 addDelay();
 168  10 retval = cache.put(NODE, KEY, 10);
 169  10 assertEquals(null, retval);
 170  10 retval = cache.put(NODE, KEY, 20);
 171  10 addDelay();
 172  10 assertEquals(10, retval);
 173  10 cache.evict(Fqn.fromString(NODE));// evicts from memory, but *not* from store
 174  10 addDelay();
 175  10 log.debug("put 30, expect 20 back");
 176  10 retval = cache.put(NODE, KEY, 30);
 177  10 assertEquals(20, retval);
 178    }
 179   
 180  10 public void testPut2() throws Exception
 181    {
 182  10 final String NODE = "/a/b/c";
 183  10 assertNull(loader.get(Fqn.fromString(NODE)));
 184  10 final String KEY = "key";
 185  10 Object retval;
 186  10 cache.remove(NODE);
 187  10 assertNull(loader.get(Fqn.fromString(NODE)));
 188  10 addDelay();
 189  10 retval = cache.put(NODE, KEY, 10);
 190  10 assertNull(retval);
 191  10 addDelay();
 192  10 retval = cache.put(NODE, KEY, 20);
 193  10 assertEquals(10, retval);
 194  10 cache.evict(Fqn.fromString(NODE));// evicts from memory, but *not* from store
 195  10 cache.evict(Fqn.fromString("/a/b"));
 196  10 cache.evict(Fqn.fromString("/a"));
 197  10 addDelay();
 198  10 log.debug("replace KEY with 30, expect 20");
 199  10 retval = cache.put(NODE, KEY, 30);
 200  10 assertEquals(20, retval);
 201    }
 202   
 203    /**
 204    * Tests various Map puts.
 205    */
 206  10 public void testPut3() throws Exception
 207    {
 208  10 final Fqn NODE = Fqn.fromString("/a/b/c");
 209   
 210  10 cache.remove(NODE);
 211  10 addDelay();
 212  10 Map m = new HashMap();
 213  10 m.put("a", "b");
 214  10 m.put("c", "d");
 215  10 Map m2 = new HashMap();
 216  10 m2.put("e", "f");
 217  10 m2.put("g", "h");
 218   
 219  10 cache.put(NODE, m);
 220   
 221  10 addDelay();
 222  10 cache.get(NODE, "X");
 223   
 224  10 assertEquals(m, loader.get(NODE));
 225  10 assertEquals(m, cache.get(NODE).getData());
 226  10 cache.evict(NODE);
 227  10 addDelay();
 228  10 cache.get(NODE, "X");
 229  10 assertEquals(m, cache.get(NODE).getData());
 230  10 cache.evict(NODE);
 231  10 cache.get(NODE, "X");
 232  10 cache.put(NODE, m2);
 233  10 assertEquals("combined", 4, cache.get(NODE).getData().size());
 234    }
 235   
 236  10 public void testShallowMove() throws Exception
 237    {
 238  10 Fqn a = Fqn.fromString("/a");
 239  10 Fqn b = Fqn.fromString("/b");
 240  10 Fqn a_b = Fqn.fromString("/a/b");
 241  10 String key = "key", valueA = "A", valueB = "B";
 242   
 243  10 cache.put(a, key, valueA);
 244  10 cache.put(b, key, valueB);
 245   
 246  10 addDelay();
 247   
 248  10 CacheLoader loader = cache.getCacheLoaderManager().getCacheLoader();
 249  10 assertEquals(valueA, loader.get(a).get(key));
 250  10 assertEquals(valueB, loader.get(b).get(key));
 251  10 assertTrue(loader.getChildrenNames(Fqn.ROOT).contains("a"));
 252  10 assertTrue(loader.getChildrenNames(Fqn.ROOT).contains("b"));
 253   
 254    // now move
 255  10 cache.move(b, a);
 256   
 257  10 addDelay();
 258   
 259  10 assertEquals(valueA, loader.get(a).get(key));
 260  10 assertNull(loader.get(b));
 261  10 assertEquals(valueB, loader.get(a_b).get(key));
 262   
 263    }
 264   
 265  10 public void testDeepMove() throws Exception
 266    {
 267  10 Fqn a = Fqn.fromString("/a");
 268  10 Fqn b = Fqn.fromString("/b");
 269  10 Fqn a_b = Fqn.fromString("/a/b");
 270  10 Fqn b_c = Fqn.fromString("/b/c");
 271  10 Fqn a_b_c = Fqn.fromString("/a/b/c");
 272   
 273  10 String key = "key", valueA = "A", valueB = "B", valueC = "C";
 274   
 275  10 cache.put(a, key, valueA);
 276  10 cache.put(b, key, valueB);
 277  10 cache.put(b_c, key, valueC);
 278   
 279   
 280  10 addDelay();
 281   
 282  10 assertEquals(valueA, cache.getCacheLoaderManager().getCacheLoader().get(a).get(key));
 283  10 assertEquals(valueB, cache.getCacheLoaderManager().getCacheLoader().get(b).get(key));
 284  10 assertEquals(valueC, cache.getCacheLoaderManager().getCacheLoader().get(b_c).get(key));
 285   
 286    // now move
 287  10 cache.move(b, a);
 288   
 289  10 addDelay();
 290   
 291  10 assertEquals(valueA, cache.getCacheLoaderManager().getCacheLoader().get(a).get(key));
 292  10 assertNull(cache.getCacheLoaderManager().getCacheLoader().get(b));
 293  10 assertEquals(valueB, cache.getCacheLoaderManager().getCacheLoader().get(a_b).get(key));
 294  10 assertNull(cache.getCacheLoaderManager().getCacheLoader().get(b_c));
 295  10 assertEquals(valueC, cache.getCacheLoaderManager().getCacheLoader().get(a_b_c).get(key));
 296   
 297    }
 298   
 299   
 300    /**
 301    * Tests various put combos which should exercise the CacheLoaderInterceptor.
 302    */
 303  10 public void testPutRemoveCombos() throws Exception
 304    {
 305  10 final String NODE = "/a/b/c";
 306  10 cache.remove(NODE);
 307  10 Fqn fqn = Fqn.fromString(NODE);
 308  10 addDelay();
 309  10 Map m = new HashMap();
 310  10 m.put("a", "b");
 311  10 m.put("c", "d");
 312  10 loader.put(fqn, m);
 313  10 System.out.println("*** MANIK: LOADER " + loader.get(fqn));
 314  10 cache.put(NODE, "e", "f");
 315  10 System.out.println("*** MANIK: CACHE " + cache.get(NODE).getData());
 316  10 System.out.println("*** MANIK: LOADER " + loader.get(fqn));
 317  10 addDelay();
 318  10 System.out.println("*** MANIK: CACHE " + cache.get(NODE));
 319  10 cache.get(NODE, "X");
 320  10 System.out.println("*** MANIK: CACHE " + cache.get(NODE).getData());
 321  10 assertEquals(3, cache.get(NODE).getData().size());
 322  10 cache.evict(fqn);
 323  10 cache.get(NODE, "X");
 324  10 cache.remove(NODE, "e");
 325  10 assertEquals(2, cache.get(NODE).getData().size());
 326    }
 327   
 328  10 public void testGet() throws CacheException
 329    {
 330  10 final String NODE = "/a/b/c";
 331  10 Object retval;
 332  10 cache.remove(NODE);
 333  10 addDelay();
 334  10 retval = cache.put(NODE, "1", 10);
 335  10 assertNull(retval);
 336  10 addDelay();
 337  10 cache.put(NODE, "2", 20);
 338  10 cache.evict(Fqn.fromString("/a/b/c"));
 339  10 assertTrue("DataNode should not exisit ", !cache.exists("/a/b/c"));
 340  10 addDelay();
 341  10 retval = cache.get(NODE, "1");
 342  10 assertEquals(10, retval);
 343  10 retval = cache.get(NODE, "2");
 344  10 assertEquals(20, retval);
 345    }
 346   
 347  10 public void testGetNode() throws CacheException
 348    {
 349  10 final String NODE = "/a/b/c";
 350  10 Object retval;
 351  10 cache.remove(NODE);
 352  10 addDelay();
 353  10 cache.put(NODE, "1", 10);
 354  10 cache.evict(Fqn.fromString(NODE));
 355  10 assertTrue("DataNode should not exisit ", !cache.exists("/a/b/c"));
 356  10 addDelay();
 357  10 retval = cache.get(NODE);
 358   
 359  10 assertNotNull("Should not be null", retval);
 360   
 361  10 Node node = (Node) retval;
 362  10 assertEquals(10, node.get("1"));
 363    }
 364   
 365   
 366  10 public void testSerialization() throws CacheException
 367    {
 368  10 SamplePojo pojo = new SamplePojo(39, "Bela");
 369  10 pojo.getHobbies().add("Running");
 370  10 pojo.getHobbies().add("Beerathlon");
 371  10 pojo.getHobbies().add("Triathlon");
 372  10 cache.put("/mypojo", 322649, pojo);
 373  10 addDelay();
 374  10 assertNotNull(cache.get("/mypojo", 322649));
 375  10 cache.evict(Fqn.fromString("/mypojo"));
 376  10 assertFalse(cache.exists("/mypojo"));
 377  10 SamplePojo pojo2 = (SamplePojo) cache.get("/mypojo", 322649);// should fetch from CacheLoader
 378  10 assertNotNull(pojo2);
 379  10 assertEquals(39, pojo2.getAge());
 380  10 assertEquals("Bela", pojo2.getName());
 381  10 assertEquals(3, pojo2.getHobbies().size());
 382    }
 383   
 384    /**
 385    * Just adds some data that wil be later retrieved. This test has to be run first
 386    */
 387  10 public void testPopulate()
 388    {
 389  10 try
 390    {
 391  10 Map m = new HashMap();
 392  10 for (int i = 0; i < 10; i++)
 393    {
 394  100 m.put("key" + i, "val" + i);
 395    }
 396  10 cache.put("/a/b/c", m);
 397  10 cache.load("/1/2/3/4/5");
 398  10 cache.put("/1/2/3/4/5", null);
 399  10 cache.put("/1/2/3/4/5/a", null);
 400  10 cache.put("/1/2/3/4/5/b", null);
 401  10 cache.put("/1/2/3/4/5/c", null);
 402  10 cache.put("/1/2/3/4/5/d", null);
 403  10 cache.put("/1/2/3/4/5/e", null);
 404  10 cache.put("/1/2/3/4/5/d/one", null);
 405  10 cache.put("/1/2/3/4/5/d/two", null);
 406  10 cache.put("/1/2/3/4/5/d/three", null);
 407    // cache.put("/a/b/c", "newKey", "newValue");
 408  10 System.out.println("cache: " + cache);
 409   
 410  10 assertTrue(cache.exists("/1/2/3/4"));
 411  10 assertTrue(cache.exists("/a/b/c"));
 412  10 assertFalse(cache.exists("/a/b/c/d"));
 413    }
 414    catch (Exception e)
 415    {
 416  0 fail(e.toString());
 417    }
 418    }
 419   
 420   
 421  10 public void testPreloading() throws CacheException
 422    {
 423  10 cache.remove("/");
 424  10 cache.put("1/2/3/4/5/d", "key", "val");
 425  10 cache.evict(Fqn.fromString("1/2/3/4/5/d"));
 426  10 System.out.println("-- checking for 1/2/3/4/5/d");
 427  10 addDelay();
 428  10 assertFalse(cache.exists("1/2/3/4/5/d"));// exists() doesn't load
 429  10 cache.get("1/2/3/4/5/d");// get *does* load
 430  10 assertTrue(cache.exists("1/2/3/4/5/d"));
 431  10 System.out.println("-- 1/2/3/4/5/d exists");
 432    }
 433   
 434   
 435  10 public void testCacheLoading2() throws CacheException
 436    {
 437  10 Set keys = null;
 438  10 cache.put("/a/b/c", "key", "val");
 439  10 try
 440    {
 441  10 keys = cache.getKeys("/a/b/c");
 442  10 assertNotNull(keys);
 443  10 assertEquals(1, keys.size());
 444    }
 445    catch (Exception e)
 446    {
 447  0 fail(e.toString());
 448    }
 449   
 450  10 try
 451    {
 452  10 keys.add("myKey");
 453    }
 454    catch (UnsupportedOperationException ex)
 455    {
 456  0 fail("unsupported operation: " + ex);
 457    }
 458    }
 459   
 460   
 461  10 public void testExists()
 462    {
 463  10 cache.put("/eins/zwei/drei", "key1", "val1");
 464  10 assertTrue(cache.exists("/eins/zwei/drei"));
 465  10 assertTrue(cache.exists("/eins/zwei/drei", "key1"));
 466  10 assertFalse(cache.exists("/eins/zwei/drei", "key2"));
 467  10 assertFalse(cache.exists("/uno/due/tre"));
 468  10 assertFalse(cache.exists("/une/due/tre", "key1"));
 469    }
 470   
 471  10 public void testGetChildren()
 472    {
 473  10 try
 474    {
 475  10 cache.put("/1/2/3/4/5/d/one", null);
 476  10 cache.put("/1/2/3/4/5/d/two", null);
 477  10 cache.put("/1/2/3/4/5/d/three", null);
 478  10 Set children = cache.getChildrenNames("/1/2/3/4/5/d");
 479  10 assertNotNull(children);
 480  10 assertEquals(3, children.size());
 481  10 assertTrue(children.contains("one"));
 482  10 assertTrue(children.contains("two"));
 483  10 assertTrue(children.contains("three"));
 484    }
 485    catch (Exception e)
 486    {
 487  0 fail(e.toString());
 488    }
 489    }
 490   
 491   
 492  10 public void testGetChildrenWithEviction() throws CacheException
 493    {
 494  10 cache.put("/a/b/c/1", null);
 495  10 cache.put("/a/b/c/2", null);
 496  10 cache.put("/a/b/c/3", null);
 497  10 cache.evict(Fqn.fromString("/a/b/c/1"));
 498  10 cache.evict(Fqn.fromString("/a/b/c/2"));
 499  10 cache.evict(Fqn.fromString("/a/b/c/3"));
 500  10 cache.evict(Fqn.fromString("/a/b/c"));
 501  10 cache.evict(Fqn.fromString("/a/b"));
 502  10 cache.evict(Fqn.fromString("/a"));
 503  10 cache.evict(Fqn.fromString("/"));
 504  10 addDelay();
 505  10 Set children = cache.getChildrenNames("/a/b/c");
 506  10 assertNotNull(children);
 507  10 assertEquals(3, children.size());
 508  10 assertTrue(children.contains("1"));
 509  10 assertTrue(children.contains("2"));
 510  10 assertTrue(children.contains("3"));
 511    }
 512   
 513  10 public void testGetChildren2()
 514    {
 515  10 try
 516    {
 517  10 cache.put("/1", null);
 518  10 cache.put("a", null);
 519  10 Set children = cache.getChildrenNames("/");
 520  10 assertNotNull(children);
 521  10 assertEquals(2, children.size());
 522  10 assertTrue(children.contains("1"));
 523  10 assertTrue(children.contains("a"));
 524    }
 525    catch (Exception e)
 526    {
 527  0 fail(e.toString());
 528    }
 529    }
 530   
 531  10 public void testGetChildren3()
 532    {
 533  10 try
 534    {
 535  10 cache.put("/1", null);
 536  10 cache.put("a", null);
 537  10 Set children = cache.getChildrenNames("");
 538  10 assertNotNull(children);
 539  10 assertEquals(2, children.size());
 540  10 assertTrue(children.contains("1"));
 541  10 assertTrue(children.contains("a"));
 542    }
 543    catch (Exception e)
 544    {
 545  0 fail(e.toString());
 546    }
 547    }
 548   
 549  10 public void testGetChildren4()
 550    {
 551  10 try
 552    {
 553  10 if (!cache.exists("/a/b/c"))
 554    {
 555  10 cache.put("/a/b/c", null);
 556    }
 557  10 Set children = cache.getChildrenNames((Fqn) null);
 558  10 assertTrue(children.isEmpty());
 559    }
 560    catch (Exception e)
 561    {
 562  0 fail(e.toString());
 563    }
 564    }
 565   
 566   
 567  10 public void testGetChildren5()
 568    {
 569  10 try
 570    {
 571  10 cache.put("/a/1", null);
 572  10 cache.put("/a/2", null);
 573  10 cache.put("/a/3", null);
 574  10 System.out.println("cache is " + cache.printLockInfo());
 575   
 576  10 Node n = cache.get("/a");
 577  10 assertNotNull(n);
 578   
 579  10 Set children = cache.getChildrenNames("/a");
 580  10 assertNotNull(children);
 581  10 assertEquals(3, children.size());
 582    }
 583    catch (Exception e)
 584    {
 585  0 fail(e.toString());
 586    }
 587    }
 588   
 589   
 590  10 public void testGetChildren6()
 591    {
 592  10 try
 593    {
 594  10 cache.put("/a/1", null);
 595  10 cache.put("/a/2", null);
 596  10 cache.put("/a/3", null);
 597  10 System.out.println("cache is " + cache.printLockInfo());
 598  10 cache.evict(Fqn.fromString("/a/1"));
 599  10 cache.evict(Fqn.fromString("/a/2"));
 600  10 cache.evict(Fqn.fromString("/a/3"));
 601  10 cache.evict(Fqn.fromString("/a"));
 602  10 System.out.println("cache is " + cache.printLockInfo());
 603  10 addDelay();
 604  10 assertNotNull(cache.get("/a"));
 605   
 606  10 Set children = cache.getChildrenNames("/a");
 607  10 assertNotNull("No children were loaded", children);
 608  10 System.out.println("children: " + children);
 609  10 assertEquals("3 children weren't loaded", 3, children.size());
 610    }
 611    catch (Exception e)
 612    {
 613  0 fail(e.toString());
 614    }
 615    }
 616   
 617  10 public void testGetChildren7()
 618    {
 619  10 try
 620    {
 621  10 cache.put("/a/1", null);
 622  10 cache.put("/a/2", null);
 623  10 cache.put("/a/3", null);
 624  10 cache.put("/a", "test", "test");
 625  10 System.out.println("cache is " + cache.printLockInfo());
 626  10 cache.evict(Fqn.fromString("/a/1"));
 627  10 cache.evict(Fqn.fromString("/a/2"));
 628  10 cache.evict(Fqn.fromString("/a/3"));
 629  10 cache.evict(Fqn.fromString("/a"));
 630  10 System.out.println("cache is " + cache.printLockInfo());
 631  10 addDelay();
 632  10 Object val = cache.get("/a", "test");
 633  10 assertEquals("attributes weren't loaded", "test", val);
 634   
 635  10 Set children = cache.getChildrenNames("/a");
 636  10 assertNotNull("No children were loaded", children);
 637  10 System.out.println("children: " + children);
 638  10 assertEquals("3 children weren't loaded", 3, children.size());
 639    }
 640    catch (Exception e)
 641    {
 642  0 fail(e.toString());
 643    }
 644    }
 645   
 646  10 public void testGetChildren8()
 647    {
 648  10 cache.put("/a/1", null);
 649  10 cache.put("/a/2", null);
 650  10 cache.put("/a/3", null);
 651  10 System.out.println("cache is " + cache.printLockInfo());
 652  10 cache.evict(Fqn.fromString("/a/1"));
 653  10 cache.evict(Fqn.fromString("/a/2"));
 654  10 cache.evict(Fqn.fromString("/a/3"));
 655  10 cache.evict(Fqn.fromString("/a"));
 656  10 System.out.println("cache is " + cache.printLockInfo());
 657  10 addDelay();
 658  10 assertNull(cache.get("/a", "test"));
 659   
 660  10 cache.get("/a/1");
 661  10 Set children = cache.getChildrenNames("/a");
 662  10 assertNotNull("No children were loaded", children);
 663  10 System.out.println("children: " + children);
 664  10 assertEquals("3 children weren't loaded", 3, children.size());
 665    }
 666   
 667  10 public void testGetChildren9()
 668    {
 669  10 try
 670    {
 671  10 cache.put("/a/1", null);
 672  10 cache.put("/a/2", null);
 673  10 cache.put("/a/3", null);
 674  10 System.out.println("cache is " + cache.printLockInfo());
 675  10 cache.evict(Fqn.fromString("/a/1"));
 676  10 cache.evict(Fqn.fromString("/a/2"));
 677  10 cache.evict(Fqn.fromString("/a/3"));
 678  10 cache.evict(Fqn.fromString("/a"));
 679  10 System.out.println("cache is " + cache.printLockInfo());
 680  10 addDelay();
 681  10 assertNull(cache.get("/a", "test"));
 682   
 683  10 cache.get("/a/1");
 684  10 Set children = cache.getChildrenNames("/a");
 685  10 assertNotNull("No children were loaded", children);
 686  10 System.out.println("children: " + children);
 687  10 assertEquals("3 children weren't loaded", 3, children.size());
 688   
 689  10 cache.evict(Fqn.fromString("/a/1"));
 690  10 cache.evict(Fqn.fromString("/a/2"));
 691  10 cache.evict(Fqn.fromString("/a/3"));
 692  10 cache.evict(Fqn.fromString("/a"));
 693  10 System.out.println("cache is " + cache.printLockInfo());
 694   
 695  10 assertNull(cache.get("/a", "test"));
 696   
 697  10 cache.get("/a/1");
 698  10 children = cache.getChildrenNames("/a");
 699  10 assertNotNull("No children were loaded", children);
 700  10 System.out.println("children: " + children);
 701  10 assertEquals("3 children weren't loaded", 3, children.size());
 702    }
 703    catch (Exception e)
 704    {
 705  0 fail(e.toString());
 706    }
 707    }
 708   
 709   
 710  10 public void testGetChildren10()
 711    {
 712  10 try
 713    {
 714  10 cache.put("/a/1", null);
 715  10 cache.put("/a/2", null);
 716  10 cache.put("/a/3", null);
 717  10 System.out.println("cache is " + cache.printLockInfo());
 718  10 cache.evict(Fqn.fromString("/a/1"));
 719  10 cache.evict(Fqn.fromString("/a/2"));
 720  10 cache.evict(Fqn.fromString("/a/3"));
 721  10 cache.evict(Fqn.fromString("/a"));
 722  10 System.out.println("cache is " + cache.printLockInfo());
 723  10 addDelay();
 724  10 assertNull(cache.get("/a", "test"));
 725   
 726  10 cache.get("/a/1");
 727  10 Set children = cache.getChildrenNames("/a");
 728  10 assertNotNull("No children were loaded", children);
 729  10 System.out.println("children: " + children);
 730  10 assertEquals("3 children weren't loaded", 3, children.size());
 731   
 732  10 children = cache.getChildrenNames("/a");
 733  10 assertNotNull("No children were loaded", children);
 734  10 System.out.println("children: " + children);
 735  10 assertEquals("3 children weren't loaded", 3, children.size());
 736    }
 737    catch (Exception e)
 738    {
 739  0 fail(e.toString());
 740    }
 741    }
 742   
 743   
 744  10 public void testGetChildren11()
 745    {
 746  10 Set children;
 747  10 try
 748    {
 749  10 cache.put("/a/b", "key", "val");
 750  10 cache.put("/a/b/1", "key", "val");
 751  10 cache.put("/a/b/2", "key", "val");
 752  10 cache.put("/a/b/3", "key", "val");
 753  10 cache.put("/a/b/1/tmp", "key", "val");
 754  10 cache.put("/a/b/2/tmp", "key", "val");
 755  10 cache.put("/a/b/3/tmp", "key", "val");
 756   
 757  10 cache.evict(Fqn.fromString("/a"));
 758  10 cache.evict(Fqn.fromString("/a/b"));
 759  10 cache.evict(Fqn.fromString("/a/b/1"));
 760  10 cache.evict(Fqn.fromString("/a/b/2"));
 761  10 cache.evict(Fqn.fromString("/a/b/3"));
 762   
 763    // now load the children - this set childrenLoaded in /a/b to true
 764  10 children = cache.getChildrenNames("/a/b");
 765  10 assertEquals(3, children.size());
 766   
 767  10 cache.evict(Fqn.fromString("/a/b"));
 768  10 cache.evict(Fqn.fromString(("/a/b/1/tmp")));
 769  10 cache.evict(Fqn.fromString(("/a/b/2/tmp")));
 770  10 cache.evict(Fqn.fromString(("/a/b/3/tmp")));
 771  10 cache.evict(Fqn.fromString(("/a/b/1")));
 772  10 cache.evict(Fqn.fromString(("/a/b/2")));
 773  10 cache.evict(Fqn.fromString(("/a/b/3")));
 774  10 cache.evict(Fqn.fromString("/a"));
 775   
 776  10 children = cache.getChildrenNames("/a/b");
 777  10 assertEquals(3, children.size());
 778    }
 779    catch (Exception e)
 780    {
 781  0 fail(e.toString());
 782    }
 783    }
 784   
 785   
 786  10 public void testGetChildren12()
 787    {
 788  10 Set children;
 789  10 try
 790    {
 791  10 cache.put("/a/b", "key", "val");
 792  10 cache.put("/a/b/1", "key", "val");
 793  10 cache.put("/a/b/2", "key", "val");
 794  10 cache.put("/a/b/3", "key", "val");
 795  10 children = cache.getChildrenNames("/a/b");
 796  10 assertEquals(3, children.size());
 797   
 798  10 cache.evict(Fqn.fromString("/a/b/3"));
 799  10 cache.evict(Fqn.fromString("/a/b/2"));
 800    // cache.evict(Fqn.fromString("/a/b/1"));
 801  10 cache.evict(Fqn.fromString("/a/b"));
 802  10 cache.evict(Fqn.fromString("/a"));
 803   
 804    // now load the children - this set childrenLoaded in /a/b to true
 805  10 cache.getChildrenNames("/a/b");
 806  10 children = cache.getChildrenNames("/a/b");
 807  10 assertEquals(3, children.size());
 808   
 809  10 cache.evict(Fqn.fromString("/a/b/3"));
 810  10 cache.evict(Fqn.fromString("/a/b/2"));
 811    // cache.evict(Fqn.fromString("/a/b/1"));
 812  10 cache.evict(Fqn.fromString("/a/b"));
 813  10 cache.evict(Fqn.fromString("/a"));
 814  10 children = cache.getChildrenNames("/a/b");
 815  10 assertEquals(3, children.size());
 816    }
 817    catch (Exception e)
 818    {
 819  0 fail(e.toString());
 820    }
 821    }
 822   
 823  10 public void testLoaderGetChildrenNames() throws Exception
 824    {
 825  10 Fqn f = Fqn.fromString("/a");
 826  10 cache.put(f, "k", "v");
 827  10 assertEquals("v", loader.get(f).get("k"));
 828  10 assertNull(loader.getChildrenNames(f));
 829    }
 830   
 831   
 832  10 public void testRemoveData()
 833    {
 834  10 String key = "/x/y/z/";
 835  10 cache.put(key, "keyA", "valA");
 836  10 cache.put(key, "keyB", "valB");
 837  10 cache.put(key, "keyC", "valC");
 838  10 assertEquals(3, cache.getKeys(key).size());
 839  10 cache.removeData(key);
 840  10 Set keys = cache.getKeys(key);
 841  10 assertEquals(0, keys.size());
 842  10 cache.remove("/x");
 843  10 Object val = cache.get(key, "keyA");
 844  10 assertNull(val);
 845    }
 846   
 847   
 848  10 public void testRemoveData2()
 849    {
 850  10 Set keys;
 851  10 Fqn key = Fqn.fromString("/x/y/z/");
 852  10 cache.put(key, "keyA", "valA");
 853  10 cache.put(key, "keyB", "valB");
 854  10 cache.put(key, "keyC", "valC");
 855  10 addDelay();
 856  10 keys = cache.getKeys(key);
 857  10 assertEquals(3, keys.size());
 858  10 cache.removeData(key);
 859  10 cache.evict(key);
 860  10 addDelay();
 861  10 keys = cache.getKeys(key);
 862  10 assertNotNull(keys);
 863  10 assertEquals(0, keys.size());
 864    }
 865   
 866  10 public void testRemoveData3()
 867    {
 868  10 Set keys;
 869  10 Fqn key = Fqn.fromString("/x/y/z/");
 870  10 cache.put(key, "keyA", "valA");
 871  10 cache.put(key, "keyB", "valB");
 872  10 cache.put(key, "keyC", "valC");
 873  10 keys = cache.getKeys(key);
 874  10 assertEquals(3, keys.size());
 875  10 cache.evict(key);
 876  10 cache.removeData(key);
 877  10 keys = cache.getKeys(key);
 878  10 assertEquals("no more keys", 0, keys.size());
 879    }
 880   
 881  10 public void testRemoveKey()
 882    {
 883  10 String key = "/x/y/z/";
 884  10 cache.put(key, "keyA", "valA");
 885  10 assertEquals(1, cache.getKeys(key).size());
 886  10 cache.put(key, "keyB", "valB");
 887  10 assertEquals(2, cache.getKeys(key).size());
 888  10 cache.put(key, "keyC", "valC");
 889  10 assertEquals(3, cache.getKeys(key).size());
 890  10 cache.remove(key, "keyA");
 891  10 assertEquals(2, cache.getKeys(key).size());
 892  10 cache.remove("/x");
 893    }
 894   
 895   
 896  10 public void testRemoveKey2() throws CacheException
 897    {
 898  10 final String NODE = "/test";
 899  10 final String KEY = "key";
 900  10 Object retval;
 901  10 cache.remove(NODE);
 902  10 retval = cache.put(NODE, KEY, 10);
 903  10 assertNull(retval);
 904  10 addDelay();
 905  10 retval = cache.remove(NODE, KEY);
 906  10 assertEquals(10, retval);
 907  10 addDelay();
 908  10 retval = cache.remove(NODE, KEY);
 909  10 assertNull(retval);
 910    }
 911   
 912  10 public void testRemoveKey3() throws CacheException
 913    {
 914  10 final String NODE = "/test";
 915  10 final String KEY = "key";
 916  10 Object retval;
 917  10 cache.remove(NODE);
 918  10 retval = cache.put(NODE, KEY, 10);
 919  10 assertNull(retval);
 920   
 921  10 cache.evict(Fqn.fromString(NODE));// evicts from memory, but *not* from store
 922  10 addDelay();
 923  10 retval = cache.remove(NODE, KEY);
 924  10 assertEquals(10, retval);
 925   
 926  10 cache.evict(Fqn.fromString(NODE));// evicts from memory, but *not* from store
 927  10 addDelay();
 928  10 retval = cache.remove(NODE, KEY);
 929  10 assertNull(retval);
 930    }
 931   
 932   
 933  10 public void testRemove()
 934    {
 935  10 String key = "/x/y/z/";
 936  10 cache.put(key, "keyA", "valA");
 937  10 cache.put(key, "keyB", "valB");
 938  10 cache.put(key, "keyC", "valC");
 939  10 cache.remove("/x");
 940  10 assertNull(cache.get(key, "keyA"));
 941  10 addDelay();
 942  10 Set keys = cache.getKeys(key);
 943  10 assertNull("got keys " + keys, keys);
 944  10 cache.remove("/x");
 945    }
 946   
 947   
 948  10 public void testRemoveRoot()
 949    {
 950  10 assertEquals(0, cache.getKeys("/").size());
 951  10 cache.put("/1/2/3/4/5", null);
 952  10 cache.put("uno/due/tre", null);
 953  10 cache.put("1/2/3/a", null);
 954  10 cache.put("/eins/zwei/drei", null);
 955  10 cache.put("/one/two/three", null);
 956  10 cache.remove("/");
 957  10 assertEquals(0, cache.getKeys("/").size());
 958    }
 959   
 960   
 961  10 public void testEvictionWithCacheLoader()
 962    {
 963  10 cache.put("/first/second", "key1", "val1");// stored in cache loader
 964  10 cache.put("/first/second/third", "key2", "val2");// stored in cache loader
 965  10 cache.evict(Fqn.fromString("/first/second"));// doesn't remove node, just data !
 966  10 addDelay();
 967  10 assertTrue(cache.exists("/first/second/third"));
 968  10 assertTrue(cache.exists("/first/second"));
 969  10 assertTrue(cache.exists("/first"));
 970  10 String val = (String) cache.get("/first/second", "key1");// should be loaded from cache loader
 971  10 assertEquals("val1", val);
 972  10 assertTrue(cache.exists("/first/second/third"));
 973  10 assertTrue(cache.exists("/first/second"));
 974  10 assertTrue(cache.exists("/first"));
 975    }
 976   
 977   
 978  10 public void testEvictionWithCacheLoader2()
 979    {
 980  10 cache.put("/first/second/third", "key1", "val1");// stored in cache loader
 981  10 cache.evict(Fqn.fromString("/first/second/third"));// removes node, because there are no children
 982  10 addDelay();
 983  10 assertFalse(cache.exists("/first/second/third"));
 984  10 assertTrue(cache.exists("/first/second"));
 985  10 assertTrue(cache.exists("/first"));
 986  10 String val = (String) cache.get("/first/second/third", "key1");// should be loaded from cache loader
 987  10 assertEquals("val1", val);
 988  10 assertTrue(cache.exists("/first/second/third"));
 989  10 assertTrue(cache.exists("/first/second"));
 990  10 assertTrue(cache.exists("/first"));
 991    }
 992   
 993   
 994  10 public void testEvictionWithGetChildrenNames() throws Exception
 995    {
 996  10 cache.put("/a/1", null);
 997  10 cache.put("/a/2", null);
 998  10 cache.put("/a/3", null);
 999    // cache.put("/a/1/tmp", null);
 1000  10 cache.evict(Fqn.fromString("/a/1"));
 1001  10 cache.evict(Fqn.fromString("/a/2"));
 1002  10 cache.evict(Fqn.fromString("/a/3"));
 1003  10 cache.evict(Fqn.fromString("/a"));
 1004  10 addDelay();
 1005   
 1006  10 TransactionManager mgr = getTransactionManager();
 1007   
 1008  10 mgr.begin();
 1009  10 tx = mgr.getTransaction();
 1010  10 Set children = cache.getChildrenNames("/a");
 1011   
 1012  10 System.out.println("**** " + cache.getTransactionManager());
 1013   
 1014  10 assertEquals(3, children.size());
 1015  10 assertTrue(children.contains("1"));
 1016  10 assertTrue(children.contains("2"));
 1017  10 assertTrue(children.contains("3"));
 1018   
 1019  10 System.out.println("lock info " + cache.printLockInfo());
 1020   
 1021  10 assertEquals(5, cache.getNumberOfLocksHeld());
 1022  10 tx.commit();
 1023   
 1024    }
 1025   
 1026   
 1027  10 public void testTxPutCommit() throws Exception
 1028    {
 1029  10 TransactionManager mgr = getTransactionManager();
 1030  10 mgr.begin();
 1031  10 tx = mgr.getTransaction();
 1032   
 1033  10 cache.put("/one/two/three", "key1", "val1");
 1034  10 cache.put("/one/two/three/four", "key2", "val2");
 1035  10 tx.commit();
 1036  10 assertNotNull("Cache has node /one/two/three", cache.getKeys("/one/two/three"));
 1037  10 assertNotNull("Loader has node /one/two/three", loader.get(Fqn.fromString("/one/two/three")));
 1038  10 Set children = cache.getChildrenNames("/one");
 1039  10 assertEquals("Cache has correct number of children", 1, children.size());
 1040  10 children = loader.getChildrenNames(Fqn.fromString("/one"));
 1041  10 assertEquals("Loader has correct number of children", 1, children.size());
 1042  10 cache.remove("/");
 1043    }
 1044   
 1045  10 public void testTxPutRollback() throws Exception
 1046    {
 1047  10 TransactionManager mgr = getTransactionManager();
 1048   
 1049  10 cache.remove("/one");
 1050  10 addDelay();
 1051  10 mgr.begin();
 1052  10 tx = mgr.getTransaction();
 1053   
 1054  10 cache.put("/one/two/three", "key1", "val1");
 1055  10 cache.put("/one/two/three/four", "key2", "val2");
 1056  10 log.debug("NODE1 " + cache.get("/one/two/three").getData());
 1057  10 tx.rollback();
 1058  10 log.debug("NODE2 " + cache.get("/one/two/three"));
 1059  10 assertEquals(null, cache.get("/one/two/three", "key1"));
 1060  10 assertEquals(null, cache.get("/one/two/three/four", "key2"));
 1061  10 addDelay();
 1062  10 assertNull("Loader does not have node /one/two/three", loader.get(Fqn.fromString("/one/two/three")));
 1063  10 assertEquals("Cache does not have node /one/two/three", null, cache.getKeys("/one/two/three"));
 1064  10 Set children = cache.getChildrenNames("/one");
 1065  10 assertEquals("Cache has no children under /one", 0, children.size());
 1066  10 children = loader.getChildrenNames(Fqn.fromString("/one"));
 1067  10 assertEquals("Loader has no children under /one", null, children);
 1068    }
 1069   
 1070   
 1071    /**
 1072    * Tests basic operations without a transaction.
 1073    */
 1074  10 public void testBasicOperations()
 1075    throws Exception
 1076    {
 1077   
 1078  10 doTestBasicOperations();
 1079    }
 1080   
 1081    /**
 1082    * Tests basic operations with a transaction.
 1083    */
 1084  10 public void testBasicOperationsTransactional()
 1085    throws Exception
 1086    {
 1087   
 1088  10 TransactionManager mgr = getTransactionManager();
 1089  10 mgr.begin();
 1090  10 tx = mgr.getTransaction();
 1091  10 doTestBasicOperations();
 1092  10 tx.commit();
 1093    }
 1094   
 1095    /**
 1096    * Tests basic operations.
 1097    */
 1098  20 private void doTestBasicOperations() throws Exception
 1099    {
 1100   
 1101    /* One FQN only. */
 1102  20 doPutTests(new Fqn("key"));
 1103  20 doRemoveTests(new Fqn("key"));
 1104    // assertEquals(0, loader.loadEntireState().length);
 1105   
 1106    /* Add three FQNs, middle FQN last. */
 1107  20 doPutTests(new Fqn("key1"));
 1108  20 doPutTests(new Fqn("key3"));
 1109  20 doPutTests(new Fqn("key2"));
 1110  20 assertEquals(4, loader.get(new Fqn("key1")).size());
 1111  20 assertEquals(4, loader.get(new Fqn("key2")).size());
 1112  20 assertEquals(4, loader.get(new Fqn("key3")).size());
 1113   
 1114    /* Remove middle FQN first, then the others. */
 1115  20 doRemoveTests(new Fqn("key2"));
 1116  20 doRemoveTests(new Fqn("key3"));
 1117  20 doRemoveTests(new Fqn("key1"));
 1118  20 assertNull(loader.get(new Fqn("key1")));
 1119  20 assertNull(loader.get(new Fqn("key2")));
 1120  20 assertNull(loader.get(new Fqn("key3")));
 1121    // assertEquals(0, loader.loadEntireState().length);
 1122    }
 1123   
 1124    /**
 1125    * Do basic put tests for a given FQN.
 1126    */
 1127  80 private void doPutTests(Fqn fqn)
 1128    throws Exception
 1129    {
 1130   
 1131  80 assertTrue(!loader.exists(fqn));
 1132   
 1133    /* put(Fqn,Object,Object) and get(Fqn,Object) */
 1134  80 Object oldVal;
 1135  80 oldVal = loader.put(fqn, "one", "two");
 1136  80 assertNull(oldVal);
 1137  80 addDelay();
 1138  80 oldVal = loader.put(fqn, "three", "four");
 1139  80 assertNull(oldVal);
 1140  80 addDelay();
 1141  80 assertEquals("two", loader.get(fqn).get("one"));
 1142  80 assertEquals("four", loader.get(fqn).get("three"));
 1143  80 addDelay();
 1144  80 oldVal = loader.put(fqn, "one", "xxx");
 1145  80 assertEquals("two", oldVal);
 1146  80 addDelay();
 1147  80 oldVal = loader.put(fqn, "one", "two");
 1148  80 assertEquals("xxx", oldVal);
 1149   
 1150    /* get(Fqn) */
 1151  80 addDelay();
 1152  80 Map map = new HashMap(loader.get(fqn));
 1153  80 assertEquals(2, map.size());
 1154  80 assertEquals("two", map.get("one"));
 1155  80 assertEquals("four", map.get("three"));
 1156   
 1157    /* put(Fqn,Map) */
 1158  80 map.put("five", "six");
 1159  80 map.put("seven", "eight");
 1160  80 loader.put(fqn, map);
 1161  80 addDelay();
 1162  80 assertEquals("six", loader.get(fqn).get("five"));
 1163  80 assertEquals("eight", loader.get(fqn).get("seven"));
 1164  80 assertEquals(map, loader.get(fqn));
 1165  80 assertEquals(4, map.size());
 1166   
 1167  80 assertTrue(loader.exists(fqn));
 1168    }
 1169   
 1170    /**
 1171    * Do basic remove tests for a given FQN.
 1172    */
 1173  80 private void doRemoveTests(Fqn fqn)
 1174    throws Exception
 1175    {
 1176   
 1177    /* remove(Fqn,Object) */
 1178  80 Object oldVal;
 1179  80 oldVal = loader.remove(fqn, "one");
 1180  80 assertEquals("two", oldVal);
 1181  80 addDelay();
 1182  80 oldVal = loader.remove(fqn, "five");
 1183  80 assertEquals("six", oldVal);
 1184  80 addDelay();
 1185  80 assertNull(loader.get(fqn).get("one"));
 1186  80 assertNull(loader.get(fqn).get("five"));
 1187  80 assertEquals("four", loader.get(fqn).get("three"));
 1188  80 assertEquals("eight", loader.get(fqn).get("seven"));
 1189  80 Map map = loader.get(fqn);
 1190  80 assertEquals(2, map.size());
 1191  80 assertEquals("four", map.get("three"));
 1192  80 assertEquals("eight", map.get("seven"));
 1193   
 1194    /* remove(Fqn) */
 1195  80 assertTrue(loader.exists(fqn));
 1196  80 loader.remove(fqn);
 1197  80 addDelay();
 1198  80 map = loader.get(fqn);
 1199  80 assertNull("Should be null", map);
 1200  80 assertTrue(!loader.exists(fqn));
 1201    }
 1202   
 1203    /**
 1204    * Tests creating implicit intermediate nodes when a leaf node is created,
 1205    * and tests removing subtrees.
 1206    */
 1207  10 public void testMultiLevelTree()
 1208    throws Exception
 1209    {
 1210   
 1211    /* Create top level node implicitly. */
 1212  10 assertTrue(!loader.exists(new Fqn("key0")));
 1213  10 loader.put(Fqn.fromString("/key0/level1/level2"), null);
 1214  10 addDelay();
 1215  10 assertTrue(loader.exists(Fqn.fromString("/key0/level1/level2")));
 1216  10 assertTrue(loader.exists(Fqn.fromString("/key0/level1")));
 1217  10 assertTrue(loader.exists(new Fqn("key0")));
 1218   
 1219    /* Remove leaf, leaving implicitly created middle level. */
 1220  10 loader.put(Fqn.fromString("/key0/x/y"), null);
 1221  10 addDelay();
 1222  10 assertTrue(loader.exists(Fqn.fromString("/key0/x/y")));
 1223  10 assertTrue(loader.exists(Fqn.fromString("/key0/x")));
 1224  10 loader.remove(Fqn.fromString("/key0/x/y"));
 1225  10 addDelay();
 1226  10 assertTrue(!loader.exists(Fqn.fromString("/key0/x/y")));
 1227  10 assertTrue(loader.exists(Fqn.fromString("/key0/x")));
 1228   
 1229    /* Delete top level to delete everything. */
 1230  10 loader.remove(new Fqn("key0"));
 1231  10 addDelay();
 1232  10 assertTrue(!loader.exists(new Fqn("key0")));
 1233  10 assertTrue(!loader.exists(Fqn.fromString("/key0/level1/level2")));
 1234  10 assertTrue(!loader.exists(Fqn.fromString("/key0/level1")));
 1235  10 assertTrue(!loader.exists(Fqn.fromString("/key0/x")));
 1236   
 1237    /* Add three top level nodes as context. */
 1238  10 loader.put(new Fqn("key1"), null);
 1239  10 loader.put(new Fqn("key2"), null);
 1240  10 loader.put(new Fqn("key3"), null);
 1241  10 addDelay();
 1242  10 assertTrue(loader.exists(new Fqn("key1")));
 1243  10 assertTrue(loader.exists(new Fqn("key2")));
 1244  10 assertTrue(loader.exists(new Fqn("key3")));
 1245   
 1246    /* Put /key3/level1/level2. level1 should be implicitly created. */
 1247  10 assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
 1248  10 assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
 1249  10 loader.put(Fqn.fromString("/key3/level1/level2"), null);
 1250  10 addDelay();
 1251  10 assertTrue(loader.exists(Fqn.fromString("/key3/level1/level2")));
 1252  10 assertTrue(loader.exists(Fqn.fromString("/key3/level1")));
 1253   
 1254    /* Context nodes should still be intact. */
 1255  10 assertTrue(loader.exists(new Fqn("key1")));
 1256  10 assertTrue(loader.exists(new Fqn("key2")));
 1257  10 assertTrue(loader.exists(new Fqn("key3")));
 1258   
 1259    /* Remove middle level only. */
 1260  10 loader.remove(Fqn.fromString("/key3/level1"));
 1261  10 addDelay();
 1262  10 assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
 1263  10 assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
 1264   
 1265    /* Context nodes should still be intact. */
 1266  10 assertTrue(loader.exists(new Fqn("key1")));
 1267  10 assertTrue(loader.exists(new Fqn("key2")));
 1268  10 assertTrue(loader.exists(new Fqn("key3")));
 1269   
 1270    /* Delete first root, leaving other roots. */
 1271  10 loader.remove(new Fqn("key1"));
 1272  10 addDelay();
 1273  10 assertTrue(!loader.exists(new Fqn("key1")));
 1274  10 assertTrue(loader.exists(new Fqn("key2")));
 1275  10 assertTrue(loader.exists(new Fqn("key3")));
 1276   
 1277    /* Delete last root, leaving other roots. */
 1278  10 loader.remove(new Fqn("key3"));
 1279  10 addDelay();
 1280  10 assertTrue(loader.exists(new Fqn("key2")));
 1281  10 assertTrue(!loader.exists(new Fqn("key3")));
 1282   
 1283    /* Delete final root, leaving none. */
 1284  10 loader.remove(new Fqn("key2"));
 1285  10 addDelay();
 1286  10 assertTrue(!loader.exists(new Fqn("key0")));
 1287  10 assertTrue(!loader.exists(new Fqn("key1")));
 1288  10 assertTrue(!loader.exists(new Fqn("key2")));
 1289  10 assertTrue(!loader.exists(new Fqn("key3")));
 1290   
 1291    /* Repeat all tests above using put(Fqn,Object,Object) and get(Fqn) */
 1292   
 1293  10 assertNull(loader.get(new Fqn("key0")));
 1294  10 loader.put(Fqn.fromString("/key0/level1/level2"), "a", "b");
 1295  10 addDelay();
 1296  10 assertNotNull(loader.get(Fqn.fromString("/key0/level1/level2")));
 1297  10 assertNotNull(loader.get(Fqn.fromString("/key0/level1")));
 1298  10 assertEquals(0, loader.get(Fqn.fromString("/key0/level1")).size());
 1299  10 assertEquals(0, loader.get(new Fqn("key0")).size());
 1300   
 1301  10 loader.put(Fqn.fromString("/key0/x/y"), "a", "b");
 1302  10 addDelay();
 1303  10 assertNotNull(loader.get(Fqn.fromString("/key0/x/y")));
 1304  10 assertNotNull(loader.get(Fqn.fromString("/key0/x")));
 1305  10 assertEquals(0, loader.get(Fqn.fromString("/key0/x")).size());
 1306  10 loader.remove(Fqn.fromString("/key0/x/y"));
 1307  10 addDelay();
 1308  10 assertNull(loader.get(Fqn.fromString("/key0/x/y")));
 1309  10 assertNotNull(loader.get(Fqn.fromString("/key0/x")));
 1310  10 assertEquals(0, loader.get(Fqn.fromString("/key0/x")).size());
 1311   
 1312  10 loader.remove(new Fqn("key0"));
 1313  10 addDelay();
 1314  10 assertNull(loader.get(new Fqn("key0")));
 1315  10 assertNull(loader.get(Fqn.fromString("/key0/level1/level2")));
 1316  10 assertNull(loader.get(Fqn.fromString("/key0/level1")));
 1317  10 assertNull(loader.get(Fqn.fromString("/key0/x")));
 1318   
 1319  10 loader.put(new Fqn("key1"), "a", "b");
 1320  10 loader.put(new Fqn("key2"), "a", "b");
 1321  10 loader.put(new Fqn("key3"), "a", "b");
 1322  10 addDelay();
 1323  10 assertNotNull(loader.get(new Fqn("key1")));
 1324  10 assertNotNull(loader.get(new Fqn("key2")));
 1325  10 assertNotNull(loader.get(new Fqn("key3")));
 1326   
 1327  10 assertNull(loader.get(Fqn.fromString("/key3/level1")));
 1328  10 assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
 1329  10 loader.put(Fqn.fromString("/key3/level1/level2"), "a", "b");
 1330  10 addDelay();
 1331  10 assertNotNull(loader.get(Fqn.fromString("/key3/level1/level2")));
 1332  10 assertNotNull(loader.get(Fqn.fromString("/key3/level1")));
 1333  10 assertEquals(0, loader.get(Fqn.fromString("/key3/level1")).size());
 1334   
 1335  10 assertNotNull(loader.get(new Fqn("key1")));
 1336  10 assertNotNull(loader.get(new Fqn("key2")));
 1337  10 assertNotNull(loader.get(new Fqn("key3")));
 1338   
 1339  10 loader.remove(Fqn.fromString("/key3/level1"));
 1340  10 addDelay();
 1341  10 assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
 1342  10 assertNull(loader.get(Fqn.fromString("/key3/level1")));
 1343   
 1344  10 assertNotNull(loader.get(new Fqn("key1")));
 1345  10 assertNotNull(loader.get(new Fqn("key2")));
 1346  10 assertNotNull(loader.get(new Fqn("key3")));
 1347   
 1348  10 loader.remove(new Fqn("key1"));
 1349  10 addDelay();
 1350  10 assertNull(loader.get(new Fqn("key1")));
 1351  10 assertNotNull(loader.get(new Fqn("key2")));
 1352  10 assertNotNull(loader.get(new Fqn("key3")));
 1353   
 1354  10 loader.remove(new Fqn("key3"));
 1355  10 addDelay();
 1356  10 assertNotNull(loader.get(new Fqn("key2")));
 1357  10 assertNull(loader.get(new Fqn("key3")));
 1358   
 1359  10 loader.remove(new Fqn("key2"));
 1360  10 addDelay();
 1361  10 assertNull(loader.get(new Fqn("key0")));
 1362  10 assertNull(loader.get(new Fqn("key1")));
 1363  10 assertNull(loader.get(new Fqn("key2")));
 1364  10 assertNull(loader.get(new Fqn("key3")));
 1365    }
 1366   
 1367    /**
 1368    * Tests the getChildrenNames() method.
 1369    */
 1370  10 public void testGetChildrenNames()
 1371    throws Exception
 1372    {
 1373   
 1374  10 checkChildren(new Fqn(), null);
 1375  10 checkChildren(Fqn.fromString("/key0"), null);
 1376   
 1377  10 loader.put(Fqn.fromString("/key0"), null);
 1378  10 addDelay();
 1379  10 checkChildren(new Fqn(), new String[]{"key0"});
 1380   
 1381  10 loader.put(Fqn.fromString("/key1/x"), null);
 1382  10 addDelay();
 1383  10 checkChildren(new Fqn(), new String[]{"key0", "key1"});
 1384  10 checkChildren(Fqn.fromString("/key1"), new String[]{"x"});
 1385   
 1386  10 loader.remove(Fqn.fromString("/key1/x"));
 1387  10 addDelay();
 1388  10 checkChildren(new Fqn(), new String[]{"key0", "key1"});
 1389  10 checkChildren(Fqn.fromString("/key0"), null);
 1390  10 checkChildren(Fqn.fromString("/key1"), null);
 1391   
 1392  10 loader.put(Fqn.fromString("/key0/a"), null);
 1393  10 loader.put(Fqn.fromString("/key0/ab"), null);
 1394  10 loader.put(Fqn.fromString("/key0/abc"), null);
 1395  10 addDelay();
 1396  10 checkChildren(Fqn.fromString("/key0"),
 1397    new String[]{"a", "ab", "abc"});
 1398   
 1399  10 loader.put(Fqn.fromString("/key0/xxx"), null);
 1400  10 loader.put(Fqn.fromString("/key0/xx"), null);
 1401  10 loader.put(Fqn.fromString("/key0/x"), null);
 1402  10 addDelay();
 1403  10 checkChildren(Fqn.fromString("/key0"),
 1404    new String[]{"a", "ab", "abc", "x", "xx", "xxx"});
 1405   
 1406  10 loader.put(Fqn.fromString("/key0/a/1"), null);
 1407  10 loader.put(Fqn.fromString("/key0/a/2"), null);
 1408  10 loader.put(Fqn.fromString("/key0/a/2/1"), null);
 1409  10 addDelay();
 1410  10 checkChildren(Fqn.fromString("/key0/a/2"), new String[]{"1"});
 1411  10 checkChildren(Fqn.fromString("/key0/a"), new String[]{"1", "2"});
 1412  10 checkChildren(Fqn.fromString("/key0"),
 1413    new String[]{"a", "ab", "abc", "x", "xx", "xxx"});
 1414    //
 1415    // loader.put(Fqn.fromString("/key0/\u0000"), null);
 1416    // loader.put(Fqn.fromString("/key0/\u0001"), null);
 1417    // checkChildren(Fqn.fromString("/key0"),
 1418    // new String[] { "a", "ab", "abc", "x", "xx", "xxx",
 1419    // "\u0000", "\u0001"});
 1420    //
 1421    // loader.put(Fqn.fromString("/\u0001"), null);
 1422    // checkChildren(new Fqn(), new String[] { "key0", "key1", "\u0001" });
 1423    //
 1424    // loader.put(Fqn.fromString("/\u0001/\u0001"), null);
 1425    // checkChildren(Fqn.fromString("/\u0001"), new String[] { "\u0001" });
 1426    //
 1427    // loader.put(Fqn.fromString("/\u0001/\uFFFF"), null);
 1428    // checkChildren(Fqn.fromString("/\u0001"),
 1429    // new String[] { "\u0001", "\uFFFF" });
 1430    //
 1431    // loader.put(Fqn.fromString("/\u0001/\uFFFF/\u0001"), null);
 1432    // checkChildren(Fqn.fromString("/\u0001/\uFFFF"),
 1433    // new String[] { "\u0001" });
 1434    }
 1435   
 1436    /**
 1437    * Checks that the given list of children part names is returned.
 1438    */
 1439  130 private void checkChildren(Fqn fqn, String[] names)
 1440    throws Exception
 1441    {
 1442   
 1443  130 Set set = loader.getChildrenNames(fqn);
 1444  130 if (names != null)
 1445    {
 1446  90 assertEquals(names.length, set.size());
 1447  90 for (int i = 0; i < names.length; i += 1)
 1448    {
 1449  240 assertTrue(set.contains(names[i]));
 1450    }
 1451    }
 1452    else
 1453    {
 1454  40 assertNull(set);
 1455    }
 1456    }
 1457   
 1458    /**
 1459    * Tests basic operations without a transaction.
 1460    */
 1461  10 public void testModifications()
 1462    throws Exception
 1463    {
 1464   
 1465  10 doTestModifications();
 1466    }
 1467   
 1468    /**
 1469    * Tests basic operations with a transaction.
 1470    */
 1471  10 public void testModificationsTransactional()
 1472    throws Exception
 1473    {
 1474   
 1475  10 TransactionManager mgr = getTransactionManager();
 1476  10 mgr.begin();
 1477  10 tx = mgr.getTransaction();
 1478  10 doTestModifications();
 1479  10 tx.commit();
 1480    }
 1481   
 1482    /**
 1483    * Tests modifications.
 1484    */
 1485  20 private void doTestModifications()
 1486    throws Exception
 1487    {
 1488   
 1489    /* PUT_KEY_VALUE, PUT_DATA */
 1490  20 List list = createUpdates();
 1491  20 loader.put(list);
 1492  20 addDelay();
 1493  20 checkModifications(list);
 1494   
 1495    /* REMOVE_KEY_VALUE */
 1496  20 list = new ArrayList();
 1497  20 Modification mod = new Modification();
 1498  20 mod.setType(Modification.ModificationType.REMOVE_KEY_VALUE);
 1499  20 mod.setFqn(FQN);
 1500  20 mod.setKey("one");
 1501  20 list.add(mod);
 1502  20 loader.put(list);
 1503  20 addDelay();
 1504  20 checkModifications(list);
 1505   
 1506    /* REMOVE_NODE */
 1507  20 list = new ArrayList();
 1508  20 mod = new Modification();
 1509  20 mod.setType(Modification.ModificationType.REMOVE_NODE);
 1510  20 mod.setFqn(FQN);
 1511  20 list.add(mod);
 1512  20 loader.put(list);
 1513  20 addDelay();
 1514  20 checkModifications(list);
 1515  20 assertNull(loader.get(FQN));
 1516   
 1517    /* REMOVE_DATA */
 1518  20 loader.put(FQN, "one", "two");
 1519  20 list = new ArrayList();
 1520  20 mod = new Modification();
 1521  20 mod.setType(Modification.ModificationType.REMOVE_DATA);
 1522  20 mod.setFqn(FQN);
 1523  20 list.add(mod);
 1524  20 loader.put(list);
 1525  20 addDelay();
 1526  20 checkModifications(list);
 1527    }
 1528   
 1529    /**
 1530    * Tests a one-phase transaction.
 1531    */
 1532  10 public void testOnePhaseTransaction()
 1533    throws Exception
 1534    {
 1535  10 List mods = createUpdates();
 1536  10 loader.prepare(null, mods, true);
 1537  10 checkModifications(mods);
 1538    }
 1539   
 1540    /**
 1541    * Tests a two-phase transaction.
 1542    */
 1543  10 public void testTwoPhaseTransaction()
 1544    throws Exception
 1545    {
 1546   
 1547    // Object txnKey = new Object();
 1548  10 TransactionManager mgr = getTransactionManager();
 1549  10 mgr.begin();
 1550  10 tx = mgr.getTransaction();
 1551   
 1552  10 List mods = createUpdates();
 1553  10 loader.prepare(tx, mods, false);
 1554  10 loader.commit(tx);
 1555  10 addDelay();
 1556  10 checkModifications(mods);
 1557    }
 1558   
 1559    /**
 1560    * Tests rollback of a two-phase transaction.
 1561    */
 1562  9 public void testTransactionRollback() throws Exception
 1563    {
 1564  9 loader.remove(Fqn.fromString("/"));
 1565  9 int num;
 1566  9 try
 1567    {
 1568  9 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 1569  9 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 1570  9 loader.loadEntireState(os);
 1571  8 num = baos.size();
 1572    }
 1573    catch (UnsupportedOperationException ex)
 1574    {
 1575  1 log.info("caught unsupported operation exception that's okay: ", ex);
 1576  1 return;
 1577    }
 1578   
 1579  8 Object txnKey = new Object();
 1580  8 List mods = createUpdates();
 1581  8 loader.prepare(txnKey, mods, false);
 1582  8 loader.rollback(txnKey);
 1583  8 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 1584  8 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 1585  8 loader.loadEntireState(os);
 1586  8 assertEquals(num, baos.size());
 1587    }
 1588   
 1589    /**
 1590    * Tests rollback of a two-phase transaction that is mediated by the cache.
 1591    */
 1592  9 public void testIntegratedTransactionRollback() throws Exception
 1593    {
 1594  9 loader.remove(Fqn.fromString("/"));
 1595  9 int num = 0;
 1596  9 try
 1597    {
 1598  9 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 1599  9 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 1600  9 loader.loadEntireState(os);
 1601  8 num = baos.size();
 1602    }
 1603    catch (UnsupportedOperationException ex)
 1604    {
 1605  1 System.out.println("caught unsupported operation exception that's okay: " + ex);
 1606  1 return;
 1607    }
 1608   
 1609  8 Object txnKey = new Object();
 1610  8 List mods = createUpdates();
 1611  8 loader.prepare(txnKey, mods, false);
 1612  8 loader.rollback(txnKey);
 1613  8 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 1614  8 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 1615  8 loader.loadEntireState(os);
 1616  8 assertEquals(num, baos.size());
 1617    }
 1618   
 1619    /**
 1620    * Creates a set of update (PUT_KEY_VALUE, PUT_DATA) modifications.
 1621    */
 1622  56 private List createUpdates()
 1623    {
 1624   
 1625  56 List list = new ArrayList();
 1626   
 1627  56 Modification mod = new Modification();
 1628  56 mod.setType(Modification.ModificationType.PUT_KEY_VALUE);
 1629  56 mod.setFqn(FQN);
 1630  56 mod.setKey("one");
 1631  56 mod.setValue("two");
 1632  56 list.add(mod);
 1633   
 1634  56 mod = new Modification();
 1635  56 mod.setType(Modification.ModificationType.PUT_KEY_VALUE);
 1636  56 mod.setFqn(FQN);
 1637  56 mod.setKey("three");
 1638  56 mod.setValue("four");
 1639  56 list.add(mod);
 1640   
 1641  56 Map map = new HashMap();
 1642  56 map.put("five", "six");
 1643  56 map.put("seven", "eight");
 1644  56 mod = new Modification();
 1645  56 mod.setType(Modification.ModificationType.PUT_DATA);
 1646  56 mod.setFqn(FQN);
 1647  56 mod.setData(map);
 1648  56 list.add(mod);
 1649   
 1650  56 return list;
 1651    }
 1652   
 1653    /**
 1654    * Checks that a list of modifications was applied.
 1655    */
 1656  100 private void checkModifications(List list)
 1657    throws Exception
 1658    {
 1659   
 1660  100 for (int i = 0; i < list.size(); i += 1)
 1661    {
 1662  180 Modification mod = (Modification) list.get(i);
 1663  180 Fqn fqn = mod.getFqn();
 1664  180 switch (mod.getType())
 1665    {
 1666  80 case PUT_KEY_VALUE:
 1667  80 assertEquals(mod.getValue(), loader.get(fqn).get(mod.getKey()));
 1668  80 break;
 1669  40 case PUT_DATA:
 1670  40 Map map = mod.getData();
 1671  40 for (Object key : map.keySet())
 1672    {
 1673  80 assertEquals(map.get(key), loader.get(fqn).get(key));
 1674    }
 1675  40 break;
 1676  20 case REMOVE_KEY_VALUE:
 1677  20 assertNull(loader.get(fqn).get(mod.getKey()));
 1678  20 break;
 1679  20 case REMOVE_DATA:
 1680  20 map = loader.get(fqn);
 1681  20 assertNotNull(map);
 1682  20 assertEquals(0, map.size());
 1683  20 break;
 1684  20 case REMOVE_NODE:
 1685  20 assertNull(loader.get(fqn));
 1686  20 break;
 1687  0 default:
 1688  0 fail("unknown type: " + mod);
 1689  0 break;
 1690    }
 1691    }
 1692    }
 1693   
 1694    /**
 1695    * Tests that null keys and values work as for a standard Java Map.
 1696    */
 1697  10 public void testNullKeysAndValues()
 1698    throws Exception
 1699    {
 1700   
 1701  10 loader.put(FQN, null, "x");
 1702  10 addDelay();
 1703  10 assertEquals("x", loader.get(FQN).get(null));
 1704  10 Map map = loader.get(FQN);
 1705  10 assertEquals(1, map.size());
 1706  10 assertEquals("x", map.get(null));
 1707   
 1708  10 loader.put(FQN, "y", null);
 1709  10 addDelay();
 1710  10 assertNull(loader.get(FQN).get("y"));
 1711  10 map = loader.get(FQN);
 1712  10 assertEquals(2, map.size());
 1713  10 assertEquals("x", map.get(null));
 1714  10 assertNull(map.get("y"));
 1715   
 1716  10 loader.remove(FQN, null);
 1717  10 addDelay();
 1718  10 assertNull(loader.get(FQN).get(null));
 1719  10 assertEquals(1, loader.get(FQN).size());
 1720   
 1721  10 loader.remove(FQN, "y");
 1722  10 addDelay();
 1723  10 assertNotNull(loader.get(FQN));
 1724  10 assertEquals(0, loader.get(FQN).size());
 1725   
 1726  10 map = new HashMap();
 1727  10 map.put(null, null);
 1728  10 loader.put(FQN, map);
 1729  10 addDelay();
 1730  10 Map m = loader.get(FQN);
 1731  10 m.toString();
 1732    //throw new RuntimeException("MAP " + loader.get(FQN).getClass());
 1733    /*
 1734    assertEquals(map, loader.get(FQN));
 1735   
 1736    loader.remove(FQN);
 1737    addDelay();
 1738    assertNull(loader.get(FQN));
 1739   
 1740    map = new HashMap();
 1741    map.put("xyz", null);
 1742    map.put(null, "abc");
 1743    loader.put(FQN, map);
 1744    addDelay();
 1745    assertEquals(map, loader.get(FQN));
 1746   
 1747    loader.remove(FQN);
 1748    addDelay();
 1749    assertNull(loader.get(FQN))*/
 1750    }
 1751   
 1752    /**
 1753    * Test non-default database name.
 1754    */
 1755  10 public void testDatabaseName()
 1756    throws Exception
 1757    {
 1758   
 1759  10 loader.put(FQN, "one", "two");
 1760  10 addDelay();
 1761  10 assertEquals("two", loader.get(FQN).get("one"));
 1762    }
 1763   
 1764    /**
 1765    * Test load/store state.
 1766    */
 1767  9 public void testLoadAndStore()
 1768    throws Exception
 1769    {
 1770   
 1771    // Empty state
 1772  9 loader.remove(Fqn.fromString("/"));
 1773   
 1774    // Use a complex object to ensure that the class catalog is used.
 1775  9 Complex c1 = new Complex();
 1776  9 Complex c2 = new Complex(c1);
 1777   
 1778    // Add objects
 1779  9 loader.put(FQN, 1, c1);
 1780  9 loader.put(FQN, 2, c2);
 1781  9 addDelay();
 1782  9 assertEquals(c1, loader.get(FQN).get(1));
 1783  9 assertEquals(c2, loader.get(FQN).get(2));
 1784  9 assertEquals(2, loader.get(FQN).size());
 1785   
 1786    // Save state
 1787  9 byte[] state;
 1788  9 ByteArrayOutputStream baos = null;
 1789  9 MarshalledValueOutputStream os = null;
 1790  9 try
 1791    {
 1792  9 baos = new ByteArrayOutputStream(1024);
 1793  9 os = new MarshalledValueOutputStream(baos);
 1794  9 loader.loadEntireState(os);
 1795    }
 1796    catch (UnsupportedOperationException ex)
 1797    {
 1798  1 System.out.println("caught unsupported operation exception (this is expected): " + ex);
 1799    }
 1800    finally
 1801    {
 1802  9 cache.getMarshaller().objectToObjectStream(StateTransferManager.STREAMING_DELIMITER_NODE, os);
 1803  9 os.close();
 1804  9 assertTrue(baos.size() > 0);
 1805  9 state = baos.toByteArray();
 1806    }
 1807   
 1808    /* Restore state. */
 1809  9 MarshalledValueInputStream is = null;
 1810  9 try
 1811    {
 1812  9 ByteArrayInputStream bais = new ByteArrayInputStream(state);
 1813  9 is = new MarshalledValueInputStream(bais);
 1814  9 loader.storeEntireState(is);
 1815    }
 1816    catch (UnsupportedOperationException ex)
 1817    {
 1818  1 System.out.println("caught unsupported operation exception (this is expected): " + ex);
 1819    }
 1820    finally
 1821    {
 1822  9 is.close();
 1823    }
 1824   
 1825  9 addDelay();
 1826  9 assertEquals(c1, loader.get(FQN).get(1));
 1827  9 assertEquals(c2, loader.get(FQN).get(2));
 1828  9 assertEquals(2, loader.get(FQN).size());
 1829    }
 1830   
 1831    /**
 1832    * Complex object whose class description is stored in the class catalog.
 1833    */
 1834    public static class Complex implements Serializable
 1835    {
 1836    /**
 1837    * The serialVersionUID
 1838    */
 1839    private static final long serialVersionUID = -6810871775584708565L;
 1840   
 1841    Complex nested;
 1842   
 1843  41 Complex()
 1844    {
 1845  41 this(null);
 1846    }
 1847   
 1848  82 Complex(Complex nested)
 1849    {
 1850  82 this.nested = nested;
 1851    }
 1852   
 1853  246 public boolean equals(Object o)
 1854    {
 1855  246 if (!(o instanceof Complex))
 1856    {
 1857  0 return false;
 1858    }
 1859  246 Complex x = (Complex) o;
 1860  246 return (nested != null) ? nested.equals(x.nested)
 1861    : (x.nested == null);
 1862    }
 1863   
 1864  732 public int hashCode()
 1865    {
 1866  732 if (nested == null)
 1867    {
 1868  518 return super.hashCode();
 1869    }
 1870    else
 1871    {
 1872  214 return 13 + nested.hashCode();
 1873    }
 1874    }
 1875    }
 1876   
 1877  10 public void testRemoveInTransactionCommit() throws Exception
 1878    {
 1879  10 Fqn fqn = Fqn.fromString("/a/b");
 1880  10 loader.remove(fqn);
 1881  10 String key = "key";
 1882  10 String value = "value";
 1883  10 cache.put(fqn, key, value);
 1884  10 loader = cache.getCacheLoaderManager().getCacheLoader();
 1885   
 1886  10 assertEquals(value, cache.get(fqn, key));
 1887  10 assertEquals(value, loader.get(fqn).get(key));
 1888   
 1889  10 cache.getTransactionManager().begin();
 1890   
 1891  10 cache.remove(fqn);
 1892   
 1893  10 cache.get(fqn);// forces the node to be loaded from cache loader again
 1894  10 cache.getTransactionManager().commit();
 1895   
 1896  10 log.debug("expect the cache and the loader to be null here.");
 1897  10 assertEquals(null, cache.get(fqn, key));
 1898  10 assertEquals(null, loader.get(fqn));
 1899    }
 1900   
 1901   
 1902  10 public void testRemoveInTransactionRollback() throws Exception
 1903    {
 1904  10 Fqn fqn = Fqn.fromString("/a/b");
 1905  10 loader.remove(fqn);
 1906  10 String key = "key";
 1907  10 String value = "value";
 1908   
 1909  10 cache.put(fqn, key, value);
 1910  10 loader = cache.getCacheLoaderManager().getCacheLoader();
 1911   
 1912  10 assertEquals(value, cache.get(fqn, key));
 1913  10 assertEquals(value, loader.get(fqn).get(key));
 1914   
 1915  10 cache.getTransactionManager().begin();
 1916   
 1917  10 cache.remove(fqn);
 1918  10 cache.get(fqn);// forces a reload from cloader
 1919  10 cache.getTransactionManager().rollback();
 1920   
 1921  10 assertEquals(value, cache.get(fqn, key));
 1922  10 assertEquals(value, loader.get(fqn).get(key));
 1923    }
 1924   
 1925   
 1926    /**
 1927    * See http://jira.jboss.com/jira/browse/JBCACHE-352
 1928    */
 1929  10 public void testRemoveAndGetInTransaction() throws Exception
 1930    {
 1931  10 Fqn fqn = new Fqn("/a/b");
 1932  10 String key = "key";
 1933  10 String value = "value";
 1934   
 1935  10 cache.put(fqn, key, value);
 1936  10 CacheLoader loader = cache.getCacheLoaderManager().getCacheLoader();
 1937   
 1938  10 assertEquals(value, cache.get(fqn, key));
 1939  10 assertEquals(value, loader.get(fqn).get(key));
 1940   
 1941  10 cache.getTransactionManager().begin();
 1942   
 1943  10 cache.remove(fqn);
 1944  10 assertNull("Expecting a null since I have already called a remove() - see JBCACHE-352", cache.get(fqn, key));
 1945  10 cache.getTransactionManager().rollback();
 1946   
 1947  10 assertEquals(value, cache.get(fqn, key));
 1948  10 assertEquals(value, loader.get(fqn).get(key));
 1949    }
 1950   
 1951   
 1952    /**
 1953    * Test load/store state.
 1954    */
 1955  8 public void testPartialLoadAndStore()
 1956    throws Exception
 1957    {
 1958   
 1959    /* Empty state. */
 1960  8 loader.remove(Fqn.fromString("/"));
 1961    // assertEquals(0, loader.loadEntireState().length);
 1962    // loader.storeEntireState(new byte[0]);
 1963    // assertEquals(0, loader.loadEntireState().length);
 1964    // loader.storeEntireState(null);
 1965    // assertEquals(0, loader.loadEntireState().length);
 1966    // assertEquals(null, loader.get(FQN));
 1967   
 1968    /* Use a complex object to ensure that the class catalog is used. */
 1969  8 Complex c1 = new Complex();
 1970  8 Complex c2 = new Complex(c1);
 1971  8 Complex c3 = new Complex();
 1972  8 Complex c4 = new Complex(c3);
 1973   
 1974    /* Add objects. */
 1975  8 loader.put(FQN, 1, c1);
 1976  8 loader.put(FQN, 2, c2);
 1977  8 loader.put(SUBTREE_FQN, 1, c3);
 1978  8 loader.put(SUBTREE_FQN, 2, c4);
 1979  8 addDelay();
 1980  8 assertEquals(c1, loader.get(FQN).get(1));
 1981  8 assertEquals(c2, loader.get(FQN).get(2));
 1982  8 assertEquals(2, loader.get(FQN).size());
 1983  8 assertEquals(c3, loader.get(SUBTREE_FQN).get(1));
 1984  8 assertEquals(c4, loader.get(SUBTREE_FQN).get(2));
 1985  8 assertEquals(2, loader.get(SUBTREE_FQN).size());
 1986   
 1987    /* Save state. */
 1988  8 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 1989  8 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 1990  8 loader.loadState(SUBTREE_FQN, os);
 1991  8 cache.getMarshaller().objectToObjectStream(StateTransferManager.STREAMING_DELIMITER_NODE, os);
 1992  8 os.close();
 1993  8 assertTrue(baos.size() > 0);
 1994  8 loader.remove(SUBTREE_FQN);
 1995   
 1996    /* Restore state. */
 1997   
 1998  8 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 1999  8 MarshalledValueInputStream is = new MarshalledValueInputStream(bais);
 2000  8 loader.storeState(SUBTREE_FQN, is);
 2001  8 is.close();
 2002  8 addDelay();
 2003  8 assertEquals(c1, loader.get(FQN).get(1));
 2004  8 assertEquals(c2, loader.get(FQN).get(2));
 2005  8 assertEquals(2, loader.get(FQN).size());
 2006  8 assertEquals(c3, loader.get(SUBTREE_FQN).get(1));
 2007  8 assertEquals(c4, loader.get(SUBTREE_FQN).get(2));
 2008  8 assertEquals(2, loader.get(SUBTREE_FQN).size());
 2009    }
 2010   
 2011  8 public void testBuddyBackupStore() throws Exception
 2012    {
 2013    /* Empty state. */
 2014  8 loader.remove(Fqn.ROOT);
 2015   
 2016    /* Use a complex object to ensure that the class catalog is used. */
 2017  8 Complex c1 = new Complex();
 2018  8 Complex c2 = new Complex(c1);
 2019  8 Complex c3 = new Complex();
 2020  8 Complex c4 = new Complex(c3);
 2021   
 2022    /* Add objects. */
 2023  8 loader.put(FQN, 1, c1);
 2024  8 loader.put(FQN, 2, c2);
 2025  8 loader.put(SUBTREE_FQN, 1, c3);
 2026  8 loader.put(SUBTREE_FQN, 2, c4);
 2027  8 addDelay();
 2028  8 assertEquals(c1, loader.get(FQN).get(1));
 2029  8 assertEquals(c2, loader.get(FQN).get(2));
 2030  8 assertEquals(2, loader.get(FQN).size());
 2031  8 assertEquals(c3, loader.get(SUBTREE_FQN).get(1));
 2032  8 assertEquals(c4, loader.get(SUBTREE_FQN).get(2));
 2033  8 assertEquals(2, loader.get(SUBTREE_FQN).size());
 2034   
 2035    /* Save state. */
 2036  8 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
 2037  8 MarshalledValueOutputStream os = new MarshalledValueOutputStream(baos);
 2038  8 loader.loadState(FQN, os);
 2039  8 cache.getMarshaller().objectToObjectStream(StateTransferManager.STREAMING_DELIMITER_NODE, os);
 2040  8 os.close();
 2041  8 assertTrue(baos.size() > 0);
 2042   
 2043    /* Restore state. */
 2044  8 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 2045  8 MarshalledValueInputStream is = new MarshalledValueInputStream(bais);
 2046  8 loader.storeState(BUDDY_BASE, is);
 2047  8 is.close();
 2048  8 addDelay();
 2049  8 assertEquals(c1, loader.get(BUDDY_PLUS_FQN).get(1));
 2050  8 assertEquals(c2, loader.get(BUDDY_PLUS_FQN).get(2));
 2051  8 assertEquals(2, loader.get(BUDDY_PLUS_FQN).size());
 2052  8 assertEquals(c3, loader.get(BUDDY_PLUS_SUBTREE_FQN).get(1));
 2053  8 assertEquals(c4, loader.get(BUDDY_PLUS_SUBTREE_FQN).get(2));
 2054  8 assertEquals(2, loader.get(BUDDY_PLUS_SUBTREE_FQN).size());
 2055   
 2056    }
 2057   
 2058  9 public void testCacheLoaderThreadSafety() throws Exception
 2059    {
 2060  9 threadSafetyTest(true);
 2061    }
 2062   
 2063  9 public void testCacheLoaderThreadSafetyMultipleFqns() throws Exception
 2064    {
 2065  9 threadSafetyTest(false);
 2066    }
 2067   
 2068  18 protected void threadSafetyTest(final boolean singleFqn) throws Exception
 2069    {
 2070  18 final CountDownLatch latch = new CountDownLatch(1);
 2071  18 final Fqn fqn = Fqn.fromString("/a/b/c");
 2072  18 final List<Fqn> fqns = new ArrayList<Fqn>(30);
 2073  18 final Random r = new Random();
 2074  18 if (!singleFqn)
 2075    {
 2076  9 for (int i = 0; i < 30; i++)
 2077    {
 2078  270 Fqn f = Fqn.fromString("/a/b/c/" + i);
 2079  270 fqns.add(f);
 2080  270 loader.put(f, "k", "v");
 2081    }
 2082    }
 2083    else
 2084    {
 2085  9 loader.put(fqn, "k", "v");
 2086    }
 2087  18 final int loops = 1000;
 2088  18 final Set<Exception> exceptions = new CopyOnWriteArraySet<Exception>();
 2089   
 2090  18 Thread remover1 = new Thread("Remover-1")
 2091    {
 2092  18 public void run()
 2093    {
 2094  18 try
 2095    {
 2096  18 latch.await();
 2097  18 for (int i = 0; i < loops; i++)
 2098    {
 2099  18000 loader.remove(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())));
 2100    }
 2101    }
 2102    catch (Exception e)
 2103    {
 2104  0 exceptions.add(e);
 2105    }
 2106    }
 2107    };
 2108   
 2109  18 remover1.start();
 2110   
 2111  18 Thread remover2 = new Thread("Remover-2")
 2112    {
 2113  18 public void run()
 2114    {
 2115  18 try
 2116    {
 2117  18 latch.await();
 2118  18 for (int i = 0; i < loops; i++)
 2119    {
 2120  18000 loader.remove(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())), "k");
 2121    }
 2122    }
 2123    catch (Exception e)
 2124    {
 2125  0 exceptions.add(e);
 2126    }
 2127    }
 2128    };
 2129   
 2130  18 remover2.start();
 2131   
 2132   
 2133  18 Thread reader1 = new Thread("Reader-1")
 2134    {
 2135  18 public void run()
 2136    {
 2137  18 try
 2138    {
 2139  18 latch.await();
 2140  18 for (int i = 0; i < loops; i++)
 2141    {
 2142  18000 loader.get(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())));
 2143    }
 2144    }
 2145    catch (Exception e)
 2146    {
 2147  0 exceptions.add(e);
 2148    }
 2149    }
 2150    };
 2151  18 reader1.start();
 2152   
 2153  18 Thread reader2 = new Thread("Reader-2")
 2154    {
 2155  18 public void run()
 2156    {
 2157  18 try
 2158    {
 2159  18 latch.await();
 2160  18 for (int i = 0; i < loops; i++)
 2161    {
 2162  18000 loader.getChildrenNames(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())));
 2163    }
 2164    }
 2165    catch (Exception e)
 2166    {
 2167  0 exceptions.add(e);
 2168    }
 2169    }
 2170    };
 2171  18 reader2.start();
 2172   
 2173   
 2174  18 Thread writer1 = new Thread("Writer-1")
 2175    {
 2176  18 public void run()
 2177    {
 2178  18 try
 2179    {
 2180  18 latch.await();
 2181  18 for (int i = 0; i < loops; i++)
 2182    {
 2183  18000 loader.put(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())), "k", "v");
 2184    }
 2185    }
 2186    catch (Exception e)
 2187    {
 2188  0 exceptions.add(e);
 2189    }
 2190    }
 2191    };
 2192  18 writer1.start();
 2193   
 2194  18 Thread writer2 = new Thread("Writer-2")
 2195    {
 2196  18 public void run()
 2197    {
 2198  18 try
 2199    {
 2200  18 latch.await();
 2201  18 for (int i = 0; i < loops; i++)
 2202    {
 2203  18000 loader.put(singleFqn ? fqn : fqns.get(r.nextInt(fqns.size())), new HashMap());
 2204    }
 2205    }
 2206    catch (Exception e)
 2207    {
 2208  0 exceptions.add(e);
 2209    }
 2210    }
 2211    };
 2212  18 writer2.start();
 2213   
 2214   
 2215  18 latch.countDown();
 2216  18 reader1.join();
 2217  18 reader2.join();
 2218  18 remover1.join();
 2219  18 remover2.join();
 2220  18 writer1.join();
 2221  18 writer2.join();
 2222   
 2223  0 for (Exception e : exceptions) throw e;
 2224    }
 2225   
 2226  60 protected TransactionManager getTransactionManager()
 2227    {
 2228  60 return DummyTransactionManager.getInstance();
 2229    }
 2230    }