* and tests removing subtrees.
*/
public void testMultiLevelTree()
throws Exception
{
CacheLoader loader = loaderTL.get();
/* Create top level node implicitly. */
Fqn k0 = Fqn.fromString("/key0");
assertTrue(!loader.exists(k0));
loader.put(Fqn.fromString("/key0/level1/level2"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key0/level1/level2")));
assertTrue(loader.exists(Fqn.fromString("/key0/level1")));
assertTrue(loader.exists(k0));
/* Remove leaf, leaving implicitly created middle level. */
loader.put(Fqn.fromString("/key0/x/y"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key0/x/y")));
assertTrue(loader.exists(Fqn.fromString("/key0/x")));
loader.remove(Fqn.fromString("/key0/x/y"));
addDelay();
assertTrue(!loader.exists(Fqn.fromString("/key0/x/y")));
assertTrue(loader.exists(Fqn.fromString("/key0/x")));
/* Delete top level to delete everything. */
loader.remove(k0);
addDelay();
assertTrue(!loader.exists(k0));
assertTrue(!loader.exists(Fqn.fromString("/key0/level1/level2")));
assertTrue(!loader.exists(Fqn.fromString("/key0/level1")));
assertTrue(!loader.exists(Fqn.fromString("/key0/x")));
/* Add three top level nodes as context. */
loader.put(Fqn.fromString("/key1"), null);
loader.put(Fqn.fromString("/key2"), null);
loader.put(Fqn.fromString("/key3"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key1")));
assertTrue(loader.exists(Fqn.fromString("/key2")));
assertTrue(loader.exists(Fqn.fromString("/key3")));
/* Put /key3/level1/level2. level1 should be implicitly created. */
assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
loader.put(Fqn.fromString("/key3/level1/level2"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key3/level1/level2")));
assertTrue(loader.exists(Fqn.fromString("/key3/level1")));
/* Context nodes should still be intact. */
assertTrue(loader.exists(Fqn.fromString("/key1")));
assertTrue(loader.exists(Fqn.fromString("/key2")));
assertTrue(loader.exists(Fqn.fromString("/key3")));
/* Remove middle level only. */
loader.remove(Fqn.fromString("/key3/level1"));
addDelay();
assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
/* Context nodes should still be intact. */
assertTrue(loader.exists(Fqn.fromString("/key1")));
assertTrue(loader.exists(Fqn.fromString("/key2")));
assertTrue(loader.exists(Fqn.fromString("/key3")));
/* Delete first root, leaving other roots. */
loader.remove(Fqn.fromString("/key1"));
addDelay();
assertTrue(!loader.exists(Fqn.fromString("/key1")));
assertTrue(loader.exists(Fqn.fromString("/key2")));
assertTrue(loader.exists(Fqn.fromString("/key3")));
/* Delete last root, leaving other roots. */
loader.remove(Fqn.fromString("/key3"));
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key2")));
assertTrue(!loader.exists(Fqn.fromString("/key3")));
/* Delete final root, leaving none. */
loader.remove(Fqn.fromString("/key2"));
addDelay();
assertTrue(!loader.exists(k0));
assertTrue(!loader.exists(Fqn.fromString("/key1")));
assertTrue(!loader.exists(Fqn.fromString("/key2")));
assertTrue(!loader.exists(Fqn.fromString("/key3")));
/* Repeat all tests above using put(Fqn,Object,Object) and get(Fqn) */
assertNull(loader.get(k0));
loader.put(Fqn.fromString("/key0/level1/level2"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key0/level1/level2")));
assertNotNull(loader.get(Fqn.fromString("/key0/level1")));
assertTrue(loader.get(Fqn.fromString("/key0/level1")).isEmpty());
assertNotNull(loader.get(k0));
assertTrue(loader.get(Fqn.fromString("/key0")).isEmpty());
loader.put(Fqn.fromString("/key0/x/y"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key0/x/y")));
assertNotNull(loader.get(Fqn.fromString("/key0/x")));
assertTrue(loader.get(Fqn.fromString("/key0/x")).isEmpty());
loader.remove(Fqn.fromString("/key0/x/y"));
addDelay();
assertNull(loader.get(Fqn.fromString("/key0/x/y")));
assertNotNull(loader.get(Fqn.fromString("/key0/x")));
assertTrue(loader.get(Fqn.fromString("/key0/x")).isEmpty());
loader.remove(k0);
addDelay();
assertNull(loader.get(k0));
assertNull(loader.get(Fqn.fromString("/key0/level1/level2")));
assertNull(loader.get(Fqn.fromString("/key0/level1")));
assertNull(loader.get(Fqn.fromString("/key0/x")));
loader.put(Fqn.fromString("/key1"), "a", "b");
loader.put(Fqn.fromString("/key2"), "a", "b");
loader.put(Fqn.fromString("/key3"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key1")));
assertNotNull(loader.get(Fqn.fromString("/key2")));
assertNotNull(loader.get(Fqn.fromString("/key3")));
assertNull(loader.get(Fqn.fromString("/key3/level1")));
assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
loader.put(Fqn.fromString("/key3/level1/level2"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key3/level1/level2")));
assertNotNull(loader.get(Fqn.fromString("/key3/level1")));
assertTrue(loader.get(Fqn.fromString("/key3/level1")).isEmpty());
assertNotNull(loader.get(Fqn.fromString("/key1")));
assertNotNull(loader.get(Fqn.fromString("/key2")));
assertNotNull(loader.get(Fqn.fromString("/key3")));
loader.remove(Fqn.fromString("/key3/level1"));
addDelay();
assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
assertNull(loader.get(Fqn.fromString("/key3/level1")));
assertNotNull(loader.get(Fqn.fromString("/key1")));
assertNotNull(loader.get(Fqn.fromString("/key2")));
assertNotNull(loader.get(Fqn.fromString("/key3")));
loader.remove(Fqn.fromString("/key1"));
addDelay();
assertNull(loader.get(Fqn.fromString("/key1")));
assertNotNull(loader.get(Fqn.fromString("/key2")));
assertNotNull(loader.get(Fqn.fromString("/key3")));
loader.remove(Fqn.fromString("/key3"));
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key2")));
assertNull(loader.get(Fqn.fromString("/key3")));
loader.remove(Fqn.fromString("/key2"));
addDelay();
assertNull(loader.get(k0));
assertNull(loader.get(Fqn.fromString("/key1")));
assertNull(loader.get(Fqn.fromString("/key2")));
assertNull(loader.get(Fqn.fromString("/key3")));
}