--- jsr166/src/test/tck/JSR166TestCase.java 2013/07/14 16:55:01 1.109 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/01/17 23:14:17 1.127 @@ -6,7 +6,9 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; @@ -14,25 +16,41 @@ import java.io.ObjectOutputStream; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.reflect.Method; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.security.SecurityPermission; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; +import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.PropertyPermission; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RecursiveAction; +import java.util.concurrent.RecursiveTask; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.security.SecurityPermission; +import java.util.regex.Pattern; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; /** * Base class for JSR166 Junit TCK tests. Defines some constants, @@ -115,6 +133,13 @@ public class JSR166TestCase extends Test Boolean.getBoolean("jsr166.expensiveTests"); /** + * If true, also run tests that are not part of the official tck + * because they test unspecified implementation details. + */ + protected static final boolean testImplementationDetails = + Boolean.getBoolean("jsr166.testImplementationDetails"); + + /** * If true, report on stdout all "slow" tests, that is, ones that * take more than profileThreshold milliseconds to execute. */ @@ -134,22 +159,38 @@ public class JSR166TestCase extends Test private static final int runsPerTest = Integer.getInteger("jsr166.runsPerTest", 1); + /** + * A filter for tests to run, matching strings of the form + * methodName(className), e.g. "testInvokeAll5(ForkJoinPoolTest)" + * Usefully combined with jsr166.runsPerTest. + */ + private static final Pattern methodFilter = methodFilter(); + + private static Pattern methodFilter() { + String regex = System.getProperty("jsr166.methodFilter"); + return (regex == null) ? null : Pattern.compile(regex); + } + protected void runTest() throws Throwable { - for (int i = 0; i < runsPerTest; i++) { - if (profileTests) - runTestProfiled(); - else - super.runTest(); + if (methodFilter == null + || methodFilter.matcher(toString()).find()) { + for (int i = 0; i < runsPerTest; i++) { + if (profileTests) + runTestProfiled(); + else + super.runTest(); + } } } protected void runTestProfiled() throws Throwable { + // Warmup run, notably to trigger all needed classloading. + super.runTest(); long t0 = System.nanoTime(); try { super.runTest(); } finally { - long elapsedMillis = - (System.nanoTime() - t0) / (1000L * 1000L); + long elapsedMillis = millisElapsedSince(t0); if (elapsedMillis >= profileThreshold) System.out.printf("%n%s: %d%n", toString(), elapsedMillis); } @@ -205,12 +246,17 @@ public class JSR166TestCase extends Test } public static final double JAVA_CLASS_VERSION; + public static final String JAVA_SPECIFICATION_VERSION; static { try { JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Double run() { return Double.valueOf(System.getProperty("java.class.version"));}}); + JAVA_SPECIFICATION_VERSION = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public String run() { + return System.getProperty("java.specification.version");}}); } catch (Throwable t) { throw new Error(t); } @@ -219,6 +265,10 @@ 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() { + // As of 2014-05, java9 still uses 52.0 class file version + return JAVA_SPECIFICATION_VERSION.startsWith("1.9"); + } /** * Collects all JSR166 unit tests as one suite. @@ -232,7 +282,6 @@ public class JSR166TestCase extends Test RecursiveTaskTest.suite(), LinkedTransferQueueTest.suite(), PhaserTest.suite(), - SplittableRandomTest.suite(), ThreadLocalRandomTest.suite(), AbstractExecutorServiceTest.suite(), AbstractQueueTest.suite(), @@ -295,19 +344,31 @@ public class JSR166TestCase extends Test // Java8+ test classes if (atLeastJava8()) { String[] java8TestClassNames = { + "Atomic8Test", "CompletableFutureTest", "ConcurrentHashMap8Test", "CountedCompleterTest", "DoubleAccumulatorTest", "DoubleAdderTest", "ForkJoinPool8Test", + "ForkJoinTask8Test", "LongAccumulatorTest", "LongAdderTest", + "SplittableRandomTest", "StampedLockTest", + "ThreadLocalRandom8Test", }; addNamedTestClasses(suite, java8TestClassNames); } + // Java9+ test classes + if (atLeastJava9()) { + String[] java9TestClassNames = { + "ThreadPoolExecutor9Test", + }; + addNamedTestClasses(suite, java9TestClassNames); + } + return suite; } @@ -405,7 +466,7 @@ public class JSR166TestCase extends Test } /** - * Find missing try { ... } finally { joinPool(e); } + * Finds missing try { ... } finally { joinPool(e); } */ void checkForkJoinPoolThreadLeaks() throws InterruptedException { Thread[] survivors = new Thread[5]; @@ -586,8 +647,9 @@ public class JSR166TestCase extends Test void joinPool(ExecutorService exec) { try { exec.shutdown(); - assertTrue("ExecutorService did not terminate in a timely manner", - exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)); + if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) + fail("ExecutorService " + exec + + " did not terminate in a timely manner"); } catch (SecurityException ok) { // Allowed in case test doesn't have privs } catch (InterruptedException ie) { @@ -863,12 +925,42 @@ public class JSR166TestCase extends Test /** * Returns the number of milliseconds since time given by * startNanoTime, which must have been previously returned from a - * call to {@link System.nanoTime()}. + * call to {@link System#nanoTime()}. */ - long millisElapsedSince(long startNanoTime) { + static long millisElapsedSince(long startNanoTime) { return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); } +// void assertTerminatesPromptly(long timeoutMillis, Runnable r) { +// long startTime = System.nanoTime(); +// try { +// r.run(); +// } catch (Throwable fail) { threadUnexpectedException(fail); } +// if (millisElapsedSince(startTime) > timeoutMillis/2) +// throw new AssertionFailedError("did not return promptly"); +// } + +// void assertTerminatesPromptly(Runnable r) { +// assertTerminatesPromptly(LONG_DELAY_MS/2, r); +// } + + /** + * Checks that timed f.get() returns the expected value, and does not + * wait for the timeout to elapse before returning. + */ + void checkTimedGet(Future f, T expectedValue, long timeoutMillis) { + long startTime = System.nanoTime(); + try { + assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS)); + } catch (Throwable fail) { threadUnexpectedException(fail); } + if (millisElapsedSince(startTime) > timeoutMillis/2) + throw new AssertionFailedError("timed get did not return promptly"); + } + + void checkTimedGet(Future f, T expectedValue) { + checkTimedGet(f, expectedValue, LONG_DELAY_MS); + } + /** * Returns a new started daemon Thread running the given runnable. */ @@ -1377,4 +1469,12 @@ public class JSR166TestCase extends Test shouldThrow(expectedExceptionClass.getName()); } } + + public void assertIteratorExhausted(Iterator it) { + try { + it.next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertFalse(it.hasNext()); + } }