ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/JSR166TestCase.java
(Generate patch)

Comparing jsr166/src/test/tck/JSR166TestCase.java (file contents):
Revision 1.246 by jsr166, Sun Jul 22 21:25:16 2018 UTC vs.
Revision 1.272 by dl, Tue Jan 26 13:33:06 2021 UTC

# Line 49 | Line 49 | import java.io.ByteArrayOutputStream;
49   import java.io.ObjectInputStream;
50   import java.io.ObjectOutputStream;
51   import java.lang.management.ManagementFactory;
52 + import java.lang.management.LockInfo;
53   import java.lang.management.ThreadInfo;
54   import java.lang.management.ThreadMXBean;
55   import java.lang.reflect.Constructor;
# Line 73 | Line 74 | import java.util.Iterator;
74   import java.util.List;
75   import java.util.NoSuchElementException;
76   import java.util.PropertyPermission;
77 + import java.util.Queue;
78   import java.util.Set;
79   import java.util.concurrent.BlockingQueue;
80   import java.util.concurrent.Callable;
# Line 117 | Line 119 | import junit.framework.TestSuite;
119   *
120   * <ol>
121   *
122 < * <li>All assertions in code running in generated threads must use
123 < * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
124 < * #threadAssertEquals}, or {@link #threadAssertNull}, (not
125 < * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
126 < * particularly recommended) for other code to use these forms too.
127 < * Only the most typically used JUnit assertion methods are defined
128 < * this way, but enough to live with.
122 > * <li>All code not running in the main test thread (manually spawned threads
123 > * or the common fork join pool) must be checked for failure (and completion!).
124 > * Mechanisms that can be used to ensure this are:
125 > *   <ol>
126 > *   <li>Signalling via a synchronizer like AtomicInteger or CountDownLatch
127 > *    that the task completed normally, which is checked before returning from
128 > *    the test method in the main thread.
129 > *   <li>Using the forms {@link #threadFail}, {@link #threadAssertTrue},
130 > *    or {@link #threadAssertNull}, (not {@code fail}, {@code assertTrue}, etc.)
131 > *    Only the most typically used JUnit assertion methods are defined
132 > *    this way, but enough to live with.
133 > *   <li>Recording failure explicitly using {@link #threadUnexpectedException}
134 > *    or {@link #threadRecordFailure}.
135 > *   <li>Using a wrapper like CheckedRunnable that uses one the mechanisms above.
136 > *   </ol>
137   *
138   * <li>If you override {@link #setUp} or {@link #tearDown}, make sure
139   * to invoke {@code super.setUp} and {@code super.tearDown} within
# Line 141 | Line 151 | import junit.framework.TestSuite;
151   * but even so, if there is ever any doubt, they can all be increased
152   * in one spot to rerun tests on slower platforms.
153   *
154 + * Class Item is used for elements of collections and related
155 + * purposes. Many tests rely on themir keys being equal to ints. To
156 + * check these, methods mustEqual, mustContain, etc adapt the JUnit
157 + * assert methods to intercept ints.
158 + *
159   * <li>All threads generated must be joined inside each test case
160   * method (or {@code fail} to do so) before returning from the
161   * method. The {@code joinPool} method can be used to do this when
# Line 235 | Line 250 | public class JSR166TestCase extends Test
250          }
251      }
252  
253 +    private static final ThreadMXBean THREAD_MXBEAN
254 +        = ManagementFactory.getThreadMXBean();
255 +
256      /**
257       * The scaling factor to apply to standard delays used in tests.
258       * May be initialized from any of:
# Line 276 | Line 294 | public class JSR166TestCase extends Test
294      static volatile TestCase currentTestCase;
295      // static volatile int currentRun = 0;
296      static {
297 <        Runnable checkForWedgedTest = new Runnable() { public void run() {
297 >        Runnable wedgedTestDetector = new Runnable() { public void run() {
298              // Avoid spurious reports with enormous runsPerTest.
299              // A single test case run should never take more than 1 second.
300              // But let's cap it at the high end too ...
301 <            final int timeoutMinutes =
302 <                Math.min(15, Math.max(runsPerTest / 60, 1));
301 >            final int timeoutMinutesMin = Math.max(runsPerTest / 60, 1)
302 >                * Math.max((int) delayFactor, 1);
303 >            final int timeoutMinutes = Math.min(15, timeoutMinutesMin);
304              for (TestCase lastTestCase = currentTestCase;;) {
305                  try { MINUTES.sleep(timeoutMinutes); }
306                  catch (InterruptedException unexpected) { break; }
# Line 301 | Line 320 | public class JSR166TestCase extends Test
320                  }
321                  lastTestCase = currentTestCase;
322              }}};
323 <        Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest");
323 >        Thread thread = new Thread(wedgedTestDetector, "WedgedTestDetector");
324          thread.setDaemon(true);
325          thread.start();
326      }
# Line 345 | Line 364 | public class JSR166TestCase extends Test
364              // Never report first run of any test; treat it as a
365              // warmup run, notably to trigger all needed classloading,
366              if (i > 0)
367 <                System.out.printf("%n%s: %d%n", toString(), elapsedMillis);
367 >                System.out.printf("%s: %d%n", toString(), elapsedMillis);
368          }
369      }
370  
# Line 452 | Line 471 | public class JSR166TestCase extends Test
471      public static boolean atLeastJava9()  { return JAVA_CLASS_VERSION >= 53.0; }
472      public static boolean atLeastJava10() { return JAVA_CLASS_VERSION >= 54.0; }
473      public static boolean atLeastJava11() { return JAVA_CLASS_VERSION >= 55.0; }
474 +    public static boolean atLeastJava12() { return JAVA_CLASS_VERSION >= 56.0; }
475 +    public static boolean atLeastJava13() { return JAVA_CLASS_VERSION >= 57.0; }
476 +    public static boolean atLeastJava14() { return JAVA_CLASS_VERSION >= 58.0; }
477 +    public static boolean atLeastJava15() { return JAVA_CLASS_VERSION >= 59.0; }
478 +    public static boolean atLeastJava16() { return JAVA_CLASS_VERSION >= 60.0; }
479 +    public static boolean atLeastJava17() { return JAVA_CLASS_VERSION >= 61.0; }
480  
481      /**
482       * Collects all JSR166 unit tests as one suite.
# Line 503 | Line 528 | public class JSR166TestCase extends Test
528              ExecutorsTest.suite(),
529              ExecutorCompletionServiceTest.suite(),
530              FutureTaskTest.suite(),
531 +            HashtableTest.suite(),
532              LinkedBlockingDequeTest.suite(),
533              LinkedBlockingQueueTest.suite(),
534              LinkedListTest.suite(),
# Line 542 | Line 568 | public class JSR166TestCase extends Test
568                  "HashMapTest",
569                  "LinkedBlockingDeque8Test",
570                  "LinkedBlockingQueue8Test",
571 +                "LinkedHashMapTest",
572                  "LongAccumulatorTest",
573                  "LongAdderTest",
574                  "SplittableRandomTest",
# Line 640 | Line 667 | public class JSR166TestCase extends Test
667      public static long MEDIUM_DELAY_MS;
668      public static long LONG_DELAY_MS;
669  
670 +    /**
671 +     * A delay significantly longer than LONG_DELAY_MS.
672 +     * Use this in a thread that is waited for via awaitTermination(Thread).
673 +     */
674 +    public static long LONGER_DELAY_MS;
675 +
676      private static final long RANDOM_TIMEOUT;
677      private static final long RANDOM_EXPIRED_TIMEOUT;
678      private static final TimeUnit RANDOM_TIMEUNIT;
# Line 668 | Line 701 | public class JSR166TestCase extends Test
701      static TimeUnit randomTimeUnit() { return RANDOM_TIMEUNIT; }
702  
703      /**
704 +     * Returns a random boolean; a "coin flip".
705 +     */
706 +    static boolean randomBoolean() {
707 +        return ThreadLocalRandom.current().nextBoolean();
708 +    }
709 +
710 +    /**
711 +     * Returns a random element from given choices.
712 +     */
713 +    <T> T chooseRandomly(List<T> choices) {
714 +        return choices.get(ThreadLocalRandom.current().nextInt(choices.size()));
715 +    }
716 +
717 +    /**
718 +     * Returns a random element from given choices.
719 +     */
720 +    @SuppressWarnings("unchecked")
721 +    <T> T chooseRandomly(T... choices) {
722 +        return choices[ThreadLocalRandom.current().nextInt(choices.length)];
723 +    }
724 +
725 +    /**
726       * Returns the shortest timed delay. This can be scaled up for
727       * slow machines using the jsr166.delay.factor system property,
728       * or via jtreg's -timeoutFactor: flag.
# Line 685 | Line 740 | public class JSR166TestCase extends Test
740          SMALL_DELAY_MS  = SHORT_DELAY_MS * 5;
741          MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
742          LONG_DELAY_MS   = SHORT_DELAY_MS * 200;
743 +        LONGER_DELAY_MS = 2 * LONG_DELAY_MS;
744      }
745  
746      private static final long TIMEOUT_DELAY_MS
# Line 723 | Line 779 | public class JSR166TestCase extends Test
779       */
780      public void threadRecordFailure(Throwable t) {
781          System.err.println(t);
782 <        dumpTestThreads();
783 <        threadFailure.compareAndSet(null, t);
782 >        if (threadFailure.compareAndSet(null, t))
783 >            dumpTestThreads();
784      }
785  
786      public void setUp() {
# Line 1045 | Line 1101 | public class JSR166TestCase extends Test
1101          }
1102      }
1103  
1104 +    /** Returns true if thread info might be useful in a thread dump. */
1105 +    static boolean threadOfInterest(ThreadInfo info) {
1106 +        final String name = info.getThreadName();
1107 +        String lockName;
1108 +        if (name == null)
1109 +            return true;
1110 +        if (name.equals("Signal Dispatcher")
1111 +            || name.equals("WedgedTestDetector"))
1112 +            return false;
1113 +        if (name.equals("Reference Handler")) {
1114 +            // Reference Handler stacktrace changed in JDK-8156500
1115 +            StackTraceElement[] stackTrace; String methodName;
1116 +            if ((stackTrace = info.getStackTrace()) != null
1117 +                && stackTrace.length > 0
1118 +                && (methodName = stackTrace[0].getMethodName()) != null
1119 +                && methodName.equals("waitForReferencePendingList"))
1120 +                return false;
1121 +            // jdk8 Reference Handler stacktrace
1122 +            if ((lockName = info.getLockName()) != null
1123 +                && lockName.startsWith("java.lang.ref"))
1124 +                return false;
1125 +        }
1126 +        if ((name.equals("Finalizer") || name.equals("Common-Cleaner"))
1127 +            && (lockName = info.getLockName()) != null
1128 +            && lockName.startsWith("java.lang.ref"))
1129 +            return false;
1130 +        if (name.startsWith("ForkJoinPool.commonPool-worker")
1131 +            && (lockName = info.getLockName()) != null
1132 +            && lockName.startsWith("java.util.concurrent.ForkJoinPool"))
1133 +            return false;
1134 +        return true;
1135 +    }
1136 +
1137      /**
1138       * A debugging tool to print stack traces of most threads, as jstack does.
1139       * Uninteresting threads are filtered out.
# Line 1059 | Line 1148 | public class JSR166TestCase extends Test
1148              }
1149          }
1150  
1062        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
1151          System.err.println("------ stacktrace dump start ------");
1152 <        for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
1153 <            final String name = info.getThreadName();
1154 <            String lockName;
1067 <            if ("Signal Dispatcher".equals(name))
1068 <                continue;
1069 <            if ("Reference Handler".equals(name)
1070 <                && (lockName = info.getLockName()) != null
1071 <                && lockName.startsWith("java.lang.ref.Reference$Lock"))
1072 <                continue;
1073 <            if ("Finalizer".equals(name)
1074 <                && (lockName = info.getLockName()) != null
1075 <                && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock"))
1076 <                continue;
1077 <            if ("checkForWedgedTest".equals(name))
1078 <                continue;
1079 <            System.err.print(info);
1080 <        }
1152 >        for (ThreadInfo info : THREAD_MXBEAN.dumpAllThreads(true, true))
1153 >            if (threadOfInterest(info))
1154 >                System.err.print(info);
1155          System.err.println("------ stacktrace dump end ------");
1156  
1157          if (sm != null) System.setSecurityManager(sm);
# Line 1104 | Line 1178 | public class JSR166TestCase extends Test
1178      }
1179  
1180      /**
1181 +     * Returns the thread's blocker's class name, if any, else null.
1182 +     */
1183 +    String blockerClassName(Thread thread) {
1184 +        ThreadInfo threadInfo; LockInfo lockInfo;
1185 +        if ((threadInfo = THREAD_MXBEAN.getThreadInfo(thread.getId(), 0)) != null
1186 +            && (lockInfo = threadInfo.getLockInfo()) != null)
1187 +            return lockInfo.getClassName();
1188 +        return null;
1189 +    }
1190 +
1191 +    /**
1192       * Checks that future.get times out, with the default timeout of
1193       * {@code timeoutMillis()}.
1194       */
1195 <    void assertFutureTimesOut(Future future) {
1195 >    void assertFutureTimesOut(Future<?> future) {
1196          assertFutureTimesOut(future, timeoutMillis());
1197      }
1198  
1199      /**
1200       * Checks that future.get times out, with the given millisecond timeout.
1201       */
1202 <    void assertFutureTimesOut(Future future, long timeoutMillis) {
1202 >    void assertFutureTimesOut(Future<?> future, long timeoutMillis) {
1203          long startTime = System.nanoTime();
1204          try {
1205              future.get(timeoutMillis, MILLISECONDS);
# Line 1122 | Line 1207 | public class JSR166TestCase extends Test
1207          } catch (TimeoutException success) {
1208          } catch (Exception fail) {
1209              threadUnexpectedException(fail);
1210 <        } finally { future.cancel(true); }
1210 >        }
1211          assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
1212 +        assertFalse(future.isDone());
1213      }
1214  
1215      /**
# Line 1148 | Line 1234 | public class JSR166TestCase extends Test
1234  
1235      /**
1236       * The number of elements to place in collections, arrays, etc.
1237 +     * Must be at least ten;
1238       */
1239 <    public static final int SIZE = 20;
1153 <
1154 <    // Some convenient Integer constants
1239 >    public static final int SIZE = 32;
1240  
1241 <    public static final Integer zero  = new Integer(0);
1242 <    public static final Integer one   = new Integer(1);
1243 <    public static final Integer two   = new Integer(2);
1244 <    public static final Integer three = new Integer(3);
1245 <    public static final Integer four  = new Integer(4);
1246 <    public static final Integer five  = new Integer(5);
1247 <    public static final Integer six   = new Integer(6);
1248 <    public static final Integer seven = new Integer(7);
1249 <    public static final Integer eight = new Integer(8);
1250 <    public static final Integer nine  = new Integer(9);
1251 <    public static final Integer m1  = new Integer(-1);
1252 <    public static final Integer m2  = new Integer(-2);
1253 <    public static final Integer m3  = new Integer(-3);
1254 <    public static final Integer m4  = new Integer(-4);
1255 <    public static final Integer m5  = new Integer(-5);
1256 <    public static final Integer m6  = new Integer(-6);
1257 <    public static final Integer m10 = new Integer(-10);
1241 >    static Item[] seqItems(int size) {
1242 >        Item[] s = new Item[size];
1243 >        for (int i = 0; i < size; ++i)
1244 >            s[i] = new Item(i);
1245 >        return s;
1246 >    }
1247 >    static Item[] negativeSeqItems(int size) {
1248 >        Item[] s = new Item[size];
1249 >        for (int i = 0; i < size; ++i)
1250 >            s[i] = new Item(-i);
1251 >        return s;
1252 >    }
1253 >
1254 >    // Many tests rely on defaultItems all being sequential nonnegative
1255 >    public static final Item[] defaultItems = seqItems(SIZE);
1256 >
1257 >    static Item itemFor(int i) { // check cache for defaultItems
1258 >        Item[] items = defaultItems;
1259 >        return (i >= 0 && i < items.length) ? items[i] : new Item(i);
1260 >    }
1261 >
1262 >    public static final Item zero  = defaultItems[0];
1263 >    public static final Item one   = defaultItems[1];
1264 >    public static final Item two   = defaultItems[2];
1265 >    public static final Item three = defaultItems[3];
1266 >    public static final Item four  = defaultItems[4];
1267 >    public static final Item five  = defaultItems[5];
1268 >    public static final Item six   = defaultItems[6];
1269 >    public static final Item seven = defaultItems[7];
1270 >    public static final Item eight = defaultItems[8];
1271 >    public static final Item nine  = defaultItems[9];
1272 >    public static final Item ten   = defaultItems[10];
1273 >
1274 >    public static final Item[] negativeItems = negativeSeqItems(SIZE);
1275 >
1276 >    public static final Item minusOne   = negativeItems[1];
1277 >    public static final Item minusTwo   = negativeItems[2];
1278 >    public static final Item minusThree = negativeItems[3];
1279 >    public static final Item minusFour  = negativeItems[4];
1280 >    public static final Item minusFive  = negativeItems[5];
1281 >    public static final Item minusSix   = negativeItems[6];
1282 >    public static final Item minusSeven = negativeItems[7];
1283 >    public static final Item minusEight = negativeItems[8];
1284 >    public static final Item minusNone  = negativeItems[9];
1285 >    public static final Item minusTen   = negativeItems[10];
1286 >
1287 >    // elements expected to be missing
1288 >    public static final Item fortytwo = new Item(42);
1289 >    public static final Item eightysix = new Item(86);
1290 >    public static final Item ninetynine = new Item(99);
1291 >
1292 >    // Interop across Item, int
1293 >
1294 >    static void mustEqual(Item x, Item y) {
1295 >        if (x != y)
1296 >            assertEquals(x.value, y.value);
1297 >    }
1298 >    static void mustEqual(Item x, int y) {
1299 >        assertEquals(x.value, y);
1300 >    }
1301 >    static void mustEqual(int x, Item y) {
1302 >        assertEquals(x, y.value);
1303 >    }
1304 >    static void mustEqual(int x, int y) {
1305 >        assertEquals(x, y);
1306 >    }
1307 >    static void mustEqual(Object x, Object y) {
1308 >        if (x != y)
1309 >            assertEquals(x, y);
1310 >    }
1311 >    static void mustEqual(int x, Object y) {
1312 >        if (y instanceof Item)
1313 >            assertEquals(x, ((Item)y).value);
1314 >        else fail();
1315 >    }
1316 >    static void mustEqual(Object x, int y) {
1317 >        if (x instanceof Item)
1318 >            assertEquals(((Item)x).value, y);
1319 >        else fail();
1320 >    }
1321 >    static void mustEqual(boolean x, boolean y) {
1322 >        assertEquals(x, y);
1323 >    }
1324 >    static void mustEqual(long x, long y) {
1325 >        assertEquals(x, y);
1326 >    }
1327 >    static void mustEqual(double x, double y) {
1328 >        assertEquals(x, y);
1329 >    }
1330 >    static void mustContain(Collection<Item> c, int i) {
1331 >        assertTrue(c.contains(itemFor(i)));
1332 >    }
1333 >    static void mustContain(Collection<Item> c, Item i) {
1334 >        assertTrue(c.contains(i));
1335 >    }
1336 >    static void mustNotContain(Collection<Item> c, int i) {
1337 >        assertFalse(c.contains(itemFor(i)));
1338 >    }
1339 >    static void mustNotContain(Collection<Item> c, Item i) {
1340 >        assertFalse(c.contains(i));
1341 >    }
1342 >    static void mustRemove(Collection<Item> c, int i) {
1343 >        assertTrue(c.remove(itemFor(i)));
1344 >    }
1345 >    static void mustRemove(Collection<Item> c, Item i) {
1346 >        assertTrue(c.remove(i));
1347 >    }
1348 >    static void mustNotRemove(Collection<Item> c, int i) {
1349 >        Item[] items = defaultItems;
1350 >        Item x = (i >= 0 && i < items.length) ? items[i] : new Item(i);
1351 >        assertFalse(c.remove(x));
1352 >    }
1353 >    static void mustNotRemove(Collection<Item> c, Item i) {
1354 >        assertFalse(c.remove(i));
1355 >    }
1356 >    static void mustAdd(Collection<Item> c, int i) {
1357 >        assertTrue(c.add(itemFor(i)));
1358 >    }
1359 >    static void mustAdd(Collection<Item> c, Item i) {
1360 >        assertTrue(c.add(i));
1361 >    }
1362 >    static void mustOffer(Queue<Item> c, int i) {
1363 >        assertTrue(c.offer(itemFor(i)));
1364 >    }
1365 >    static void mustOffer(Queue<Item> c, Item i) {
1366 >        assertTrue(c.offer(i));
1367 >    }
1368  
1369      /**
1370       * Runs Runnable r with a security policy that permits precisely
# Line 1291 | Line 1486 | public class JSR166TestCase extends Test
1486      /**
1487       * Spin-waits up to the specified number of milliseconds for the given
1488       * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
1489 +     * @param waitingForGodot if non-null, an additional condition to satisfy
1490       */
1491 <    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
1492 <        long startTime = 0L;
1493 <        for (;;) {
1494 <            Thread.State s = thread.getState();
1495 <            if (s == Thread.State.BLOCKED ||
1496 <                s == Thread.State.WAITING ||
1497 <                s == Thread.State.TIMED_WAITING)
1498 <                return;
1499 <            else if (s == Thread.State.TERMINATED)
1491 >    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis,
1492 >                                       Callable<Boolean> waitingForGodot) {
1493 >        for (long startTime = 0L;;) {
1494 >            switch (thread.getState()) {
1495 >            default: break;
1496 >            case BLOCKED: case WAITING: case TIMED_WAITING:
1497 >                try {
1498 >                    if (waitingForGodot == null || waitingForGodot.call())
1499 >                        return;
1500 >                } catch (Throwable fail) { threadUnexpectedException(fail); }
1501 >                break;
1502 >            case TERMINATED:
1503                  fail("Unexpected thread termination");
1504 <            else if (startTime == 0L)
1504 >            }
1505 >
1506 >            if (startTime == 0L)
1507                  startTime = System.nanoTime();
1508              else if (millisElapsedSince(startTime) > timeoutMillis) {
1509 <                threadAssertTrue(thread.isAlive());
1510 <                fail("timed out waiting for thread to enter wait state");
1509 >                assertTrue(thread.isAlive());
1510 >                if (waitingForGodot == null
1511 >                    || thread.getState() == Thread.State.RUNNABLE)
1512 >                    fail("timed out waiting for thread to enter wait state");
1513 >                else
1514 >                    fail("timed out waiting for condition, thread state="
1515 >                         + thread.getState());
1516              }
1517              Thread.yield();
1518          }
# Line 1314 | Line 1520 | public class JSR166TestCase extends Test
1520  
1521      /**
1522       * Spin-waits up to the specified number of milliseconds for the given
1523 <     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
1318 <     * and additionally satisfy the given condition.
1523 >     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
1524       */
1525 <    void waitForThreadToEnterWaitState(
1526 <        Thread thread, long timeoutMillis, Callable<Boolean> waitingForGodot) {
1322 <        long startTime = 0L;
1323 <        for (;;) {
1324 <            Thread.State s = thread.getState();
1325 <            if (s == Thread.State.BLOCKED ||
1326 <                s == Thread.State.WAITING ||
1327 <                s == Thread.State.TIMED_WAITING) {
1328 <                try {
1329 <                    if (waitingForGodot.call())
1330 <                        return;
1331 <                } catch (Throwable fail) { threadUnexpectedException(fail); }
1332 <            }
1333 <            else if (s == Thread.State.TERMINATED)
1334 <                fail("Unexpected thread termination");
1335 <            else if (startTime == 0L)
1336 <                startTime = System.nanoTime();
1337 <            else if (millisElapsedSince(startTime) > timeoutMillis) {
1338 <                threadAssertTrue(thread.isAlive());
1339 <                fail("timed out waiting for thread to enter wait state");
1340 <            }
1341 <            Thread.yield();
1342 <        }
1525 >    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
1526 >        waitForThreadToEnterWaitState(thread, timeoutMillis, null);
1527      }
1528  
1529      /**
# Line 1347 | Line 1531 | public class JSR166TestCase extends Test
1531       * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
1532       */
1533      void waitForThreadToEnterWaitState(Thread thread) {
1534 <        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
1534 >        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, null);
1535      }
1536  
1537      /**
# Line 1355 | Line 1539 | public class JSR166TestCase extends Test
1539       * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
1540       * and additionally satisfy the given condition.
1541       */
1542 <    void waitForThreadToEnterWaitState(
1543 <        Thread thread, Callable<Boolean> waitingForGodot) {
1542 >    void waitForThreadToEnterWaitState(Thread thread,
1543 >                                       Callable<Boolean> waitingForGodot) {
1544          waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
1545      }
1546  
1547      /**
1548 +     * Spin-waits up to LONG_DELAY_MS milliseconds for the current thread to
1549 +     * be interrupted.  Clears the interrupt status before returning.
1550 +     */
1551 +    void awaitInterrupted() {
1552 +        for (long startTime = 0L; !Thread.interrupted(); ) {
1553 +            if (startTime == 0L)
1554 +                startTime = System.nanoTime();
1555 +            else if (millisElapsedSince(startTime) > LONG_DELAY_MS)
1556 +                fail("timed out waiting for thread interrupt");
1557 +            Thread.yield();
1558 +        }
1559 +    }
1560 +
1561 +    /**
1562       * Returns the number of milliseconds since time given by
1563       * startNanoTime, which must have been previously returned from a
1564       * call to {@link System#nanoTime()}.
# Line 1369 | Line 1567 | public class JSR166TestCase extends Test
1567          return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
1568      }
1569  
1372 //     void assertTerminatesPromptly(long timeoutMillis, Runnable r) {
1373 //         long startTime = System.nanoTime();
1374 //         try {
1375 //             r.run();
1376 //         } catch (Throwable fail) { threadUnexpectedException(fail); }
1377 //         if (millisElapsedSince(startTime) > timeoutMillis/2)
1378 //             throw new AssertionError("did not return promptly");
1379 //     }
1380
1381 //     void assertTerminatesPromptly(Runnable r) {
1382 //         assertTerminatesPromptly(LONG_DELAY_MS/2, r);
1383 //     }
1384
1570      /**
1571       * Checks that timed f.get() returns the expected value, and does not
1572       * wait for the timeout to elapse before returning.
# Line 1412 | Line 1597 | public class JSR166TestCase extends Test
1597      }
1598  
1599      /**
1600 +     * Returns a new started daemon Thread running the given action,
1601 +     * wrapped in a CheckedRunnable.
1602 +     */
1603 +    Thread newStartedThread(Action action) {
1604 +        return newStartedThread(checkedRunnable(action));
1605 +    }
1606 +
1607 +    /**
1608       * Waits for the specified time (in milliseconds) for the thread
1609       * to terminate (using {@link Thread#join(long)}), else interrupts
1610       * the thread (in the hope that it may terminate later) and fails.
1611       */
1612 <    void awaitTermination(Thread t, long timeoutMillis) {
1612 >    void awaitTermination(Thread thread, long timeoutMillis) {
1613          try {
1614 <            t.join(timeoutMillis);
1614 >            thread.join(timeoutMillis);
1615          } catch (InterruptedException fail) {
1616              threadUnexpectedException(fail);
1617 <        } finally {
1618 <            if (t.getState() != Thread.State.TERMINATED) {
1619 <                t.interrupt();
1620 <                threadFail("timed out waiting for thread to terminate");
1617 >        }
1618 >        if (thread.getState() != Thread.State.TERMINATED) {
1619 >            String detail = String.format(
1620 >                    "timed out waiting for thread to terminate, thread=%s, state=%s" ,
1621 >                    thread, thread.getState());
1622 >            try {
1623 >                threadFail(detail);
1624 >            } finally {
1625 >                // Interrupt thread __after__ having reported its stack trace
1626 >                thread.interrupt();
1627              }
1628          }
1629      }
# Line 1452 | Line 1651 | public class JSR166TestCase extends Test
1651          }
1652      }
1653  
1654 +    Runnable checkedRunnable(Action action) {
1655 +        return new CheckedRunnable() {
1656 +            public void realRun() throws Throwable {
1657 +                action.run();
1658 +            }};
1659 +    }
1660 +
1661      public abstract class ThreadShouldThrow extends Thread {
1662          protected abstract void realRun() throws Throwable;
1663  
# Line 1464 | Line 1670 | public class JSR166TestCase extends Test
1670          public final void run() {
1671              try {
1672                  realRun();
1467                threadShouldThrow(exceptionClass.getSimpleName());
1673              } catch (Throwable t) {
1674                  if (! exceptionClass.isInstance(t))
1675                      threadUnexpectedException(t);
1676 +                return;
1677              }
1678 +            threadShouldThrow(exceptionClass.getSimpleName());
1679          }
1680      }
1681  
# Line 1478 | Line 1685 | public class JSR166TestCase extends Test
1685          public final void run() {
1686              try {
1687                  realRun();
1481                threadShouldThrow("InterruptedException");
1688              } catch (InterruptedException success) {
1689                  threadAssertFalse(Thread.interrupted());
1690 +                return;
1691              } catch (Throwable fail) {
1692                  threadUnexpectedException(fail);
1693              }
1694 +            threadShouldThrow("InterruptedException");
1695          }
1696      }
1697  
# Line 1495 | Line 1703 | public class JSR166TestCase extends Test
1703                  return realCall();
1704              } catch (Throwable fail) {
1705                  threadUnexpectedException(fail);
1498                return null;
1706              }
1707 <        }
1501 <    }
1502 <
1503 <    public abstract class CheckedInterruptedCallable<T>
1504 <        implements Callable<T> {
1505 <        protected abstract T realCall() throws Throwable;
1506 <
1507 <        public final T call() {
1508 <            try {
1509 <                T result = realCall();
1510 <                threadShouldThrow("InterruptedException");
1511 <                return result;
1512 <            } catch (InterruptedException success) {
1513 <                threadAssertFalse(Thread.interrupted());
1514 <            } catch (Throwable fail) {
1515 <                threadUnexpectedException(fail);
1516 <            }
1517 <            return null;
1707 >            throw new AssertionError("unreached");
1708          }
1709      }
1710  
# Line 1522 | Line 1712 | public class JSR166TestCase extends Test
1712          public void run() {}
1713      }
1714  
1715 <    public static class NoOpCallable implements Callable {
1715 >    public static class NoOpCallable implements Callable<Object> {
1716          public Object call() { return Boolean.TRUE; }
1717      }
1718  
# Line 1629 | Line 1819 | public class JSR166TestCase extends Test
1819          public String call() { throw new NullPointerException(); }
1820      }
1821  
1632    public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
1633        protected void realRun() {
1634            try {
1635                delay(SMALL_DELAY_MS);
1636            } catch (InterruptedException ok) {}
1637        }
1638    }
1639
1822      public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
1823          return new CheckedRunnable() {
1824              protected void realRun() {
# Line 1692 | Line 1874 | public class JSR166TestCase extends Test
1874                  return realCompute();
1875              } catch (Throwable fail) {
1876                  threadUnexpectedException(fail);
1695                return null;
1877              }
1878 +            throw new AssertionError("unreached");
1879          }
1880      }
1881  
# Line 1714 | Line 1896 | public class JSR166TestCase extends Test
1896  
1897          public int await() {
1898              try {
1899 <                return super.await(2 * LONG_DELAY_MS, MILLISECONDS);
1899 >                return super.await(LONGER_DELAY_MS, MILLISECONDS);
1900              } catch (TimeoutException timedOut) {
1901                  throw new AssertionError("timed out");
1902              } catch (Exception fail) {
# Line 1723 | Line 1905 | public class JSR166TestCase extends Test
1905          }
1906      }
1907  
1908 <    void checkEmpty(BlockingQueue q) {
1908 >    void checkEmpty(BlockingQueue<?> q) {
1909          try {
1910              assertTrue(q.isEmpty());
1911              assertEquals(0, q.size());
# Line 1770 | Line 1952 | public class JSR166TestCase extends Test
1952          }
1953      }
1954  
1955 <    void assertImmutable(final Object o) {
1955 >    @SuppressWarnings("unchecked")
1956 >    void assertImmutable(Object o) {
1957          if (o instanceof Collection) {
1958              assertThrows(
1959                  UnsupportedOperationException.class,
1960 <                new Runnable() { public void run() {
1778 <                        ((Collection) o).add(null);}});
1960 >                () -> ((Collection) o).add(null));
1961          }
1962      }
1963  
1964      @SuppressWarnings("unchecked")
1965      <T> T serialClone(T o) {
1966 +        T clone = null;
1967          try {
1968              ObjectInputStream ois = new ObjectInputStream
1969                  (new ByteArrayInputStream(serialBytes(o)));
1970 <            T clone = (T) ois.readObject();
1788 <            if (o == clone) assertImmutable(o);
1789 <            assertSame(o.getClass(), clone.getClass());
1790 <            return clone;
1970 >            clone = (T) ois.readObject();
1971          } catch (Throwable fail) {
1972              threadUnexpectedException(fail);
1793            return null;
1973          }
1974 +        if (o == clone) assertImmutable(o);
1975 +        else assertSame(o.getClass(), clone.getClass());
1976 +        return clone;
1977      }
1978  
1979      /**
# Line 1810 | Line 1992 | public class JSR166TestCase extends Test
1992              (new ByteArrayInputStream(bos.toByteArray()));
1993          T clone = (T) ois.readObject();
1994          if (o == clone) assertImmutable(o);
1995 <        assertSame(o.getClass(), clone.getClass());
1995 >        else assertSame(o.getClass(), clone.getClass());
1996          return clone;
1997      }
1998  
# Line 1835 | Line 2017 | public class JSR166TestCase extends Test
2017      }
2018  
2019      public void assertThrows(Class<? extends Throwable> expectedExceptionClass,
2020 <                             Runnable... throwingActions) {
2021 <        for (Runnable throwingAction : throwingActions) {
2020 >                             Action... throwingActions) {
2021 >        for (Action throwingAction : throwingActions) {
2022              boolean threw = false;
2023              try { throwingAction.run(); }
2024              catch (Throwable t) {
# Line 1920 | Line 2102 | public class JSR166TestCase extends Test
2102              shouldThrow();
2103          } catch (NullPointerException success) {}
2104          try {
2105 <            es.submit((Callable) null);
2105 >            es.submit((Callable<?>) null);
2106              shouldThrow();
2107          } catch (NullPointerException success) {}
2108  
# Line 1932 | Line 2114 | public class JSR166TestCase extends Test
2114              shouldThrow();
2115          } catch (NullPointerException success) {}
2116          try {
2117 <            ses.schedule((Callable) null,
2117 >            ses.schedule((Callable<?>) null,
2118                           randomTimeout(), randomTimeUnit());
2119              shouldThrow();
2120          } catch (NullPointerException success) {}
# Line 2091 | Line 2273 | public class JSR166TestCase extends Test
2273          else {
2274              assertEquals(x.isEmpty(), y.isEmpty());
2275              assertEquals(x.size(), y.size());
2276 <            assertEquals(new HashSet(x), new HashSet(y));
2276 >            assertEquals(new HashSet<Object>(x), new HashSet<Object>(y));
2277              if (x instanceof Deque) {
2278                  assertTrue(Arrays.equals(x.toArray(), y.toArray()));
2279                  assertTrue(Arrays.equals(x.toArray(new Object[0]),

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines