--- jsr166/src/test/tck/JSR166TestCase.java 2010/10/29 06:58:56 1.67 +++ jsr166/src/test/tck/JSR166TestCase.java 2011/05/06 11:22:07 1.76 @@ -1,12 +1,14 @@ /* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain + * http://creativecommons.org/publicdomain/zero/1.0/ * Other contributors include Andrew Wright, Jeffrey Hayes, * Pat Fisher, Mike Judd. */ import junit.framework.*; +import java.util.Arrays; +import java.util.NoSuchElementException; import java.util.PropertyPermission; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; @@ -260,7 +262,7 @@ public class JSR166TestCase extends Test SHORT_DELAY_MS = getShortDelay(); SMALL_DELAY_MS = SHORT_DELAY_MS * 5; MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10; - LONG_DELAY_MS = SHORT_DELAY_MS * 50; + LONG_DELAY_MS = SHORT_DELAY_MS * 200; } /** @@ -289,7 +291,7 @@ public class JSR166TestCase extends Test * earlier by threadRecordFailure. */ public void tearDown() throws Exception { - Throwable t = threadFailure.get(); + Throwable t = threadFailure.getAndSet(null); if (t != null) { if (t instanceof Error) throw (Error) t; @@ -441,13 +443,34 @@ public class JSR166TestCase extends Test } /** + * Delays, via Thread.sleep for the given millisecond delay, but + * if the sleep is shorter than specified, may re-sleep or yield + * until time elapses. + */ + public static void delay(long ms) throws InterruptedException { + long startTime = System.nanoTime(); + long ns = ms * 1000 * 1000; + for (;;) { + if (ms > 0L) + Thread.sleep(ms); + else // too short to sleep + Thread.yield(); + long d = ns - (System.nanoTime() - startTime); + if (d > 0L) + ms = d / (1000 * 1000); + else + break; + } + } + + /** * Waits out termination of a thread pool or fails doing so. */ public void joinPool(ExecutorService exec) { try { exec.shutdown(); assertTrue("ExecutorService did not terminate in a timely manner", - exec.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); + exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)); } catch (SecurityException ok) { // Allowed in case test doesn't have privs } catch (InterruptedException ie) { @@ -586,7 +609,7 @@ public class JSR166TestCase extends Test */ void sleep(long millis) { try { - Thread.sleep(millis); + delay(millis); } catch (InterruptedException ie) { AssertionFailedError afe = new AssertionFailedError("Unexpected InterruptedException"); @@ -629,6 +652,14 @@ public class JSR166TestCase extends Test } /** + * Waits up to LONG_DELAY_MS for the given thread to enter a wait + * state: BLOCKED, WAITING, or TIMED_WAITING. + */ + void waitForThreadToEnterWaitState(Thread thread) { + waitForThreadToEnterWaitState(thread, LONG_DELAY_MS); + } + + /** * Returns the number of milliseconds since time given by * startNanoTime, which must have been previously returned from a * call to {@link System.nanoTime()}. @@ -636,7 +667,7 @@ public class JSR166TestCase extends Test long millisElapsedSince(long startNanoTime) { return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); } - + /** * Returns a new started daemon Thread running the given runnable. */ @@ -665,6 +696,15 @@ public class JSR166TestCase extends Test } } + /** + * Waits for LONG_DELAY_MS milliseconds for the thread to + * terminate (using {@link Thread#join(long)}), else interrupts + * the thread (in the hope that it may terminate later) and fails. + */ + void awaitTermination(Thread t) { + awaitTermination(t, LONG_DELAY_MS); + } + // Some convenient Runnable classes public abstract class CheckedRunnable implements Runnable { @@ -787,6 +827,13 @@ public class JSR166TestCase extends Test }}; } + public Runnable awaiter(final CountDownLatch latch) { + return new CheckedRunnable() { + public void realRun() throws InterruptedException { + latch.await(); + }}; + } + public static class NPETask implements Callable { public String call() { throw new NullPointerException(); } } @@ -797,46 +844,46 @@ public class JSR166TestCase extends Test public class ShortRunnable extends CheckedRunnable { protected void realRun() throws Throwable { - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); } } public class ShortInterruptedRunnable extends CheckedInterruptedRunnable { protected void realRun() throws InterruptedException { - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); } } public class SmallRunnable extends CheckedRunnable { protected void realRun() throws Throwable { - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); } } public class SmallPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); } catch (InterruptedException ok) {} } } public class SmallCallable extends CheckedCallable { protected Object realCall() throws InterruptedException { - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); return Boolean.TRUE; } } public class MediumRunnable extends CheckedRunnable { protected void realRun() throws Throwable { - Thread.sleep(MEDIUM_DELAY_MS); + delay(MEDIUM_DELAY_MS); } } public class MediumInterruptedRunnable extends CheckedInterruptedRunnable { protected void realRun() throws InterruptedException { - Thread.sleep(MEDIUM_DELAY_MS); + delay(MEDIUM_DELAY_MS); } } @@ -844,7 +891,7 @@ public class JSR166TestCase extends Test return new CheckedRunnable() { protected void realRun() { try { - Thread.sleep(timeoutMillis); + delay(timeoutMillis); } catch (InterruptedException ok) {} }}; } @@ -852,7 +899,7 @@ public class JSR166TestCase extends Test public class MediumPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { - Thread.sleep(MEDIUM_DELAY_MS); + delay(MEDIUM_DELAY_MS); } catch (InterruptedException ok) {} } } @@ -860,7 +907,7 @@ public class JSR166TestCase extends Test public class LongPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { - Thread.sleep(LONG_DELAY_MS); + delay(LONG_DELAY_MS); } catch (InterruptedException ok) {} } } @@ -884,7 +931,7 @@ public class JSR166TestCase extends Test public boolean isDone() { return done; } public void run() { try { - Thread.sleep(timeoutMillis); + delay(timeoutMillis); done = true; } catch (InterruptedException ok) {} } @@ -895,7 +942,7 @@ public class JSR166TestCase extends Test public volatile boolean done = false; public void run() { try { - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); done = true; } catch (InterruptedException ok) {} } @@ -905,7 +952,7 @@ public class JSR166TestCase extends Test public volatile boolean done = false; public void run() { try { - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); done = true; } catch (InterruptedException ok) {} } @@ -915,7 +962,7 @@ public class JSR166TestCase extends Test public volatile boolean done = false; public void run() { try { - Thread.sleep(MEDIUM_DELAY_MS); + delay(MEDIUM_DELAY_MS); done = true; } catch (InterruptedException ok) {} } @@ -925,7 +972,7 @@ public class JSR166TestCase extends Test public volatile boolean done = false; public void run() { try { - Thread.sleep(LONG_DELAY_MS); + delay(LONG_DELAY_MS); done = true; } catch (InterruptedException ok) {} } @@ -942,7 +989,7 @@ public class JSR166TestCase extends Test public volatile boolean done = false; public Object call() { try { - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); done = true; } catch (InterruptedException ok) {} return Boolean.TRUE; @@ -1007,4 +1054,31 @@ public class JSR166TestCase extends Test } } + public void checkEmpty(BlockingQueue q) { + try { + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertNull(q.peek()); + assertNull(q.poll()); + assertNull(q.poll(0, MILLISECONDS)); + assertEquals(q.toString(), "[]"); + assertTrue(Arrays.equals(q.toArray(), new Object[0])); + assertFalse(q.iterator().hasNext()); + try { + q.element(); + shouldThrow(); + } catch (NoSuchElementException success) {} + try { + q.iterator().next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } catch (InterruptedException ie) { + threadUnexpectedException(ie); + } + } + }