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 ; 15 import java.util.Random ; 16 17 23 public class NodeMoveAPITest extends AbstractCacheLoaderTestBase 24 { 25 26 protected Node rootNode, nodeA, nodeB, nodeC, nodeD, nodeE; 27 protected CacheImpl cache; 28 protected TransactionManager 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 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 36 { 37 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 64 65 assertTrue(rootNode.hasChild(A)); 66 assertTrue(rootNode.hasChild(B)); 67 assertFalse(rootNode.hasChild(C)); 68 assertTrue(nodeA.hasChild(C)); 69 70 assertEquals("" + nodeA, vA, nodeA.get(k)); 72 assertEquals(vB, nodeB.get(k)); 73 assertEquals(vC, nodeC.get(k)); 74 75 assertEquals(nodeA, nodeC.getParent()); 77 78 log.info("BEFORE MOVE " + cache); 79 cache.move(nodeC.getFqn(), nodeB.getFqn()); 81 82 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 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 assertEquals(vA, nodeA.get(k)); 103 assertEquals(vB, nodeB.get(k)); 104 assertEquals(vC, nodeC.get(k)); 105 106 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 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 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 log.info("move " + nodeC + " to " + nodeB); 146 cache.move(nodeC.getFqn(), nodeB.getFqn()); 147 150 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 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 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 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 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 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 cache.move(nodeB.getFqn(), Fqn.ROOT); 221 222 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 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 246 { 247 doCacheLoaderTest(false, false); 248 } 249 250 public void testWithPassivation() throws Exception 251 { 252 doCacheLoaderTest(true, false); 253 } 254 255 public void testWithCacheloadersTx() throws Exception 256 { 257 doCacheLoaderTest(false, true); 258 } 259 260 public void testWithPassivationTx() throws Exception 261 { 262 doCacheLoaderTest(true, true); 263 } 264 265 protected void doCacheLoaderTest(boolean pasv, boolean useTx) throws Exception 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 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 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 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 if (useTx) tm.begin(); 325 cache.move(nodeC.getFqn(), nodeB.getFqn()); 326 327 if (useTx) tm.commit(); 335 342 log.info("Post commit tree is " + cache.printDetails()); 343 344 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 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 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 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 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 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 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 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 445 { 446 if (optimistic) return; 448 449 final int N = 3; final int loops = 1 << 6; 460 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 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 [] movers = new Thread [N]; 474 final Latch latch = new Latch(); 475 final Random r = new Random (); 476 477 for (int i = 0; i < N; i++) 478 { 479 movers[i] = new Thread ("Mover-" + i) 480 { 481 public void run() 482 { 483 try 484 { 485 latch.acquire(); 486 } 487 catch (InterruptedException 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 } 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 } 512 TestingUtil.sleepRandom(250); 513 } 514 } 515 }; 516 movers[i].start(); 517 } 518 519 latch.release(); 520 521 for (Thread 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 |