--- jsr166/src/test/tck/JSR166TestCase.java 2013/02/05 03:39:34 1.99 +++ jsr166/src/test/tck/JSR166TestCase.java 2013/04/01 20:06:26 1.106 @@ -286,8 +286,15 @@ public class JSR166TestCase extends Test // Java8+ test classes if (atLeastJava8()) { String[] java8TestClassNames = { - "StampedLockTest", + "CompletableFutureTest", + "ConcurrentHashMap8Test", + "CountedCompleterTest", + "DoubleAccumulatorTest", + "DoubleAdderTest", "ForkJoinPool8Test", + "LongAccumulatorTest", + "LongAdderTest", + "StampedLockTest", }; addNamedTestClasses(suite, java8TestClassNames); } @@ -384,6 +391,29 @@ public class JSR166TestCase extends Test if (Thread.interrupted()) throw new AssertionFailedError("interrupt status set in main thread"); + + checkForkJoinPoolThreadLeaks(); + } + + /** + * Find missing try { ... } finally { joinPool(e); } + */ + void checkForkJoinPoolThreadLeaks() throws InterruptedException { + Thread[] survivors = new Thread[5]; + int count = Thread.enumerate(survivors); + for (int i = 0; i < count; i++) { + Thread thread = survivors[i]; + String name = thread.getName(); + if (name.startsWith("ForkJoinPool-")) { + // give thread some time to terminate + thread.join(LONG_DELAY_MS); + if (!thread.isAlive()) continue; + thread.stop(); + throw new AssertionFailedError + (String.format("Found leaked ForkJoinPool thread test=%s thread=%s%n", + toString(), name)); + } + } } /** @@ -1318,4 +1348,25 @@ public class JSR166TestCase extends Test return null; } } + + public void assertThrows(Class expectedExceptionClass, + Runnable... throwingActions) { + for (Runnable throwingAction : throwingActions) { + boolean threw = false; + try { throwingAction.run(); } + catch (Throwable t) { + threw = true; + if (!expectedExceptionClass.isInstance(t)) { + AssertionFailedError afe = + new AssertionFailedError + ("Expected " + expectedExceptionClass.getName() + + ", got " + t.getClass().getName()); + afe.initCause(t); + threadUnexpectedException(afe); + } + } + if (!threw) + shouldThrow(expectedExceptionClass.getName()); + } + } }