--- jsr166/src/test/tck/JSR166TestCase.java 2010/09/16 00:52:49 1.53 +++ jsr166/src/test/tck/JSR166TestCase.java 2010/10/11 08:30:01 1.63 @@ -96,6 +96,42 @@ public class JSR166TestCase extends Test private static final boolean useSecurityManager = Boolean.getBoolean("jsr166.useSecurityManager"); + protected static final boolean expensiveTests = + Boolean.getBoolean("jsr166.expensiveTests"); + + /** + * If true, report on stdout all "slow" tests, that is, ones that + * take more than profileThreshold milliseconds to execute. + */ + private static final boolean profileTests = + Boolean.getBoolean("jsr166.profileTests"); + + /** + * The number of milliseconds that tests are permitted for + * execution without being reported, when profileTests is set. + */ + private static final long profileThreshold = + Long.getLong("jsr166.profileThreshold", 100); + + protected void runTest() throws Throwable { + if (profileTests) + runTestProfiled(); + else + super.runTest(); + } + + protected void runTestProfiled() throws Throwable { + long t0 = System.nanoTime(); + try { + super.runTest(); + } finally { + long elapsedMillis = + (System.nanoTime() - t0) / (1000L * 1000L); + if (elapsedMillis >= profileThreshold) + System.out.printf("%n%s: %d%n", toString(), elapsedMillis); + } + } + /** * Runs all JSR166 unit tests using junit.textui.TestRunner */ @@ -105,9 +141,8 @@ public class JSR166TestCase extends Test Policy.setPolicy(permissivePolicy()); System.setSecurityManager(new SecurityManager()); } - int iters = 1; - if (args.length > 0) - iters = Integer.parseInt(args[0]); + int iters = (args.length == 0) ? 1 : Integer.parseInt(args[0]); + Test s = suite(); for (int i = 0; i < iters; ++i) { junit.textui.TestRunner.run(s); @@ -117,78 +152,88 @@ public class JSR166TestCase extends Test System.exit(0); } + public static TestSuite newTestSuite(Object... suiteOrClasses) { + TestSuite suite = new TestSuite(); + for (Object suiteOrClass : suiteOrClasses) { + if (suiteOrClass instanceof TestSuite) + suite.addTest((TestSuite) suiteOrClass); + else if (suiteOrClass instanceof Class) + suite.addTest(new TestSuite((Class) suiteOrClass)); + else + throw new ClassCastException("not a test suite or class"); + } + return suite; + } + /** - * Collects all JSR166 unit tests as one suite + * Collects all JSR166 unit tests as one suite. */ public static Test suite() { - TestSuite suite = new TestSuite("JSR166 Unit Tests"); - - suite.addTest(new TestSuite(ForkJoinPoolTest.class)); - suite.addTest(new TestSuite(ForkJoinTaskTest.class)); - suite.addTest(new TestSuite(RecursiveActionTest.class)); - suite.addTest(new TestSuite(RecursiveTaskTest.class)); - suite.addTest(new TestSuite(LinkedTransferQueueTest.class)); - suite.addTest(new TestSuite(PhaserTest.class)); - suite.addTest(new TestSuite(ThreadLocalRandomTest.class)); - suite.addTest(new TestSuite(AbstractExecutorServiceTest.class)); - suite.addTest(new TestSuite(AbstractQueueTest.class)); - suite.addTest(new TestSuite(AbstractQueuedSynchronizerTest.class)); - suite.addTest(new TestSuite(AbstractQueuedLongSynchronizerTest.class)); - suite.addTest(new TestSuite(ArrayBlockingQueueTest.class)); - suite.addTest(new TestSuite(ArrayDequeTest.class)); - suite.addTest(new TestSuite(AtomicBooleanTest.class)); - suite.addTest(new TestSuite(AtomicIntegerArrayTest.class)); - suite.addTest(new TestSuite(AtomicIntegerFieldUpdaterTest.class)); - suite.addTest(new TestSuite(AtomicIntegerTest.class)); - suite.addTest(new TestSuite(AtomicLongArrayTest.class)); - suite.addTest(new TestSuite(AtomicLongFieldUpdaterTest.class)); - suite.addTest(new TestSuite(AtomicLongTest.class)); - suite.addTest(new TestSuite(AtomicMarkableReferenceTest.class)); - suite.addTest(new TestSuite(AtomicReferenceArrayTest.class)); - suite.addTest(new TestSuite(AtomicReferenceFieldUpdaterTest.class)); - suite.addTest(new TestSuite(AtomicReferenceTest.class)); - suite.addTest(new TestSuite(AtomicStampedReferenceTest.class)); - suite.addTest(new TestSuite(ConcurrentHashMapTest.class)); - suite.addTest(new TestSuite(ConcurrentLinkedDequeTest.class)); - suite.addTest(new TestSuite(ConcurrentLinkedQueueTest.class)); - suite.addTest(new TestSuite(ConcurrentSkipListMapTest.class)); - suite.addTest(new TestSuite(ConcurrentSkipListSubMapTest.class)); - suite.addTest(new TestSuite(ConcurrentSkipListSetTest.class)); - suite.addTest(new TestSuite(ConcurrentSkipListSubSetTest.class)); - suite.addTest(new TestSuite(CopyOnWriteArrayListTest.class)); - suite.addTest(new TestSuite(CopyOnWriteArraySetTest.class)); - suite.addTest(new TestSuite(CountDownLatchTest.class)); - suite.addTest(new TestSuite(CyclicBarrierTest.class)); - suite.addTest(new TestSuite(DelayQueueTest.class)); - suite.addTest(new TestSuite(EntryTest.class)); - suite.addTest(new TestSuite(ExchangerTest.class)); - suite.addTest(new TestSuite(ExecutorsTest.class)); - suite.addTest(new TestSuite(ExecutorCompletionServiceTest.class)); - suite.addTest(new TestSuite(FutureTaskTest.class)); - suite.addTest(new TestSuite(LinkedBlockingDequeTest.class)); - suite.addTest(new TestSuite(LinkedBlockingQueueTest.class)); - suite.addTest(new TestSuite(LinkedListTest.class)); - suite.addTest(new TestSuite(LockSupportTest.class)); - suite.addTest(new TestSuite(PriorityBlockingQueueTest.class)); - suite.addTest(new TestSuite(PriorityQueueTest.class)); - suite.addTest(new TestSuite(ReentrantLockTest.class)); - suite.addTest(new TestSuite(ReentrantReadWriteLockTest.class)); - suite.addTest(new TestSuite(ScheduledExecutorTest.class)); - suite.addTest(new TestSuite(ScheduledExecutorSubclassTest.class)); - suite.addTest(new TestSuite(SemaphoreTest.class)); - suite.addTest(new TestSuite(SynchronousQueueTest.class)); - suite.addTest(new TestSuite(SystemTest.class)); - suite.addTest(new TestSuite(ThreadLocalTest.class)); - suite.addTest(new TestSuite(ThreadPoolExecutorTest.class)); - suite.addTest(new TestSuite(ThreadPoolExecutorSubclassTest.class)); - suite.addTest(new TestSuite(ThreadTest.class)); - suite.addTest(new TestSuite(TimeUnitTest.class)); - suite.addTest(new TestSuite(TreeMapTest.class)); - suite.addTest(new TestSuite(TreeSetTest.class)); - suite.addTest(new TestSuite(TreeSubMapTest.class)); - suite.addTest(new TestSuite(TreeSubSetTest.class)); - - return suite; + return newTestSuite( + ForkJoinPoolTest.suite(), + ForkJoinTaskTest.suite(), + RecursiveActionTest.suite(), + RecursiveTaskTest.suite(), + LinkedTransferQueueTest.suite(), + PhaserTest.suite(), + ThreadLocalRandomTest.suite(), + AbstractExecutorServiceTest.suite(), + AbstractQueueTest.suite(), + AbstractQueuedSynchronizerTest.suite(), + AbstractQueuedLongSynchronizerTest.suite(), + ArrayBlockingQueueTest.suite(), + ArrayDequeTest.suite(), + AtomicBooleanTest.suite(), + AtomicIntegerArrayTest.suite(), + AtomicIntegerFieldUpdaterTest.suite(), + AtomicIntegerTest.suite(), + AtomicLongArrayTest.suite(), + AtomicLongFieldUpdaterTest.suite(), + AtomicLongTest.suite(), + AtomicMarkableReferenceTest.suite(), + AtomicReferenceArrayTest.suite(), + AtomicReferenceFieldUpdaterTest.suite(), + AtomicReferenceTest.suite(), + AtomicStampedReferenceTest.suite(), + ConcurrentHashMapTest.suite(), + ConcurrentLinkedDequeTest.suite(), + ConcurrentLinkedQueueTest.suite(), + ConcurrentSkipListMapTest.suite(), + ConcurrentSkipListSubMapTest.suite(), + ConcurrentSkipListSetTest.suite(), + ConcurrentSkipListSubSetTest.suite(), + CopyOnWriteArrayListTest.suite(), + CopyOnWriteArraySetTest.suite(), + CountDownLatchTest.suite(), + CyclicBarrierTest.suite(), + DelayQueueTest.suite(), + EntryTest.suite(), + ExchangerTest.suite(), + ExecutorsTest.suite(), + ExecutorCompletionServiceTest.suite(), + FutureTaskTest.suite(), + LinkedBlockingDequeTest.suite(), + LinkedBlockingQueueTest.suite(), + LinkedListTest.suite(), + LockSupportTest.suite(), + PriorityBlockingQueueTest.suite(), + PriorityQueueTest.suite(), + ReentrantLockTest.suite(), + ReentrantReadWriteLockTest.suite(), + ScheduledExecutorTest.suite(), + ScheduledExecutorSubclassTest.suite(), + SemaphoreTest.suite(), + SynchronousQueueTest.suite(), + SystemTest.suite(), + ThreadLocalTest.suite(), + ThreadPoolExecutorTest.suite(), + ThreadPoolExecutorSubclassTest.suite(), + ThreadTest.suite(), + TimeUnitTest.suite(), + TreeMapTest.suite(), + TreeSetTest.suite(), + TreeSubMapTest.suite(), + TreeSubSetTest.suite()); } @@ -251,20 +296,24 @@ public class JSR166TestCase extends Test throw (RuntimeException) t; else if (t instanceof Exception) throw (Exception) t; - else - throw new AssertionError(t); + else { + AssertionFailedError afe = + new AssertionFailedError(t.toString()); + afe.initCause(t); + throw afe; + } } } /** * Just like fail(reason), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the current - * testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadFail(String reason) { try { fail(reason); - } catch (Throwable t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); fail(reason); } @@ -272,13 +321,13 @@ public class JSR166TestCase extends Test /** * Just like assertTrue(b), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the current - * testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertTrue(boolean b) { try { assertTrue(b); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } @@ -286,13 +335,13 @@ public class JSR166TestCase extends Test /** * Just like assertFalse(b), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the - * current testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertFalse(boolean b) { try { assertFalse(b); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } @@ -300,13 +349,13 @@ public class JSR166TestCase extends Test /** * Just like assertNull(x), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the - * current testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertNull(Object x) { try { assertNull(x); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } @@ -314,13 +363,13 @@ public class JSR166TestCase extends Test /** * Just like assertEquals(x, y), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the - * current testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertEquals(long x, long y) { try { assertEquals(x, y); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } @@ -328,27 +377,29 @@ public class JSR166TestCase extends Test /** * Just like assertEquals(x, y), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the - * current testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertEquals(Object x, Object y) { try { assertEquals(x, y); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; + } catch (Throwable t) { + threadUnexpectedException(t); } } /** * Just like assertSame(x, y), but additionally recording (using - * threadRecordFailure) any AssertionError thrown, so that the - * current testcase will fail. + * threadRecordFailure) any AssertionFailedError thrown, so that + * the current testcase will fail. */ public void threadAssertSame(Object x, Object y) { try { assertSame(x, y); - } catch (AssertionError t) { + } catch (AssertionFailedError t) { threadRecordFailure(t); throw t; } @@ -369,21 +420,23 @@ public class JSR166TestCase extends Test } /** - * Calls threadFail with message "Unexpected exception" + ex. + * Records the given exception using {@link #threadRecordFailure}, + * then rethrows the exception, wrapping it in an + * AssertionFailedError if necessary. */ public void threadUnexpectedException(Throwable t) { threadRecordFailure(t); t.printStackTrace(); - // Rethrow, wrapping in an AssertionError if necessary if (t instanceof RuntimeException) throw (RuntimeException) t; else if (t instanceof Error) throw (Error) t; else { - AssertionError ae = new AssertionError("unexpected exception: " + t); + AssertionFailedError afe = + new AssertionFailedError("unexpected exception: " + t); t.initCause(t); - throw ae; - } + throw afe; + } } /** @@ -392,7 +445,8 @@ public class JSR166TestCase extends Test public void joinPool(ExecutorService exec) { try { exec.shutdown(); - assertTrue(exec.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); + assertTrue("ExecutorService did not terminate in a timely manner", + exec.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); } catch (SecurityException ok) { // Allowed in case test doesn't have privs } catch (InterruptedException ie) { @@ -416,15 +470,6 @@ public class JSR166TestCase extends Test } /** - * Fails with message "Unexpected exception: " + ex. - */ - public void unexpectedException(Throwable ex) { - ex.printStackTrace(); - fail("Unexpected exception: " + ex); - } - - - /** * The number of elements to place in collections, arrays, etc. */ public static final int SIZE = 20; @@ -535,7 +580,22 @@ public class JSR166TestCase extends Test } /** - * Sleep until the timeout has elapsed, or interrupted. + * Sleeps until the given time has elapsed. + * Throws AssertionFailedError if interrupted. + */ + void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ie) { + AssertionFailedError afe = + new AssertionFailedError("Unexpected InterruptedException"); + afe.initCause(ie); + throw afe; + } + } + + /** + * Sleeps until the timeout has elapsed, or interrupted. * Does NOT throw InterruptedException. */ void sleepTillInterrupted(long timeoutMillis) { @@ -545,14 +605,33 @@ public class JSR166TestCase extends Test } /** - * Returns a new started Thread running the given runnable. + * Returns a new started daemon Thread running the given runnable. */ Thread newStartedThread(Runnable runnable) { Thread t = new Thread(runnable); + t.setDaemon(true); t.start(); return t; } + /** + * Waits for the specified time (in 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, long timeoutMillis) { + try { + t.join(timeoutMillis); + } catch (InterruptedException ie) { + threadUnexpectedException(ie); + } finally { + if (t.isAlive()) { + t.interrupt(); + fail("Test timed out"); + } + } + } + // Some convenient Runnable classes public abstract class CheckedRunnable implements Runnable { @@ -716,12 +795,6 @@ public class JSR166TestCase extends Test } } - public class SmallInterruptedRunnable extends CheckedInterruptedRunnable { - protected void realRun() throws InterruptedException { - Thread.sleep(SMALL_DELAY_MS); - } - } - public class MediumRunnable extends CheckedRunnable { protected void realRun() throws Throwable { Thread.sleep(MEDIUM_DELAY_MS); @@ -734,6 +807,15 @@ public class JSR166TestCase extends Test } } + public Runnable possiblyInterruptedRunnable(final long timeoutMillis) { + return new CheckedRunnable() { + protected void realRun() { + try { + Thread.sleep(timeoutMillis); + } catch (InterruptedException ok) {} + }}; + } + public class MediumPossiblyInterruptedRunnable extends CheckedRunnable { protected void realRun() { try { @@ -759,10 +841,37 @@ public class JSR166TestCase extends Test } } + public interface TrackedRunnable extends Runnable { + boolean isDone(); + } + + public static TrackedRunnable trackedRunnable(final long timeoutMillis) { + return new TrackedRunnable() { + private volatile boolean done = false; + public boolean isDone() { return done; } + public void run() { + try { + Thread.sleep(timeoutMillis); + done = true; + } catch (InterruptedException ok) {} + } + }; + } + public static class TrackedShortRunnable implements Runnable { public volatile boolean done = false; public void run() { try { + Thread.sleep(SHORT_DELAY_MS); + done = true; + } catch (InterruptedException ok) {} + } + } + + public static class TrackedSmallRunnable implements Runnable { + public volatile boolean done = false; + public void run() { + try { Thread.sleep(SMALL_DELAY_MS); done = true; } catch (InterruptedException ok) {} @@ -846,4 +955,23 @@ public class JSR166TestCase extends Test ThreadPoolExecutor executor) {} } + /** + * A CyclicBarrier that fails with AssertionFailedErrors instead + * of throwing checked exceptions. + */ + public class CheckedBarrier extends CyclicBarrier { + public CheckedBarrier(int parties) { super(parties); } + + public int await() { + try { + return super.await(); + } catch (Exception e) { + AssertionFailedError afe = + new AssertionFailedError("Unexpected exception: " + e); + afe.initCause(e); + throw afe; + } + } + } + }