--- jsr166/src/test/tck/JSR166TestCase.java 2015/06/14 20:58:14 1.134 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/09/13 16:28:14 1.143 @@ -37,6 +37,8 @@ import java.util.concurrent.BlockingQueu import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RecursiveAction; @@ -65,18 +67,18 @@ import junit.framework.TestSuite; * *
    * - *
  1. All assertions in code running in generated threads must use + *
  2. All assertions in code running in generated threads must use * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link * #threadAssertEquals}, or {@link #threadAssertNull}, (not * {@code fail}, {@code assertTrue}, etc.) It is OK (but not * particularly recommended) for other code to use these forms too. * Only the most typically used JUnit assertion methods are defined - * this way, but enough to live with.
  3. + * this way, but enough to live with. * - *
  4. If you override {@link #setUp} or {@link #tearDown}, make sure + *
  5. If you override {@link #setUp} or {@link #tearDown}, make sure * to invoke {@code super.setUp} and {@code super.tearDown} within * them. These methods are used to clear and check for thread - * assertion failures.
  6. + * assertion failures. * *
  7. All delays and timeouts must use one of the constants {@code * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS}, @@ -87,44 +89,44 @@ import junit.framework.TestSuite; * is always discriminable as larger than SHORT and smaller than * MEDIUM. And so on. These constants are set to conservative values, * but even so, if there is ever any doubt, they can all be increased - * in one spot to rerun tests on slower platforms.
  8. + * in one spot to rerun tests on slower platforms. * - *
  9. All threads generated must be joined inside each test case + *
  10. All threads generated must be joined inside each test case * method (or {@code fail} to do so) before returning from the * method. The {@code joinPool} method can be used to do this when - * using Executors.
  11. + * using Executors. * *
* *

Other notes *

*/ @@ -281,7 +283,15 @@ public class JSR166TestCase extends Test 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; } - public static boolean atLeastJava9() { return JAVA_CLASS_VERSION >= 53.0; } + public static boolean atLeastJava9() { + return JAVA_CLASS_VERSION >= 53.0 + // As of 2015-09, java9 still uses 52.0 class file version + || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?(9|[0-9][0-9])$"); + } + public static boolean atLeastJava10() { + return JAVA_CLASS_VERSION >= 54.0 + || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?[0-9][0-9]$"); + } /** * Collects all JSR166 unit tests as one suite. @@ -369,6 +379,7 @@ public class JSR166TestCase extends Test "LongAdderTest", "SplittableRandomTest", "StampedLockTest", + "SubmissionPublisherTest", "ThreadLocalRandom8Test", }; addNamedTestClasses(suite, java8TestClassNames); @@ -377,7 +388,7 @@ public class JSR166TestCase extends Test // Java9+ test classes if (atLeastJava9()) { String[] java9TestClassNames = { - "ThreadPoolExecutor9Test", + // Currently empty, but expecting varhandle tests }; addNamedTestClasses(suite, java9TestClassNames); } @@ -481,11 +492,12 @@ public class JSR166TestCase extends Test } /** - * Returns a new Date instance representing a time delayMillis - * milliseconds in the future. + * Returns a new Date instance representing a time at least + * delayMillis milliseconds in the future. */ Date delayedDate(long delayMillis) { - return new Date(System.currentTimeMillis() + delayMillis); + // Add 1 because currentTimeMillis is known to round into the past. + return new Date(System.currentTimeMillis() + delayMillis + 1); } /** @@ -718,11 +730,11 @@ public class JSR166TestCase extends Test /** * Waits out termination of a thread pool or fails doing so. */ - void joinPool(ExecutorService exec) { + void joinPool(ExecutorService pool) { try { - exec.shutdown(); - if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) - fail("ExecutorService " + exec + + pool.shutdown(); + if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) + fail("ExecutorService " + pool + " did not terminate in a timely manner"); } catch (SecurityException ok) { // Allowed in case test doesn't have privs @@ -731,6 +743,34 @@ public class JSR166TestCase extends Test } } + /** Like Runnable, but with the freedom to throw anything */ + interface Action { public void run() throws Throwable; } + + /** + * Runs all the given actions in parallel, failing if any fail. + * Useful for running multiple variants of tests that are + * necessarily individually slow because they must block. + */ + void testInParallel(Action ... actions) { + ExecutorService pool = Executors.newCachedThreadPool(); + try { + ArrayList> futures = new ArrayList<>(actions.length); + for (final Action action : actions) + futures.add(pool.submit(new CheckedRunnable() { + public void realRun() throws Throwable { action.run();}})); + for (Future future : futures) + try { + assertNull(future.get(LONG_DELAY_MS, MILLISECONDS)); + } catch (ExecutionException ex) { + threadUnexpectedException(ex.getCause()); + } catch (Exception ex) { + threadUnexpectedException(ex); + } + } finally { + joinPool(pool); + } + } + /** * A debugging tool to print all stack traces, as jstack does. */