1 package org.jboss.cache.lock; 2 3 import java.util.concurrent.TimeUnit ; 4 import java.util.concurrent.locks.Lock ; 5 import junit.framework.Test; 6 import junit.framework.TestCase; 7 import junit.framework.TestSuite; 8 import org.jboss.cache.misc.TestingUtil; 9 10 import java.io.FileWriter ; 11 import java.io.IOException ; 12 import java.io.Writer ; 13 import java.util.Vector ; 14 15 30 public class NonBlockingWriterLockTest extends TestCase 31 { 32 static final NonBlockingWriterLock lock_ = new NonBlockingWriterLock(); 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 NonBlockingWriterLockTest(String name) 41 { 42 super(name); 43 } 44 45 46 public static void main(String [] args) throws Exception 47 { 48 log("\nBeginning NonBlockingWriterLock 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(NonBlockingWriterLockTest.class); 59 return suite; 60 } 61 62 public void setUp() throws Exception { 63 super.setUp(); 64 logX("\n"); 65 log("Setting up test case ..."); 66 } 67 68 public void tearDown() throws Exception { 69 super.tearDown(); 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 ("./ReadCommittedLog.txt", true); 93 out.write(str); 94 out.close(); 95 } 96 97 98 99 100 145 146 protected Thread readThread(final String caseNum, final String name, 147 final long msecs, final long sleepSecs, 148 final String errMsg, final int secondOP) 149 { 150 return new Thread (name) 151 { 152 public void run() 153 { 154 Lock rlock = lock_.readLock(); 155 try { 156 if (! rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) { 157 logX(caseNum+"-"+name+" requesting read lock failed!\n"); 158 String str = caseNum + "-" + name + "-RL-0"; 159 postLockingResult(str); 160 return; 161 } 162 logX(caseNum+"-"+name+" requesting read lock succeeded!\n"); 164 String str = caseNum + "-" + name + "-RL-1"; 165 postLockingResult(str); 166 TestingUtil.sleepThread(sleepSecs); 167 168 if (secondOP == INVOKE_READ) 169 acquireReadLock(caseNum, name, msecs, errMsg); 170 else if (secondOP == INVOKE_WRITE) 171 acquireWriteLock(caseNum, name, msecs, errMsg); 172 else if (secondOP == INVOKE_UPGRADE) 173 acquireUpgradeLock(caseNum, name, msecs, errMsg); 174 175 rlock.unlock(); 176 logX(caseNum+"-"+name+" releasing read lock.\n"); 177 } catch (Exception ex) { 178 } 179 } 180 }; 181 } 182 183 189 protected Thread writeThread(final String caseNum, final String name, 190 final long msecs, final long sleepSecs, 191 final String errMsg, final int secondOP) 192 { 193 return new Thread (name) 194 { 195 public void run() 196 { 197 try { 198 Lock wlock = lock_.writeLock(); 199 if (! wlock.tryLock(msecs, TimeUnit.MILLISECONDS)) { 200 logX(caseNum+"-"+name+" requesting write lock failed!\n"); 201 String str = caseNum + "-" + name + "-WL-0"; 202 postLockingResult(str); 203 return; 204 } 205 logX(caseNum+"-"+name+" requesting write lock succeeded!\n"); 207 String str = caseNum + "-" + name + "-WL-1"; 208 postLockingResult(str); 209 TestingUtil.sleepThread(sleepSecs); 210 211 if (secondOP == INVOKE_READ) 212 acquireReadLock(caseNum, name, msecs, errMsg); 213 else if (secondOP == INVOKE_WRITE) 214 acquireWriteLock(caseNum, name, msecs, errMsg); 215 else if (secondOP == INVOKE_UPGRADE) 216 acquireUpgradeLock(caseNum, name, msecs, errMsg); 217 218 wlock.unlock(); 219 logX(caseNum+"-"+name+" releasing write lock.\n"); 220 } catch (Exception ex) { 221 } 222 } 223 }; 224 } 225 226 233 protected Thread upgradeThread(final String caseNum, final String name, 234 final long msecs, final String errMsg) 235 { 236 return new Thread (name) 237 { 238 public void run() 239 { 240 try { 241 Lock rlock = lock_.readLock(); 242 Lock wlock = null; 243 if (! rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) { 244 logX(caseNum+"-"+name+" requesting read lock failed!\n"); 245 String str = caseNum + "-" + name + "-RL-0"; 246 postLockingResult(str); 247 return; 248 } 249 logX(caseNum+"-"+name+" requesting read lock succeeded (upgrade later)!\n"); 251 TestingUtil.sleepThread(SLEEP_MSECS/2); 252 String str = caseNum + "-" + name + "-UL-"; 253 if ((wlock = lock_.upgradeLockAttempt(msecs)) == null) 254 { 255 logX(caseNum+"-"+name+" requesting upgrade lock failed!\n"); 256 str += "0"; 257 } 258 else 259 { 260 logX(caseNum+"-"+name+" requesting upgrade lock succeeded!\n"); 261 str += "1"; 262 } 263 postLockingResult(str); 264 TestingUtil.sleepThread(SLEEP_MSECS); 266 if (wlock != null) 267 { 268 wlock.unlock(); 269 logX(caseNum+"-"+name+" releasing upgrade lock.\n"); 270 } 271 rlock.unlock(); 272 } catch (Exception ex) { 273 } 274 } 275 }; 276 } 277 278 279 280 281 287 288 protected void acquireReadLock(final String caseNum, final String name, 289 final long msecs, final String errMsg) 290 { 291 try { 292 Lock rlock = lock_.readLock(); 293 if (! rlock.tryLock(msecs, TimeUnit.MILLISECONDS)) { 294 logX(caseNum+"-"+name+" requesting read lock failed!\n"); 295 String str = caseNum + "-" + name + "-RL-0"; 296 postLockingResult(str); 297 return; 298 } 299 logX(caseNum+"-"+name+" requesting read lock succeeded!\n"); 301 String str = caseNum + "-" + name + "-RL-1"; 302 postLockingResult(str); 303 TestingUtil.sleepThread(SLEEP_MSECS); 304 rlock.unlock(); 305 logX(caseNum+"-"+name+" releasing read lock.\n"); 306 } catch (Exception ex) { 307 } 308 } 309 310 314 protected void acquireWriteLock(final String caseNum, final String name, 315 final long msecs, final String errMsg) 316 { 317 try { 318 Lock wlock = lock_.writeLock(); 319 if (! wlock.tryLock(msecs, TimeUnit.MILLISECONDS)) { 320 logX(caseNum+"-"+name+" requesting write lock failed!\n"); 321 String str = caseNum + "-" + name + "-WL-0"; 322 postLockingResult(str); 323 return; 324 } 325 logX(caseNum+"-"+name+" requesting write lock succeeded!\n"); 327 String str = caseNum + "-" + name + "-WL-1"; 328 postLockingResult(str); 329 TestingUtil.sleepThread(SLEEP_MSECS); 330 wlock.unlock(); 331 logX(caseNum+"-"+name+" releasing write lock.\n"); 332 } catch (Exception ex) { 333 } 334 } 335 336 340 protected void acquireUpgradeLock(final String caseNum, final String name, 341 final long msecs, final String errMsg) 342 { 343 try { 344 Lock ulock = null; 345 if ((ulock = lock_.upgradeLockAttempt(msecs)) == null) { 346 logX(caseNum+"-"+name+" requesting upgrade lock failed!\n"); 347 String str = caseNum + "-" + name + "-UL-0"; 348 postLockingResult(str); 349 return; 350 } 351 logX(caseNum+"-"+name+" requesting upgrade lock succeeded!\n"); 353 String str = caseNum + "-" + name + "-UL-1"; 354 postLockingResult(str); 355 TestingUtil.sleepThread(SLEEP_MSECS); 356 ulock.unlock(); 357 logX(caseNum+"-"+name+" releasing upgrade lock.\n"); 358 } catch (Exception ex) { 359 } 360 } 361 362 363 364 365 368 protected synchronized void cleanLockingResult() 369 { 370 lockResult.removeAllElements(); 371 } 372 373 376 protected synchronized void postLockingResult(Object obj) 377 { 378 logX(" Added *" + obj + "* to the result vector\n"); 379 lockResult.addElement(obj); 382 } 383 384 387 protected synchronized boolean checkLockingResult(String expected) 388 { 389 boolean rc = false; 390 for (int i=0; i<lockResult.size(); i++) 391 { 392 Object ele = lockResult.elementAt(i); 393 String str = (String )ele; 394 if (expected.equals(str)) 395 { 396 rc = true; 397 break; 398 } 399 } 400 if (rc) 401 logX(" Searching for *" + expected + "* SUCCEEDED.\n"); 402 else 403 logX(" Searching for *" + expected + "* FAILED.\n"); 404 return rc; 405 } 406 407 408 409 410 411 public void testWriteWithMultipleReaders() throws Exception 412 { 413 String caseNum = "10"; 414 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS*2, 415 "1st read lock attempt failed", NO_MORE_OP); 416 Thread t2=readThread(caseNum, "t2", 0, SLEEP_MSECS, 417 "2nd read lock attempt failed", INVOKE_WRITE); 418 419 t1.start(); 420 t2.start(); 421 t1.join(3000); 422 t2.join(3000); 423 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 424 checkLockingResult(caseNum+"-t2-RL-1") && 425 checkLockingResult(caseNum+"-t2-WL-1")); 426 cleanLockingResult(); 427 if (t1.isAlive() || t2.isAlive()) 429 fail("Possible deadlock resulted in testRead."); 430 } 431 432 433 public void testUpgradeWithMultipleReadersOn1() throws Exception 434 { 435 String caseNum = "11"; 436 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS, 437 "1st read lock attempt failed", INVOKE_WRITE); 438 Thread t2=readThread(caseNum, "t2", 0, SLEEP_MSECS*2, 439 "2nd read lock attempt failed", NO_MORE_OP); 440 441 t1.start(); 442 t2.start(); 443 t1.join(3000); 444 t2.join(3000); 445 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 446 checkLockingResult(caseNum+"-t2-RL-1") && 447 checkLockingResult(caseNum+"-t1-WL-1")); 448 cleanLockingResult(); 449 if (t1.isAlive() || t2.isAlive()) 451 fail("Possible deadlock resulted in testRead."); 452 } 453 454 455 public void testUpgradeReadLock() throws Exception 456 { 457 String caseNum = "2"; 458 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS, 459 "1st read lock attempt failed", INVOKE_UPGRADE); 460 461 t1.start(); 462 t1.join(3000); 463 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 464 checkLockingResult(caseNum+"-t1-UL-1")); 465 cleanLockingResult(); 466 } 467 468 469 470 public void testReadThenWrite() throws Exception 471 { 472 String caseNum = "3"; 473 acquireReadLock(caseNum, "t1", 0, "1st read lock attempt failed"); 474 acquireWriteLock(caseNum, "t1.1", 0, "2nd write lock attempt failed"); 475 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 476 checkLockingResult(caseNum+"-t1.1-WL-1")); 477 cleanLockingResult(); 478 } 479 480 481 482 483 public void testWriteThenRead() throws Exception 484 { 485 String caseNum = "5"; 486 acquireWriteLock(caseNum, "t1", 0, "1st write lock attempt failed"); 487 acquireReadLock(caseNum, "t1.1", 0, "2nd read lock attempt failed"); 488 assertTrue(checkLockingResult(caseNum+"-t1-WL-1") && 489 checkLockingResult(caseNum+"-t1.1-RL-1")); 490 cleanLockingResult(); 491 } 492 493 494 495 public void testMultipleReadlock() throws Exception 496 { 497 String caseNum = "6"; 498 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS, 499 "1st read lock attempt failed", NO_MORE_OP); 500 Thread t2=readThread(caseNum, "t2", 0, SLEEP_MSECS, 501 "2nd read lock attempt failed", NO_MORE_OP); 502 503 t1.start(); 504 t2.start(); 505 t1.join(3000); 506 t2.join(3000); 507 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 508 checkLockingResult(caseNum+"-t2-RL-1")); 509 cleanLockingResult(); 510 if (t1.isAlive() || t2.isAlive()) 512 fail("Possible deadlock resulted in testRead."); 513 } 514 515 516 public void testWriteWithExistingReader() throws Exception 517 { 518 String caseNum = "8"; 519 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS, 520 "1st write lock attempt failed", NO_MORE_OP); 521 Thread t2=writeThread(caseNum, "t2", 0, SLEEP_MSECS, 522 "2nd read lock attempt failed", NO_MORE_OP); 523 524 t1.start(); 525 t2.start(); 526 t1.join(3000); 527 t2.join(3000); 528 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 529 checkLockingResult(caseNum+"-t2-WL-1")); 530 cleanLockingResult(); 531 if (t1.isAlive() || t2.isAlive()) 533 fail("Possible deadlock resulted in testRead."); 534 } 535 536 537 public void testReadWithExistingWriter() throws Exception 538 { 539 String caseNum = "13"; 540 Thread t1=writeThread(caseNum, "t1", 0, SLEEP_MSECS, 541 "1st write lock attempt failed", NO_MORE_OP); 542 Thread t2=readThread(caseNum, "t2", 0, SLEEP_MSECS, 543 "2nd read lock attempt failed", NO_MORE_OP); 544 545 t1.start(); 546 t2.start(); 547 t1.join(3000); 548 t2.join(3000); 549 assertTrue(checkLockingResult(caseNum+"-t1-WL-1") && 550 checkLockingResult(caseNum+"-t2-RL-0")); 551 cleanLockingResult(); 552 if (t1.isAlive() || t2.isAlive()) 554 fail("Possible deadlock resulted in testRead."); 555 } 556 557 558 public void testMultipleWritelocks() throws Exception 559 { 560 String caseNum = "14"; 561 Thread t1=writeThread(caseNum, "t1", 0, SLEEP_MSECS, 562 "1st write lock attempt failed", NO_MORE_OP); 563 Thread t2=writeThread(caseNum, "t2", 0, SLEEP_MSECS, 564 "2nd write lock attempt failed", NO_MORE_OP); 565 566 t1.start(); 567 t2.start(); 568 t1.join(3000); 569 t2.join(3000); 570 assertTrue(checkLockingResult(caseNum+"-t1-WL-1") && 571 checkLockingResult(caseNum+"-t2-WL-0")); 572 cleanLockingResult(); 573 if (t1.isAlive() || t2.isAlive()) 575 fail("Possible deadlock resulted in testRead."); 576 } 577 578 579 public void testUpgradeWithExistingReader() throws Exception 580 { 581 String caseNum = "7"; 582 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS, 583 "1st read lock attempt failed", NO_MORE_OP); 584 Thread t2=upgradeThread(caseNum, "t2", 0, 585 "2nd upgrade lock attempt failed"); 586 587 t1.start(); 588 t2.start(); 589 t1.join(3000); 590 t2.join(3000); 591 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 592 checkLockingResult(caseNum+"-t2-UL-1")); 593 cleanLockingResult(); 594 if (t1.isAlive() || t2.isAlive()) 596 fail("Possible deadlock resulted in testRead."); 597 } 598 599 600 public void testUpgradeWithMultipleReaders() throws Exception 601 { 602 String caseNum = "9"; 603 Thread t1=readThread(caseNum, "t1", 0, SLEEP_MSECS*2, 604 "1st read lock attempt failed", NO_MORE_OP); 605 Thread t2=readThread(caseNum, "t2", 0, SLEEP_MSECS, 606 "2nd read lock attempt failed", INVOKE_UPGRADE); 607 608 t1.start(); 609 t2.start(); 610 t1.join(3000); 611 t2.join(3000); 612 assertTrue(checkLockingResult(caseNum+"-t1-RL-1") && 613 checkLockingResult(caseNum+"-t2-RL-1") && 614 checkLockingResult(caseNum+"-t2-UL-1")); 615 cleanLockingResult(); 616 if (t1.isAlive() || t2.isAlive()) 618 fail("Possible deadlock resulted in testRead."); 619 } 620 } 621 622 | Popular Tags |