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;
uncaughtException(Thread t, Throwable e)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 {
FailingFJWSubclass(ForkJoinPool p)75         public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
onStart()76         protected void onStart() { super.onStart(); throw new MyError(); }
77     }
78 
79     static class FailingThreadFactory
80             implements ForkJoinPool.ForkJoinWorkerThreadFactory {
81         volatile int calls = 0;
newThread(ForkJoinPool p)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
SubFJP()89         SubFJP() { super(1); }
drainTasksTo(Collection<? super ForkJoinTask<?>> c)90         public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
91             return super.drainTasksTo(c);
92         }
pollSubmission()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;
ManagedLocker(ReentrantLock lock)101         ManagedLocker(ReentrantLock lock) { this.lock = lock; }
block()102         public boolean block() {
103             if (!hasLock)
104                 lock.lock();
105             return true;
106         }
isReleasable()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;
FibTask(int n)115         FibTask(int n) { number = n; }
compute()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> {
getRawResult()128         public final Void getRawResult() { return null; }
setRawResult(Void mustBeNull)129         protected final void setRawResult(Void mustBeNull) { }
exec()130         protected final boolean exec() { throw new Error(); }
FailingTask()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;
LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock)139         LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
140             number = n;
141             this.locker = locker;
142             this.lock = lock;
143         }
compute()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      */
testDefaultInitialState()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      */
testConstructor1()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      */
testConstructor2()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      */
testGetParallelism()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      */
testGetPoolSize()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      */
testAwaitTermination_timesOut()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      */
testSetUncaughtExceptionHandler()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      */
testIsQuiescent()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      */
testExecuteRunnable()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      */
testSubmitCallable()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      */
testSubmitRunnable()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      */
testSubmitRunnable2()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      */
testSubmitPrivilegedAction()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      */
testSubmitPrivilegedExceptionAction()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      */
testSubmitFailedPrivilegedExceptionAction()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      */
testExecuteNullRunnable()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      */
testSubmitNullCallable()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      */
testInterruptedSubmit()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      */
testSubmitEE()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      */
testInvokeAny1()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      */
testInvokeAny2()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      */
testInvokeAny3()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      */
testInvokeAny4()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      */
testInvokeAny5()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      */
testInvokeAny6()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      */
testInvokeAll1()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      */
testInvokeAll2()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      */
testInvokeAll3()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      */
testInvokeAll4()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      */
testInvokeAll5()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      */
testTimedInvokeAny1()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      */
testTimedInvokeAnyNullTimeUnit()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      */
testTimedInvokeAny2()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      */
testTimedInvokeAny3()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      */
testTimedInvokeAny4()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