OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / test / java / tests / api / java / util / concurrent / JSR166TestCase.java
1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/licenses/publicdomain
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8
9 package tests.api.java.util.concurrent; // android-added
10
11 import junit.framework.*;
12 import java.util.*;
13 import java.util.concurrent.*;
14 import static java.util.concurrent.TimeUnit.MILLISECONDS;
15 import java.io.*;
16 import java.security.*;
17
18 /**
19  * Base class for JSR166 Junit TCK tests.  Defines some constants,
20  * utility methods and classes, as well as a simple framework for
21  * helping to make sure that assertions failing in generated threads
22  * cause the associated test that generated them to itself fail (which
23  * JUnit does not otherwise arrange).  The rules for creating such
24  * tests are:
25  *
26  * <ol>
27  *
28  * <li> All assertions in code running in generated threads must use
29  * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
30  * #threadAssertEquals}, or {@link #threadAssertNull}, (not
31  * <tt>fail</tt>, <tt>assertTrue</tt>, etc.) It is OK (but not
32  * particularly recommended) for other code to use these forms too.
33  * Only the most typically used JUnit assertion methods are defined
34  * this way, but enough to live with.</li>
35  *
36  * <li> If you override {@link #setUp} or {@link #tearDown}, make sure
37  * to invoke <tt>super.setUp</tt> and <tt>super.tearDown</tt> within
38  * them. These methods are used to clear and check for thread
39  * assertion failures.</li>
40  *
41  * <li>All delays and timeouts must use one of the constants <tt>
42  * SHORT_DELAY_MS</tt>, <tt> SMALL_DELAY_MS</tt>, <tt> MEDIUM_DELAY_MS</tt>,
43  * <tt> LONG_DELAY_MS</tt>. The idea here is that a SHORT is always
44  * discriminable from zero time, and always allows enough time for the
45  * small amounts of computation (creating a thread, calling a few
46  * methods, etc) needed to reach a timeout point. Similarly, a SMALL
47  * is always discriminable as larger than SHORT and smaller than
48  * MEDIUM.  And so on. These constants are set to conservative values,
49  * but even so, if there is ever any doubt, they can all be increased
50  * in one spot to rerun tests on slower platforms.</li>
51  *
52  * <li> All threads generated must be joined inside each test case
53  * method (or <tt>fail</tt> to do so) before returning from the
54  * method. The <tt> joinPool</tt> method can be used to do this when
55  * using Executors.</li>
56  *
57  * </ol>
58  *
59  * <p> <b>Other notes</b>
60  * <ul>
61  *
62  * <li> Usually, there is one testcase method per JSR166 method
63  * covering "normal" operation, and then as many exception-testing
64  * methods as there are exceptions the method can throw. Sometimes
65  * there are multiple tests per JSR166 method when the different
66  * "normal" behaviors differ significantly. And sometimes testcases
67  * cover multiple methods when they cannot be tested in
68  * isolation.</li>
69  *
70  * <li> The documentation style for testcases is to provide as javadoc
71  * a simple sentence or two describing the property that the testcase
72  * method purports to test. The javadocs do not say anything about how
73  * the property is tested. To find out, read the code.</li>
74  *
75  * <li> These tests are "conformance tests", and do not attempt to
76  * test throughput, latency, scalability or other performance factors
77  * (see the separate "jtreg" tests for a set intended to check these
78  * for the most central aspects of functionality.) So, most tests use
79  * the smallest sensible numbers of threads, collection sizes, etc
80  * needed to check basic conformance.</li>
81  *
82  * <li>The test classes currently do not declare inclusion in
83  * any particular package to simplify things for people integrating
84  * them in TCK test suites.</li>
85  *
86  * <li> As a convenience, the <tt>main</tt> of this class (JSR166TestCase)
87  * runs all JSR166 unit tests.</li>
88  *
89  * </ul>
90  */
91 public class JSR166TestCase extends TestCase {
92     private static final boolean useSecurityManager =
93         Boolean.getBoolean("jsr166.useSecurityManager");
94
95     // BEGIN android-removed
96     // /**
97     //  * Runs all JSR166 unit tests using junit.textui.TestRunner
98     //  */
99     // public static void main(String[] args) {
100     //     if (useSecurityManager) {
101     //         System.err.println("Setting a permissive security manager");
102     //         Policy.setPolicy(permissivePolicy());
103     //         System.setSecurityManager(new SecurityManager());
104     //     }
105     //     int iters = 1;
106     //     if (args.length > 0)
107     //         iters = Integer.parseInt(args[0]);
108     //     Test s = suite();
109     //     for (int i = 0; i < iters; ++i) {
110     //         junit.textui.TestRunner.run(s);
111     //         System.gc();
112     //         System.runFinalization();
113     //     }
114     //     System.exit(0);
115     // }
116     // END android-removed
117
118     /**
119      * Collects all JSR166 unit tests as one suite
120      */
121     public static Test suite() {
122         TestSuite suite = new TestSuite("JSR166 Unit Tests");
123
124         suite.addTest(new TestSuite(AbstractExecutorServiceTest.class));
125         suite.addTest(new TestSuite(AbstractQueueTest.class));
126         suite.addTest(new TestSuite(AbstractQueuedSynchronizerTest.class));
127         suite.addTest(new TestSuite(AbstractQueuedLongSynchronizerTest.class));
128         suite.addTest(new TestSuite(ArrayBlockingQueueTest.class));
129         suite.addTest(new TestSuite(ArrayDequeTest.class));
130         suite.addTest(new TestSuite(AtomicBooleanTest.class));
131         suite.addTest(new TestSuite(AtomicIntegerArrayTest.class));
132         suite.addTest(new TestSuite(AtomicIntegerFieldUpdaterTest.class));
133         suite.addTest(new TestSuite(AtomicIntegerTest.class));
134         suite.addTest(new TestSuite(AtomicLongArrayTest.class));
135         suite.addTest(new TestSuite(AtomicLongFieldUpdaterTest.class));
136         suite.addTest(new TestSuite(AtomicLongTest.class));
137         suite.addTest(new TestSuite(AtomicMarkableReferenceTest.class));
138         suite.addTest(new TestSuite(AtomicReferenceArrayTest.class));
139         suite.addTest(new TestSuite(AtomicReferenceFieldUpdaterTest.class));
140         suite.addTest(new TestSuite(AtomicReferenceTest.class));
141         suite.addTest(new TestSuite(AtomicStampedReferenceTest.class));
142         suite.addTest(new TestSuite(ConcurrentHashMapTest.class));
143         suite.addTest(new TestSuite(ConcurrentLinkedQueueTest.class));
144         suite.addTest(new TestSuite(ConcurrentSkipListMapTest.class));
145         suite.addTest(new TestSuite(ConcurrentSkipListSubMapTest.class));
146         suite.addTest(new TestSuite(ConcurrentSkipListSetTest.class));
147         suite.addTest(new TestSuite(ConcurrentSkipListSubSetTest.class));
148         suite.addTest(new TestSuite(CopyOnWriteArrayListTest.class));
149         suite.addTest(new TestSuite(CopyOnWriteArraySetTest.class));
150         suite.addTest(new TestSuite(CountDownLatchTest.class));
151         suite.addTest(new TestSuite(CyclicBarrierTest.class));
152         suite.addTest(new TestSuite(DelayQueueTest.class));
153         suite.addTest(new TestSuite(EntryTest.class));
154         suite.addTest(new TestSuite(ExchangerTest.class));
155         suite.addTest(new TestSuite(ExecutorsTest.class));
156         suite.addTest(new TestSuite(ExecutorCompletionServiceTest.class));
157         suite.addTest(new TestSuite(FutureTaskTest.class));
158         suite.addTest(new TestSuite(LinkedBlockingDequeTest.class));
159         suite.addTest(new TestSuite(LinkedBlockingQueueTest.class));
160         suite.addTest(new TestSuite(LinkedListTest.class));
161         suite.addTest(new TestSuite(LockSupportTest.class));
162         suite.addTest(new TestSuite(PriorityBlockingQueueTest.class));
163         suite.addTest(new TestSuite(PriorityQueueTest.class));
164         suite.addTest(new TestSuite(ReentrantLockTest.class));
165         suite.addTest(new TestSuite(ReentrantReadWriteLockTest.class));
166         suite.addTest(new TestSuite(ScheduledExecutorTest.class));
167         suite.addTest(new TestSuite(ScheduledExecutorSubclassTest.class));
168         suite.addTest(new TestSuite(SemaphoreTest.class));
169         suite.addTest(new TestSuite(SynchronousQueueTest.class));
170         suite.addTest(new TestSuite(SystemTest.class));
171         suite.addTest(new TestSuite(ThreadLocalTest.class));
172         suite.addTest(new TestSuite(ThreadPoolExecutorTest.class));
173         suite.addTest(new TestSuite(ThreadPoolExecutorSubclassTest.class));
174         suite.addTest(new TestSuite(ThreadTest.class));
175         suite.addTest(new TestSuite(TimeUnitTest.class));
176
177         return suite;
178     }
179
180
181     public static long SHORT_DELAY_MS;
182     public static long SMALL_DELAY_MS;
183     public static long MEDIUM_DELAY_MS;
184     public static long LONG_DELAY_MS;
185
186
187     /**
188      * Returns the shortest timed delay. This could
189      * be reimplemented to use for example a Property.
190      */
191     protected long getShortDelay() {
192         // BEGIN android-changed
193         // original value is 50
194         return 250;
195         // END android-changed
196     }
197
198
199     /**
200      * Sets delays as multiples of SHORT_DELAY.
201      */
202     protected void setDelays() {
203         SHORT_DELAY_MS = getShortDelay();
204         SMALL_DELAY_MS = SHORT_DELAY_MS * 5;
205         MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
206         LONG_DELAY_MS = SHORT_DELAY_MS * 50;
207     }
208
209     /**
210      * Flag set true if any threadAssert methods fail
211      */
212     volatile boolean threadFailed;
213
214     /**
215      * Initializes test to indicate that no thread assertions have failed
216      */
217     public void setUp() {
218         setDelays();
219         threadFailed = false;
220     }
221
222     /**
223      * Triggers test case failure if any thread assertions have failed
224      */
225     public void tearDown() {
226         assertFalse(threadFailed);
227     }
228
229     /**
230      * Fail, also setting status to indicate current testcase should fail
231      */
232     public void threadFail(String reason) {
233         threadFailed = true;
234         fail(reason);
235     }
236
237     /**
238      * If expression not true, set status to indicate current testcase
239      * should fail
240      */
241     public void threadAssertTrue(boolean b) {
242         if (!b) {
243             threadFailed = true;
244             assertTrue(b);
245         }
246     }
247
248     /**
249      * If expression not false, set status to indicate current testcase
250      * should fail
251      */
252     public void threadAssertFalse(boolean b) {
253         if (b) {
254             threadFailed = true;
255             assertFalse(b);
256         }
257     }
258
259     /**
260      * If argument not null, set status to indicate current testcase
261      * should fail
262      */
263     public void threadAssertNull(Object x) {
264         if (x != null) {
265             threadFailed = true;
266             assertNull(x);
267         }
268     }
269
270     /**
271      * If arguments not equal, set status to indicate current testcase
272      * should fail
273      */
274     public void threadAssertEquals(long x, long y) {
275         if (x != y) {
276             threadFailed = true;
277             assertEquals(x, y);
278         }
279     }
280
281     /**
282      * If arguments not equal, set status to indicate current testcase
283      * should fail
284      */
285     public void threadAssertEquals(Object x, Object y) {
286         if (x != y && (x == null || !x.equals(y))) {
287             threadFailed = true;
288             assertEquals(x, y);
289         }
290     }
291
292     /**
293      * threadFail with message "should throw exception"
294      */
295     public void threadShouldThrow() {
296         threadFailed = true;
297         fail("should throw exception");
298     }
299
300     /**
301      * threadFail with message "should throw" + exceptionName
302      */
303     public void threadShouldThrow(String exceptionName) {
304         threadFailed = true;
305         fail("should throw " + exceptionName);
306     }
307
308     /**
309      * threadFail with message "Unexpected exception"
310      */
311     public void threadUnexpectedException() {
312         threadFailed = true;
313         fail("Unexpected exception");
314     }
315
316     /**
317      * threadFail with message "Unexpected exception", with argument
318      */
319     public void threadUnexpectedException(Throwable ex) {
320         threadFailed = true;
321         ex.printStackTrace();
322         fail("Unexpected exception: " + ex);
323     }
324
325     /**
326      * Wait out termination of a thread pool or fail doing so
327      */
328     public void joinPool(ExecutorService exec) {
329         try {
330             exec.shutdown();
331             assertTrue(exec.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
332         } catch (SecurityException ok) {
333             // Allowed in case test doesn't have privs
334         } catch (InterruptedException ie) {
335             fail("Unexpected InterruptedException");
336         }
337     }
338
339
340     /**
341      * fail with message "should throw exception"
342      */
343     public void shouldThrow() {
344         fail("Should throw exception");
345     }
346
347     /**
348      * fail with message "should throw " + exceptionName
349      */
350     public void shouldThrow(String exceptionName) {
351         fail("Should throw " + exceptionName);
352     }
353
354     /**
355      * fail with message "Unexpected exception"
356      */
357     public void unexpectedException() {
358         fail("Unexpected exception");
359     }
360
361     /**
362      * fail with message "Unexpected exception", with argument
363      */
364     public void unexpectedException(Throwable ex) {
365         ex.printStackTrace();
366         fail("Unexpected exception: " + ex);
367     }
368
369
370     /**
371      * The number of elements to place in collections, arrays, etc.
372      */
373     public static final int SIZE = 20;
374
375     // Some convenient Integer constants
376
377     public static final Integer zero  = new Integer(0);
378     public static final Integer one   = new Integer(1);
379     public static final Integer two   = new Integer(2);
380     public static final Integer three = new Integer(3);
381     public static final Integer four  = new Integer(4);
382     public static final Integer five  = new Integer(5);
383     public static final Integer six   = new Integer(6);
384     public static final Integer seven = new Integer(7);
385     public static final Integer eight = new Integer(8);
386     public static final Integer nine  = new Integer(9);
387     public static final Integer m1  = new Integer(-1);
388     public static final Integer m2  = new Integer(-2);
389     public static final Integer m3  = new Integer(-3);
390     public static final Integer m4  = new Integer(-4);
391     public static final Integer m5  = new Integer(-5);
392     public static final Integer m6  = new Integer(-6);
393     public static final Integer m10 = new Integer(-10);
394
395
396     /**
397      * Runs Runnable r with a security policy that permits precisely
398      * the specified permissions.  If there is no current security
399      * manager, the runnable is run twice, both with and without a
400      * security manager.  We require that any security manager permit
401      * getPolicy/setPolicy.
402      */
403     public void runWithPermissions(Runnable r, Permission... permissions) {
404         SecurityManager sm = System.getSecurityManager();
405         if (sm == null) {
406             r.run();
407             Policy savedPolicy = Policy.getPolicy();
408             try {
409                 Policy.setPolicy(permissivePolicy());
410                 System.setSecurityManager(new SecurityManager());
411                 runWithPermissions(r, permissions);
412             } finally {
413                 System.setSecurityManager(null);
414                 Policy.setPolicy(savedPolicy);
415             }
416         } else {
417             Policy savedPolicy = Policy.getPolicy();
418             AdjustablePolicy policy = new AdjustablePolicy(permissions);
419             Policy.setPolicy(policy);
420
421             try {
422                 r.run();
423             } finally {
424                 policy.addPermission(new SecurityPermission("setPolicy"));
425                 Policy.setPolicy(savedPolicy);
426             }
427         }
428     }
429
430     /**
431      * Runs a runnable without any permissions.
432      */
433     public void runWithoutPermissions(Runnable r) {
434         runWithPermissions(r);
435     }
436
437     /**
438      * A security policy where new permissions can be dynamically added
439      * or all cleared.
440      */
441     public static class AdjustablePolicy extends java.security.Policy {
442         Permissions perms = new Permissions();
443         AdjustablePolicy(Permission... permissions) {
444             for (Permission permission : permissions)
445                 perms.add(permission);
446         }
447         void addPermission(Permission perm) { perms.add(perm); }
448         void clearPermissions() { perms = new Permissions(); }
449         public PermissionCollection getPermissions(CodeSource cs) {
450             return perms;
451         }
452         public PermissionCollection getPermissions(ProtectionDomain pd) {
453             return perms;
454         }
455         public boolean implies(ProtectionDomain pd, Permission p) {
456             return perms.implies(p);
457         }
458         public void refresh() {}
459     }
460
461     /**
462      * Returns a policy containing all the permissions we ever need.
463      */
464     public static Policy permissivePolicy() {
465         return new AdjustablePolicy
466             // Permissions j.u.c. needs directly
467             (new RuntimePermission("modifyThread"),
468              new RuntimePermission("getClassLoader"),
469              new RuntimePermission("setContextClassLoader"),
470              // Permissions needed to change permissions!
471              new SecurityPermission("getPolicy"),
472              new SecurityPermission("setPolicy"),
473              new RuntimePermission("setSecurityManager"),
474              // Permissions needed by the junit test harness
475              new RuntimePermission("accessDeclaredMembers"),
476              new PropertyPermission("*", "read"),
477              new java.io.FilePermission("<<ALL FILES>>", "read"));
478     }
479
480     /**
481      * Sleep until the timeout has elapsed, or interrupted.
482      * Does <em>NOT</em> throw InterruptedException.
483      */
484     void sleepTillInterrupted(long timeoutMillis) {
485         try {
486             Thread.sleep(timeoutMillis);
487         } catch (InterruptedException wakeup) {}
488     }
489
490     /**
491      * Returns a new started Thread running the given runnable.
492      */
493     Thread newStartedThread(Runnable runnable) {
494         Thread t = new Thread(runnable);
495         t.start();
496         return t;
497     }
498
499     // Some convenient Runnable classes
500
501     public abstract class CheckedRunnable implements Runnable {
502         protected abstract void realRun() throws Throwable;
503
504         public final void run() {
505             try {
506                 realRun();
507             } catch (Throwable t) {
508                 threadUnexpectedException(t);
509             }
510         }
511     }
512
513     public abstract class RunnableShouldThrow implements Runnable {
514         protected abstract void realRun() throws Throwable;
515
516         final Class<?> exceptionClass;
517
518         <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) {
519             this.exceptionClass = exceptionClass;
520         }
521
522         public final void run() {
523             try {
524                 realRun();
525                 threadShouldThrow(exceptionClass.getSimpleName());
526             } catch (Throwable t) {
527                 if (! exceptionClass.isInstance(t))
528                     threadUnexpectedException(t);
529             }
530         }
531     }
532
533     public abstract class ThreadShouldThrow extends Thread {
534         protected abstract void realRun() throws Throwable;
535
536         final Class<?> exceptionClass;
537
538         <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) {
539             this.exceptionClass = exceptionClass;
540         }
541
542         public final void run() {
543             try {
544                 realRun();
545                 threadShouldThrow(exceptionClass.getSimpleName());
546             } catch (Throwable t) {
547                 if (! exceptionClass.isInstance(t))
548                     threadUnexpectedException(t);
549             }
550         }
551     }
552
553     public abstract class CheckedInterruptedRunnable implements Runnable {
554         protected abstract void realRun() throws Throwable;
555
556         public final void run() {
557             try {
558                 realRun();
559                 threadShouldThrow("InterruptedException");
560             } catch (InterruptedException success) {
561             } catch (Throwable t) {
562                 threadUnexpectedException(t);
563             }
564         }
565     }
566
567     public abstract class CheckedCallable<T> implements Callable<T> {
568         protected abstract T realCall() throws Throwable;
569
570         public final T call() {
571             try {
572                 return realCall();
573             } catch (Throwable t) {
574                 threadUnexpectedException(t);
575             }
576             return null;
577         }
578     }
579
580     public abstract class CheckedInterruptedCallable<T> implements Callable<T> {
581         protected abstract T realCall() throws Throwable;
582
583         public final T call() {
584             try {
585                 T result = realCall();
586                 threadShouldThrow("InterruptedException");
587                 return result;
588             } catch (InterruptedException success) {
589             } catch (Throwable t) {
590                 threadUnexpectedException(t);
591             }
592             return null;
593         }
594     }
595
596     public static class NoOpRunnable implements Runnable {
597         public void run() {}
598     }
599
600     public static class NoOpCallable implements Callable {
601         public Object call() { return Boolean.TRUE; }
602     }
603
604     public static final String TEST_STRING = "a test string";
605
606     public static class StringTask implements Callable<String> {
607         public String call() { return TEST_STRING; }
608     }
609
610     public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
611         return new CheckedCallable<String>() {
612             public String realCall() {
613                 try {
614                     latch.await();
615                 } catch (InterruptedException quittingTime) {}
616                 return TEST_STRING;
617             }};
618     }
619
620     public static class NPETask implements Callable<String> {
621         public String call() { throw new NullPointerException(); }
622     }
623
624     public static class CallableOne implements Callable<Integer> {
625         public Integer call() { return one; }
626     }
627
628     public class ShortRunnable extends CheckedRunnable {
629         protected void realRun() throws Throwable {
630             Thread.sleep(SHORT_DELAY_MS);
631         }
632     }
633
634     public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
635         protected void realRun() throws InterruptedException {
636             Thread.sleep(SHORT_DELAY_MS);
637         }
638     }
639
640     public class SmallRunnable extends CheckedRunnable {
641         protected void realRun() throws Throwable {
642             Thread.sleep(SMALL_DELAY_MS);
643         }
644     }
645
646     public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
647         protected void realRun() {
648             try {
649                 Thread.sleep(SMALL_DELAY_MS);
650             } catch (InterruptedException ok) {}
651         }
652     }
653
654     public class SmallCallable extends CheckedCallable {
655         protected Object realCall() throws InterruptedException {
656             Thread.sleep(SMALL_DELAY_MS);
657             return Boolean.TRUE;
658         }
659     }
660
661     public class SmallInterruptedRunnable extends CheckedInterruptedRunnable {
662         protected void realRun() throws InterruptedException {
663             Thread.sleep(SMALL_DELAY_MS);
664         }
665     }
666
667     public class MediumRunnable extends CheckedRunnable {
668         protected void realRun() throws Throwable {
669             Thread.sleep(MEDIUM_DELAY_MS);
670         }
671     }
672
673     public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
674         protected void realRun() throws InterruptedException {
675             Thread.sleep(MEDIUM_DELAY_MS);
676         }
677     }
678
679     public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
680         protected void realRun() {
681             try {
682                 Thread.sleep(MEDIUM_DELAY_MS);
683             } catch (InterruptedException ok) {}
684         }
685     }
686
687     public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
688         protected void realRun() {
689             try {
690                 Thread.sleep(LONG_DELAY_MS);
691             } catch (InterruptedException ok) {}
692         }
693     }
694
695     /**
696      * For use as ThreadFactory in constructors
697      */
698     public static class SimpleThreadFactory implements ThreadFactory {
699         public Thread newThread(Runnable r) {
700             return new Thread(r);
701         }
702     }
703
704     public static class TrackedShortRunnable implements Runnable {
705         public volatile boolean done = false;
706         public void run() {
707             try {
708                 Thread.sleep(SMALL_DELAY_MS);
709                 done = true;
710             } catch (InterruptedException ok) {}
711         }
712     }
713
714     public static class TrackedMediumRunnable implements Runnable {
715         public volatile boolean done = false;
716         public void run() {
717             try {
718                 Thread.sleep(MEDIUM_DELAY_MS);
719                 done = true;
720             } catch (InterruptedException ok) {}
721         }
722     }
723
724     public static class TrackedLongRunnable implements Runnable {
725         public volatile boolean done = false;
726         public void run() {
727             try {
728                 Thread.sleep(LONG_DELAY_MS);
729                 done = true;
730             } catch (InterruptedException ok) {}
731         }
732     }
733
734     public static class TrackedNoOpRunnable implements Runnable {
735         public volatile boolean done = false;
736         public void run() {
737             done = true;
738         }
739     }
740
741     public static class TrackedCallable implements Callable {
742         public volatile boolean done = false;
743         public Object call() {
744             try {
745                 Thread.sleep(SMALL_DELAY_MS);
746                 done = true;
747             } catch (InterruptedException ok) {}
748             return Boolean.TRUE;
749         }
750     }
751
752
753     /**
754      * For use as RejectedExecutionHandler in constructors
755      */
756     public static class NoOpREHandler implements RejectedExecutionHandler {
757         public void rejectedExecution(Runnable r,
758                                       ThreadPoolExecutor executor) {}
759     }
760
761 }