--- jsr166/src/test/tck/JSR166TestCase.java 2013/02/01 19:07:36 1.97 +++ jsr166/src/test/tck/JSR166TestCase.java 2013/02/06 16:55:50 1.100 @@ -182,13 +182,17 @@ public class JSR166TestCase extends Test return suite; } - static void addTestReflectively(TestSuite suite, String testClassName) { - try { - Class klazz = Class.forName(testClassName); - Method m = klazz.getDeclaredMethod("suite", new Class[0]); - suite.addTest(newTestSuite((Test)m.invoke(null))); - } catch (Exception e) { - throw new Error(e); + public static void addNamedTestClasses(TestSuite suite, + String... testClassNames) { + for (String testClassName : testClassNames) { + try { + Class testClass = Class.forName(testClassName); + Method m = testClass.getDeclaredMethod("suite", + new Class[0]); + suite.addTest(newTestSuite((Test)m.invoke(null))); + } catch (Exception e) { + throw new Error("Missing test class", e); + } } } @@ -204,14 +208,15 @@ public class JSR166TestCase extends Test } } - public static boolean isAtLeastJdk6() { return JAVA_CLASS_VERSION >= 50.0; } - public static boolean isAtLeastJdk7() { return JAVA_CLASS_VERSION >= 51.0; } - public static boolean isAtLeastJdk8() { return JAVA_CLASS_VERSION >= 52.0; } + public static boolean atLeastJava6() { return JAVA_CLASS_VERSION >= 50.0; } + public static boolean atLeastJava7() { return JAVA_CLASS_VERSION >= 51.0; } + public static boolean atLeastJava8() { return JAVA_CLASS_VERSION >= 52.0; } /** * Collects all JSR166 unit tests as one suite. */ public static Test suite() { + // Java7+ test classes TestSuite suite = newTestSuite( ForkJoinPoolTest.suite(), ForkJoinTaskTest.suite(), @@ -277,9 +282,16 @@ public class JSR166TestCase extends Test TreeSetTest.suite(), TreeSubMapTest.suite(), TreeSubSetTest.suite()); - if (isAtLeastJdk8()) { - addTestReflectively(suite, "StampedLockTest"); + + // Java8+ test classes + if (atLeastJava8()) { + String[] java8TestClassNames = { + "StampedLockTest", + "ForkJoinPool8Test", + }; + addNamedTestClasses(suite, java8TestClassNames); } + return suite; } @@ -372,9 +384,32 @@ 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)); + } + } + } + + /** * Just like fail(reason), but additionally recording (using * threadRecordFailure) any AssertionFailedError thrown, so that * the current testcase will fail.