Home | History | Annotate | Download | only in jsr166
      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/publicdomain/zero/1.0/
      5  */
      6 
      7 package jsr166;
      8 
      9 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     10 import static java.util.concurrent.TimeUnit.NANOSECONDS;
     11 
     12 import java.security.PrivilegedAction;
     13 import java.security.PrivilegedExceptionAction;
     14 import java.util.ArrayList;
     15 import java.util.Collection;
     16 import java.util.List;
     17 import java.util.concurrent.Callable;
     18 import java.util.concurrent.CountDownLatch;
     19 import java.util.concurrent.ExecutionException;
     20 import java.util.concurrent.Executors;
     21 import java.util.concurrent.ExecutorService;
     22 import java.util.concurrent.ForkJoinPool;
     23 import java.util.concurrent.ForkJoinTask;
     24 import java.util.concurrent.ForkJoinWorkerThread;
     25 import java.util.concurrent.Future;
     26 import java.util.concurrent.RecursiveTask;
     27 import java.util.concurrent.RejectedExecutionException;
     28 import java.util.concurrent.atomic.AtomicBoolean;
     29 import java.util.concurrent.locks.ReentrantLock;
     30 
     31 import junit.framework.AssertionFailedError;
     32 import junit.framework.Test;
     33 import junit.framework.TestSuite;
     34 
     35 public class ForkJoinPoolTest extends JSR166TestCase {
     36     // android-note: Removed because the CTS runner does a bad job of
     37     // retrying tests that have suite() declarations.
     38     //
     39     // public static void main(String[] args) {
     40     //     main(suite(), args);
     41     // }
     42     // public static Test suite() {
     43     //     return new TestSuite(ForkJoinPoolTest.class);
     44     // }
     45 
     46     /*
     47      * Testing coverage notes:
     48      *
     49      * 1. shutdown and related methods are tested via super.joinPool.
     50      *
     51      * 2. newTaskFor and adapters are tested in submit/invoke tests
     52      *
     53      * 3. We cannot portably test monitoring methods such as
     54      * getStealCount() since they rely ultimately on random task
     55      * stealing that may cause tasks not to be stolen/propagated
     56      * across threads, especially on uniprocessors.
     57      *
     58      * 4. There are no independently testable ForkJoinWorkerThread
     59      * methods, but they are covered here and in task tests.
     60      */
     61 
     62     // Some classes to test extension and factory methods
     63 
     64     static class MyHandler implements Thread.UncaughtExceptionHandler {
     65         volatile int catches = 0;
     66         public void uncaughtException(Thread t, Throwable e) {
     67             ++catches;
     68         }
     69     }
     70 
     71     static class MyError extends Error {}
     72 
     73     // to test handlers
     74     static class FailingFJWSubclass extends ForkJoinWorkerThread {
     75         public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
     76         protected void onStart() { super.onStart(); throw new MyError(); }
     77     }
     78 
     79     static class FailingThreadFactory
     80             implements ForkJoinPool.ForkJoinWorkerThreadFactory {
     81         volatile int calls = 0;
     82         public ForkJoinWorkerThread newThread(ForkJoinPool p) {
     83             if (++calls > 1) return null;
     84             return new FailingFJWSubclass(p);
     85         }
     86     }
     87 
     88     static class SubFJP extends ForkJoinPool { // to expose protected
     89         SubFJP() { super(1); }
     90         public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
     91             return super.drainTasksTo(c);
     92         }
     93         public ForkJoinTask<?> pollSubmission() {
     94             return super.pollSubmission();
     95         }
     96     }
     97 
     98     static class ManagedLocker implements ForkJoinPool.ManagedBlocker {
     99         final ReentrantLock lock;
    100         boolean hasLock = false;
    101         ManagedLocker(ReentrantLock lock) { this.lock = lock; }
    102         public boolean block() {
    103             if (!hasLock)
    104                 lock.lock();
    105             return true;
    106         }
    107         public boolean isReleasable() {
    108             return hasLock || (hasLock = lock.tryLock());
    109         }
    110     }
    111 
    112     // A simple recursive task for testing
    113     static final class FibTask extends RecursiveTask<Integer> {
    114         final int number;
    115         FibTask(int n) { number = n; }
    116         protected Integer compute() {
    117             int n = number;
    118             if (n <= 1)
    119                 return n;
    120             FibTask f1 = new FibTask(n - 1);
    121             f1.fork();
    122             return (new FibTask(n - 2)).compute() + f1.join();
    123         }
    124     }
    125 
    126     // A failing task for testing
    127     static final class FailingTask extends ForkJoinTask<Void> {
    128         public final Void getRawResult() { return null; }
    129         protected final void setRawResult(Void mustBeNull) { }
    130         protected final boolean exec() { throw new Error(); }
    131         FailingTask() {}
    132     }
    133 
    134     // Fib needlessly using locking to test ManagedBlockers
    135     static final class LockingFibTask extends RecursiveTask<Integer> {
    136         final int number;
    137         final ManagedLocker locker;
    138         final ReentrantLock lock;
    139         LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
    140             number = n;
    141             this.locker = locker;
    142             this.lock = lock;
    143         }
    144         protected Integer compute() {
    145             int n;
    146             LockingFibTask f1 = null;
    147             LockingFibTask f2 = null;
    148             locker.block();
    149             n = number;
    150             if (n > 1) {
    151                 f1 = new LockingFibTask(n - 1, locker, lock);
    152                 f2 = new LockingFibTask(n - 2, locker, lock);
    153             }
    154             lock.unlock();
    155             if (n <= 1)
    156                 return n;
    157             else {
    158                 f1.fork();
    159                 return f2.compute() + f1.join();
    160             }
    161         }
    162     }
    163 
    164     /**
    165      * Successfully constructed pool reports default factory,
    166      * parallelism and async mode policies, no active threads or
    167      * tasks, and quiescent running state.
    168      */
    169     public void testDefaultInitialState() {
    170         ForkJoinPool p = new ForkJoinPool(1);
    171         try (PoolCleaner cleaner = cleaner(p)) {
    172             assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
    173                        p.getFactory());
    174             assertFalse(p.getAsyncMode());
    175             assertEquals(0, p.getActiveThreadCount());
    176             assertEquals(0, p.getStealCount());
    177             assertEquals(0, p.getQueuedTaskCount());
    178             assertEquals(0, p.getQueuedSubmissionCount());
    179             assertFalse(p.hasQueuedSubmissions());
    180             assertFalse(p.isShutdown());
    181             assertFalse(p.isTerminating());
    182             assertFalse(p.isTerminated());
    183         }
    184     }
    185 
    186     /**
    187      * Constructor throws if size argument is less than zero
    188      */
    189     public void testConstructor1() {
    190         try {
    191             new ForkJoinPool(-1);
    192             shouldThrow();
    193         } catch (IllegalArgumentException success) {}
    194     }
    195 
    196     /**
    197      * Constructor throws if factory argument is null
    198      */
    199     public void testConstructor2() {
    200         try {
    201             new ForkJoinPool(1, null, null, false);
    202             shouldThrow();
    203         } catch (NullPointerException success) {}
    204     }
    205 
    206     /**
    207      * getParallelism returns size set in constructor
    208      */
    209     public void testGetParallelism() {
    210         ForkJoinPool p = new ForkJoinPool(1);
    211         try (PoolCleaner cleaner = cleaner(p)) {
    212             assertEquals(1, p.getParallelism());
    213         }
    214     }
    215 
    216     /**
    217      * getPoolSize returns number of started workers.
    218      */
    219     public void testGetPoolSize() {
    220         final CountDownLatch taskStarted = new CountDownLatch(1);
    221         final CountDownLatch done = new CountDownLatch(1);
    222         final ForkJoinPool p = new ForkJoinPool(1);
    223         try (PoolCleaner cleaner = cleaner(p)) {
    224             assertEquals(0, p.getActiveThreadCount());
    225             final Runnable task = new CheckedRunnable() {
    226                 public void realRun() throws InterruptedException {
    227                     taskStarted.countDown();
    228                     assertEquals(1, p.getPoolSize());
    229                     assertEquals(1, p.getActiveThreadCount());
    230                     done.await();
    231                 }};
    232             Future<?> future = p.submit(task);
    233             await(taskStarted);
    234             assertEquals(1, p.getPoolSize());
    235             assertEquals(1, p.getActiveThreadCount());
    236             done.countDown();
    237         }
    238         assertEquals(0, p.getPoolSize());
    239         assertEquals(0, p.getActiveThreadCount());
    240     }
    241 
    242     /**
    243      * awaitTermination on a non-shutdown pool times out
    244      */
    245     public void testAwaitTermination_timesOut() throws InterruptedException {
    246         ForkJoinPool p = new ForkJoinPool(1);
    247         try (PoolCleaner cleaner = cleaner(p)) {
    248             assertFalse(p.isTerminated());
    249             assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
    250             assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
    251             assertFalse(p.awaitTermination(-1L, NANOSECONDS));
    252             assertFalse(p.awaitTermination(-1L, MILLISECONDS));
    253             assertFalse(p.awaitTermination(0L, NANOSECONDS));
    254             assertFalse(p.awaitTermination(0L, MILLISECONDS));
    255             long timeoutNanos = 999999L;
    256             long startTime = System.nanoTime();
    257             assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
    258             assertTrue(System.nanoTime() - startTime >= timeoutNanos);
    259             assertFalse(p.isTerminated());
    260             startTime = System.nanoTime();
    261             long timeoutMillis = timeoutMillis();
    262             assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
    263             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    264             assertFalse(p.isTerminated());
    265             p.shutdown();
    266             assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    267             assertTrue(p.isTerminated());
    268         }
    269     }
    270 
    271     /**
    272      * setUncaughtExceptionHandler changes handler for uncaught exceptions.
    273      *
    274      * Additionally tests: Overriding ForkJoinWorkerThread.onStart
    275      * performs its defined action
    276      */
    277     public void testSetUncaughtExceptionHandler() throws InterruptedException {
    278         final CountDownLatch uehInvoked = new CountDownLatch(1);
    279         final Thread.UncaughtExceptionHandler ueh =
    280             new Thread.UncaughtExceptionHandler() {
    281                 public void uncaughtException(Thread t, Throwable e) {
    282                     threadAssertTrue(e instanceof MyError);
    283                     threadAssertTrue(t instanceof FailingFJWSubclass);
    284                     uehInvoked.countDown();
    285                 }};
    286         ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
    287                                           ueh, false);
    288         try (PoolCleaner cleaner = cleaner(p)) {
    289             assertSame(ueh, p.getUncaughtExceptionHandler());
    290             try {
    291                 p.execute(new FibTask(8));
    292                 await(uehInvoked);
    293             } finally {
    294                 p.shutdownNow(); // failure might have prevented processing task
    295             }
    296         }
    297     }
    298 
    299     /**
    300      * After invoking a single task, isQuiescent eventually becomes
    301      * true, at which time queues are empty, threads are not active,
    302      * the task has completed successfully, and construction
    303      * parameters continue to hold
    304      */
    305     public void testIsQuiescent() throws Exception {
    306         ForkJoinPool p = new ForkJoinPool(2);
    307         try (PoolCleaner cleaner = cleaner(p)) {
    308             assertTrue(p.isQuiescent());
    309             long startTime = System.nanoTime();
    310             FibTask f = new FibTask(20);
    311             p.invoke(f);
    312             assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
    313                        p.getFactory());
    314             while (! p.isQuiescent()) {
    315                 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
    316                     throw new AssertionFailedError("timed out");
    317                 assertFalse(p.getAsyncMode());
    318                 assertFalse(p.isShutdown());
    319                 assertFalse(p.isTerminating());
    320                 assertFalse(p.isTerminated());
    321                 Thread.yield();
    322             }
    323 
    324             assertTrue(p.isQuiescent());
    325             assertFalse(p.getAsyncMode());
    326             assertEquals(0, p.getQueuedTaskCount());
    327             assertEquals(0, p.getQueuedSubmissionCount());
    328             assertFalse(p.hasQueuedSubmissions());
    329             while (p.getActiveThreadCount() != 0
    330                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
    331                 Thread.yield();
    332             assertFalse(p.isShutdown());
    333             assertFalse(p.isTerminating());
    334             assertFalse(p.isTerminated());
    335             assertTrue(f.isDone());
    336             assertEquals(6765, (int) f.get());
    337             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    338         }
    339     }
    340 
    341     /**
    342      * Completed submit(ForkJoinTask) returns result
    343      */
    344     public void testSubmitForkJoinTask() throws Throwable {
    345         ForkJoinPool p = new ForkJoinPool(1);
    346         try (PoolCleaner cleaner = cleaner(p)) {
    347             ForkJoinTask<Integer> f = p.submit(new FibTask(8));
    348             assertEquals(21, (int) f.get());
    349         }
    350     }
    351 
    352     /**
    353      * A task submitted after shutdown is rejected
    354      */
    355     public void testSubmitAfterShutdown() {
    356         ForkJoinPool p = new ForkJoinPool(1);
    357         try (PoolCleaner cleaner = cleaner(p)) {
    358             p.shutdown();
    359             assertTrue(p.isShutdown());
    360             try {
    361                 ForkJoinTask<Integer> f = p.submit(new FibTask(8));
    362                 shouldThrow();
    363             } catch (RejectedExecutionException success) {}
    364         }
    365     }
    366 
    367     /**
    368      * Pool maintains parallelism when using ManagedBlocker
    369      */
    370     public void testBlockingForkJoinTask() throws Throwable {
    371         ForkJoinPool p = new ForkJoinPool(4);
    372         try {
    373             ReentrantLock lock = new ReentrantLock();
    374             ManagedLocker locker = new ManagedLocker(lock);
    375             ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock);
    376             p.execute(f);
    377             assertEquals(6765, (int) f.get());
    378         } finally {
    379             p.shutdownNow(); // don't wait out shutdown
    380         }
    381     }
    382 
    383     /**
    384      * pollSubmission returns unexecuted submitted task, if present
    385      */
    386     public void testPollSubmission() {
    387         final CountDownLatch done = new CountDownLatch(1);
    388         SubFJP p = new SubFJP();
    389         try (PoolCleaner cleaner = cleaner(p)) {
    390             ForkJoinTask a = p.submit(awaiter(done));
    391             ForkJoinTask b = p.submit(awaiter(done));
    392             ForkJoinTask c = p.submit(awaiter(done));
    393             ForkJoinTask r = p.pollSubmission();
    394             assertTrue(r == a || r == b || r == c);
    395             assertFalse(r.isDone());
    396             done.countDown();
    397         }
    398     }
    399 
    400     /**
    401      * drainTasksTo transfers unexecuted submitted tasks, if present
    402      */
    403     public void testDrainTasksTo() {
    404         final CountDownLatch done = new CountDownLatch(1);
    405         SubFJP p = new SubFJP();
    406         try (PoolCleaner cleaner = cleaner(p)) {
    407             ForkJoinTask a = p.submit(awaiter(done));
    408             ForkJoinTask b = p.submit(awaiter(done));
    409             ForkJoinTask c = p.submit(awaiter(done));
    410             ArrayList<ForkJoinTask> al = new ArrayList();
    411             p.drainTasksTo(al);
    412             assertTrue(al.size() > 0);
    413             for (ForkJoinTask r : al) {
    414                 assertTrue(r == a || r == b || r == c);
    415                 assertFalse(r.isDone());
    416             }
    417             done.countDown();
    418         }
    419     }
    420 
    421     // FJ Versions of AbstractExecutorService tests
    422 
    423     /**
    424      * execute(runnable) runs it to completion
    425      */
    426     public void testExecuteRunnable() throws Throwable {
    427         ExecutorService e = new ForkJoinPool(1);
    428         try (PoolCleaner cleaner = cleaner(e)) {
    429             final AtomicBoolean done = new AtomicBoolean(false);
    430             Future<?> future = e.submit(new CheckedRunnable() {
    431                 public void realRun() {
    432                     done.set(true);
    433                 }});
    434             assertNull(future.get());
    435             assertNull(future.get(0, MILLISECONDS));
    436             assertTrue(done.get());
    437             assertTrue(future.isDone());
    438             assertFalse(future.isCancelled());
    439         }
    440     }
    441 
    442     /**
    443      * Completed submit(callable) returns result
    444      */
    445     public void testSubmitCallable() throws Throwable {
    446         ExecutorService e = new ForkJoinPool(1);
    447         try (PoolCleaner cleaner = cleaner(e)) {
    448             Future<String> future = e.submit(new StringTask());
    449             assertSame(TEST_STRING, future.get());
    450             assertTrue(future.isDone());
    451             assertFalse(future.isCancelled());
    452         }
    453     }
    454 
    455     /**
    456      * Completed submit(runnable) returns successfully
    457      */
    458     public void testSubmitRunnable() throws Throwable {
    459         ExecutorService e = new ForkJoinPool(1);
    460         try (PoolCleaner cleaner = cleaner(e)) {
    461             Future<?> future = e.submit(new NoOpRunnable());
    462             assertNull(future.get());
    463             assertTrue(future.isDone());
    464             assertFalse(future.isCancelled());
    465         }
    466     }
    467 
    468     /**
    469      * Completed submit(runnable, result) returns result
    470      */
    471     public void testSubmitRunnable2() throws Throwable {
    472         ExecutorService e = new ForkJoinPool(1);
    473         try (PoolCleaner cleaner = cleaner(e)) {
    474             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
    475             assertSame(TEST_STRING, future.get());
    476             assertTrue(future.isDone());
    477             assertFalse(future.isCancelled());
    478         }
    479     }
    480 
    481     /**
    482      * A submitted privileged action runs to completion
    483      */
    484     public void testSubmitPrivilegedAction() throws Exception {
    485         final Callable callable = Executors.callable(new PrivilegedAction() {
    486                 public Object run() { return TEST_STRING; }});
    487         Runnable r = new CheckedRunnable() {
    488         public void realRun() throws Exception {
    489             ExecutorService e = new ForkJoinPool(1);
    490             try (PoolCleaner cleaner = cleaner(e)) {
    491                 Future future = e.submit(callable);
    492                 assertSame(TEST_STRING, future.get());
    493             }
    494         }};
    495 
    496         runWithPermissions(r, new RuntimePermission("modifyThread"));
    497     }
    498 
    499     /**
    500      * A submitted privileged exception action runs to completion
    501      */
    502     public void testSubmitPrivilegedExceptionAction() throws Exception {
    503         final Callable callable =
    504             Executors.callable(new PrivilegedExceptionAction() {
    505                 public Object run() { return TEST_STRING; }});
    506         Runnable r = new CheckedRunnable() {
    507         public void realRun() throws Exception {
    508             ExecutorService e = new ForkJoinPool(1);
    509             try (PoolCleaner cleaner = cleaner(e)) {
    510                 Future future = e.submit(callable);
    511                 assertSame(TEST_STRING, future.get());
    512             }
    513         }};
    514 
    515         runWithPermissions(r, new RuntimePermission("modifyThread"));
    516     }
    517 
    518     /**
    519      * A submitted failed privileged exception action reports exception
    520      */
    521     public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
    522         final Callable callable =
    523             Executors.callable(new PrivilegedExceptionAction() {
    524                 public Object run() { throw new IndexOutOfBoundsException(); }});
    525         Runnable r = new CheckedRunnable() {
    526         public void realRun() throws Exception {
    527             ExecutorService e = new ForkJoinPool(1);
    528             try (PoolCleaner cleaner = cleaner(e)) {
    529                 Future future = e.submit(callable);
    530                 try {
    531                     future.get();
    532                     shouldThrow();
    533                 } catch (ExecutionException success) {
    534                     assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
    535                 }
    536             }
    537         }};
    538 
    539         runWithPermissions(r, new RuntimePermission("modifyThread"));
    540     }
    541 
    542     /**
    543      * execute(null runnable) throws NullPointerException
    544      */
    545     public void testExecuteNullRunnable() {
    546         ExecutorService e = new ForkJoinPool(1);
    547         try (PoolCleaner cleaner = cleaner(e)) {
    548             try {
    549                 Future<?> future = e.submit((Runnable) null);
    550                 shouldThrow();
    551             } catch (NullPointerException success) {}
    552         }
    553     }
    554 
    555     /**
    556      * submit(null callable) throws NullPointerException
    557      */
    558     public void testSubmitNullCallable() {
    559         ExecutorService e = new ForkJoinPool(1);
    560         try (PoolCleaner cleaner = cleaner(e)) {
    561             try {
    562                 Future<String> future = e.submit((Callable) null);
    563                 shouldThrow();
    564             } catch (NullPointerException success) {}
    565         }
    566     }
    567 
    568     /**
    569      * submit(callable).get() throws InterruptedException if interrupted
    570      */
    571     public void testInterruptedSubmit() throws InterruptedException {
    572         final CountDownLatch submitted    = new CountDownLatch(1);
    573         final CountDownLatch quittingTime = new CountDownLatch(1);
    574         final Callable<Void> awaiter = new CheckedCallable<Void>() {
    575             public Void realCall() throws InterruptedException {
    576                 assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
    577                 return null;
    578             }};
    579         final ExecutorService p = new ForkJoinPool(1);
    580         try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
    581             Thread t = new Thread(new CheckedInterruptedRunnable() {
    582                 public void realRun() throws Exception {
    583                     Future<Void> future = p.submit(awaiter);
    584                     submitted.countDown();
    585                     future.get();
    586                 }});
    587             t.start();
    588             await(submitted);
    589             t.interrupt();
    590             awaitTermination(t);
    591         }
    592     }
    593 
    594     /**
    595      * get of submit(callable) throws ExecutionException if callable
    596      * throws exception
    597      */
    598     public void testSubmitEE() throws Throwable {
    599         ForkJoinPool p = new ForkJoinPool(1);
    600         try (PoolCleaner cleaner = cleaner(p)) {
    601             try {
    602                 p.submit(new Callable() {
    603                         public Object call() { throw new ArithmeticException(); }})
    604                     .get();
    605                 shouldThrow();
    606             } catch (ExecutionException success) {
    607                 assertTrue(success.getCause() instanceof ArithmeticException);
    608             }
    609         }
    610     }
    611 
    612     /**
    613      * invokeAny(null) throws NullPointerException
    614      */
    615     public void testInvokeAny1() throws Throwable {
    616         ExecutorService e = new ForkJoinPool(1);
    617         try (PoolCleaner cleaner = cleaner(e)) {
    618             try {
    619                 e.invokeAny(null);
    620                 shouldThrow();
    621             } catch (NullPointerException success) {}
    622         }
    623     }
    624 
    625     /**
    626      * invokeAny(empty collection) throws IllegalArgumentException
    627      */
    628     public void testInvokeAny2() throws Throwable {
    629         ExecutorService e = new ForkJoinPool(1);
    630         try (PoolCleaner cleaner = cleaner(e)) {
    631             try {
    632                 e.invokeAny(new ArrayList<Callable<String>>());
    633                 shouldThrow();
    634             } catch (IllegalArgumentException success) {}
    635         }
    636     }
    637 
    638     /**
    639      * invokeAny(c) throws NullPointerException if c has a single null element
    640      */
    641     public void testInvokeAny3() throws Throwable {
    642         ExecutorService e = new ForkJoinPool(1);
    643         try (PoolCleaner cleaner = cleaner(e)) {
    644             List<Callable<String>> l = new ArrayList<Callable<String>>();
    645             l.add(null);
    646             try {
    647                 e.invokeAny(l);
    648                 shouldThrow();
    649             } catch (NullPointerException success) {}
    650         }
    651     }
    652 
    653     /**
    654      * invokeAny(c) throws NullPointerException if c has null elements
    655      */
    656     public void testInvokeAny4() throws Throwable {
    657         CountDownLatch latch = new CountDownLatch(1);
    658         ExecutorService e = new ForkJoinPool(1);
    659         try (PoolCleaner cleaner = cleaner(e)) {
    660             List<Callable<String>> l = new ArrayList<Callable<String>>();
    661             l.add(latchAwaitingStringTask(latch));
    662             l.add(null);
    663             try {
    664                 e.invokeAny(l);
    665                 shouldThrow();
    666             } catch (NullPointerException success) {}
    667             latch.countDown();
    668         }
    669     }
    670 
    671     /**
    672      * invokeAny(c) throws ExecutionException if no task in c completes
    673      */
    674     public void testInvokeAny5() throws Throwable {
    675         ExecutorService e = new ForkJoinPool(1);
    676         try (PoolCleaner cleaner = cleaner(e)) {
    677             List<Callable<String>> l = new ArrayList<Callable<String>>();
    678             l.add(new NPETask());
    679             try {
    680                 e.invokeAny(l);
    681                 shouldThrow();
    682             } catch (ExecutionException success) {
    683                 assertTrue(success.getCause() instanceof NullPointerException);
    684             }
    685         }
    686     }
    687 
    688     /**
    689      * invokeAny(c) returns result of some task in c if at least one completes
    690      */
    691     public void testInvokeAny6() throws Throwable {
    692         ExecutorService e = new ForkJoinPool(1);
    693         try (PoolCleaner cleaner = cleaner(e)) {
    694             List<Callable<String>> l = new ArrayList<Callable<String>>();
    695             l.add(new StringTask());
    696             l.add(new StringTask());
    697             String result = e.invokeAny(l);
    698             assertSame(TEST_STRING, result);
    699         }
    700     }
    701 
    702     /**
    703      * invokeAll(null) throws NullPointerException
    704      */
    705     public void testInvokeAll1() throws Throwable {
    706         ExecutorService e = new ForkJoinPool(1);
    707         try (PoolCleaner cleaner = cleaner(e)) {
    708             try {
    709                 e.invokeAll(null);
    710                 shouldThrow();
    711             } catch (NullPointerException success) {}
    712         }
    713     }
    714 
    715     /**
    716      * invokeAll(empty collection) returns empty collection
    717      */
    718     public void testInvokeAll2() throws InterruptedException {
    719         ExecutorService e = new ForkJoinPool(1);
    720         try (PoolCleaner cleaner = cleaner(e)) {
    721             List<Future<String>> r
    722                 = e.invokeAll(new ArrayList<Callable<String>>());
    723             assertTrue(r.isEmpty());
    724         }
    725     }
    726 
    727     /**
    728      * invokeAll(c) throws NullPointerException if c has null elements
    729      */
    730     public void testInvokeAll3() throws InterruptedException {
    731         ExecutorService e = new ForkJoinPool(1);
    732         try (PoolCleaner cleaner = cleaner(e)) {
    733             List<Callable<String>> l = new ArrayList<Callable<String>>();
    734             l.add(new StringTask());
    735             l.add(null);
    736             try {
    737                 e.invokeAll(l);
    738                 shouldThrow();
    739             } catch (NullPointerException success) {}
    740         }
    741     }
    742 
    743     /**
    744      * get of returned element of invokeAll(c) throws
    745      * ExecutionException on failed task
    746      */
    747     public void testInvokeAll4() throws Throwable {
    748         ExecutorService e = new ForkJoinPool(1);
    749         try (PoolCleaner cleaner = cleaner(e)) {
    750             List<Callable<String>> l = new ArrayList<Callable<String>>();
    751             l.add(new NPETask());
    752             List<Future<String>> futures = e.invokeAll(l);
    753             assertEquals(1, futures.size());
    754             try {
    755                 futures.get(0).get();
    756                 shouldThrow();
    757             } catch (ExecutionException success) {
    758                 assertTrue(success.getCause() instanceof NullPointerException);
    759             }
    760         }
    761     }
    762 
    763     /**
    764      * invokeAll(c) returns results of all completed tasks in c
    765      */
    766     public void testInvokeAll5() throws Throwable {
    767         ExecutorService e = new ForkJoinPool(1);
    768         try (PoolCleaner cleaner = cleaner(e)) {
    769             List<Callable<String>> l = new ArrayList<Callable<String>>();
    770             l.add(new StringTask());
    771             l.add(new StringTask());
    772             List<Future<String>> futures = e.invokeAll(l);
    773             assertEquals(2, futures.size());
    774             for (Future<String> future : futures)
    775                 assertSame(TEST_STRING, future.get());
    776         }
    777     }
    778 
    779     /**
    780      * timed invokeAny(null) throws NullPointerException
    781      */
    782     public void testTimedInvokeAny1() throws Throwable {
    783         ExecutorService e = new ForkJoinPool(1);
    784         try (PoolCleaner cleaner = cleaner(e)) {
    785             try {
    786                 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
    787                 shouldThrow();
    788             } catch (NullPointerException success) {}
    789         }
    790     }
    791 
    792     /**
    793      * timed invokeAny(null time unit) throws NullPointerException
    794      */
    795     public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
    796         ExecutorService e = new ForkJoinPool(1);
    797         try (PoolCleaner cleaner = cleaner(e)) {
    798             List<Callable<String>> l = new ArrayList<Callable<String>>();
    799             l.add(new StringTask());
    800             try {
    801                 e.invokeAny(l, MEDIUM_DELAY_MS, null);
    802                 shouldThrow();
    803             } catch (NullPointerException success) {}
    804         }
    805     }
    806 
    807     /**
    808      * timed invokeAny(empty collection) throws IllegalArgumentException
    809      */
    810     public void testTimedInvokeAny2() throws Throwable {
    811         ExecutorService e = new ForkJoinPool(1);
    812         try (PoolCleaner cleaner = cleaner(e)) {
    813             try {
    814                 e.invokeAny(new ArrayList<Callable<String>>(),
    815                             MEDIUM_DELAY_MS, MILLISECONDS);
    816                 shouldThrow();
    817             } catch (IllegalArgumentException success) {}
    818         }
    819     }
    820 
    821     /**
    822      * timed invokeAny(c) throws NullPointerException if c has null elements
    823      */
    824     public void testTimedInvokeAny3() throws Throwable {
    825         CountDownLatch latch = new CountDownLatch(1);
    826         ExecutorService e = new ForkJoinPool(1);
    827         try (PoolCleaner cleaner = cleaner(e)) {
    828             List<Callable<String>> l = new ArrayList<Callable<String>>();
    829             l.add(latchAwaitingStringTask(latch));
    830             l.add(null);
    831             try {
    832                 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
    833                 shouldThrow();
    834             } catch (NullPointerException success) {}
    835             latch.countDown();
    836         }
    837     }
    838 
    839     /**
    840      * timed invokeAny(c) throws ExecutionException if no task completes
    841      */
    842     public void testTimedInvokeAny4() throws Throwable {
    843         ExecutorService e = new ForkJoinPool(1);
    844         try (PoolCleaner cleaner = cleaner(e)) {
    845             long startTime = System.nanoTime();
    846             List<Callable<String>> l = new ArrayList<Callable<String>>();
    847             l.add(new NPETask());
    848             try {
    849                 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
    850                 shouldThrow();
    851             } catch (ExecutionException success) {
    852                 assertTrue(success.getCause() instanceof NullPointerException);
    853             }
    854             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    855         }
    856     }
    857 
    858     /**
    859      * timed invokeAny(c) returns result of some task in c
    860      */
    861     public void testTimedInvokeAny5() throws Throwable {
    862         ExecutorService e = new ForkJoinPool(1);
    863         try (PoolCleaner cleaner = cleaner(e)) {
    864             long startTime = System.nanoTime();
    865             List<Callable<String>> l = new ArrayList<Callable<String>>();
    866             l.add(new StringTask());
    867             l.add(new StringTask());
    868             String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
    869             assertSame(TEST_STRING, result);
    870             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    871         }
    872     }
    873 
    874     /**
    875      * timed invokeAll(null) throws NullPointerException
    876      */
    877     public void testTimedInvokeAll1() throws Throwable {
    878         ExecutorService e = new ForkJoinPool(1);
    879         try (PoolCleaner cleaner = cleaner(e)) {
    880             try {
    881                 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
    882                 shouldThrow();
    883             } catch (NullPointerException success) {}
    884         }
    885     }
    886 
    887     /**
    888      * timed invokeAll(null time unit) throws NullPointerException
    889      */
    890     public void testTimedInvokeAllNullTimeUnit() throws Throwable {
    891         ExecutorService e = new ForkJoinPool(1);
    892         try (PoolCleaner cleaner = cleaner(e)) {
    893             List<Callable<String>> l = new ArrayList<Callable<String>>();
    894             l.add(new StringTask());
    895             try {
    896                 e.invokeAll(l, MEDIUM_DELAY_MS, null);
    897                 shouldThrow();
    898             } catch (NullPointerException success) {}
    899         }
    900     }
    901 
    902     /**
    903      * timed invokeAll(empty collection) returns empty collection
    904      */
    905     public void testTimedInvokeAll2() throws InterruptedException {
    906         ExecutorService e = new ForkJoinPool(1);
    907         try (PoolCleaner cleaner = cleaner(e)) {
    908             List<Future<String>> r
    909                 = e.invokeAll(new ArrayList<Callable<String>>(),
    910                               MEDIUM_DELAY_MS, MILLISECONDS);
    911             assertTrue(r.isEmpty());
    912         }
    913     }
    914 
    915     /**
    916      * timed invokeAll(c) throws NullPointerException if c has null elements
    917      */
    918     public void testTimedInvokeAll3() throws InterruptedException {
    919         ExecutorService e = new ForkJoinPool(1);
    920         try (PoolCleaner cleaner = cleaner(e)) {
    921             List<Callable<String>> l = new ArrayList<Callable<String>>();
    922             l.add(new StringTask());
    923             l.add(null);
    924             try {
    925                 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
    926                 shouldThrow();
    927             } catch (NullPointerException success) {}
    928         }
    929     }
    930 
    931     /**
    932      * get of returned element of invokeAll(c) throws exception on failed task
    933      */
    934     public void testTimedInvokeAll4() throws Throwable {
    935         ExecutorService e = new ForkJoinPool(1);
    936         try (PoolCleaner cleaner = cleaner(e)) {
    937             List<Callable<String>> l = new ArrayList<Callable<String>>();
    938             l.add(new NPETask());
    939             List<Future<String>> futures
    940                 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
    941             assertEquals(1, futures.size());
    942             try {
    943                 futures.get(0).get();
    944                 shouldThrow();
    945             } catch (ExecutionException success) {
    946                 assertTrue(success.getCause() instanceof NullPointerException);
    947             }
    948         }
    949     }
    950 
    951     /**
    952      * timed invokeAll(c) returns results of all completed tasks in c
    953      */
    954     public void testTimedInvokeAll5() throws Throwable {
    955         ForkJoinPool e = new ForkJoinPool(1);
    956         try (PoolCleaner cleaner = cleaner(e)) {
    957             List<Callable<String>> l = new ArrayList<Callable<String>>();
    958             l.add(new StringTask());
    959             l.add(new StringTask());
    960             List<Future<String>> futures
    961                 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
    962             assertEquals(2, futures.size());
    963             for (Future<String> future : futures)
    964                 assertSame(TEST_STRING, future.get());
    965         }
    966     }
    967 
    968 }
    969