--- jsr166/src/test/tck/JSR166TestCase.java 2016/06/22 14:40:36 1.197
+++ jsr166/src/test/tck/JSR166TestCase.java 2022/03/22 21:29:24 1.275
@@ -1,6 +1,7 @@
/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
* Other contributors include Andrew Wright, Jeffrey Hayes,
* Pat Fisher, Mike Judd.
@@ -8,11 +9,35 @@
/*
* @test
- * @summary JSR-166 tck tests
- * @modules java.management
+ * @summary JSR-166 tck tests, in a number of variations.
+ * The first is the conformance testing variant,
+ * while others also test implementation details.
* @build *
- * @run junit/othervm/timeout=1000 -Djsr166.testImplementationDetails=true JSR166TestCase
- * @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 -Djsr166.testImplementationDetails=true JSR166TestCase
+ * @modules java.management
+ * @run junit/othervm/timeout=1000 JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ * --add-opens java.base/java.util.concurrent=ALL-UNNAMED
+ * --add-opens java.base/java.lang=ALL-UNNAMED
+ * -Djsr166.testImplementationDetails=true
+ * JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ * --add-opens java.base/java.util.concurrent=ALL-UNNAMED
+ * --add-opens java.base/java.lang=ALL-UNNAMED
+ * -Djsr166.testImplementationDetails=true
+ * -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
+ * JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ * --add-opens java.base/java.util.concurrent=ALL-UNNAMED
+ * --add-opens java.base/java.lang=ALL-UNNAMED
+ * -Djsr166.testImplementationDetails=true
+ * -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
+ * -Djava.util.secureRandomSeed=true
+ * JSR166TestCase
+ * @run junit/othervm/timeout=1000/policy=tck.policy
+ * --add-opens java.base/java.util.concurrent=ALL-UNNAMED
+ * --add-opens java.base/java.lang=ALL-UNNAMED
+ * -Djsr166.testImplementationDetails=true
+ * JSR166TestCase
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -24,13 +49,12 @@ import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.management.ManagementFactory;
+import java.lang.management.LockInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
@@ -40,35 +64,46 @@ import java.security.ProtectionDomain;
import java.security.SecurityPermission;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
+import java.util.Deque;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.PropertyPermission;
+import java.util.Queue;
+import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Semaphore;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestResult;
@@ -84,13 +119,21 @@ import junit.framework.TestSuite;
*
*
*
- *
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.
+ *
All code not running in the main test thread (manually spawned threads
+ * or the common fork join pool) must be checked for failure (and completion!).
+ * Mechanisms that can be used to ensure this are:
+ *
+ *
Signalling via a synchronizer like AtomicInteger or CountDownLatch
+ * that the task completed normally, which is checked before returning from
+ * the test method in the main thread.
+ *
Using the forms {@link #threadFail}, {@link #threadAssertTrue},
+ * or {@link #threadAssertNull}, (not {@code fail}, {@code assertTrue}, etc.)
+ * Only the most typically used JUnit assertion methods are defined
+ * this way, but enough to live with.
+ *
Recording failure explicitly using {@link #threadUnexpectedException}
+ * or {@link #threadRecordFailure}.
+ *
Using a wrapper like CheckedRunnable that uses one the mechanisms above.
+ *
*
*
If you override {@link #setUp} or {@link #tearDown}, make sure
* to invoke {@code super.setUp} and {@code super.tearDown} within
@@ -108,6 +151,11 @@ import junit.framework.TestSuite;
* but even so, if there is ever any doubt, they can all be increased
* in one spot to rerun tests on slower platforms.
*
+ * Class Item is used for elements of collections and related
+ * purposes. Many tests rely on their keys being equal to ints. To
+ * check these, methods mustEqual, mustContain, etc adapt the JUnit
+ * assert methods to intercept ints.
+ *
*
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
@@ -147,8 +195,9 @@ import junit.framework.TestSuite;
*
*/
public class JSR166TestCase extends TestCase {
+ // No longer run with custom securityManagers
private static final boolean useSecurityManager =
- Boolean.getBoolean("jsr166.useSecurityManager");
+ Boolean.getBoolean("jsr166.useSecurityManager");
protected static final boolean expensiveTests =
Boolean.getBoolean("jsr166.expensiveTests");
@@ -202,6 +251,9 @@ public class JSR166TestCase extends Test
}
}
+ private static final ThreadMXBean THREAD_MXBEAN
+ = ManagementFactory.getThreadMXBean();
+
/**
* The scaling factor to apply to standard delays used in tests.
* May be initialized from any of:
@@ -243,12 +295,13 @@ public class JSR166TestCase extends Test
static volatile TestCase currentTestCase;
// static volatile int currentRun = 0;
static {
- Runnable checkForWedgedTest = new Runnable() { public void run() {
+ Runnable wedgedTestDetector = new Runnable() { public void run() {
// Avoid spurious reports with enormous runsPerTest.
// A single test case run should never take more than 1 second.
// But let's cap it at the high end too ...
- final int timeoutMinutes =
- Math.min(15, Math.max(runsPerTest / 60, 1));
+ final int timeoutMinutesMin = Math.max(runsPerTest / 60, 1)
+ * Math.max((int) delayFactor, 1);
+ final int timeoutMinutes = Math.min(15, timeoutMinutesMin);
for (TestCase lastTestCase = currentTestCase;;) {
try { MINUTES.sleep(timeoutMinutes); }
catch (InterruptedException unexpected) { break; }
@@ -268,16 +321,18 @@ public class JSR166TestCase extends Test
}
lastTestCase = currentTestCase;
}}};
- Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest");
+ Thread thread = new Thread(wedgedTestDetector, "WedgedTestDetector");
thread.setDaemon(true);
thread.start();
}
// public static String cpuModel() {
// try {
-// Matcher matcher = Pattern.compile("model name\\s*: (.*)")
+// java.util.regex.Matcher matcher
+// = Pattern.compile("model name\\s*: (.*)")
// .matcher(new String(
-// Files.readAllBytes(Paths.get("/proc/cpuinfo")), "UTF-8"));
+// java.nio.file.Files.readAllBytes(
+// java.nio.file.Paths.get("/proc/cpuinfo")), "UTF-8"));
// matcher.find();
// return matcher.group(1);
// } catch (Exception ex) { return null; }
@@ -310,7 +365,7 @@ public class JSR166TestCase extends Test
// Never report first run of any test; treat it as a
// warmup run, notably to trigger all needed classloading,
if (i > 0)
- System.out.printf("%n%s: %d%n", toString(), elapsedMillis);
+ System.out.printf("%s: %d%n", toString(), elapsedMillis);
}
}
@@ -353,11 +408,15 @@ public class JSR166TestCase extends Test
* Runs all unit tests in the given test suite.
* Actual behavior influenced by jsr166.* system properties.
*/
+ @SuppressWarnings("removal")
static void main(Test suite, String[] args) {
if (useSecurityManager) {
System.err.println("Setting a permissive security manager");
Policy.setPolicy(permissivePolicy());
- System.setSecurityManager(new SecurityManager());
+ try {
+ System.setSecurityManager(new SecurityManager());
+ } catch(Throwable ok) { // failure OK during deprecation
+ }
}
for (int i = 0; i < suiteRuns; i++) {
TestResult result = newPithyTestRunner().doRun(suite);
@@ -386,11 +445,10 @@ public class JSR166TestCase extends Test
for (String testClassName : testClassNames) {
try {
Class> testClass = Class.forName(testClassName);
- Method m = testClass.getDeclaredMethod("suite",
- new Class>[0]);
+ Method m = testClass.getDeclaredMethod("suite");
suite.addTest(newTestSuite((Test)m.invoke(null)));
- } catch (Exception e) {
- throw new Error("Missing test class", e);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError("Missing test class", e);
}
}
}
@@ -399,31 +457,35 @@ public class JSR166TestCase extends Test
public static final String JAVA_SPECIFICATION_VERSION;
static {
try {
- JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged(
+ @SuppressWarnings("removal") double jcv =
+ 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(
+ JAVA_CLASS_VERSION = jcv;
+ @SuppressWarnings("removal") String jsv =
+ java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public String run() {
return System.getProperty("java.specification.version");}});
+ JAVA_SPECIFICATION_VERSION = jsv;
} catch (Throwable t) {
throw new Error(t);
}
}
- 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
- // 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]$");
- }
+ 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 atLeastJava10() { return JAVA_CLASS_VERSION >= 54.0; }
+ public static boolean atLeastJava11() { return JAVA_CLASS_VERSION >= 55.0; }
+ public static boolean atLeastJava12() { return JAVA_CLASS_VERSION >= 56.0; }
+ public static boolean atLeastJava13() { return JAVA_CLASS_VERSION >= 57.0; }
+ public static boolean atLeastJava14() { return JAVA_CLASS_VERSION >= 58.0; }
+ public static boolean atLeastJava15() { return JAVA_CLASS_VERSION >= 59.0; }
+ public static boolean atLeastJava16() { return JAVA_CLASS_VERSION >= 60.0; }
+ public static boolean atLeastJava17() { return JAVA_CLASS_VERSION >= 61.0; }
/**
* Collects all JSR166 unit tests as one suite.
@@ -444,6 +506,7 @@ public class JSR166TestCase extends Test
AbstractQueuedLongSynchronizerTest.suite(),
ArrayBlockingQueueTest.suite(),
ArrayDequeTest.suite(),
+ ArrayListTest.suite(),
AtomicBooleanTest.suite(),
AtomicIntegerArrayTest.suite(),
AtomicIntegerFieldUpdaterTest.suite(),
@@ -466,6 +529,7 @@ public class JSR166TestCase extends Test
CopyOnWriteArrayListTest.suite(),
CopyOnWriteArraySetTest.suite(),
CountDownLatchTest.suite(),
+ CountedCompleterTest.suite(),
CyclicBarrierTest.suite(),
DelayQueueTest.suite(),
EntryTest.suite(),
@@ -473,6 +537,7 @@ public class JSR166TestCase extends Test
ExecutorsTest.suite(),
ExecutorCompletionServiceTest.suite(),
FutureTaskTest.suite(),
+ HashtableTest.suite(),
LinkedBlockingDequeTest.suite(),
LinkedBlockingQueueTest.suite(),
LinkedListTest.suite(),
@@ -494,19 +559,25 @@ public class JSR166TestCase extends Test
TreeMapTest.suite(),
TreeSetTest.suite(),
TreeSubMapTest.suite(),
- TreeSubSetTest.suite());
+ TreeSubSetTest.suite(),
+ VectorTest.suite());
// Java8+ test classes
if (atLeastJava8()) {
String[] java8TestClassNames = {
+ "ArrayDeque8Test",
"Atomic8Test",
"CompletableFutureTest",
"ConcurrentHashMap8Test",
- "CountedCompleterTest",
+ "CountedCompleter8Test",
"DoubleAccumulatorTest",
"DoubleAdderTest",
"ForkJoinPool8Test",
"ForkJoinTask8Test",
+ "HashMapTest",
+ "LinkedBlockingDeque8Test",
+ "LinkedBlockingQueue8Test",
+ "LinkedHashMapTest",
"LongAccumulatorTest",
"LongAdderTest",
"SplittableRandomTest",
@@ -529,17 +600,24 @@ public class JSR166TestCase extends Test
"AtomicReference9Test",
"AtomicReferenceArray9Test",
"ExecutorCompletionService9Test",
+ "ForkJoinPool9Test",
};
addNamedTestClasses(suite, java9TestClassNames);
}
+ if (atLeastJava17()) {
+ String[] java17TestClassNames = {
+ "ForkJoinPool19Test",
+ };
+ addNamedTestClasses(suite, java17TestClassNames);
+ }
return suite;
}
/** Returns list of junit-style test method names in given class. */
public static ArrayList testMethodNames(Class> testClass) {
Method[] methods = testClass.getDeclaredMethods();
- ArrayList names = new ArrayList(methods.length);
+ ArrayList names = new ArrayList<>(methods.length);
for (Method method : methods) {
if (method.getName().startsWith("test")
&& Modifier.isPublic(method.getModifiers())
@@ -566,8 +644,8 @@ public class JSR166TestCase extends Test
for (String methodName : testMethodNames(testClass))
suite.addTest((Test) c.newInstance(data, methodName));
return suite;
- } catch (Exception e) {
- throw new Error(e);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
}
}
@@ -583,14 +661,14 @@ public class JSR166TestCase extends Test
if (atLeastJava8()) {
String name = testClass.getName();
String name8 = name.replaceAll("Test$", "8Test");
- if (name.equals(name8)) throw new Error(name);
+ if (name.equals(name8)) throw new AssertionError(name);
try {
return (Test)
Class.forName(name8)
- .getMethod("testSuite", new Class[] { dataClass })
+ .getMethod("testSuite", dataClass)
.invoke(null, data);
- } catch (Exception e) {
- throw new Error(e);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
}
} else {
return new TestSuite();
@@ -605,6 +683,61 @@ public class JSR166TestCase extends Test
public static long LONG_DELAY_MS;
/**
+ * A delay significantly longer than LONG_DELAY_MS.
+ * Use this in a thread that is waited for via awaitTermination(Thread).
+ */
+ public static long LONGER_DELAY_MS;
+
+ private static final long RANDOM_TIMEOUT;
+ private static final long RANDOM_EXPIRED_TIMEOUT;
+ private static final TimeUnit RANDOM_TIMEUNIT;
+ static {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ long[] timeouts = { Long.MIN_VALUE, -1, 0, 1, Long.MAX_VALUE };
+ RANDOM_TIMEOUT = timeouts[rnd.nextInt(timeouts.length)];
+ RANDOM_EXPIRED_TIMEOUT = timeouts[rnd.nextInt(3)];
+ TimeUnit[] timeUnits = TimeUnit.values();
+ RANDOM_TIMEUNIT = timeUnits[rnd.nextInt(timeUnits.length)];
+ }
+
+ /**
+ * Returns a timeout for use when any value at all will do.
+ */
+ static long randomTimeout() { return RANDOM_TIMEOUT; }
+
+ /**
+ * Returns a timeout that means "no waiting", i.e. not positive.
+ */
+ static long randomExpiredTimeout() { return RANDOM_EXPIRED_TIMEOUT; }
+
+ /**
+ * Returns a random non-null TimeUnit.
+ */
+ static TimeUnit randomTimeUnit() { return RANDOM_TIMEUNIT; }
+
+ /**
+ * Returns a random boolean; a "coin flip".
+ */
+ static boolean randomBoolean() {
+ return ThreadLocalRandom.current().nextBoolean();
+ }
+
+ /**
+ * Returns a random element from given choices.
+ */
+ T chooseRandomly(List choices) {
+ return choices.get(ThreadLocalRandom.current().nextInt(choices.size()));
+ }
+
+ /**
+ * Returns a random element from given choices.
+ */
+ @SuppressWarnings("unchecked")
+ T chooseRandomly(T... choices) {
+ return choices[ThreadLocalRandom.current().nextInt(choices.length)];
+ }
+
+ /**
* Returns the shortest timed delay. This can be scaled up for
* slow machines using the jsr166.delay.factor system property,
* or via jtreg's -timeoutFactor: flag.
@@ -622,14 +755,20 @@ public class JSR166TestCase extends Test
SMALL_DELAY_MS = SHORT_DELAY_MS * 5;
MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
LONG_DELAY_MS = SHORT_DELAY_MS * 200;
+ LONGER_DELAY_MS = 2 * LONG_DELAY_MS;
}
+ private static final long TIMEOUT_DELAY_MS
+ = (long) (12.0 * Math.cbrt(delayFactor));
+
/**
- * Returns a timeout in milliseconds to be used in tests that
- * verify that operations block or time out.
+ * Returns a timeout in milliseconds to be used in tests that verify
+ * that operations block or time out. We want this to be longer
+ * than the OS scheduling quantum, but not too long, so don't scale
+ * linearly with delayFactor; we use "crazy" cube root instead.
*/
- long timeoutMillis() {
- return SHORT_DELAY_MS / 4;
+ static long timeoutMillis() {
+ return TIMEOUT_DELAY_MS;
}
/**
@@ -645,7 +784,7 @@ public class JSR166TestCase extends Test
* The first exception encountered if any threadAssertXXX method fails.
*/
private final AtomicReference threadFailure
- = new AtomicReference(null);
+ = new AtomicReference<>(null);
/**
* Records an exception so that it can be rethrown later in the test
@@ -655,8 +794,8 @@ public class JSR166TestCase extends Test
*/
public void threadRecordFailure(Throwable t) {
System.err.println(t);
- dumpTestThreads();
- threadFailure.compareAndSet(null, t);
+ if (threadFailure.compareAndSet(null, t))
+ dumpTestThreads();
}
public void setUp() {
@@ -667,7 +806,7 @@ public class JSR166TestCase extends Test
String msg = toString() + ": " + String.format(format, args);
System.err.println(msg);
dumpTestThreads();
- throw new AssertionFailedError(msg);
+ throw new AssertionError(msg);
}
/**
@@ -688,12 +827,8 @@ public class JSR166TestCase extends Test
throw (RuntimeException) t;
else if (t instanceof Exception)
throw (Exception) t;
- else {
- AssertionFailedError afe =
- new AssertionFailedError(t.toString());
- afe.initCause(t);
- throw afe;
- }
+ else
+ throw new AssertionError(t.toString(), t);
}
if (Thread.interrupted())
@@ -727,83 +862,83 @@ public class JSR166TestCase extends Test
/**
* Just like fail(reason), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadFail(String reason) {
try {
fail(reason);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
/**
* Just like assertTrue(b), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertTrue(boolean b) {
try {
assertTrue(b);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
/**
* Just like assertFalse(b), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertFalse(boolean b) {
try {
assertFalse(b);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
/**
* Just like assertNull(x), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertNull(Object x) {
try {
assertNull(x);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
/**
* Just like assertEquals(x, y), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertEquals(long x, long y) {
try {
assertEquals(x, y);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
/**
* Just like assertEquals(x, y), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertEquals(Object x, Object y) {
try {
assertEquals(x, y);
- } catch (AssertionFailedError fail) {
+ } catch (AssertionError fail) {
threadRecordFailure(fail);
throw fail;
} catch (Throwable fail) {
@@ -813,13 +948,13 @@ public class JSR166TestCase extends Test
/**
* Just like assertSame(x, y), but additionally recording (using
- * threadRecordFailure) any AssertionFailedError thrown, so that
- * the current testcase will fail.
+ * threadRecordFailure) any AssertionError thrown, so that the
+ * current testcase will fail.
*/
public void threadAssertSame(Object x, Object y) {
try {
assertSame(x, y);
- } catch (AssertionFailedError fail) {
+ } catch (AssertionError fail) {
threadRecordFailure(fail);
throw fail;
}
@@ -841,8 +976,8 @@ public class JSR166TestCase extends Test
/**
* Records the given exception using {@link #threadRecordFailure},
- * then rethrows the exception, wrapping it in an
- * AssertionFailedError if necessary.
+ * then rethrows the exception, wrapping it in an AssertionError
+ * if necessary.
*/
public void threadUnexpectedException(Throwable t) {
threadRecordFailure(t);
@@ -851,12 +986,8 @@ public class JSR166TestCase extends Test
throw (RuntimeException) t;
else if (t instanceof Error)
throw (Error) t;
- else {
- AssertionFailedError afe =
- new AssertionFailedError("unexpected exception: " + t);
- afe.initCause(t);
- throw afe;
- }
+ else
+ throw new AssertionError("unexpected exception: " + t, t);
}
/**
@@ -938,7 +1069,7 @@ public class JSR166TestCase extends Test
void joinPool(ExecutorService pool) {
try {
pool.shutdown();
- if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) {
+ if (!pool.awaitTermination(20 * LONG_DELAY_MS, MILLISECONDS)) {
try {
threadFail("ExecutorService " + pool +
" did not terminate in a timely manner");
@@ -985,10 +1116,44 @@ public class JSR166TestCase extends Test
}
}
+ /** Returns true if thread info might be useful in a thread dump. */
+ static boolean threadOfInterest(ThreadInfo info) {
+ final String name = info.getThreadName();
+ String lockName;
+ if (name == null)
+ return true;
+ if (name.equals("Signal Dispatcher")
+ || name.equals("WedgedTestDetector"))
+ return false;
+ if (name.equals("Reference Handler")) {
+ // Reference Handler stacktrace changed in JDK-8156500
+ StackTraceElement[] stackTrace; String methodName;
+ if ((stackTrace = info.getStackTrace()) != null
+ && stackTrace.length > 0
+ && (methodName = stackTrace[0].getMethodName()) != null
+ && methodName.equals("waitForReferencePendingList"))
+ return false;
+ // jdk8 Reference Handler stacktrace
+ if ((lockName = info.getLockName()) != null
+ && lockName.startsWith("java.lang.ref"))
+ return false;
+ }
+ if ((name.equals("Finalizer") || name.equals("Common-Cleaner"))
+ && (lockName = info.getLockName()) != null
+ && lockName.startsWith("java.lang.ref"))
+ return false;
+ if (name.startsWith("ForkJoinPool.commonPool-worker")
+ && (lockName = info.getLockName()) != null
+ && lockName.startsWith("java.util.concurrent.ForkJoinPool"))
+ return false;
+ return true;
+ }
+
/**
* A debugging tool to print stack traces of most threads, as jstack does.
* Uninteresting threads are filtered out.
*/
+ @SuppressWarnings("removal")
static void dumpTestThreads() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -999,82 +1164,58 @@ public class JSR166TestCase extends Test
}
}
- ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
System.err.println("------ stacktrace dump start ------");
- for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
- String name = info.getThreadName();
- if ("Signal Dispatcher".equals(name))
- continue;
- if ("Reference Handler".equals(name)
- && info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
- continue;
- if ("Finalizer".equals(name)
- && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
- continue;
- if ("checkForWedgedTest".equals(name))
- continue;
- System.err.print(info);
- }
+ for (ThreadInfo info : THREAD_MXBEAN.dumpAllThreads(true, true))
+ if (threadOfInterest(info))
+ System.err.print(info);
System.err.println("------ stacktrace dump end ------");
if (sm != null) System.setSecurityManager(sm);
}
/**
- * Checks that thread does not terminate within the default
- * millisecond delay of {@code timeoutMillis()}.
- */
- void assertThreadStaysAlive(Thread thread) {
- assertThreadStaysAlive(thread, timeoutMillis());
- }
-
- /**
- * Checks that thread does not terminate within the given millisecond delay.
+ * Checks that thread eventually enters the expected blocked thread state.
*/
- void assertThreadStaysAlive(Thread thread, long millis) {
- try {
- // No need to optimize the failing case via Thread.join.
- delay(millis);
- assertTrue(thread.isAlive());
- } catch (InterruptedException fail) {
- threadFail("Unexpected InterruptedException");
+ void assertThreadBlocks(Thread thread, Thread.State expected) {
+ // always sleep at least 1 ms, with high probability avoiding
+ // transitory states
+ for (long retries = LONG_DELAY_MS * 3 / 4; retries-->0; ) {
+ try { delay(1); }
+ catch (InterruptedException fail) {
+ throw new AssertionError("Unexpected InterruptedException", fail);
+ }
+ Thread.State s = thread.getState();
+ if (s == expected)
+ return;
+ else if (s == Thread.State.TERMINATED)
+ fail("Unexpected thread termination");
}
+ fail("timed out waiting for thread to enter thread state " + expected);
}
/**
- * Checks that the threads do not terminate within the default
- * millisecond delay of {@code timeoutMillis()}.
- */
- void assertThreadsStayAlive(Thread... threads) {
- assertThreadsStayAlive(timeoutMillis(), threads);
- }
-
- /**
- * Checks that the threads do not terminate within the given millisecond delay.
+ * Returns the thread's blocker's class name, if any, else null.
*/
- void assertThreadsStayAlive(long millis, Thread... threads) {
- try {
- // No need to optimize the failing case via Thread.join.
- delay(millis);
- for (Thread thread : threads)
- assertTrue(thread.isAlive());
- } catch (InterruptedException fail) {
- threadFail("Unexpected InterruptedException");
- }
+ String blockerClassName(Thread thread) {
+ ThreadInfo threadInfo; LockInfo lockInfo;
+ if ((threadInfo = THREAD_MXBEAN.getThreadInfo(thread.getId(), 0)) != null
+ && (lockInfo = threadInfo.getLockInfo()) != null)
+ return lockInfo.getClassName();
+ return null;
}
/**
* Checks that future.get times out, with the default timeout of
* {@code timeoutMillis()}.
*/
- void assertFutureTimesOut(Future future) {
+ void assertFutureTimesOut(Future> future) {
assertFutureTimesOut(future, timeoutMillis());
}
/**
* Checks that future.get times out, with the given millisecond timeout.
*/
- void assertFutureTimesOut(Future future, long timeoutMillis) {
+ void assertFutureTimesOut(Future> future, long timeoutMillis) {
long startTime = System.nanoTime();
try {
future.get(timeoutMillis, MILLISECONDS);
@@ -1082,8 +1223,9 @@ public class JSR166TestCase extends Test
} catch (TimeoutException success) {
} catch (Exception fail) {
threadUnexpectedException(fail);
- } finally { future.cancel(true); }
+ }
assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ assertFalse(future.isDone());
}
/**
@@ -1101,29 +1243,142 @@ public class JSR166TestCase extends Test
}
/**
- * The number of elements to place in collections, arrays, etc.
+ * The maximum number of consecutive spurious wakeups we should
+ * tolerate (from APIs like LockSupport.park) before failing a test.
*/
- public static final int SIZE = 20;
+ static final int MAX_SPURIOUS_WAKEUPS = 10;
- // Some convenient Integer constants
+ /**
+ * The number of elements to place in collections, arrays, etc.
+ * Must be at least ten;
+ */
+ public static final int SIZE = 32;
- public static final Integer zero = new Integer(0);
- public static final Integer one = new Integer(1);
- public static final Integer two = new Integer(2);
- public static final Integer three = new Integer(3);
- public static final Integer four = new Integer(4);
- public static final Integer five = new Integer(5);
- public static final Integer six = new Integer(6);
- public static final Integer seven = new Integer(7);
- public static final Integer eight = new Integer(8);
- public static final Integer nine = new Integer(9);
- public static final Integer m1 = new Integer(-1);
- public static final Integer m2 = new Integer(-2);
- public static final Integer m3 = new Integer(-3);
- public static final Integer m4 = new Integer(-4);
- public static final Integer m5 = new Integer(-5);
- public static final Integer m6 = new Integer(-6);
- public static final Integer m10 = new Integer(-10);
+ static Item[] seqItems(int size) {
+ Item[] s = new Item[size];
+ for (int i = 0; i < size; ++i)
+ s[i] = new Item(i);
+ return s;
+ }
+ static Item[] negativeSeqItems(int size) {
+ Item[] s = new Item[size];
+ for (int i = 0; i < size; ++i)
+ s[i] = new Item(-i);
+ return s;
+ }
+
+ // Many tests rely on defaultItems all being sequential nonnegative
+ public static final Item[] defaultItems = seqItems(SIZE);
+
+ static Item itemFor(int i) { // check cache for defaultItems
+ Item[] items = defaultItems;
+ return (i >= 0 && i < items.length) ? items[i] : new Item(i);
+ }
+
+ public static final Item zero = defaultItems[0];
+ public static final Item one = defaultItems[1];
+ public static final Item two = defaultItems[2];
+ public static final Item three = defaultItems[3];
+ public static final Item four = defaultItems[4];
+ public static final Item five = defaultItems[5];
+ public static final Item six = defaultItems[6];
+ public static final Item seven = defaultItems[7];
+ public static final Item eight = defaultItems[8];
+ public static final Item nine = defaultItems[9];
+ public static final Item ten = defaultItems[10];
+
+ public static final Item[] negativeItems = negativeSeqItems(SIZE);
+
+ public static final Item minusOne = negativeItems[1];
+ public static final Item minusTwo = negativeItems[2];
+ public static final Item minusThree = negativeItems[3];
+ public static final Item minusFour = negativeItems[4];
+ public static final Item minusFive = negativeItems[5];
+ public static final Item minusSix = negativeItems[6];
+ public static final Item minusSeven = negativeItems[7];
+ public static final Item minusEight = negativeItems[8];
+ public static final Item minusNone = negativeItems[9];
+ public static final Item minusTen = negativeItems[10];
+
+ // elements expected to be missing
+ public static final Item fortytwo = new Item(42);
+ public static final Item eightysix = new Item(86);
+ public static final Item ninetynine = new Item(99);
+
+ // Interop across Item, int
+
+ static void mustEqual(Item x, Item y) {
+ if (x != y)
+ assertEquals(x.value, y.value);
+ }
+ static void mustEqual(Item x, int y) {
+ assertEquals(x.value, y);
+ }
+ static void mustEqual(int x, Item y) {
+ assertEquals(x, y.value);
+ }
+ static void mustEqual(int x, int y) {
+ assertEquals(x, y);
+ }
+ static void mustEqual(Object x, Object y) {
+ if (x != y)
+ assertEquals(x, y);
+ }
+ static void mustEqual(int x, Object y) {
+ if (y instanceof Item)
+ assertEquals(x, ((Item)y).value);
+ else fail();
+ }
+ static void mustEqual(Object x, int y) {
+ if (x instanceof Item)
+ assertEquals(((Item)x).value, y);
+ else fail();
+ }
+ static void mustEqual(boolean x, boolean y) {
+ assertEquals(x, y);
+ }
+ static void mustEqual(long x, long y) {
+ assertEquals(x, y);
+ }
+ static void mustEqual(double x, double y) {
+ assertEquals(x, y);
+ }
+ static void mustContain(Collection c, int i) {
+ assertTrue(c.contains(itemFor(i)));
+ }
+ static void mustContain(Collection c, Item i) {
+ assertTrue(c.contains(i));
+ }
+ static void mustNotContain(Collection c, int i) {
+ assertFalse(c.contains(itemFor(i)));
+ }
+ static void mustNotContain(Collection c, Item i) {
+ assertFalse(c.contains(i));
+ }
+ static void mustRemove(Collection c, int i) {
+ assertTrue(c.remove(itemFor(i)));
+ }
+ static void mustRemove(Collection c, Item i) {
+ assertTrue(c.remove(i));
+ }
+ static void mustNotRemove(Collection c, int i) {
+ assertFalse(c.remove(itemFor(i)));
+ }
+ static void mustNotRemove(Collection c, Item i) {
+ assertFalse(c.remove(i));
+ }
+ static void mustAdd(Collection c, int i) {
+ assertTrue(c.add(itemFor(i)));
+ }
+ static void mustAdd(Collection c, Item i) {
+ assertTrue(c.add(i));
+ }
+ static void mustOffer(Queue c, int i) {
+ assertTrue(c.offer(itemFor(i)));
+ }
+ static void mustOffer(Queue c, Item i) {
+ assertTrue(c.offer(i));
+ }
/**
* Runs Runnable r with a security policy that permits precisely
@@ -1132,6 +1387,7 @@ public class JSR166TestCase extends Test
* security manager. We require that any security manager permit
* getPolicy/setPolicy.
*/
+ @SuppressWarnings("removal")
public void runWithPermissions(Runnable r, Permission... permissions) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
@@ -1147,8 +1403,10 @@ public class JSR166TestCase extends Test
* Runnable. We require that any security manager permit
* getPolicy/setPolicy.
*/
+ @SuppressWarnings("removal")
public void runWithSecurityManagerWithPermissions(Runnable r,
Permission... permissions) {
+ if (!useSecurityManager) return;
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
Policy savedPolicy = Policy.getPolicy();
@@ -1156,9 +1414,13 @@ public class JSR166TestCase extends Test
Policy.setPolicy(permissivePolicy());
System.setSecurityManager(new SecurityManager());
runWithSecurityManagerWithPermissions(r, permissions);
+ } catch (UnsupportedOperationException ok) {
} finally {
- System.setSecurityManager(null);
- Policy.setPolicy(savedPolicy);
+ try {
+ System.setSecurityManager(null);
+ Policy.setPolicy(savedPolicy);
+ } catch (Exception ok) {
+ }
}
} else {
Policy savedPolicy = Policy.getPolicy();
@@ -1185,6 +1447,7 @@ public class JSR166TestCase extends Test
* A security policy where new permissions can be dynamically added
* or all cleared.
*/
+ @SuppressWarnings("removal")
public static class AdjustablePolicy extends java.security.Policy {
Permissions perms = new Permissions();
AdjustablePolicy(Permission... permissions) {
@@ -1204,7 +1467,7 @@ public class JSR166TestCase extends Test
}
public void refresh() {}
public String toString() {
- List ps = new ArrayList();
+ List ps = new ArrayList<>();
for (Enumeration e = perms.elements(); e.hasMoreElements();)
ps.add(e.nextElement());
return "AdjustablePolicy with permissions " + ps;
@@ -1214,6 +1477,7 @@ public class JSR166TestCase extends Test
/**
* Returns a policy containing all the permissions we ever need.
*/
+ @SuppressWarnings("removal")
public static Policy permissivePolicy() {
return new AdjustablePolicy
// Permissions j.u.c. needs directly
@@ -1232,47 +1496,89 @@ public class JSR166TestCase extends Test
/**
* Sleeps until the given time has elapsed.
- * Throws AssertionFailedError if interrupted.
+ * Throws AssertionError if interrupted.
*/
- void sleep(long millis) {
+ static void sleep(long millis) {
try {
delay(millis);
} catch (InterruptedException fail) {
- AssertionFailedError afe =
- new AssertionFailedError("Unexpected InterruptedException");
- afe.initCause(fail);
- throw afe;
+ throw new AssertionError("Unexpected InterruptedException", fail);
}
}
/**
* Spin-waits up to the specified number of milliseconds for the given
* thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+ * @param waitingForGodot if non-null, an additional condition to satisfy
*/
- void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
- long startTime = System.nanoTime();
- for (;;) {
- Thread.State s = thread.getState();
- if (s == Thread.State.BLOCKED ||
- s == Thread.State.WAITING ||
- s == Thread.State.TIMED_WAITING)
- return;
- else if (s == Thread.State.TERMINATED)
+ void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis,
+ Callable waitingForGodot) {
+ for (long startTime = 0L;;) {
+ switch (thread.getState()) {
+ default: break;
+ case BLOCKED: case WAITING: case TIMED_WAITING:
+ try {
+ if (waitingForGodot == null || waitingForGodot.call())
+ return;
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ break;
+ case TERMINATED:
fail("Unexpected thread termination");
+ }
+
+ if (startTime == 0L)
+ startTime = System.nanoTime();
else if (millisElapsedSince(startTime) > timeoutMillis) {
- threadAssertTrue(thread.isAlive());
- return;
+ assertTrue(thread.isAlive());
+ if (waitingForGodot == null
+ || thread.getState() == Thread.State.RUNNABLE)
+ fail("timed out waiting for thread to enter wait state");
+ else
+ fail("timed out waiting for condition, thread state="
+ + thread.getState());
}
Thread.yield();
}
}
/**
- * Waits up to LONG_DELAY_MS for the given thread to enter a wait
- * state: BLOCKED, WAITING, or TIMED_WAITING.
+ * Spin-waits up to the specified number of milliseconds for the given
+ * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+ */
+ void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
+ waitForThreadToEnterWaitState(thread, timeoutMillis, null);
+ }
+
+ /**
+ * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
+ * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
*/
void waitForThreadToEnterWaitState(Thread thread) {
- waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
+ waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, null);
+ }
+
+ /**
+ * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
+ * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
+ * and additionally satisfy the given condition.
+ */
+ void waitForThreadToEnterWaitState(Thread thread,
+ Callable waitingForGodot) {
+ waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
+ }
+
+ /**
+ * Spin-waits up to LONG_DELAY_MS milliseconds for the current thread to
+ * be interrupted. Clears the interrupt status before returning.
+ */
+ void awaitInterrupted() {
+ for (long startTime = 0L; !Thread.interrupted(); ) {
+ if (startTime == 0L)
+ startTime = System.nanoTime();
+ else if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out waiting for thread interrupt");
+ Thread.yield();
+ }
}
/**
@@ -1284,30 +1590,19 @@ public class JSR166TestCase extends Test
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();
+ T actual = null;
try {
- assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS));
+ actual = f.get(timeoutMillis, MILLISECONDS);
} catch (Throwable fail) { threadUnexpectedException(fail); }
+ assertEquals(expectedValue, actual);
if (millisElapsedSince(startTime) > timeoutMillis/2)
- throw new AssertionFailedError("timed get did not return promptly");
+ throw new AssertionError("timed get did not return promptly");
}
void checkTimedGet(Future f, T expectedValue) {
@@ -1325,19 +1620,33 @@ public class JSR166TestCase extends Test
}
/**
+ * Returns a new started daemon Thread running the given action,
+ * wrapped in a CheckedRunnable.
+ */
+ Thread newStartedThread(Action action) {
+ return newStartedThread(checkedRunnable(action));
+ }
+
+ /**
* 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) {
+ void awaitTermination(Thread thread, long timeoutMillis) {
try {
- t.join(timeoutMillis);
+ thread.join(timeoutMillis);
} catch (InterruptedException fail) {
threadUnexpectedException(fail);
- } finally {
- if (t.getState() != Thread.State.TERMINATED) {
- t.interrupt();
- threadFail("timed out waiting for thread to terminate");
+ }
+ if (thread.getState() != Thread.State.TERMINATED) {
+ String detail = String.format(
+ "timed out waiting for thread to terminate, thread=%s, state=%s" ,
+ thread, thread.getState());
+ try {
+ threadFail(detail);
+ } finally {
+ // Interrupt thread __after__ having reported its stack trace
+ thread.interrupt();
}
}
}
@@ -1365,24 +1674,11 @@ public class JSR166TestCase extends Test
}
}
- public abstract class RunnableShouldThrow implements Runnable {
- protected abstract void realRun() throws Throwable;
-
- final Class> exceptionClass;
-
- RunnableShouldThrow(Class exceptionClass) {
- this.exceptionClass = exceptionClass;
- }
-
- public final void run() {
- try {
- realRun();
- threadShouldThrow(exceptionClass.getSimpleName());
- } catch (Throwable t) {
- if (! exceptionClass.isInstance(t))
- threadUnexpectedException(t);
- }
- }
+ Runnable checkedRunnable(Action action) {
+ return new CheckedRunnable() {
+ public void realRun() throws Throwable {
+ action.run();
+ }};
}
public abstract class ThreadShouldThrow extends Thread {
@@ -1397,11 +1693,12 @@ public class JSR166TestCase extends Test
public final void run() {
try {
realRun();
- threadShouldThrow(exceptionClass.getSimpleName());
} catch (Throwable t) {
if (! exceptionClass.isInstance(t))
threadUnexpectedException(t);
+ return;
}
+ threadShouldThrow(exceptionClass.getSimpleName());
}
}
@@ -1411,12 +1708,13 @@ public class JSR166TestCase extends Test
public final void run() {
try {
realRun();
- threadShouldThrow("InterruptedException");
} catch (InterruptedException success) {
threadAssertFalse(Thread.interrupted());
+ return;
} catch (Throwable fail) {
threadUnexpectedException(fail);
}
+ threadShouldThrow("InterruptedException");
}
}
@@ -1428,26 +1726,8 @@ public class JSR166TestCase extends Test
return realCall();
} catch (Throwable fail) {
threadUnexpectedException(fail);
- return null;
}
- }
- }
-
- public abstract class CheckedInterruptedCallable
- implements Callable {
- protected abstract T realCall() throws Throwable;
-
- public final T call() {
- try {
- T result = realCall();
- threadShouldThrow("InterruptedException");
- return result;
- } catch (InterruptedException success) {
- threadAssertFalse(Thread.interrupted());
- } catch (Throwable fail) {
- threadUnexpectedException(fail);
- }
- return null;
+ throw new AssertionError("unreached");
}
}
@@ -1455,7 +1735,7 @@ public class JSR166TestCase extends Test
public void run() {}
}
- public static class NoOpCallable implements Callable {
+ public static class NoOpCallable implements Callable