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