1 package org.jboss.cache.lock; 2 3 import junit.framework.Test; 4 import junit.framework.TestCase; 5 import junit.framework.TestSuite; 6 import org.jboss.cache.misc.TestingUtil; 7 8 import java.io.FileWriter ; 9 import java.io.IOException ; 10 import java.io.Writer ; 11 import java.util.Vector ; 12 import java.util.concurrent.TimeUnit ; 13 import java.util.concurrent.locks.Lock ; 14 15 30 public class ReadWriteLockWithUpgradeTest extends TestCase 31 { 32 static final ReadWriteLockWithUpgrade lock_ = new ReadWriteLockWithUpgrade(); 33 static long SLEEP_MSECS = 500; 34 Vector lockResult = new Vector (); 35 int NO_MORE_OP = 0; 36 int INVOKE_READ = 1; 37 int INVOKE_WRITE = 2; 38 int INVOKE_UPGRADE = 3; 39 40 public ReadWriteLockWithUpgradeTest(String name) 41 { 42 super(name); 43 } 44 45 46 public static void main(String [] args) throws Exception 47 { 48 log("\nBeginning ReadWriteLockWithUpgrade automated testing ...\n"); 49 50 junit.textui.TestRunner.run(suite()); 51 } 52 53 public static Test suite() 55 { 56 TestSuite suite = new TestSuite(); 57 suite.addTestSuite(ReadWriteLockWithUpgradeTest.class); 59 return suite; 60 } 61 62 public void setUp() 63 { 64 logX("\n"); 65 log("Setting up test case ..."); 66 } 67 68 public void tearDown() 69 { 70 log("Tearing down test case ..."); 71 } 72 73 public static void log(String str) 74 { 75 System.out.println(Thread.currentThread() + ": " 76 + java.util.Calendar.getInstance().getTime() + " : " + str); 77 } 78 79 public static void logX(String str) 81 { 82 log(str); 83 } 88 89 public static void logToFile(String str) throws IOException 91 { 92 Writer out = new FileWriter ("./RepeatableLogs.txt", true); 93 out.write(str); 94 out.close(); 95 } 96 97 98 99 100 146 147 protected Thread readThread(final String caseNum, final String name, 148 final long msecs, final long sleepSecs, 149 final String errMsg, final int secondOP) 150 { 151 return new Thread (name) 152 { 153 public void run() 154 { 155 Lock rlock = lock_.readLock(); 156 try 157 { 158 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) 159 { 160 logX(caseNum + "-" + name + " requesting read lock failed!\n"); 161 String str = caseNum + "-" + name + "-RL-0"; 162 postLockingResult(str); 163 return; 164 } 165 logX(caseNum + "-" + name + " requesting read lock succeeded!\n"); 167 String str = caseNum + "-" + name + "-RL-1"; 168 postLockingResult(str); 169 TestingUtil.sleepThread(sleepSecs); 170 171 if (secondOP == INVOKE_READ) 172 { 173 acquireReadLock(caseNum, name, msecs, errMsg); 174 } 175 else if (secondOP == INVOKE_WRITE) 176 { 177 acquireWriteLock(caseNum, name, msecs, errMsg); 178 } 179 else if (secondOP == INVOKE_UPGRADE) 180 { 181 acquireUpgradeLock(caseNum, name, msecs, errMsg); 182 } 183 184 rlock.unlock(); 185 logX(caseNum + "-" + name + " releasing read lock.\n"); 186 } 187 catch (Exception ex) 188 { 189 } 190 } 191 }; 192 } 193 194 201 protected Thread writeThread(final String caseNum, final String name, 202 final long msecs, final long sleepSecs, 203 final String errMsg, final int secondOP) 204 { 205 return new Thread (name) 206 { 207 public void run() 208 { 209 try 210 { 211 Lock wlock = lock_.writeLock(); 212 if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS)) 213 { 214 logX(caseNum + "-" + name + " requesting write lock failed!\n"); 215 String str = caseNum + "-" + name + "-WL-0"; 216 postLockingResult(str); 217 return; 218 } 219 logX(caseNum + "-" + name + " requesting write lock succeeded!\n"); 221 String str = caseNum + "-" + name + "-WL-1"; 222 postLockingResult(str); 223 TestingUtil.sleepThread(sleepSecs); 224 225 if (secondOP == INVOKE_READ) 226 { 227 acquireReadLock(caseNum, name, msecs, errMsg); 228 } 229 else if (secondOP == INVOKE_WRITE) 230 { 231 acquireWriteLock(caseNum, name, msecs, errMsg); 232 } 233 else if (secondOP == INVOKE_UPGRADE) 234 { 235 acquireUpgradeLock(caseNum, name, msecs, errMsg); 236 } 237 238 wlock.unlock(); 239 logX(caseNum + "-" + name + " releasing write lock.\n"); 240 } 241 catch (Exception ex) 242 { 243 } 244 } 245 }; 246 } 247 248 256 protected Thread upgradeThread(final String caseNum, final String name, 257 final long msecs, final String errMsg) 258 { 259 return new Thread (name) 260 { 261 public void run() 262 { 263 try 264 { 265 Lock rlock = lock_.readLock(); 266 Lock wlock = null; 267 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) 268 { 269 logX(caseNum + "-" + name + " requesting read lock failed!\n"); 270 String str = caseNum + "-" + name + "-RL-0"; 271 postLockingResult(str); 272 return; 273 } 274 logX(caseNum + "-" + name + " requesting read lock succeeded (upgrade later)!\n"); 276 TestingUtil.sleepThread(SLEEP_MSECS / 2); 277 String str = caseNum + "-" + name + "-UL-"; 278 if ((wlock = lock_.upgradeLockAttempt(msecs)) == null) 279 { 280 logX(caseNum + "-" + name + " requesting upgrade lock failed!\n"); 281 str += "0"; 282 } 283 else 284 { 285 logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n"); 286 str += "1"; 287 } 288 postLockingResult(str); 289 TestingUtil.sleepThread(SLEEP_MSECS); 291 if (wlock != null) 292 { 293 wlock.unlock(); 294 logX(caseNum + "-" + name + " releasing upgrade lock.\n"); 295 } 296 rlock.unlock(); 297 } 298 catch (Exception ex) 299 { 300 } 301 } 302 }; 303 } 304 305 306 307 308 314 315 protected void acquireReadLock(final String caseNum, final String name, 316 final long msecs, final String errMsg) 317 { 318 try 319 { 320 Lock rlock = lock_.readLock(); 321 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) 322 { 323 logX(caseNum + "-" + name + " requesting read lock failed!\n"); 324 String str = caseNum + "-" + name + "-RL-0"; 325 postLockingResult(str); 326 return; 327 } 328 logX(caseNum + "-" + name + " requesting read lock succeeded!\n"); 330 String str = caseNum + "-" + name + "-RL-1"; 331 postLockingResult(str); 332 TestingUtil.sleepThread(SLEEP_MSECS); 333 rlock.unlock(); 334 logX(caseNum + "-" + name + " releasing read lock.\n"); 335 } 336 catch (Exception ex) 337 { 338 } 339 } 340 341 345 protected void acquireWriteLock(final String caseNum, final String name, 346 final long msecs, final String errMsg) 347 { 348 try 349 { 350 Lock wlock = lock_.writeLock(); 351 if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS)) 352 { 353 logX(caseNum + "-" + name + " requesting write lock failed!\n"); 354 String str = caseNum + "-" + name + "-WL-0"; 355 postLockingResult(str); 356 return; 357 } 358 logX(caseNum + "-" + name + " requesting write lock succeeded!\n"); 360 String str = caseNum + "-" + name + "-WL-1"; 361 postLockingResult(str); 362 TestingUtil.sleepThread(SLEEP_MSECS); 363 wlock.unlock(); 364 logX(caseNum + "-" + name + " releasing write lock.\n"); 365 } 366 catch (Exception ex) 367 { 368 } 369 } 370 371 375 protected void acquireUpgradeLock(final String caseNum, final String name, 376 final long msecs, final String errMsg) 377 { 378 try 379 { 380 Lock ulock = null; 381 if ((ulock = lock_.upgradeLockAttempt(msecs)) == null) 382 { 383 logX(caseNum + "-" + name + " requesting upgrade lock failed!\n"); 384 String str = caseNum + "-" + name + "-UL-0"; 385 postLockingResult(str); 386 return; 387 } 388 logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n"); 390 String str = caseNum + "-" + name + "-UL-1"; 391 postLockingResult(str); 392 TestingUtil.sleepThread(SLEEP_MSECS); 393 ulock.unlock(); 394 logX(caseNum + "-" + name + " releasing upgrade lock.\n"); 395 } 396 catch (Exception ex) 397 { 398 } 399 } 400 401 402 403 404 407 protected synchronized void cleanLockingResult() 408 { 409 lockResult.removeAllElements(); 410 } 411 412 415 protected synchronized void postLockingResult(Object obj) 416 { 417 logX(" Added *" + obj + "* to the result vector\n"); 418 lockResult.addElement(obj); 421 } 422 423 426 protected synchronized boolean checkLockingResult(String expected) 427 { 428 boolean rc = false; 429 for (int i = 0; i < lockResult.size(); i++) 430 { 431 Object ele = lockResult.elementAt(i); 432 String str = (String ) ele; 433 if (expected.equals(str)) 434 { 435 rc = true; 436 break; 437 } 438 } 439 if (rc) 440 { 441 logX(" Searching for *" + expected + "* SUCCEEDED.\n"); 442 } 443 else 444 { 445 logX(" Searching for *" + expected + "* FAILED.\n"); 446 } 447 return rc; 448 } 449 450 451 452 453 456 public void testWriteWithMultipleReaders() throws Exception 457 { 458 String caseNum = "10"; 459 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2, 460 "1st read lock attempt failed", NO_MORE_OP); 461 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS, 462 "2nd read lock attempt failed", INVOKE_WRITE); 463 464 t1.start(); 465 t2.start(); 466 t1.join(3000); 467 t2.join(3000); 468 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 469 checkLockingResult(caseNum + "-t2-RL-1") && 470 checkLockingResult(caseNum + "-t2-WL-0")); 471 cleanLockingResult(); 472 if (t1.isAlive() || t2.isAlive()) 474 { 475 fail("Possible deadlock resulted in testRead."); 476 } 477 } 478 479 482 public void testUpgradeWithMultipleReadersOn1() throws Exception 483 { 484 String caseNum = "11"; 485 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS, 486 "1st read lock attempt failed", INVOKE_WRITE); 487 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS * 2, 488 "2nd read lock attempt failed", NO_MORE_OP); 489 490 t1.start(); 491 t2.start(); 492 t1.join(3000); 493 t2.join(3000); 494 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 495 checkLockingResult(caseNum + "-t2-RL-1") && 496 checkLockingResult(caseNum + "-t1-WL-0")); 497 cleanLockingResult(); 498 if (t1.isAlive() || t2.isAlive()) 500 { 501 fail("Possible deadlock resulted in testRead."); 502 } 503 } 504 505 508 public void testUpgradeReadLock() throws Exception 509 { 510 String caseNum = "2"; 511 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS, 512 "1st read lock attempt failed", INVOKE_UPGRADE); 513 514 t1.start(); 515 t1.join(3000); 516 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 517 checkLockingResult(caseNum + "-t1-UL-1")); 518 cleanLockingResult(); 519 } 520 521 524 525 public void testReadThenWrite() throws Exception 526 { 527 String caseNum = "3"; 528 acquireReadLock(caseNum, "t1", 0, "1st read lock attempt failed"); 529 acquireWriteLock(caseNum, "t1.1", 0, "2nd write lock attempt failed"); 530 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 531 checkLockingResult(caseNum + "-t1.1-WL-1")); 532 cleanLockingResult(); 533 } 534 535 536 539 540 public void testWriteThenRead() throws Exception 541 { 542 String caseNum = "5"; 543 acquireWriteLock(caseNum, "t1", 0, "1st write lock attempt failed"); 544 acquireReadLock(caseNum, "t1.1", 0, "2nd read lock attempt failed"); 545 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") && 546 checkLockingResult(caseNum + "-t1.1-RL-1")); 547 cleanLockingResult(); 548 } 549 550 553 public void testMultipleReadlock() throws Exception 554 { 555 String caseNum = "6"; 556 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS, 557 "1st read lock attempt failed", NO_MORE_OP); 558 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS, 559 "2nd read lock attempt failed", NO_MORE_OP); 560 561 t1.start(); 562 t2.start(); 563 t1.join(3000); 564 t2.join(3000); 565 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 566 checkLockingResult(caseNum + "-t2-RL-1")); 567 cleanLockingResult(); 568 if (t1.isAlive() || t2.isAlive()) 570 { 571 fail("Possible deadlock resulted in testRead."); 572 } 573 } 574 575 578 public void testWriteWithExistingReader() throws Exception 579 { 580 String caseNum = "8"; 581 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS, 582 "1st write lock attempt failed", NO_MORE_OP); 583 Thread t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS, 584 "2nd read lock attempt failed", NO_MORE_OP); 585 586 t1.start(); 587 t2.start(); 588 t1.join(3000); 589 t2.join(3000); 590 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 591 checkLockingResult(caseNum + "-t2-WL-0")); 592 cleanLockingResult(); 593 if (t1.isAlive() || t2.isAlive()) 595 { 596 fail("Possible deadlock resulted in testRead."); 597 } 598 } 599 600 603 public void testReadWithExistingWriter() throws Exception 604 { 605 String caseNum = "13"; 606 Thread t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS, 607 "1st write lock attempt failed", NO_MORE_OP); 608 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS, 609 "2nd read lock attempt failed", NO_MORE_OP); 610 611 t1.start(); 612 t2.start(); 613 t1.join(3000); 614 t2.join(3000); 615 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") && 616 checkLockingResult(caseNum + "-t2-RL-0")); 617 cleanLockingResult(); 618 if (t1.isAlive() || t2.isAlive()) 620 { 621 fail("Possible deadlock resulted in testRead."); 622 } 623 } 624 625 628 public void testMultipleWritelocks() throws Exception 629 { 630 String caseNum = "14"; 631 Thread t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS, 632 "1st write lock attempt failed", NO_MORE_OP); 633 Thread t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS, 634 "2nd write lock attempt failed", NO_MORE_OP); 635 636 t1.start(); 637 t2.start(); 638 t1.join(3000); 639 t2.join(3000); 640 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") && 641 checkLockingResult(caseNum + "-t2-WL-0")); 642 cleanLockingResult(); 643 if (t1.isAlive() || t2.isAlive()) 645 { 646 fail("Possible deadlock resulted in testRead."); 647 } 648 } 649 650 653 654 public void testUpgradeWithExistingReader() throws Exception 655 { 656 String caseNum = "7"; 657 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS, 658 "1st read lock attempt failed", NO_MORE_OP); 659 Thread t2 = upgradeThread(caseNum, "t2", 0, 660 "2nd upgrade lock attempt failed"); 661 662 t1.start(); 663 t2.start(); 664 t1.join(3000); 665 t2.join(3000); 666 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 667 checkLockingResult(caseNum + "-t2-UL-0")); 668 cleanLockingResult(); 669 if (t1.isAlive() || t2.isAlive()) 671 { 672 fail("Possible deadlock resulted in testRead."); 673 } 674 } 675 676 679 public void testUpgradeWithMultipleReaders() throws Exception 680 { 681 String caseNum = "9"; 682 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2, 683 "1st read lock attempt failed", NO_MORE_OP); 684 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS, 685 "2nd read lock attempt failed", INVOKE_UPGRADE); 686 687 t1.start(); 688 t2.start(); 689 t1.join(3000); 690 t2.join(3000); 691 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") && 692 checkLockingResult(caseNum + "-t2-RL-1") && 693 checkLockingResult(caseNum + "-t2-UL-0")); 694 cleanLockingResult(); 695 if (t1.isAlive() || t2.isAlive()) 697 { 698 fail("Possible deadlock resulted in testRead."); 699 } 700 } 701 } 702 703 | Popular Tags |