KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > api > NodeMoveAPITest


1 package org.jboss.cache.api;
2
3 import EDU.oswego.cs.dl.util.concurrent.Latch;
4 import org.jboss.cache.CacheImpl;
5 import org.jboss.cache.Fqn;
6 import org.jboss.cache.Node;
7 import org.jboss.cache.NodeNotExistsException;
8 import org.jboss.cache.config.Configuration;
9 import org.jboss.cache.factories.DefaultCacheFactory;
10 import org.jboss.cache.loader.AbstractCacheLoaderTestBase;
11 import org.jboss.cache.loader.DummyInMemoryCacheLoader;
12 import org.jboss.cache.misc.TestingUtil;
13
14 import javax.transaction.TransactionManager JavaDoc;
15 import java.util.Random JavaDoc;
16
17 /**
18  * Excercises and tests the new move() api
19  *
20  * @author <a HREF="mailto:manik@jboss.org">Manik Surtani</a>
21  * @since 2.0.0
22  */

23 public class NodeMoveAPITest extends AbstractCacheLoaderTestBase
24 {
25
26    protected Node rootNode, nodeA, nodeB, nodeC, nodeD, nodeE;
27    protected CacheImpl cache;
28    protected TransactionManager JavaDoc tm;
29    protected static final Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b"), C = Fqn.fromString("/c"), D = Fqn.fromString("/d"), E = Fqn.fromString("/e");
30    protected Object JavaDoc k = "key", vA = "valueA", vB = "valueB", vC = "valueC", vD = "valueD", vE = "valueE";
31
32    protected boolean optimistic = false;
33
34
35    protected void setUp() throws Exception JavaDoc
36    {
37       // start a single cache instance
38
cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache("META-INF/local-tx-service.xml", false);
39       cache.getConfiguration().setNodeLockingScheme(optimistic ? Configuration.NodeLockingScheme.OPTIMISTIC : Configuration.NodeLockingScheme.PESSIMISTIC);
40       cache.start();
41       rootNode = cache.getRoot();
42       tm = cache.getTransactionManager();
43    }
44
45    protected void tearDown()
46    {
47       if (cache != null) cache.stop();
48       if (rootNode != null) rootNode = null;
49    }
50
51
52    public void testBasicMove()
53    {
54       nodeA = rootNode.addChild(A);
55       nodeA.put(k, vA);
56       nodeB = rootNode.addChild(B);
57       nodeB.put(k, vB);
58       nodeC = nodeA.addChild(C);
59       nodeC.put(k, vC);
60       /*
61          /a/c
62          /b
63        */

64
65       assertTrue(rootNode.hasChild(A));
66       assertTrue(rootNode.hasChild(B));
67       assertFalse(rootNode.hasChild(C));
68       assertTrue(nodeA.hasChild(C));
69
70       // test data
71
assertEquals("" + nodeA, vA, nodeA.get(k));
72       assertEquals(vB, nodeB.get(k));
73       assertEquals(vC, nodeC.get(k));
74
75       // parentage
76
assertEquals(nodeA, nodeC.getParent());
77
78       log.info("BEFORE MOVE " + cache);
79       // move
80
cache.move(nodeC.getFqn(), nodeB.getFqn());
81
82       // re-fetch nodeC
83
nodeC = cache.get(new Fqn(nodeB.getFqn(), C));
84
85       log.info("POST MOVE " + cache);
86       log.info("HC " + nodeC + " " + System.identityHashCode(nodeC));
87       Node x = cache.getRoot().getChild(Fqn.fromString("b/c"));
88       log.info("HC " + x + " " + System.identityHashCode(x));
89       /*
90          /a
91          /b/c
92       */

93       assertEquals("NODE C " + nodeC, "/b/c", nodeC.getFqn().toString());
94
95       assertTrue(rootNode.hasChild(A));
96       assertTrue(rootNode.hasChild(B));
97       assertFalse(rootNode.hasChild(C));
98       assertFalse(nodeA.hasChild(C));
99       assertTrue(nodeB.hasChild(C));
100
101       // test data
102
assertEquals(vA, nodeA.get(k));
103       assertEquals(vB, nodeB.get(k));
104       assertEquals(vC, nodeC.get(k));
105
106       // parentage
107
assertEquals("B is parent of C: " + nodeB, nodeB, nodeC.getParent());
108    }
109
110    public void testMoveWithChildren()
111    {
112       nodeA = rootNode.addChild(A);
113       nodeA.put(k, vA);
114       nodeB = rootNode.addChild(B);
115       nodeB.put(k, vB);
116       nodeC = nodeA.addChild(C);
117       nodeC.put(k, vC);
118       nodeD = nodeC.addChild(D);
119       nodeD.put(k, vD);
120       nodeE = nodeD.addChild(E);
121       nodeE.put(k, vE);
122
123       assertTrue(rootNode.hasChild(A));
124       assertTrue(rootNode.hasChild(B));
125       assertFalse(rootNode.hasChild(C));
126       assertTrue(nodeA.hasChild(C));
127       assertTrue(nodeC.hasChild(D));
128       assertTrue(nodeD.hasChild(E));
129
130       // test data
131
assertEquals(vA, nodeA.get(k));
132       assertEquals(vB, nodeB.get(k));
133       assertEquals(vC, nodeC.get(k));
134       assertEquals(vD, nodeD.get(k));
135       assertEquals(vE, nodeE.get(k));
136
137       // parentage
138
assertEquals(rootNode, nodeA.getParent());
139       assertEquals(rootNode, nodeB.getParent());
140       assertEquals(nodeA, nodeC.getParent());
141       assertEquals(nodeC, nodeD.getParent());
142       assertEquals(nodeD, nodeE.getParent());
143
144       // move
145
log.info("move " + nodeC + " to " + nodeB);
146       cache.move(nodeC.getFqn(), nodeB.getFqn());
147       //System.out.println("nodeB " + nodeB);
148
//System.out.println("nodeC " + nodeC);
149

150       // child nodes will need refreshing, since existing pointers will be stale.
151
nodeC = nodeB.getChild(C);
152       nodeD = nodeC.getChild(D);
153       nodeE = nodeD.getChild(E);
154
155       System.out.println("Tree " + cache.printLockInfo());
156
157       assertTrue(rootNode.hasChild(A));
158       assertTrue(rootNode.hasChild(B));
159       assertFalse(rootNode.hasChild(C));
160       assertFalse(nodeA.hasChild(C));
161       assertTrue(nodeB.hasChild(C));
162       assertTrue(nodeC.hasChild(D));
163       assertTrue(nodeD.hasChild(E));
164
165       // test data
166
assertEquals(vA, nodeA.get(k));
167       assertEquals(vB, nodeB.get(k));
168       assertEquals(vC, nodeC.get(k));
169       assertEquals(vD, nodeD.get(k));
170       assertEquals(vE, nodeE.get(k));
171
172       // parentage
173
assertEquals(rootNode, nodeA.getParent());
174       assertEquals(rootNode, nodeB.getParent());
175       assertEquals(nodeB, nodeC.getParent());
176       assertEquals(nodeC, nodeD.getParent());
177       assertEquals(nodeD, nodeE.getParent());
178    }
179
180    public void testTxCommit() throws Exception JavaDoc
181    {
182       nodeA = rootNode.addChild(A);
183       nodeB = nodeA.addChild(B);
184
185       assertEquals(rootNode, nodeA.getParent());
186       assertEquals(nodeA, nodeB.getParent());
187       assertEquals(nodeA, rootNode.getChildren().iterator().next());
188       assertEquals(nodeB, nodeA.getChildren().iterator().next());
189
190       tm.begin();
191       // move node B up to hang off the root
192
cache.move(nodeB.getFqn(), Fqn.ROOT);
193
194       tm.commit();
195
196       nodeB = rootNode.getChild(B);
197
198       assertEquals(rootNode, nodeA.getParent());
199       assertEquals(rootNode, nodeB.getParent());
200
201       assertTrue(rootNode.getChildren().contains(nodeA));
202       assertTrue(rootNode.getChildren().contains(nodeB));
203
204       assertTrue(nodeA.getChildren().isEmpty());
205    }
206
207    public void testTxRollback() throws Exception JavaDoc
208    {
209       nodeA = rootNode.addChild(A);
210       nodeB = nodeA.addChild(B);
211
212       assertEquals(rootNode, nodeA.getParent());
213       assertEquals(nodeA, nodeB.getParent());
214       assertEquals(nodeA, rootNode.getChildren().iterator().next());
215       assertEquals(nodeB, nodeA.getChildren().iterator().next());
216
217
218       tm.begin();
219       // move node B up to hang off the root
220
cache.move(nodeB.getFqn(), Fqn.ROOT);
221
222       // need to think of a way to test the same with optimistically locked nodes
223
if (!optimistic)
224       {
225          assertEquals(rootNode, nodeA.getParent());
226          assertEquals(rootNode, nodeB.getParent());
227          assertTrue(rootNode.getChildren().contains(nodeA));
228          assertTrue(rootNode.getChildren().contains(nodeB));
229          assertTrue(nodeA.getChildren().isEmpty());
230       }
231
232
233       tm.rollback();
234
235       nodeA = rootNode.getChild(A);
236       nodeB = nodeA.getChild(B);
237
238       // should revert
239
assertEquals(rootNode, nodeA.getParent());
240       assertEquals(nodeA, nodeB.getParent());
241       assertEquals(nodeA, rootNode.getChildren().iterator().next());
242       assertEquals(nodeB, nodeA.getChildren().iterator().next());
243    }
244
245    public void testWithCacheloaders() throws Exception JavaDoc
246    {
247       doCacheLoaderTest(false, false);
248    }
249
250    public void testWithPassivation() throws Exception JavaDoc
251    {
252       doCacheLoaderTest(true, false);
253    }
254
255    public void testWithCacheloadersTx() throws Exception JavaDoc
256    {
257       doCacheLoaderTest(false, true);
258    }
259
260    public void testWithPassivationTx() throws Exception JavaDoc
261    {
262       doCacheLoaderTest(true, true);
263    }
264
265    protected void doCacheLoaderTest(boolean pasv, boolean useTx) throws Exception JavaDoc
266    {
267       cache.stop();
268       cache.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig(pasv, "", DummyInMemoryCacheLoader.class.getName(), null, false, false, false, false));
269       cache.start();
270
271       DummyInMemoryCacheLoader loader = (DummyInMemoryCacheLoader) cache.getCacheLoaderManager().getCacheLoader();
272
273       rootNode.put("key", "value");
274
275       if (!pasv) assertEquals("value", loader.get(Fqn.ROOT).get("key"));
276
277       nodeA = rootNode.addChild(A);
278       nodeA.put(k, vA);
279       nodeB = rootNode.addChild(B);
280       nodeB.put(k, vB);
281       nodeC = nodeA.addChild(C);
282       nodeC.put(k, vC);
283       nodeD = nodeC.addChild(D);
284       nodeD.put(k, vD);
285       nodeE = nodeD.addChild(E);
286       nodeE.put(k, vE);
287       /*
288       Node nodeF = nodeE.addChild(Fqn.fromString("F"));
289       nodeF.put(k, vE);
290       Node nodeG = nodeF.addChild(Fqn.fromString("G"));
291       nodeG.put(k, vE);
292       */

293
294       assertTrue(rootNode.hasChild(A));
295       assertTrue(rootNode.hasChild(B));
296       assertFalse(rootNode.hasChild(C));
297       assertTrue(nodeA.hasChild(C));
298       assertTrue(nodeC.hasChild(D));
299       assertTrue(nodeD.hasChild(E));
300
301       // test data
302
assertEquals(vA, nodeA.get(k));
303       assertEquals(vB, nodeB.get(k));
304       assertEquals(vC, nodeC.get(k));
305       assertEquals(vD, nodeD.get(k));
306       assertEquals(vE, nodeE.get(k));
307
308       // parentage
309
assertEquals(rootNode, nodeA.getParent());
310       assertEquals(rootNode, nodeB.getParent());
311       assertEquals(nodeA, nodeC.getParent());
312       assertEquals(nodeC, nodeD.getParent());
313       assertEquals(nodeD, nodeE.getParent());
314
315       System.out.println("Loader" + loader);
316
317       log.info("Current tree is " + cache.printDetails());
318
319       cache.evict(Fqn.ROOT, true);
320
321       log.info("POST EVICT tree is " + cache.printDetails());
322
323       // move
324
if (useTx) tm.begin();
325       cache.move(nodeC.getFqn(), nodeB.getFqn());
326
327 // Fqn[] fqns = {A, B, new Fqn(B, C), new Fqn(new Fqn(B, C), D), new Fqn(new Fqn(new Fqn(B, C), D), E)};
328
// System.out.println("*** LOADER BEFORE COMMIT ");
329
// for (Fqn f: fqns)
330
// {
331
// System.out.println(" Fqn: " + f);
332
// System.out.println(" Contents in loader: " + loader.get(f));
333
// }
334
if (useTx) tm.commit();
335 // System.out.println("*** LOADER AFTER COMMIT ");
336
// for (Fqn f: fqns)
337
// {
338
// System.out.println(" Fqn: " + f);
339
// System.out.println(" Contents in loader: " + loader.get(f));
340
// }
341

342       log.info("Post commit tree is " + cache.printDetails());
343
344       // after eviction, the node objects we hold are probably stale.
345
nodeA = rootNode.getChild(A);
346       nodeB = rootNode.getChild(B);
347       nodeC = nodeB.getChild(C);
348       log.info("Current tree is " + cache.printDetails());
349       log.info("nodeC get child B ");
350       nodeD = nodeC.getChild(D);
351       log.info("Current tree is " + cache.printDetails());
352       log.info("nodeD get child E ");
353       nodeE = nodeD.getChild(E);
354
355       log.info("Current tree is " + cache.printDetails());
356
357       Fqn old_C = new Fqn(C);
358       Fqn old_D = new Fqn(old_C, D);
359       Fqn old_E = new Fqn(old_D, E);
360
361       assertTrue(rootNode.hasChild(A));
362       assertTrue(rootNode.hasChild(B));
363       assertFalse(rootNode.hasChild(C));
364       assertFalse(nodeA.hasChild(C));
365       assertTrue(nodeB.hasChild(C));
366
367       assertTrue(nodeC.hasChild(D));
368       assertTrue(nodeD.hasChild(E));
369
370       // test data
371
assertEquals(vA, nodeA.get(k));
372       assertEquals(vB, nodeB.get(k));
373       assertEquals(vC, nodeC.get(k));
374       assertEquals(vD, nodeD.get(k));
375       assertEquals(vE, nodeE.get(k));
376
377       // parentage
378
assertEquals(rootNode, nodeA.getParent());
379       assertEquals(rootNode, nodeB.getParent());
380       assertEquals(nodeB, nodeC.getParent());
381       assertEquals(nodeC, nodeD.getParent());
382       assertEquals(nodeD, nodeE.getParent());
383
384       if (pasv) cache.evict(Fqn.ROOT, true);
385
386       //now inspect the loader.
387
assertEquals(vA, loader.get(nodeA.getFqn()).get(k));
388       assertEquals(vB, loader.get(nodeB.getFqn()).get(k));
389       assertEquals(vC, loader.get(nodeC.getFqn()).get(k));
390       assertEquals(vD, loader.get(nodeD.getFqn()).get(k));
391       assertEquals(vE, loader.get(nodeE.getFqn()).get(k));
392
393       assertNull(loader.get(old_C));
394       assertNull(loader.get(old_D));
395       assertNull(loader.get(old_E));
396
397    }
398
399    public void testLocksDeepMove() throws Exception JavaDoc
400    {
401       nodeA = rootNode.addChild(A);
402       nodeB = nodeA.addChild(B);
403       nodeD = nodeB.addChild(D);
404       nodeC = rootNode.addChild(C);
405       assertEquals(0, cache.getNumberOfLocksHeld());
406       tm.begin();
407
408       cache.move(nodeC.getFqn(), nodeB.getFqn());
409 // nodeC should have a RL, nodeA should have a RL, nodeB should have a WL, nodeD should have a WL
410

411       System.out.println("LOCKS: " + cache.printLockInfo());
412
413       assertEquals("ROOT should have a RL, nodeC should have a RL, nodeA should have a RL, nodeB should have a WL, nodeD should have a WL", 5, cache.getNumberOfLocksHeld());
414
415
416       tm.commit();
417
418       assertEquals(0, cache.getNumberOfLocksHeld());
419    }
420
421    public void testLocks() throws Exception JavaDoc
422    {
423       nodeA = rootNode.addChild(A);
424       nodeB = nodeA.addChild(B);
425       nodeC = rootNode.addChild(C);
426       assertEquals(0, cache.getNumberOfLocksHeld());
427       tm.begin();
428
429       cache.move(nodeC.getFqn(), nodeB.getFqn());
430
431 // nodeC should have a RL, nodeA should have a RL, nodeB should have a WL
432

433       System.out.println("LOCKS: " + cache.printLockInfo());
434
435       assertEquals("ROOT should have a RL, nodeC should have a RL, nodeA should have a RL, nodeB should have a WL", 4, cache.getNumberOfLocksHeld());
436
437
438       tm.commit();
439
440       assertEquals(0, cache.getNumberOfLocksHeld());
441    }
442
443
444    public void XtestConcurrency() throws InterruptedException JavaDoc
445    {
446       // TODO: investigate intermittent failure when in optimistic mode.
447
if (optimistic) return;
448
449       final int N = 3; // number of threads
450
final int loops = 1 << 6; // number of loops
451
// tests a tree structure as such:
452
// /a
453
// /b
454
// /c
455
// /d
456
// /e
457
// /x
458
// /y
459

460       // N threads constantly move /x and /y around to hang off either /a ~ /e randomly.
461

462       final Fqn FQN_A = A, FQN_B = B, FQN_C = C, FQN_D = D, FQN_E = E, FQN_X = Fqn.fromString("/x"), FQN_Y = Fqn.fromString("/y");
463
464       // set up the initial structure.
465
final Node[] NODES = {
466               rootNode.addChild(FQN_A), rootNode.addChild(FQN_B),
467               rootNode.addChild(FQN_C), rootNode.addChild(FQN_D), rootNode.addChild(FQN_E)
468       };
469
470       final Node NODE_X = NODES[0].addChild(FQN_X);
471       final Node NODE_Y = NODES[1].addChild(FQN_Y);
472
473       Thread JavaDoc[] movers = new Thread JavaDoc[N];
474       final Latch latch = new Latch();
475       final Random JavaDoc r = new Random JavaDoc();
476
477       for (int i = 0; i < N; i++)
478       {
479          movers[i] = new Thread JavaDoc("Mover-" + i)
480          {
481             public void run()
482             {
483                try
484                {
485                   latch.acquire();
486                }
487                catch (InterruptedException JavaDoc e)
488                {
489                }
490
491                for (int counter = 0; counter < loops; counter++)
492                {
493
494                   System.out.println(getName() + ": Attempt " + counter);
495                   try
496                   {
497                      cache.move(NODE_X.getFqn(), NODES[r.nextInt(NODES.length)].getFqn());
498                   }
499                   catch (NodeNotExistsException e)
500                   {
501                      // this may happen ...
502
}
503                   TestingUtil.sleepRandom(250);
504                   try
505                   {
506                      cache.move(NODE_Y.getFqn(), NODES[r.nextInt(NODES.length)].getFqn());
507                   }
508                   catch (NodeNotExistsException e)
509                   {
510                      // this may happen ...
511
}
512                   TestingUtil.sleepRandom(250);
513                }
514             }
515          };
516          movers[i].start();
517       }
518
519       latch.release();
520
521       for (Thread JavaDoc t : movers)
522       {
523          t.join();
524       }
525
526       assertEquals(0, cache.getNumberOfLocksHeld());
527       boolean found_x = false, found_x_again = false;
528       for (Node n : NODES)
529       {
530          if (!found_x)
531          {
532             found_x = n.hasChild(FQN_X);
533          }
534          else
535          {
536             found_x_again = found_x_again || n.hasChild(FQN_X);
537          }
538       }
539       boolean found_y = false, found_y_again = false;
540       for (Node n : NODES)
541       {
542          if (!found_y)
543          {
544             found_y = n.hasChild(FQN_Y);
545          }
546          else
547          {
548             found_y_again = found_y_again || n.hasChild(FQN_Y);
549          }
550       }
551
552       assertTrue("Should have found x", found_x);
553       assertTrue("Should have found y", found_y);
554       assertFalse("Should have only found x once", found_x_again);
555       assertFalse("Should have only found y once", found_y_again);
556    }
557 }
558
Popular Tags