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