1 5 package com.tc.object.lockmanager.impl; 6 7 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; 8 9 import com.tc.logging.NullTCLogger; 10 import com.tc.object.lockmanager.api.LockID; 11 import com.tc.object.lockmanager.api.LockLevel; 12 import com.tc.object.lockmanager.api.LockRequest; 13 import com.tc.object.lockmanager.api.ThreadID; 14 import com.tc.object.lockmanager.api.WaitListener; 15 import com.tc.object.session.TestSessionManager; 16 import com.tc.object.tx.WaitInvocation; 17 import com.tc.objectserver.lockmanager.api.LockHolder; 18 import com.tc.objectserver.lockmanager.api.LockMBean; 19 import com.tc.objectserver.lockmanager.api.NullChannelManager; 20 import com.tc.objectserver.lockmanager.api.ServerLockRequest; 21 import com.tc.objectserver.lockmanager.api.Waiter; 22 import com.tc.objectserver.lockmanager.impl.LockManagerImpl; 23 import com.tc.util.Assert; 24 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 28 import junit.framework.TestCase; 29 30 public class ClientServerLockManagerTest extends TestCase { 31 32 private ClientLockManagerImpl clientLockManager; 33 private LockManagerImpl serverLockManager; 34 private ClientServerLockManagerGlue glue; 35 private TestSessionManager sessionManager; 36 37 protected void setUp() throws Exception { 38 super.setUp(); 39 sessionManager = new TestSessionManager(); 40 glue = new ClientServerLockManagerGlue(sessionManager); 41 clientLockManager = new ClientLockManagerImpl(new NullTCLogger(), glue, sessionManager); 42 43 serverLockManager = new LockManagerImpl(new NullChannelManager()); 44 serverLockManager.setLockPolicy(LockManagerImpl.ALTRUISTIC_LOCK_POLICY); 45 glue.set(clientLockManager, serverLockManager); 46 } 47 48 public void testRWServer() { 49 final LockID lockID1 = new LockID("1"); 50 final LockID lockID2 = new LockID("2"); 51 final ThreadID tx1 = new ThreadID(1); 52 final ThreadID tx2 = new ThreadID(2); 53 final ThreadID tx3 = new ThreadID(3); 54 55 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 56 clientLockManager.lock(lockID1, tx3, LockLevel.READ); 57 clientLockManager.lock(lockID2, tx2, LockLevel.READ); 58 clientLockManager.lock(lockID2, tx2, LockLevel.WRITE); 60 clientLockManager.pause(); 61 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 62 63 LockManagerImpl server2 = glue.restartServer(); 64 65 LockMBean[] lockBeans2 = server2.getAllLocks(); 66 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 67 } 68 69 public void testWRServer() { 70 final LockID lockID1 = new LockID("1"); 71 final LockID lockID2 = new LockID("2"); 72 final ThreadID tx1 = new ThreadID(1); 73 final ThreadID tx2 = new ThreadID(2); 74 final ThreadID tx3 = new ThreadID(3); 75 76 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 77 clientLockManager.lock(lockID1, tx3, LockLevel.READ); 78 clientLockManager.lock(lockID2, tx2, LockLevel.WRITE); 79 clientLockManager.lock(lockID2, tx2, LockLevel.READ); 81 clientLockManager.pause(); 82 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 83 84 LockManagerImpl server2 = glue.restartServer(); 85 86 LockMBean[] lockBeans2 = server2.getAllLocks(); 87 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 88 } 89 90 public void testLockWaitWriteServer() throws Exception { 91 final LockID lockID1 = new LockID("1"); 92 final ThreadID tx1 = new ThreadID(1); 93 94 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 95 96 final CyclicBarrier barrier = new CyclicBarrier(2); 97 Thread waitCallThread = new Thread () { 98 99 public void run() { 100 try { 101 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 102 103 public void handleWaitEvent() { 104 try { 105 barrier.barrier(); 106 } catch (Exception e) { 107 e.printStackTrace(); 108 throw new AssertionError (e); 109 } 110 } 111 }); 112 } catch (InterruptedException ie) { 113 handleExceptionForTest(ie); 114 } 115 } 116 }; 117 waitCallThread.start(); 118 barrier.barrier(); 119 120 clientLockManager.pause(); 121 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 122 123 LockManagerImpl server2 = glue.restartServer(); 124 125 LockMBean[] lockBeans2 = server2.getAllLocks(); 126 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 127 } 128 129 public void testWaitRWServer() { 130 final LockID lockID1 = new LockID("1"); 131 final ThreadID tx1 = new ThreadID(1); 132 133 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 134 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 136 Thread waitCallThread = new Thread () { 137 138 public void run() { 139 try { 140 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 141 142 public void handleWaitEvent() { 143 } 145 }); 146 } catch (InterruptedException ie) { 147 handleExceptionForTest(ie); 148 } 149 } 150 }; 151 waitCallThread.start(); 152 sleep(1000l); 153 154 clientLockManager.pause(); 155 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 156 157 LockManagerImpl server2 = glue.restartServer(); 158 159 LockMBean[] lockBeans2 = server2.getAllLocks(); 160 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 161 } 162 163 public void testWaitWRServer() { 164 final LockID lockID1 = new LockID("1"); 165 final ThreadID tx1 = new ThreadID(1); 166 167 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 168 clientLockManager.lock(lockID1, tx1, LockLevel.READ); Thread waitCallThread = new Thread () { 170 171 public void run() { 172 try { 173 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 174 175 public void handleWaitEvent() { 176 } 178 }); 179 } catch (InterruptedException ie) { 180 handleExceptionForTest(ie); 181 } 182 } 183 }; 184 waitCallThread.start(); 185 sleep(1000l); 186 187 clientLockManager.pause(); 188 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 189 190 LockManagerImpl server2 = glue.restartServer(); 191 192 LockMBean[] lockBeans2 = server2.getAllLocks(); 193 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 194 } 195 196 public void testWaitNotifyRWServer() { 197 final LockID lockID1 = new LockID("1"); 198 final ThreadID tx1 = new ThreadID(1); 199 final ThreadID tx2 = new ThreadID(2); 200 201 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 202 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 204 Thread waitCallThread = new Thread () { 205 206 public void run() { 207 try { 208 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 209 210 public void handleWaitEvent() { 211 } 213 }); 214 } catch (InterruptedException ie) { 215 handleExceptionForTest(ie); 216 } 217 } 218 }; 219 waitCallThread.start(); 220 sleep(1000l); 221 222 clientLockManager.lock(lockID1, tx2, LockLevel.WRITE); 227 glue.notify(lockID1, tx2, true); 228 clientLockManager.unlock(lockID1, tx2); 229 sleep(1000l); 230 231 clientLockManager.pause(); 232 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 233 234 LockManagerImpl server2 = glue.restartServer(); 235 236 LockMBean[] lockBeans2 = server2.getAllLocks(); 237 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 238 } 239 240 public void testWaitNotifyRWClientServer() { 241 final LockID lockID1 = new LockID("1"); 242 final ThreadID tx1 = new ThreadID(1); 243 final ThreadID tx2 = new ThreadID(2); 244 245 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 246 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 248 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 249 250 Thread waitCallThread = new Thread () { 251 252 public void run() { 253 try { 254 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 255 256 public void handleWaitEvent() { 257 } 259 }); 260 } catch (InterruptedException ie) { 261 handleExceptionForTest(ie); 262 } 263 } 264 }; 265 waitCallThread.start(); 266 sleep(1000l); 267 268 clientLockManager.lock(lockID1, tx2, LockLevel.WRITE); 269 273 glue.notify(lockID1, tx2, true); 274 clientLockManager.unlock(lockID1, tx2); 275 sleep(1000l); 276 277 clientLockManager.pause(); 278 clientLockManager.starting(); 279 boolean found = false; 280 for (Iterator i = clientLockManager.addAllHeldLocksTo(new HashSet ()).iterator(); i.hasNext();) { 281 LockRequest request = (LockRequest) i.next(); 282 if (request.lockID().equals(lockID1) && request.threadID().equals(tx1)) { 283 if (!LockLevel.isRead(request.lockLevel()) || !LockLevel.isWrite(request.lockLevel())) { 284 throw new AssertionError ("Lock Level is not READ WRITE"); 286 } 287 found = true; 288 break; 289 } 290 } 291 if (!found) { 292 throw new AssertionError ("Didn't find the lock I am looking for"); 294 } 295 LockMBean[] lockBeans2 = serverLockManager.getAllLocks(); 296 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 297 } 298 299 public void testWaitNotifyWRClientServer() { 300 final LockID lockID1 = new LockID("1"); 301 final ThreadID tx1 = new ThreadID(1); 302 final ThreadID tx2 = new ThreadID(2); 303 304 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 305 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 306 307 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 308 309 Thread waitCallThread = new Thread () { 310 311 public void run() { 312 try { 313 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 314 315 public void handleWaitEvent() { 316 } 318 }); 319 } catch (InterruptedException ie) { 320 handleExceptionForTest(ie); 321 } 322 } 323 }; 324 waitCallThread.start(); 325 sleep(1000l); 326 327 clientLockManager.lock(lockID1, tx2, LockLevel.WRITE); 328 332 glue.notify(lockID1, tx2, true); 333 clientLockManager.unlock(lockID1, tx2); 334 sleep(1000l); 335 336 clientLockManager.pause(); 337 clientLockManager.starting(); 338 boolean found = false; 339 for (Iterator i = clientLockManager.addAllHeldLocksTo(new HashSet ()).iterator(); i.hasNext();) { 340 LockRequest request = (LockRequest) i.next(); 341 if (request.lockID().equals(lockID1) && request.threadID().equals(tx1)) { 342 if (LockLevel.isRead(request.lockLevel()) || !LockLevel.isWrite(request.lockLevel())) { 344 throw new AssertionError ("Server Lock Level is not WRITE only on the client side"); 346 } 347 found = true; 348 break; 349 } 350 } 351 Assert.assertTrue(clientLockManager.haveLock(lockID1, tx1, LockLevel.READ | LockLevel.WRITE)); 352 if (!found) { 353 throw new AssertionError ("Didn't find the lock I am looking for"); 355 } 356 LockMBean[] lockBeans2 = serverLockManager.getAllLocks(); 357 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 358 } 359 360 public void testPendingWaitNotifiedRWClientServer() { 361 final LockID lockID1 = new LockID("1"); 362 final ThreadID tx1 = new ThreadID(1); 363 final ThreadID tx2 = new ThreadID(2); 364 365 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 366 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 367 368 Thread waitCallThread = new Thread () { 369 370 public void run() { 371 try { 372 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 373 374 public void handleWaitEvent() { 375 } 377 }); 378 } catch (InterruptedException ie) { 379 handleExceptionForTest(ie); 380 } 381 } 382 }; 383 waitCallThread.start(); 384 sleep(1000l); 385 386 clientLockManager.lock(lockID1, tx2, LockLevel.WRITE); 387 391 glue.notify(lockID1, tx2, true); 392 sleep(1000l); 393 394 clientLockManager.pause(); 395 clientLockManager.starting(); 396 boolean found = false; 397 for (Iterator i = clientLockManager.addAllHeldLocksTo(new HashSet ()).iterator(); i.hasNext();) { 398 LockRequest request = (LockRequest) i.next(); 399 if (request.lockID().equals(lockID1) && request.threadID().equals(tx2)) { 400 if (LockLevel.isRead(request.lockLevel()) || !LockLevel.isWrite(request.lockLevel())) { 401 throw new AssertionError ("Server Lock Level is not WRITE only on tx2 the client side"); 403 } 404 found = true; 405 break; 406 } 407 } 408 if (!found) { 409 throw new AssertionError ("Didn't find the lock I am looking for"); 411 } 412 413 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 414 415 LockManagerImpl server2 = glue.restartServer(); 416 417 LockMBean[] lockBeans2 = server2.getAllLocks(); 418 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 419 } 420 421 public void testPendingWaitNotifiedWRClientServer() { 422 final LockID lockID1 = new LockID("1"); 423 final ThreadID tx1 = new ThreadID(1); 424 final ThreadID tx2 = new ThreadID(2); 425 426 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 427 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 428 429 Thread waitCallThread = new Thread () { 430 431 public void run() { 432 try { 433 clientLockManager.wait(lockID1, tx1, new WaitInvocation(), new Object (), new WaitListener() { 434 435 public void handleWaitEvent() { 436 } 438 }); 439 } catch (InterruptedException ie) { 440 handleExceptionForTest(ie); 441 } 442 } 443 }; 444 waitCallThread.start(); 445 sleep(1000l); 446 447 clientLockManager.lock(lockID1, tx2, LockLevel.WRITE); 448 452 glue.notify(lockID1, tx2, true); 453 sleep(1000l); 454 455 clientLockManager.pause(); 456 clientLockManager.starting(); 457 boolean found = false; 458 for (Iterator i = clientLockManager.addAllHeldLocksTo(new HashSet ()).iterator(); i.hasNext();) { 459 LockRequest request = (LockRequest) i.next(); 460 if (request.lockID().equals(lockID1) && request.threadID().equals(tx2)) { 461 if (LockLevel.isRead(request.lockLevel()) || !LockLevel.isWrite(request.lockLevel())) { 462 throw new AssertionError ("Server Lock Level is not WRITE only on tx2 the client side"); 464 } 465 found = true; 466 break; 467 } 468 } 469 if (!found) { 470 throw new AssertionError ("Didn't find the lock I am looking for"); 472 } 473 474 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 475 LockManagerImpl server2 = glue.restartServer(); 476 477 LockMBean[] lockBeans2 = server2.getAllLocks(); 478 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 479 } 480 481 public void testPendingRequestClientServer() { 482 final LockID lockID1 = new LockID("1"); 483 final ThreadID tx1 = new ThreadID(1); 484 485 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 486 clientLockManager.lock(lockID1, tx1, LockLevel.READ); 487 488 Thread pendingLockRequestThread = new Thread () { 489 490 public void run() { 491 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 492 } 493 }; 494 pendingLockRequestThread.start(); 495 sleep(1000l); 496 497 clientLockManager.pause(); 498 499 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 500 LockManagerImpl server2 = glue.restartServer(); 501 502 LockMBean[] lockBeans2 = server2.getAllLocks(); 503 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 504 } 505 506 public void testWRClient() { 507 final LockID lockID1 = new LockID("1"); 508 final ThreadID tx1 = new ThreadID(1); 509 510 clientLockManager.lock(lockID1, tx1, LockLevel.WRITE); 511 clientLockManager.lock(lockID1, tx1, LockLevel.READ); clientLockManager.unlock(lockID1, tx1); 514 clientLockManager.pause(); 515 clientLockManager.starting(); 516 517 boolean found = false; 518 for (Iterator i = clientLockManager.addAllHeldLocksTo(new HashSet ()).iterator(); i.hasNext();) { 519 LockRequest request = (LockRequest) i.next(); 520 if (request.lockID().equals(lockID1) && request.threadID().equals(tx1)) { 521 if (LockLevel.isRead(request.lockLevel()) || !LockLevel.isWrite(request.lockLevel())) { 522 throw new AssertionError ("Lock Level is not WRITE only"); 524 } 525 found = true; 526 break; 527 } 528 } 529 if (!found) { throw new AssertionError ("Didn't find the lock I am looking for"); } 530 } 531 532 public void testConcurrentLocksServerRestart() { 533 final LockID lockID1 = new LockID("1"); 534 final ThreadID tx1 = new ThreadID(1); 535 final ThreadID tx2 = new ThreadID(2); 536 537 clientLockManager.lock(lockID1, tx1, LockLevel.CONCURRENT); 538 clientLockManager.lock(lockID1, tx2, LockLevel.CONCURRENT); 539 540 clientLockManager.pause(); 541 LockMBean[] lockBeans1 = serverLockManager.getAllLocks(); 542 543 LockManagerImpl server2 = glue.restartServer(); 544 545 LockMBean[] lockBeans2 = server2.getAllLocks(); 546 if (!equals(lockBeans1, lockBeans2)) { throw new AssertionError ("The locks are not the same"); } 547 } 548 549 private boolean equals(LockMBean[] lockBeans1, LockMBean[] lockBeans2) { 550 if (lockBeans1.length != lockBeans2.length) { return false; } 551 for (int i = 0; i < lockBeans1.length; i++) { 552 String lockName1 = lockBeans1[i].getLockName(); 553 boolean found = false; 554 for (int j = 0; j < lockBeans2.length; j++) { 555 String lockName2 = lockBeans2[j].getLockName(); 556 if (lockName1.equals(lockName2)) { 557 if (!equals(lockBeans1[i], lockBeans2[j])) { return false; } 558 found = true; 559 break; 560 } 561 } 562 if (!found) { return false; } 563 } 564 return true; 565 } 566 567 private boolean equals(LockMBean bean1, LockMBean bean2) { 568 return equals(bean1.getHolders(), bean2.getHolders()) 569 && equals(bean1.getPendingRequests(), bean2.getPendingRequests()) 570 && equals(bean1.getPendingUpgrades(), bean2.getPendingUpgrades()) 571 && equals(bean1.getWaiters(), bean2.getWaiters()); 572 } 573 574 private boolean equals(Waiter[] waiters1, Waiter[] waiters2) { 575 if (waiters1 == null && waiters2 == null) { 576 return true; 577 } else if (waiters1 == null || waiters2 == null || waiters1.length != waiters2.length) { return false; } 578 for (int i = 0; i < waiters1.length; i++) { 579 boolean found = false; 580 for (int j = 0; j < waiters2.length; j++) { 581 if (waiters1[i].getThreadID().equals(waiters2[j].getThreadID())) { 582 589 found = true; 590 break; 591 } 592 } 593 if (!found) { return false; } 594 } 595 return true; 596 } 597 598 private boolean equals(ServerLockRequest[] pendingRequests1, ServerLockRequest[] pendingRequests2) { 599 if (pendingRequests1 == null && pendingRequests2 == null) { 600 return true; 601 } else if (pendingRequests1 == null || pendingRequests2 == null 602 || pendingRequests1.length != pendingRequests2.length) { 603 return false; 605 } 606 for (int i = 0; i < pendingRequests1.length; i++) { 607 boolean found = false; 608 for (int j = 0; j < pendingRequests2.length; j++) { 609 if (pendingRequests1[i].getThreadID().equals(pendingRequests2[j].getThreadID())) { 610 if (!pendingRequests1[i].getLockLevel().equals(pendingRequests2[j].getLockLevel())) { 611 System.err.println("Not equal - " + pendingRequests1[i].getLockLevel() + " - " 612 + pendingRequests2[j].getLockLevel()); 613 return false; 614 } 615 found = true; 616 break; 617 } 618 } 619 if (!found) { return false; } 620 } 621 return true; 622 } 623 624 private boolean equals(LockHolder[] holders1, LockHolder[] holders2) { 625 if (holders1 == null && holders2 == null) { 626 return true; 627 } else if (holders1 == null || holders2 == null || holders1.length != holders2.length) { return false; } 628 for (int i = 0; i < holders1.length; i++) { 629 boolean found = false; 630 for (int j = 0; j < holders2.length; j++) { 631 if (holders1[i].getThreadID().equals(holders2[j].getThreadID())) { 632 if (!holders1[i].getLockLevel().equals(holders2[j].getLockLevel())) { 633 System.out.println("Not equal - " + holders1[i] + " - " + holders2[j]); 634 return false; 635 } 636 found = true; 637 break; 638 } 639 } 640 if (!found) { return false; } 641 } 642 return true; 643 } 644 645 private void sleep(long l) { 646 try { 647 Thread.sleep(l); 648 } catch (InterruptedException e) { 649 } 651 } 652 653 private void handleExceptionForTest(Exception e) { 654 e.printStackTrace(); 655 throw new AssertionError (e); 656 } 657 658 protected void tearDown() throws Exception { 659 glue.stop(); 660 super.tearDown(); 661 } 662 } 663 | Popular Tags |