Clover coverage report -
Coverage timestamp: Wed Jan 31 2007 15:38:53 EST
file stats: LOC: 702   Methods: 31
NCLOC: 480   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ReadWriteLockWithUpgradeTest.java 58% 87.2% 93.5% 83.2%
coverage coverage
 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    /**
 16    * NonBlockingWriterLock is a read/write lock (with upgrade) that has
 17    * non-blocking write lock acquisition on existing read lock(s).
 18    * <p>Note that the write lock is exclusive among write locks, e.g.,
 19    * only one write lock can be granted at one time, but the write lock
 20    * is independent of the read locks. For example,
 21    * a read lock to be acquired will be blocked if there is existing write lock, but
 22    * will not be blocked if there are mutiple read locks already granted to other
 23    * owners. On the other hand, a write lock can be acquired as long as there
 24    * is no existing write lock, regardless how many read locks have been
 25    * granted.
 26    *
 27    * @author <a href="mailto:cavin_song@yahoo.com">Cavin Song</a> April 22, 2004
 28    * @version 1.0
 29    */
 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  11 public ReadWriteLockWithUpgradeTest(String name)
 41    {
 42  11 super(name);
 43    }
 44   
 45   
 46  0 public static void main(String[] args) throws Exception
 47    {
 48  0 log("\nBeginning ReadWriteLockWithUpgrade automated testing ...\n");
 49   
 50  0 junit.textui.TestRunner.run(suite());
 51    }
 52   
 53    // Needed for JUnit.
 54  1 public static Test suite()
 55    {
 56  1 TestSuite suite = new TestSuite();
 57    // Adding test cases here ...
 58  1 suite.addTestSuite(ReadWriteLockWithUpgradeTest.class);
 59  1 return suite;
 60    }
 61   
 62  11 public void setUp()
 63    {
 64  11 logX("\n");
 65  11 log("Setting up test case ...");
 66    }
 67   
 68  11 public void tearDown()
 69    {
 70  11 log("Tearing down test case ...");
 71    }
 72   
 73  127 public static void log(String str)
 74    {
 75  127 System.out.println(Thread.currentThread() + ": "
 76    + java.util.Calendar.getInstance().getTime() + " : " + str);
 77    }
 78   
 79    // For debugging purpose
 80  105 public static void logX(String str)
 81    {
 82  105 log(str);
 83    // try {
 84    // logToFile(str);
 85    // } catch (IOException ioe) {
 86    // }
 87    }
 88   
 89    // Debugging intrnal function
 90  0 public static void logToFile(String str) throws IOException
 91    {
 92  0 Writer out = new FileWriter("./RepeatableLogs.txt", true/*append*/);
 93  0 out.write(str);
 94  0 out.close();
 95    }
 96   
 97    /***************************************************************/
 98    /* Utility functions to creat threads for RL, WL and UL */
 99    /***************************************************************/
 100    /**
 101    * Creates a new thread and acquires a read lock with a timeout
 102    * value specified by the caller. Optionally, the caller can request
 103    * a second read or write lock after the first read lock request.
 104    * The locking result is stored in a vector with the following
 105    * format:
 106    * <p><DL>
 107    * <DD>'case number'-'thread name'-[RL|WL|UL]-[0|1]
 108    * </DL>
 109    * <p>where:
 110    * <DL>
 111    * <DD> 'case number' is the passed in test case # by the caller.
 112    * <DD> 'thread name' is the passed in thread name by the caller.
 113    * <DD> RL - indicating was doing read lock request.
 114    * <DD> WL - indicating was doing write lock request.
 115    * <DD> UL - indicating was doing upgrade lock request.
 116    * <DD> 0 - indicating the locking request failed.
 117    * <DD> 1 - indicating the locking request succeeded.
 118    * </DL>
 119    * <p/>
 120    * After all threads in each test case terminate, the test case
 121    * should make the following call to verify the test result:
 122    * <DL>
 123    * <DD> asssertTrue(checkLockingResult(expected-result-string);
 124    * </DL>
 125    * <p/>
 126    * 'expected-result-string' is the locking result string
 127    * described above. For example, "8-t1-RL-0" means that thread
 128    * t1 in test case #8 doing a Read Lock request expects the
 129    * operation to fail. If the expected result string can't be
 130    * found then the test case is considered FAILED (ie, either
 131    * the read lock request was successful or did not complete).
 132    * <p/>
 133    * Each test case should also call cleanLockingResult() to reset
 134    * result vector for the next test cases.
 135    *
 136    * @param caseNum Arbitrary string for the test case number.
 137    * @param name Arbitrary string for the calling thread name.
 138    * @param msecs Milliseconds that the thread should sleep after
 139    * acquiring the read lock.
 140    * @param errMsg Error msg to log in case of error.
 141    * @param secondOP Set to NO_MORE_OP if a 2nd lock request is not required.
 142    * Set to INVOKE_READ, INVOKE_READ or INVOKE_UPGRADE
 143    * respectively if the 2nd lock is a read, write or
 144    * upgrade request respectively.
 145    */
 146   
 147  12 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  12 return new Thread(name)
 152    {
 153  12 public void run()
 154    {
 155  12 Lock rlock = lock_.readLock();
 156  12 try
 157    {
 158  12 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
 159    {
 160  1 logX(caseNum + "-" + name + " requesting read lock failed!\n");
 161  1 String str = caseNum + "-" + name + "-RL-0";
 162  1 postLockingResult(str);
 163  1 return;
 164    }
 165    // OK, read lock obtained, sleep and release it.
 166  11 logX(caseNum + "-" + name + " requesting read lock succeeded!\n");
 167  11 String str = caseNum + "-" + name + "-RL-1";
 168  11 postLockingResult(str);
 169  11 TestingUtil.sleepThread(sleepSecs);
 170   
 171  11 if (secondOP == INVOKE_READ)
 172    {
 173  0 acquireReadLock(caseNum, name, msecs, errMsg);
 174    }
 175  11 else if (secondOP == INVOKE_WRITE)
 176    {
 177  2 acquireWriteLock(caseNum, name, msecs, errMsg);
 178    }
 179  9 else if (secondOP == INVOKE_UPGRADE)
 180    {
 181  2 acquireUpgradeLock(caseNum, name, msecs, errMsg);
 182    }
 183   
 184  11 rlock.unlock();
 185  11 logX(caseNum + "-" + name + " releasing read lock.\n");
 186    }
 187    catch (Exception ex)
 188    {
 189    }
 190    }
 191    };
 192    }
 193   
 194    /**
 195    * Creates a new thread and acquires a write lock with a timeout
 196    * value specified by the caller. Similar to {@link #readThread readThread()}
 197    * except it's used for write locks.
 198    *
 199    * @see #readThread readThread()
 200    */
 201  4 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  4 return new Thread(name)
 206    {
 207  4 public void run()
 208    {
 209  4 try
 210    {
 211  4 Lock wlock = lock_.writeLock();
 212  4 if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS))
 213    {
 214  2 logX(caseNum + "-" + name + " requesting write lock failed!\n");
 215  2 String str = caseNum + "-" + name + "-WL-0";
 216  2 postLockingResult(str);
 217  2 return;
 218    }
 219    // OK, write lock obtained, sleep and release it.
 220  2 logX(caseNum + "-" + name + " requesting write lock succeeded!\n");
 221  2 String str = caseNum + "-" + name + "-WL-1";
 222  2 postLockingResult(str);
 223  2 TestingUtil.sleepThread(sleepSecs);
 224   
 225  2 if (secondOP == INVOKE_READ)
 226    {
 227  0 acquireReadLock(caseNum, name, msecs, errMsg);
 228    }
 229  2 else if (secondOP == INVOKE_WRITE)
 230    {
 231  0 acquireWriteLock(caseNum, name, msecs, errMsg);
 232    }
 233  2 else if (secondOP == INVOKE_UPGRADE)
 234    {
 235  0 acquireUpgradeLock(caseNum, name, msecs, errMsg);
 236    }
 237   
 238  2 wlock.unlock();
 239  2 logX(caseNum + "-" + name + " releasing write lock.\n");
 240    }
 241    catch (Exception ex)
 242    {
 243    }
 244    }
 245    };
 246    }
 247   
 248    /**
 249    * Creates a new thread, acquires a read lock, sleeps for a while
 250    * and then tries to upgrade the read lock to a write one. Similar
 251    * to {@link #readThread readThread()} except it's used for upgrading
 252    * locks.
 253    *
 254    * @see #readThread readThread()
 255    */
 256  1 protected Thread upgradeThread(final String caseNum, final String name,
 257    final long msecs, final String errMsg)
 258    {
 259  1 return new Thread(name)
 260    {
 261  1 public void run()
 262    {
 263  1 try
 264    {
 265  1 Lock rlock = lock_.readLock();
 266  1 Lock wlock = null;
 267  1 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
 268    {
 269  0 logX(caseNum + "-" + name + " requesting read lock failed!\n");
 270  0 String str = caseNum + "-" + name + "-RL-0";
 271  0 postLockingResult(str);
 272  0 return;
 273    }
 274    // OK, read lock obtained, sleep and upgrade it later.
 275  1 logX(caseNum + "-" + name + " requesting read lock succeeded (upgrade later)!\n");
 276  1 TestingUtil.sleepThread(SLEEP_MSECS / 2);
 277  1 String str = caseNum + "-" + name + "-UL-";
 278  ? if ((wlock = lock_.upgradeLockAttempt(msecs)) == null)
 279    {
 280  1 logX(caseNum + "-" + name + " requesting upgrade lock failed!\n");
 281  1 str += "0";
 282    }
 283    else
 284    {
 285  0 logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n");
 286  0 str += "1";
 287    }
 288  1 postLockingResult(str);
 289    // Sleep again and then release the lock.
 290  1 TestingUtil.sleepThread(SLEEP_MSECS);
 291  1 if (wlock != null)
 292    {
 293  0 wlock.unlock();
 294  0 logX(caseNum + "-" + name + " releasing upgrade lock.\n");
 295    }
 296  1 rlock.unlock();
 297    }
 298    catch (Exception ex)
 299    {
 300    }
 301    }
 302    };
 303    }
 304   
 305    /***************************************************************/
 306    /* Utility functions to acquire RL and WL (no thread) */
 307    /***************************************************************/
 308    /**
 309    * This routine tries to acquire a read lock with a timeout value
 310    * passed in by the caller. Like {@link #readThread readThread()}
 311    * it then stores the locking result in the result vector depending
 312    * on the outcome of the request.
 313    */
 314   
 315  2 protected void acquireReadLock(final String caseNum, final String name,
 316    final long msecs, final String errMsg)
 317    {
 318  2 try
 319    {
 320  2 Lock rlock = lock_.readLock();
 321  2 if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
 322    {
 323  0 logX(caseNum + "-" + name + " requesting read lock failed!\n");
 324  0 String str = caseNum + "-" + name + "-RL-0";
 325  0 postLockingResult(str);
 326  0 return;
 327    }
 328    // OK, read lock obtained, sleep and release it.
 329  2 logX(caseNum + "-" + name + " requesting read lock succeeded!\n");
 330  2 String str = caseNum + "-" + name + "-RL-1";
 331  2 postLockingResult(str);
 332  2 TestingUtil.sleepThread(SLEEP_MSECS);
 333  2 rlock.unlock();
 334  2 logX(caseNum + "-" + name + " releasing read lock.\n");
 335    }
 336    catch (Exception ex)
 337    {
 338    }
 339    }
 340   
 341    /**
 342    * Same as {@link #acquireReadLock acquireReadLock()} except
 343    * it's for write lock request.
 344    */
 345  4 protected void acquireWriteLock(final String caseNum, final String name,
 346    final long msecs, final String errMsg)
 347    {
 348  4 try
 349    {
 350  4 Lock wlock = lock_.writeLock();
 351  4 if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS))
 352    {
 353  2 logX(caseNum + "-" + name + " requesting write lock failed!\n");
 354  2 String str = caseNum + "-" + name + "-WL-0";
 355  2 postLockingResult(str);
 356  2 return;
 357    }
 358    // OK, write lock obtained, sleep and release it.
 359  2 logX(caseNum + "-" + name + " requesting write lock succeeded!\n");
 360  2 String str = caseNum + "-" + name + "-WL-1";
 361  2 postLockingResult(str);
 362  2 TestingUtil.sleepThread(SLEEP_MSECS);
 363  2 wlock.unlock();
 364  2 logX(caseNum + "-" + name + " releasing write lock.\n");
 365    }
 366    catch (Exception ex)
 367    {
 368    }
 369    }
 370   
 371    /**
 372    * Same as {@link #acquireReadLock acquireReadLock()} except
 373    * it's for upgrade lock request.
 374    */
 375  2 protected void acquireUpgradeLock(final String caseNum, final String name,
 376    final long msecs, final String errMsg)
 377    {
 378  2 try
 379    {
 380  2 Lock ulock = null;
 381  ? if ((ulock = lock_.upgradeLockAttempt(msecs)) == null)
 382    {
 383  1 logX(caseNum + "-" + name + " requesting upgrade lock failed!\n");
 384  1 String str = caseNum + "-" + name + "-UL-0";
 385  1 postLockingResult(str);
 386  1 return;
 387    }
 388    // OK, write lock obtained, sleep and release it.
 389  1 logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n");
 390  1 String str = caseNum + "-" + name + "-UL-1";
 391  1 postLockingResult(str);
 392  1 TestingUtil.sleepThread(SLEEP_MSECS);
 393  1 ulock.unlock();
 394  1 logX(caseNum + "-" + name + " releasing upgrade lock.\n");
 395    }
 396    catch (Exception ex)
 397    {
 398    }
 399    }
 400   
 401    /***************************************************************/
 402    /* Synchronized methods handling locking result vector */
 403    /***************************************************************/
 404    /**
 405    * Clean/remove all locking results in the vector.
 406    */
 407  11 protected synchronized void cleanLockingResult()
 408    {
 409  11 lockResult.removeAllElements();
 410    }
 411   
 412    /**
 413    * Post a locking result to the vector for later verification.
 414    */
 415  25 protected synchronized void postLockingResult(Object obj)
 416    {
 417  25 logX(" Added *" + obj + "* to the result vector\n");
 418    // Make sure we only have one in the vector
 419    //if (!checkLockingResult((String)obj))
 420  25 lockResult.addElement(obj);
 421    }
 422   
 423    /**
 424    * Check if a given expected locking result is in the vector.
 425    */
 426  25 protected synchronized boolean checkLockingResult(String expected)
 427    {
 428  25 boolean rc = false;
 429  42 for (int i = 0; i < lockResult.size(); i++)
 430    {
 431  42 Object ele = lockResult.elementAt(i);
 432  42 String str = (String) ele;
 433  42 if (expected.equals(str))
 434    {
 435  25 rc = true;
 436  25 break;
 437    }
 438    }
 439  25 if (rc)
 440    {
 441  25 logX(" Searching for *" + expected + "* SUCCEEDED.\n");
 442    }
 443    else
 444    {
 445  0 logX(" Searching for *" + expected + "* FAILED.\n");
 446    }
 447  25 return rc;
 448    }
 449   
 450    /***************************************************************/
 451    /* T e s t C a s e s */
 452    /***************************************************************/
 453    /**
 454    * Case #10 - T1 acquires RL, T2 acquires RL followed by WL.
 455    */
 456  1 public void testWriteWithMultipleReaders() throws Exception
 457    {
 458  1 String caseNum = "10";
 459  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2,
 460    "1st read lock attempt failed", NO_MORE_OP);
 461  1 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
 462    "2nd read lock attempt failed", INVOKE_WRITE);
 463   
 464  1 t1.start();
 465  1 t2.start();
 466  1 t1.join(3000);
 467  1 t2.join(3000);
 468  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 469    checkLockingResult(caseNum + "-t2-RL-1") &&
 470    checkLockingResult(caseNum + "-t2-WL-0"));
 471  1 cleanLockingResult();
 472    // possilbe deadlock check
 473  1 if (t1.isAlive() || t2.isAlive())
 474    {
 475  0 fail("Possible deadlock resulted in testRead.");
 476    }
 477    }
 478   
 479    /**
 480    * Case #11 - T1 acquires RL followed by WL, T2 acquires RL.
 481    */
 482  1 public void testUpgradeWithMultipleReadersOn1() throws Exception
 483    {
 484  1 String caseNum = "11";
 485  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
 486    "1st read lock attempt failed", INVOKE_WRITE);
 487  1 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS * 2,
 488    "2nd read lock attempt failed", NO_MORE_OP);
 489   
 490  1 t1.start();
 491  1 t2.start();
 492  1 t1.join(3000);
 493  1 t2.join(3000);
 494  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 495    checkLockingResult(caseNum + "-t2-RL-1") &&
 496    checkLockingResult(caseNum + "-t1-WL-0"));
 497  1 cleanLockingResult();
 498    // possilbe deadlock check
 499  1 if (t1.isAlive() || t2.isAlive())
 500    {
 501  0 fail("Possible deadlock resulted in testRead.");
 502    }
 503    }
 504   
 505    /**
 506    * Case #2 - T1 acquires RL followed by UL.
 507    */
 508  1 public void testUpgradeReadLock() throws Exception
 509    {
 510  1 String caseNum = "2";
 511  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
 512    "1st read lock attempt failed", INVOKE_UPGRADE);
 513   
 514  1 t1.start();
 515  1 t1.join(3000);
 516  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 517    checkLockingResult(caseNum + "-t1-UL-1"));
 518  1 cleanLockingResult();
 519    }
 520   
 521    /**
 522    * Case #3 - T1 acquires RL followed by WL.
 523    */
 524   
 525  1 public void testReadThenWrite() throws Exception
 526    {
 527  1 String caseNum = "3";
 528  1 acquireReadLock(caseNum, "t1", 0, "1st read lock attempt failed");
 529  1 acquireWriteLock(caseNum, "t1.1", 0, "2nd write lock attempt failed");
 530  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 531    checkLockingResult(caseNum + "-t1.1-WL-1"));
 532  1 cleanLockingResult();
 533    }
 534   
 535   
 536    /**
 537    * Case #5 - T1 acquires WL followed by RL.
 538    */
 539   
 540  1 public void testWriteThenRead() throws Exception
 541    {
 542  1 String caseNum = "5";
 543  1 acquireWriteLock(caseNum, "t1", 0, "1st write lock attempt failed");
 544  1 acquireReadLock(caseNum, "t1.1", 0, "2nd read lock attempt failed");
 545  1 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
 546    checkLockingResult(caseNum + "-t1.1-RL-1"));
 547  1 cleanLockingResult();
 548    }
 549   
 550    /**
 551    * Case #6 - T1 acquires RL, T2 acquires RL.
 552    */
 553  1 public void testMultipleReadlock() throws Exception
 554    {
 555  1 String caseNum = "6";
 556  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
 557    "1st read lock attempt failed", NO_MORE_OP);
 558  1 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
 559    "2nd read lock attempt failed", NO_MORE_OP);
 560   
 561  1 t1.start();
 562  1 t2.start();
 563  1 t1.join(3000);
 564  1 t2.join(3000);
 565  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 566    checkLockingResult(caseNum + "-t2-RL-1"));
 567  1 cleanLockingResult();
 568    // possilbe deadlock check
 569  1 if (t1.isAlive() || t2.isAlive())
 570    {
 571  0 fail("Possible deadlock resulted in testRead.");
 572    }
 573    }
 574   
 575    /**
 576    * Case #8 - T1 acquires WL, T2 acquires RL.
 577    */
 578  1 public void testWriteWithExistingReader() throws Exception
 579    {
 580  1 String caseNum = "8";
 581  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
 582    "1st write lock attempt failed", NO_MORE_OP);
 583  1 Thread t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS,
 584    "2nd read lock attempt failed", NO_MORE_OP);
 585   
 586  1 t1.start();
 587  1 t2.start();
 588  1 t1.join(3000);
 589  1 t2.join(3000);
 590  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 591    checkLockingResult(caseNum + "-t2-WL-0"));
 592  1 cleanLockingResult();
 593    // possilbe deadlock check
 594  1 if (t1.isAlive() || t2.isAlive())
 595    {
 596  0 fail("Possible deadlock resulted in testRead.");
 597    }
 598    }
 599   
 600    /**
 601    * Case #13 - T1 acquires RL, T2 acquires WL.
 602    */
 603  1 public void testReadWithExistingWriter() throws Exception
 604    {
 605  1 String caseNum = "13";
 606  1 Thread t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS,
 607    "1st write lock attempt failed", NO_MORE_OP);
 608  1 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
 609    "2nd read lock attempt failed", NO_MORE_OP);
 610   
 611  1 t1.start();
 612  1 t2.start();
 613  1 t1.join(3000);
 614  1 t2.join(3000);
 615  1 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
 616    checkLockingResult(caseNum + "-t2-RL-0"));
 617  1 cleanLockingResult();
 618    // possilbe deadlock check
 619  1 if (t1.isAlive() || t2.isAlive())
 620    {
 621  0 fail("Possible deadlock resulted in testRead.");
 622    }
 623    }
 624   
 625    /**
 626    * Case #14 - T1 acquires WL, T2 acquires WL.
 627    */
 628  1 public void testMultipleWritelocks() throws Exception
 629    {
 630  1 String caseNum = "14";
 631  1 Thread t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS,
 632    "1st write lock attempt failed", NO_MORE_OP);
 633  1 Thread t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS,
 634    "2nd write lock attempt failed", NO_MORE_OP);
 635   
 636  1 t1.start();
 637  1 t2.start();
 638  1 t1.join(3000);
 639  1 t2.join(3000);
 640  1 assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
 641    checkLockingResult(caseNum + "-t2-WL-0"));
 642  1 cleanLockingResult();
 643    // possilbe deadlock check
 644  1 if (t1.isAlive() || t2.isAlive())
 645    {
 646  0 fail("Possible deadlock resulted in testRead.");
 647    }
 648    }
 649   
 650    /**
 651    * Case #7 - T1 acquires RL, T2 acquires UL.
 652    */
 653   
 654  1 public void testUpgradeWithExistingReader() throws Exception
 655    {
 656  1 String caseNum = "7";
 657  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
 658    "1st read lock attempt failed", NO_MORE_OP);
 659  1 Thread t2 = upgradeThread(caseNum, "t2", 0,
 660    "2nd upgrade lock attempt failed");
 661   
 662  1 t1.start();
 663  1 t2.start();
 664  1 t1.join(3000);
 665  1 t2.join(3000);
 666  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 667    checkLockingResult(caseNum + "-t2-UL-0"));
 668  1 cleanLockingResult();
 669    // possilbe deadlock check
 670  1 if (t1.isAlive() || t2.isAlive())
 671    {
 672  0 fail("Possible deadlock resulted in testRead.");
 673    }
 674    }
 675   
 676    /**
 677    * Case #9 - T1 acquires RL, T2 acquires RL followed by UL.
 678    */
 679  1 public void testUpgradeWithMultipleReaders() throws Exception
 680    {
 681  1 String caseNum = "9";
 682  1 Thread t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2,
 683    "1st read lock attempt failed", NO_MORE_OP);
 684  1 Thread t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
 685    "2nd read lock attempt failed", INVOKE_UPGRADE);
 686   
 687  1 t1.start();
 688  1 t2.start();
 689  1 t1.join(3000);
 690  1 t2.join(3000);
 691  1 assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
 692    checkLockingResult(caseNum + "-t2-RL-1") &&
 693    checkLockingResult(caseNum + "-t2-UL-0"));
 694  1 cleanLockingResult();
 695    // possilbe deadlock check
 696  1 if (t1.isAlive() || t2.isAlive())
 697    {
 698  0 fail("Possible deadlock resulted in testRead.");
 699    }
 700    }
 701    }
 702