1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea with assistance from members of JCP JSR-166
30  * Expert Group and released to the public domain, as explained at
31  * http://creativecommons.org/publicdomain/zero/1.0/
32  */
33 
34 import static java.util.concurrent.TimeUnit.MILLISECONDS;
35 
36 import java.util.Arrays;
37 import java.util.HashSet;
38 import java.util.concurrent.Callable;
39 import java.util.concurrent.CancellationException;
40 import java.util.concurrent.ExecutionException;
41 import java.util.concurrent.ForkJoinPool;
42 import java.util.concurrent.ForkJoinTask;
43 import java.util.concurrent.RecursiveAction;
44 import java.util.concurrent.TimeoutException;
45 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
46 
47 import junit.framework.Test;
48 import junit.framework.TestSuite;
49 
50 public class ForkJoinTaskTest extends JSR166TestCase {
51 
main(String[] args)52     public static void main(String[] args) {
53         main(suite(), args);
54     }
55 
suite()56     public static Test suite() {
57         return new TestSuite(ForkJoinTaskTest.class);
58     }
59 
60     // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
61     static final int mainPoolSize =
62         Math.max(2, Runtime.getRuntime().availableProcessors());
63 
mainPool()64     private static ForkJoinPool mainPool() {
65         return new ForkJoinPool(mainPoolSize);
66     }
67 
singletonPool()68     private static ForkJoinPool singletonPool() {
69         return new ForkJoinPool(1);
70     }
71 
asyncSingletonPool()72     private static ForkJoinPool asyncSingletonPool() {
73         return new ForkJoinPool(1,
74                                 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
75                                 null, true);
76     }
77 
testInvokeOnPool(ForkJoinPool pool, RecursiveAction a)78     private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
79         try (PoolCleaner cleaner = cleaner(pool)) {
80             assertFalse(a.isDone());
81             assertFalse(a.isCompletedNormally());
82             assertFalse(a.isCompletedAbnormally());
83             assertFalse(a.isCancelled());
84             assertNull(a.getException());
85             assertNull(a.getRawResult());
86 
87             assertNull(pool.invoke(a));
88 
89             assertTrue(a.isDone());
90             assertTrue(a.isCompletedNormally());
91             assertFalse(a.isCompletedAbnormally());
92             assertFalse(a.isCancelled());
93             assertNull(a.getException());
94             assertNull(a.getRawResult());
95         }
96     }
97 
checkNotDone(ForkJoinTask a)98     void checkNotDone(ForkJoinTask a) {
99         assertFalse(a.isDone());
100         assertFalse(a.isCompletedNormally());
101         assertFalse(a.isCompletedAbnormally());
102         assertFalse(a.isCancelled());
103         assertNull(a.getException());
104         assertNull(a.getRawResult());
105 
106         try {
107             a.get(randomExpiredTimeout(), randomTimeUnit());
108             shouldThrow();
109         } catch (TimeoutException success) {
110         } catch (Throwable fail) { threadUnexpectedException(fail); }
111     }
112 
checkCompletedNormally(ForkJoinTask<T> a)113     <T> void checkCompletedNormally(ForkJoinTask<T> a) {
114         checkCompletedNormally(a, null);
115     }
116 
checkCompletedNormally(ForkJoinTask<T> a, T expected)117     <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
118         assertTrue(a.isDone());
119         assertFalse(a.isCancelled());
120         assertTrue(a.isCompletedNormally());
121         assertFalse(a.isCompletedAbnormally());
122         assertNull(a.getException());
123         assertSame(expected, a.getRawResult());
124 
125         {
126             Thread.currentThread().interrupt();
127             long startTime = System.nanoTime();
128             assertSame(expected, a.join());
129             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
130             Thread.interrupted();
131         }
132 
133         {
134             Thread.currentThread().interrupt();
135             long startTime = System.nanoTime();
136             a.quietlyJoin();        // should be no-op
137             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
138             Thread.interrupted();
139         }
140 
141         assertFalse(a.cancel(false));
142         assertFalse(a.cancel(true));
143         try {
144             assertSame(expected, a.get());
145             assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
146         } catch (Throwable fail) { threadUnexpectedException(fail); }
147     }
148 
149     void checkCancelled(ForkJoinTask a) {
150         assertTrue(a.isDone());
151         assertTrue(a.isCancelled());
152         assertFalse(a.isCompletedNormally());
153         assertTrue(a.isCompletedAbnormally());
154         assertTrue(a.getException() instanceof CancellationException);
155         assertNull(a.getRawResult());
156         assertTrue(a.cancel(false));
157         assertTrue(a.cancel(true));
158 
159         try {
160             Thread.currentThread().interrupt();
161             a.join();
162             shouldThrow();
163         } catch (CancellationException success) {
164         } catch (Throwable fail) { threadUnexpectedException(fail); }
165         Thread.interrupted();
166 
167         {
168             long startTime = System.nanoTime();
169             a.quietlyJoin();        // should be no-op
170             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
171         }
172 
173         try {
174             a.get();
175             shouldThrow();
176         } catch (CancellationException success) {
177         } catch (Throwable fail) { threadUnexpectedException(fail); }
178 
179         try {
180             a.get(randomTimeout(), randomTimeUnit());
181             shouldThrow();
182         } catch (CancellationException success) {
183         } catch (Throwable fail) { threadUnexpectedException(fail); }
184     }
185 
186     void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
187         assertTrue(a.isDone());
188         assertFalse(a.isCancelled());
189         assertFalse(a.isCompletedNormally());
190         assertTrue(a.isCompletedAbnormally());
191         assertSame(t.getClass(), a.getException().getClass());
192         assertNull(a.getRawResult());
193         assertFalse(a.cancel(false));
194         assertFalse(a.cancel(true));
195 
196         try {
197             Thread.currentThread().interrupt();
198             a.join();
199             shouldThrow();
200         } catch (Throwable expected) {
201             assertSame(t.getClass(), expected.getClass());
202         }
203         Thread.interrupted();
204 
205         {
206             long startTime = System.nanoTime();
207             a.quietlyJoin();        // should be no-op
208             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
209         }
210 
211         try {
212             a.get();
213             shouldThrow();
214         } catch (ExecutionException success) {
215             assertSame(t.getClass(), success.getCause().getClass());
216         } catch (Throwable fail) { threadUnexpectedException(fail); }
217 
218         try {
219             a.get(randomTimeout(), randomTimeUnit());
220             shouldThrow();
221         } catch (ExecutionException success) {
222             assertSame(t.getClass(), success.getCause().getClass());
223         } catch (Throwable fail) { threadUnexpectedException(fail); }
224     }
225 
226     /*
227      * Testing coverage notes:
228      *
229      * To test extension methods and overrides, most tests use
230      * BinaryAsyncAction extension class that processes joins
231      * differently than supplied Recursive forms.
232      */
233 
234     public static final class FJException extends RuntimeException {
235         FJException() { super(); }
236     }
237 
238     abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
239         private volatile int controlState;
240 
241         static final AtomicIntegerFieldUpdater<BinaryAsyncAction> controlStateUpdater =
242             AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class,
243                                                  "controlState");
244 
245         private volatile BinaryAsyncAction parent;
246 
247         private volatile BinaryAsyncAction sibling;
248 
249         protected BinaryAsyncAction() {
250         }
251 
252         public final Void getRawResult() { return null; }
253         protected final void setRawResult(Void mustBeNull) { }
254 
255         public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
256             x.parent = y.parent = this;
257             x.sibling = y;
258             y.sibling = x;
259         }
260 
261         protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
262         }
263 
264         protected boolean onException() {
265             return true;
266         }
267 
268         public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
269             linkSubtasks(x, y);
270             y.fork();
271             x.fork();
272         }
273 
274         private void completeThis() {
275             super.complete(null);
276         }
277 
278         private void completeThisExceptionally(Throwable ex) {
279             super.completeExceptionally(ex);
280         }
281 
282         public boolean cancel(boolean mayInterruptIfRunning) {
283             if (super.cancel(mayInterruptIfRunning)) {
284                 completeExceptionally(new FJException());
285                 return true;
286             }
287             return false;
288         }
289 
290         public final void complete() {
291             BinaryAsyncAction a = this;
292             for (;;) {
293                 BinaryAsyncAction s = a.sibling;
294                 BinaryAsyncAction p = a.parent;
295                 a.sibling = null;
296                 a.parent = null;
297                 a.completeThis();
298                 if (p == null || p.compareAndSetControlState(0, 1))
299                     break;
300                 try {
301                     p.onComplete(a, s);
302                 } catch (Throwable rex) {
303                     p.completeExceptionally(rex);
304                     return;
305                 }
306                 a = p;
307             }
308         }
309 
310         public final void completeExceptionally(Throwable ex) {
311             for (BinaryAsyncAction a = this;;) {
312                 a.completeThisExceptionally(ex);
313                 BinaryAsyncAction s = a.sibling;
314                 if (s != null && !s.isDone())
315                     s.completeExceptionally(ex);
316                 if ((a = a.parent) == null)
317                     break;
318             }
319         }
320 
321         public final BinaryAsyncAction getParent() {
322             return parent;
323         }
324 
325         public BinaryAsyncAction getSibling() {
326             return sibling;
327         }
328 
329         public void reinitialize() {
330             parent = sibling = null;
331             super.reinitialize();
332         }
333 
334         protected final int getControlState() {
335             return controlState;
336         }
337 
338         protected final boolean compareAndSetControlState(int expect,
339                                                           int update) {
340             return controlStateUpdater.compareAndSet(this, expect, update);
341         }
342 
343         protected final void setControlState(int value) {
344             controlState = value;
345         }
346 
347         protected final void incrementControlState() {
348             controlStateUpdater.incrementAndGet(this);
349         }
350 
351         protected final void decrementControlState() {
352             controlStateUpdater.decrementAndGet(this);
353         }
354 
355     }
356 
357     static final class AsyncFib extends BinaryAsyncAction {
358         int number;
359         public AsyncFib(int n) {
360             this.number = n;
361         }
362 
363         public final boolean exec() {
364             AsyncFib f = this;
365             int n = f.number;
366             while (n > 1) {
367                 AsyncFib p = f;
368                 AsyncFib r = new AsyncFib(n - 2);
369                 f = new AsyncFib(--n);
370                 p.linkSubtasks(r, f);
371                 r.fork();
372             }
373             f.complete();
374             return false;
375         }
376 
377         protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
378             number = ((AsyncFib)x).number + ((AsyncFib)y).number;
379         }
380     }
381 
382     static final class FailingAsyncFib extends BinaryAsyncAction {
383         int number;
384         public FailingAsyncFib(int n) {
385             this.number = n;
386         }
387 
388         public final boolean exec() {
389             FailingAsyncFib f = this;
390             int n = f.number;
391             while (n > 1) {
392                 FailingAsyncFib p = f;
393                 FailingAsyncFib r = new FailingAsyncFib(n - 2);
394                 f = new FailingAsyncFib(--n);
395                 p.linkSubtasks(r, f);
396                 r.fork();
397             }
398             f.complete();
399             return false;
400         }
401 
402         protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
403             completeExceptionally(new FJException());
404         }
405     }
406 
407     /**
408      * invoke returns when task completes normally.
409      * isCompletedAbnormally and isCancelled return false for normally
410      * completed tasks; getRawResult returns null.
411      */
412     public void testInvoke() {
413         RecursiveAction a = new CheckedRecursiveAction() {
414             protected void realCompute() {
415                 AsyncFib f = new AsyncFib(8);
416                 assertNull(f.invoke());
417                 assertEquals(21, f.number);
418                 checkCompletedNormally(f);
419             }};
420         testInvokeOnPool(mainPool(), a);
421     }
422 
423     /**
424      * quietlyInvoke task returns when task completes normally.
425      * isCompletedAbnormally and isCancelled return false for normally
426      * completed tasks
427      */
428     public void testQuietlyInvoke() {
429         RecursiveAction a = new CheckedRecursiveAction() {
430             protected void realCompute() {
431                 AsyncFib f = new AsyncFib(8);
432                 f.quietlyInvoke();
433                 assertEquals(21, f.number);
434                 checkCompletedNormally(f);
435             }};
436         testInvokeOnPool(mainPool(), a);
437     }
438 
439     /**
440      * join of a forked task returns when task completes
441      */
442     public void testForkJoin() {
443         RecursiveAction a = new CheckedRecursiveAction() {
444             protected void realCompute() {
445                 AsyncFib f = new AsyncFib(8);
446                 assertSame(f, f.fork());
447                 assertNull(f.join());
448                 assertEquals(21, f.number);
449                 checkCompletedNormally(f);
450             }};
451         testInvokeOnPool(mainPool(), a);
452     }
453 
454     /**
455      * get of a forked task returns when task completes
456      */
457     public void testForkGet() {
458         RecursiveAction a = new CheckedRecursiveAction() {
459             protected void realCompute() throws Exception {
460                 AsyncFib f = new AsyncFib(8);
461                 assertSame(f, f.fork());
462                 assertNull(f.get());
463                 assertEquals(21, f.number);
464                 checkCompletedNormally(f);
465             }};
466         testInvokeOnPool(mainPool(), a);
467     }
468 
469     /**
470      * timed get of a forked task returns when task completes
471      */
472     public void testForkTimedGet() {
473         RecursiveAction a = new CheckedRecursiveAction() {
474             protected void realCompute() throws Exception {
475                 AsyncFib f = new AsyncFib(8);
476                 assertSame(f, f.fork());
477                 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
478                 assertEquals(21, f.number);
479                 checkCompletedNormally(f);
480             }};
481         testInvokeOnPool(mainPool(), a);
482     }
483 
484     /**
485      * timed get with null time unit throws NPE
486      */
487     public void testForkTimedGetNPE() {
488         RecursiveAction a = new CheckedRecursiveAction() {
489             protected void realCompute() throws Exception {
490                 AsyncFib f = new AsyncFib(8);
491                 assertSame(f, f.fork());
492                 try {
493                     f.get(randomTimeout(), null);
494                     shouldThrow();
495                 } catch (NullPointerException success) {}
496             }};
497         testInvokeOnPool(mainPool(), a);
498     }
499 
500     /**
501      * quietlyJoin of a forked task returns when task completes
502      */
503     public void testForkQuietlyJoin() {
504         RecursiveAction a = new CheckedRecursiveAction() {
505             protected void realCompute() {
506                 AsyncFib f = new AsyncFib(8);
507                 assertSame(f, f.fork());
508                 f.quietlyJoin();
509                 assertEquals(21, f.number);
510                 checkCompletedNormally(f);
511             }};
512         testInvokeOnPool(mainPool(), a);
513     }
514 
515     /**
516      * helpQuiesce returns when tasks are complete.
517      * getQueuedTaskCount returns 0 when quiescent
518      */
519     public void testForkHelpQuiesce() {
520         RecursiveAction a = new CheckedRecursiveAction() {
521             protected void realCompute() {
522                 AsyncFib f = new AsyncFib(8);
523                 assertSame(f, f.fork());
524                 helpQuiesce();
525                 assertEquals(21, f.number);
526                 assertEquals(0, getQueuedTaskCount());
527                 checkCompletedNormally(f);
528             }};
529         testInvokeOnPool(mainPool(), a);
530     }
531 
532     /**
533      * invoke task throws exception when task completes abnormally
534      */
535     public void testAbnormalInvoke() {
536         RecursiveAction a = new CheckedRecursiveAction() {
537             protected void realCompute() {
538                 FailingAsyncFib f = new FailingAsyncFib(8);
539                 try {
540                     f.invoke();
541                     shouldThrow();
542                 } catch (FJException success) {
543                     checkCompletedAbnormally(f, success);
544                 }
545             }};
546         testInvokeOnPool(mainPool(), a);
547     }
548 
549     /**
550      * quietlyInvoke task returns when task completes abnormally
551      */
552     public void testAbnormalQuietlyInvoke() {
553         RecursiveAction a = new CheckedRecursiveAction() {
554             protected void realCompute() {
555                 FailingAsyncFib f = new FailingAsyncFib(8);
556                 f.quietlyInvoke();
557                 assertTrue(f.getException() instanceof FJException);
558                 checkCompletedAbnormally(f, f.getException());
559             }};
560         testInvokeOnPool(mainPool(), a);
561     }
562 
563     /**
564      * join of a forked task throws exception when task completes abnormally
565      */
566     public void testAbnormalForkJoin() {
567         RecursiveAction a = new CheckedRecursiveAction() {
568             protected void realCompute() {
569                 FailingAsyncFib f = new FailingAsyncFib(8);
570                 assertSame(f, f.fork());
571                 try {
572                     f.join();
573                     shouldThrow();
574                 } catch (FJException success) {
575                     checkCompletedAbnormally(f, success);
576                 }
577             }};
578         testInvokeOnPool(mainPool(), a);
579     }
580 
581     /**
582      * get of a forked task throws exception when task completes abnormally
583      */
584     public void testAbnormalForkGet() {
585         RecursiveAction a = new CheckedRecursiveAction() {
586             protected void realCompute() throws Exception {
587                 FailingAsyncFib f = new FailingAsyncFib(8);
588                 assertSame(f, f.fork());
589                 try {
590                     f.get();
591                     shouldThrow();
592                 } catch (ExecutionException success) {
593                     Throwable cause = success.getCause();
594                     assertTrue(cause instanceof FJException);
595                     checkCompletedAbnormally(f, cause);
596                 }
597             }};
598         testInvokeOnPool(mainPool(), a);
599     }
600 
601     /**
602      * timed get of a forked task throws exception when task completes abnormally
603      */
604     public void testAbnormalForkTimedGet() {
605         RecursiveAction a = new CheckedRecursiveAction() {
606             protected void realCompute() throws Exception {
607                 FailingAsyncFib f = new FailingAsyncFib(8);
608                 assertSame(f, f.fork());
609                 try {
610                     f.get(LONG_DELAY_MS, MILLISECONDS);
611                     shouldThrow();
612                 } catch (ExecutionException success) {
613                     Throwable cause = success.getCause();
614                     assertTrue(cause instanceof FJException);
615                     checkCompletedAbnormally(f, cause);
616                 }
617             }};
618         testInvokeOnPool(mainPool(), a);
619     }
620 
621     /**
622      * quietlyJoin of a forked task returns when task completes abnormally
623      */
624     public void testAbnormalForkQuietlyJoin() {
625         RecursiveAction a = new CheckedRecursiveAction() {
626             protected void realCompute() {
627                 FailingAsyncFib f = new FailingAsyncFib(8);
628                 assertSame(f, f.fork());
629                 f.quietlyJoin();
630                 assertTrue(f.getException() instanceof FJException);
631                 checkCompletedAbnormally(f, f.getException());
632             }};
633         testInvokeOnPool(mainPool(), a);
634     }
635 
636     /**
637      * invoke task throws exception when task cancelled
638      */
639     public void testCancelledInvoke() {
640         RecursiveAction a = new CheckedRecursiveAction() {
641             protected void realCompute() {
642                 AsyncFib f = new AsyncFib(8);
643                 assertTrue(f.cancel(true));
644                 try {
645                     f.invoke();
646                     shouldThrow();
647                 } catch (CancellationException success) {
648                     checkCancelled(f);
649                 }
650             }};
651         testInvokeOnPool(mainPool(), a);
652     }
653 
654     /**
655      * join of a forked task throws exception when task cancelled
656      */
657     public void testCancelledForkJoin() {
658         RecursiveAction a = new CheckedRecursiveAction() {
659             protected void realCompute() {
660                 AsyncFib f = new AsyncFib(8);
661                 assertTrue(f.cancel(true));
662                 assertSame(f, f.fork());
663                 try {
664                     f.join();
665                     shouldThrow();
666                 } catch (CancellationException success) {
667                     checkCancelled(f);
668                 }
669             }};
670         testInvokeOnPool(mainPool(), a);
671     }
672 
673     /**
674      * get of a forked task throws exception when task cancelled
675      */
676     public void testCancelledForkGet() {
677         RecursiveAction a = new CheckedRecursiveAction() {
678             protected void realCompute() throws Exception {
679                 AsyncFib f = new AsyncFib(8);
680                 assertTrue(f.cancel(true));
681                 assertSame(f, f.fork());
682                 try {
683                     f.get();
684                     shouldThrow();
685                 } catch (CancellationException success) {
686                     checkCancelled(f);
687                 }
688             }};
689         testInvokeOnPool(mainPool(), a);
690     }
691 
692     /**
693      * timed get of a forked task throws exception when task cancelled
694      */
695     public void testCancelledForkTimedGet() throws Exception {
696         RecursiveAction a = new CheckedRecursiveAction() {
697             protected void realCompute() throws Exception {
698                 AsyncFib f = new AsyncFib(8);
699                 assertTrue(f.cancel(true));
700                 assertSame(f, f.fork());
701                 try {
702                     f.get(LONG_DELAY_MS, MILLISECONDS);
703                     shouldThrow();
704                 } catch (CancellationException success) {
705                     checkCancelled(f);
706                 }
707             }};
708         testInvokeOnPool(mainPool(), a);
709     }
710 
711     /**
712      * quietlyJoin of a forked task returns when task cancelled
713      */
714     public void testCancelledForkQuietlyJoin() {
715         RecursiveAction a = new CheckedRecursiveAction() {
716             protected void realCompute() {
717                 AsyncFib f = new AsyncFib(8);
718                 assertTrue(f.cancel(true));
719                 assertSame(f, f.fork());
720                 f.quietlyJoin();
721                 checkCancelled(f);
722             }};
723         testInvokeOnPool(mainPool(), a);
724     }
725 
726     /**
727      * getPool of executing task returns its pool
728      */
729     public void testGetPool() {
730         final ForkJoinPool mainPool = mainPool();
731         RecursiveAction a = new CheckedRecursiveAction() {
732             protected void realCompute() {
733                 assertSame(mainPool, getPool());
734             }};
735         testInvokeOnPool(mainPool, a);
736     }
737 
738     /**
739      * getPool of non-FJ task returns null
740      */
741     public void testGetPool2() {
742         RecursiveAction a = new CheckedRecursiveAction() {
743             protected void realCompute() {
744                 assertNull(getPool());
745             }};
746         assertNull(a.invoke());
747     }
748 
749     /**
750      * inForkJoinPool of executing task returns true
751      */
752     public void testInForkJoinPool() {
753         RecursiveAction a = new CheckedRecursiveAction() {
754             protected void realCompute() {
755                 assertTrue(inForkJoinPool());
756             }};
757         testInvokeOnPool(mainPool(), a);
758     }
759 
760     /**
761      * inForkJoinPool of non-FJ task returns false
762      */
763     public void testInForkJoinPool2() {
764         RecursiveAction a = new CheckedRecursiveAction() {
765             protected void realCompute() {
766                 assertFalse(inForkJoinPool());
767             }};
768         assertNull(a.invoke());
769     }
770 
771     /**
772      * setRawResult(null) succeeds
773      */
774     public void testSetRawResult() {
775         RecursiveAction a = new CheckedRecursiveAction() {
776             protected void realCompute() {
777                 setRawResult(null);
778                 assertNull(getRawResult());
779             }};
780         assertNull(a.invoke());
781     }
782 
783     /**
784      * invoke task throws exception after invoking completeExceptionally
785      */
786     public void testCompleteExceptionally() {
787         RecursiveAction a = new CheckedRecursiveAction() {
788             protected void realCompute() {
789                 AsyncFib f = new AsyncFib(8);
790                 f.completeExceptionally(new FJException());
791                 try {
792                     f.invoke();
793                     shouldThrow();
794                 } catch (FJException success) {
795                     checkCompletedAbnormally(f, success);
796                 }
797             }};
798         testInvokeOnPool(mainPool(), a);
799     }
800 
801     /**
802      * completeExceptionally(null) surprisingly has the same effect as
803      * completeExceptionally(new RuntimeException())
804      */
805     public void testCompleteExceptionally_null() {
806         RecursiveAction a = new CheckedRecursiveAction() {
807             protected void realCompute() {
808                 AsyncFib f = new AsyncFib(8);
809                 f.completeExceptionally(null);
810                 try {
811                     f.invoke();
812                     shouldThrow();
813                 } catch (RuntimeException success) {
814                     assertSame(success.getClass(), RuntimeException.class);
815                     assertNull(success.getCause());
816                     checkCompletedAbnormally(f, success);
817                 }
818             }};
819         testInvokeOnPool(mainPool(), a);
820     }
821 
822     /**
823      * invokeAll(t1, t2) invokes all task arguments
824      */
825     public void testInvokeAll2() {
826         RecursiveAction a = new CheckedRecursiveAction() {
827             protected void realCompute() {
828                 AsyncFib f = new AsyncFib(8);
829                 AsyncFib g = new AsyncFib(9);
830                 invokeAll(f, g);
831                 assertEquals(21, f.number);
832                 assertEquals(34, g.number);
833                 checkCompletedNormally(f);
834                 checkCompletedNormally(g);
835             }};
836         testInvokeOnPool(mainPool(), a);
837     }
838 
839     /**
840      * invokeAll(tasks) with 1 argument invokes task
841      */
842     public void testInvokeAll1() {
843         RecursiveAction a = new CheckedRecursiveAction() {
844             protected void realCompute() {
845                 AsyncFib f = new AsyncFib(8);
846                 invokeAll(f);
847                 checkCompletedNormally(f);
848                 assertEquals(21, f.number);
849             }};
850         testInvokeOnPool(mainPool(), a);
851     }
852 
853     /**
854      * invokeAll(tasks) with > 2 argument invokes tasks
855      */
856     public void testInvokeAll3() {
857         RecursiveAction a = new CheckedRecursiveAction() {
858             protected void realCompute() {
859                 AsyncFib f = new AsyncFib(8);
860                 AsyncFib g = new AsyncFib(9);
861                 AsyncFib h = new AsyncFib(7);
862                 invokeAll(f, g, h);
863                 assertEquals(21, f.number);
864                 assertEquals(34, g.number);
865                 assertEquals(13, h.number);
866                 checkCompletedNormally(f);
867                 checkCompletedNormally(g);
868                 checkCompletedNormally(h);
869             }};
870         testInvokeOnPool(mainPool(), a);
871     }
872 
873     /**
874      * invokeAll(collection) invokes all tasks in the collection
875      */
876     public void testInvokeAllCollection() {
877         RecursiveAction a = new CheckedRecursiveAction() {
878             protected void realCompute() {
879                 AsyncFib f = new AsyncFib(8);
880                 AsyncFib g = new AsyncFib(9);
881                 AsyncFib h = new AsyncFib(7);
882                 HashSet set = new HashSet();
883                 set.add(f);
884                 set.add(g);
885                 set.add(h);
886                 invokeAll(set);
887                 assertEquals(21, f.number);
888                 assertEquals(34, g.number);
889                 assertEquals(13, h.number);
890                 checkCompletedNormally(f);
891                 checkCompletedNormally(g);
892                 checkCompletedNormally(h);
893             }};
894         testInvokeOnPool(mainPool(), a);
895     }
896 
897     /**
898      * invokeAll(tasks) with any null task throws NPE
899      */
900     public void testInvokeAllNPE() {
901         RecursiveAction a = new CheckedRecursiveAction() {
902             protected void realCompute() {
903                 AsyncFib f = new AsyncFib(8);
904                 AsyncFib g = new AsyncFib(9);
905                 AsyncFib h = null;
906                 try {
907                     invokeAll(f, g, h);
908                     shouldThrow();
909                 } catch (NullPointerException success) {}
910             }};
911         testInvokeOnPool(mainPool(), a);
912     }
913 
914     /**
915      * invokeAll(t1, t2) throw exception if any task does
916      */
917     public void testAbnormalInvokeAll2() {
918         RecursiveAction a = new CheckedRecursiveAction() {
919             protected void realCompute() {
920                 AsyncFib f = new AsyncFib(8);
921                 FailingAsyncFib g = new FailingAsyncFib(9);
922                 ForkJoinTask[] tasks = { f, g };
923                 shuffle(tasks);
924                 try {
925                     invokeAll(tasks);
926                     shouldThrow();
927                 } catch (FJException success) {
928                     checkCompletedAbnormally(g, success);
929                 }
930             }};
931         testInvokeOnPool(mainPool(), a);
932     }
933 
934     /**
935      * invokeAll(tasks) with 1 argument throws exception if task does
936      */
937     public void testAbnormalInvokeAll1() {
938         RecursiveAction a = new CheckedRecursiveAction() {
939             protected void realCompute() {
940                 FailingAsyncFib g = new FailingAsyncFib(9);
941                 try {
942                     invokeAll(g);
943                     shouldThrow();
944                 } catch (FJException success) {
945                     checkCompletedAbnormally(g, success);
946                 }
947             }};
948         testInvokeOnPool(mainPool(), a);
949     }
950 
951     /**
952      * invokeAll(tasks) with > 2 argument throws exception if any task does
953      */
954     public void testAbnormalInvokeAll3() {
955         RecursiveAction a = new CheckedRecursiveAction() {
956             protected void realCompute() {
957                 AsyncFib f = new AsyncFib(8);
958                 FailingAsyncFib g = new FailingAsyncFib(9);
959                 AsyncFib h = new AsyncFib(7);
960                 ForkJoinTask[] tasks = { f, g, h };
961                 shuffle(tasks);
962                 try {
963                     invokeAll(tasks);
964                     shouldThrow();
965                 } catch (FJException success) {
966                     checkCompletedAbnormally(g, success);
967                 }
968             }};
969         testInvokeOnPool(mainPool(), a);
970     }
971 
972     /**
973      * invokeAll(collection) throws exception if any task does
974      */
975     public void testAbnormalInvokeAllCollection() {
976         RecursiveAction a = new CheckedRecursiveAction() {
977             protected void realCompute() {
978                 FailingAsyncFib f = new FailingAsyncFib(8);
979                 AsyncFib g = new AsyncFib(9);
980                 AsyncFib h = new AsyncFib(7);
981                 ForkJoinTask[] tasks = { f, g, h };
982                 shuffle(tasks);
983                 try {
984                     invokeAll(Arrays.asList(tasks));
985                     shouldThrow();
986                 } catch (FJException success) {
987                     checkCompletedAbnormally(f, success);
988                 }
989             }};
990         testInvokeOnPool(mainPool(), a);
991     }
992 
993     /**
994      * tryUnfork returns true for most recent unexecuted task,
995      * and suppresses execution
996      */
997     public void testTryUnfork() {
998         RecursiveAction a = new CheckedRecursiveAction() {
999             protected void realCompute() {
1000                 AsyncFib g = new AsyncFib(9);
1001                 assertSame(g, g.fork());
1002                 AsyncFib f = new AsyncFib(8);
1003                 assertSame(f, f.fork());
1004                 assertTrue(f.tryUnfork());
1005                 helpQuiesce();
1006                 checkNotDone(f);
1007                 checkCompletedNormally(g);
1008             }};
1009         testInvokeOnPool(singletonPool(), a);
1010     }
1011 
1012     /**
1013      * getSurplusQueuedTaskCount returns > 0 when
1014      * there are more tasks than threads
1015      */
1016     public void testGetSurplusQueuedTaskCount() {
1017         RecursiveAction a = new CheckedRecursiveAction() {
1018             protected void realCompute() {
1019                 AsyncFib h = new AsyncFib(7);
1020                 assertSame(h, h.fork());
1021                 AsyncFib g = new AsyncFib(9);
1022                 assertSame(g, g.fork());
1023                 AsyncFib f = new AsyncFib(8);
1024                 assertSame(f, f.fork());
1025                 assertTrue(getSurplusQueuedTaskCount() > 0);
1026                 helpQuiesce();
1027                 assertEquals(0, getSurplusQueuedTaskCount());
1028                 checkCompletedNormally(f);
1029                 checkCompletedNormally(g);
1030                 checkCompletedNormally(h);
1031             }};
1032         testInvokeOnPool(singletonPool(), a);
1033     }
1034 
1035     /**
1036      * peekNextLocalTask returns most recent unexecuted task.
1037      */
1038     public void testPeekNextLocalTask() {
1039         RecursiveAction a = new CheckedRecursiveAction() {
1040             protected void realCompute() {
1041                 AsyncFib g = new AsyncFib(9);
1042                 assertSame(g, g.fork());
1043                 AsyncFib f = new AsyncFib(8);
1044                 assertSame(f, f.fork());
1045                 assertSame(f, peekNextLocalTask());
1046                 assertNull(f.join());
1047                 checkCompletedNormally(f);
1048                 helpQuiesce();
1049                 checkCompletedNormally(g);
1050             }};
1051         testInvokeOnPool(singletonPool(), a);
1052     }
1053 
1054     /**
1055      * pollNextLocalTask returns most recent unexecuted task without
1056      * executing it
1057      */
1058     public void testPollNextLocalTask() {
1059         RecursiveAction a = new CheckedRecursiveAction() {
1060             protected void realCompute() {
1061                 AsyncFib g = new AsyncFib(9);
1062                 assertSame(g, g.fork());
1063                 AsyncFib f = new AsyncFib(8);
1064                 assertSame(f, f.fork());
1065                 assertSame(f, pollNextLocalTask());
1066                 helpQuiesce();
1067                 checkNotDone(f);
1068                 assertEquals(34, g.number);
1069                 checkCompletedNormally(g);
1070             }};
1071         testInvokeOnPool(singletonPool(), a);
1072     }
1073 
1074     /**
1075      * pollTask returns an unexecuted task without executing it
1076      */
1077     public void testPollTask() {
1078         RecursiveAction a = new CheckedRecursiveAction() {
1079             protected void realCompute() {
1080                 AsyncFib g = new AsyncFib(9);
1081                 assertSame(g, g.fork());
1082                 AsyncFib f = new AsyncFib(8);
1083                 assertSame(f, f.fork());
1084                 assertSame(f, pollTask());
1085                 helpQuiesce();
1086                 checkNotDone(f);
1087                 checkCompletedNormally(g);
1088             }};
1089         testInvokeOnPool(singletonPool(), a);
1090     }
1091 
1092     /**
1093      * peekNextLocalTask returns least recent unexecuted task in async mode
1094      */
1095     public void testPeekNextLocalTaskAsync() {
1096         RecursiveAction a = new CheckedRecursiveAction() {
1097             protected void realCompute() {
1098                 AsyncFib g = new AsyncFib(9);
1099                 assertSame(g, g.fork());
1100                 AsyncFib f = new AsyncFib(8);
1101                 assertSame(f, f.fork());
1102                 assertSame(g, peekNextLocalTask());
1103                 assertNull(f.join());
1104                 helpQuiesce();
1105                 checkCompletedNormally(f);
1106                 assertEquals(34, g.number);
1107                 checkCompletedNormally(g);
1108             }};
1109         testInvokeOnPool(asyncSingletonPool(), a);
1110     }
1111 
1112     /**
1113      * pollNextLocalTask returns least recent unexecuted task without
1114      * executing it, in async mode
1115      */
1116     public void testPollNextLocalTaskAsync() {
1117         RecursiveAction a = new CheckedRecursiveAction() {
1118             protected void realCompute() {
1119                 AsyncFib g = new AsyncFib(9);
1120                 assertSame(g, g.fork());
1121                 AsyncFib f = new AsyncFib(8);
1122                 assertSame(f, f.fork());
1123                 assertSame(g, pollNextLocalTask());
1124                 helpQuiesce();
1125                 assertEquals(21, f.number);
1126                 checkCompletedNormally(f);
1127                 checkNotDone(g);
1128             }};
1129         testInvokeOnPool(asyncSingletonPool(), a);
1130     }
1131 
1132     /**
1133      * pollTask returns an unexecuted task without executing it, in
1134      * async mode
1135      */
1136     public void testPollTaskAsync() {
1137         RecursiveAction a = new CheckedRecursiveAction() {
1138             protected void realCompute() {
1139                 AsyncFib g = new AsyncFib(9);
1140                 assertSame(g, g.fork());
1141                 AsyncFib f = new AsyncFib(8);
1142                 assertSame(f, f.fork());
1143                 assertSame(g, pollTask());
1144                 helpQuiesce();
1145                 assertEquals(21, f.number);
1146                 checkCompletedNormally(f);
1147                 checkNotDone(g);
1148             }};
1149         testInvokeOnPool(asyncSingletonPool(), a);
1150     }
1151 
1152     // versions for singleton pools
1153 
1154     /**
1155      * invoke returns when task completes normally.
1156      * isCompletedAbnormally and isCancelled return false for normally
1157      * completed tasks; getRawResult returns null.
1158      */
1159     public void testInvokeSingleton() {
1160         RecursiveAction a = new CheckedRecursiveAction() {
1161             protected void realCompute() {
1162                 AsyncFib f = new AsyncFib(8);
1163                 assertNull(f.invoke());
1164                 assertEquals(21, f.number);
1165                 checkCompletedNormally(f);
1166             }};
1167         testInvokeOnPool(singletonPool(), a);
1168     }
1169 
1170     /**
1171      * quietlyInvoke task returns when task completes normally.
1172      * isCompletedAbnormally and isCancelled return false for normally
1173      * completed tasks
1174      */
1175     public void testQuietlyInvokeSingleton() {
1176         RecursiveAction a = new CheckedRecursiveAction() {
1177             protected void realCompute() {
1178                 AsyncFib f = new AsyncFib(8);
1179                 f.quietlyInvoke();
1180                 assertEquals(21, f.number);
1181                 checkCompletedNormally(f);
1182             }};
1183         testInvokeOnPool(singletonPool(), a);
1184     }
1185 
1186     /**
1187      * join of a forked task returns when task completes
1188      */
1189     public void testForkJoinSingleton() {
1190         RecursiveAction a = new CheckedRecursiveAction() {
1191             protected void realCompute() {
1192                 AsyncFib f = new AsyncFib(8);
1193                 assertSame(f, f.fork());
1194                 assertNull(f.join());
1195                 assertEquals(21, f.number);
1196                 checkCompletedNormally(f);
1197             }};
1198         testInvokeOnPool(singletonPool(), a);
1199     }
1200 
1201     /**
1202      * get of a forked task returns when task completes
1203      */
1204     public void testForkGetSingleton() {
1205         RecursiveAction a = new CheckedRecursiveAction() {
1206             protected void realCompute() throws Exception {
1207                 AsyncFib f = new AsyncFib(8);
1208                 assertSame(f, f.fork());
1209                 assertNull(f.get());
1210                 assertEquals(21, f.number);
1211                 checkCompletedNormally(f);
1212             }};
1213         testInvokeOnPool(singletonPool(), a);
1214     }
1215 
1216     /**
1217      * timed get of a forked task returns when task completes
1218      */
1219     public void testForkTimedGetSingleton() {
1220         RecursiveAction a = new CheckedRecursiveAction() {
1221             protected void realCompute() throws Exception {
1222                 AsyncFib f = new AsyncFib(8);
1223                 assertSame(f, f.fork());
1224                 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
1225                 assertEquals(21, f.number);
1226                 checkCompletedNormally(f);
1227             }};
1228         testInvokeOnPool(singletonPool(), a);
1229     }
1230 
1231     /**
1232      * timed get with null time unit throws NPE
1233      */
1234     public void testForkTimedGetNPESingleton() {
1235         RecursiveAction a = new CheckedRecursiveAction() {
1236             protected void realCompute() throws Exception {
1237                 AsyncFib f = new AsyncFib(8);
1238                 assertSame(f, f.fork());
1239                 try {
1240                     f.get(randomTimeout(), null);
1241                     shouldThrow();
1242                 } catch (NullPointerException success) {}
1243             }};
1244         testInvokeOnPool(singletonPool(), a);
1245     }
1246 
1247     /**
1248      * quietlyJoin of a forked task returns when task completes
1249      */
1250     public void testForkQuietlyJoinSingleton() {
1251         RecursiveAction a = new CheckedRecursiveAction() {
1252             protected void realCompute() {
1253                 AsyncFib f = new AsyncFib(8);
1254                 assertSame(f, f.fork());
1255                 f.quietlyJoin();
1256                 assertEquals(21, f.number);
1257                 checkCompletedNormally(f);
1258             }};
1259         testInvokeOnPool(singletonPool(), a);
1260     }
1261 
1262     /**
1263      * helpQuiesce returns when tasks are complete.
1264      * getQueuedTaskCount returns 0 when quiescent
1265      */
1266     public void testForkHelpQuiesceSingleton() {
1267         RecursiveAction a = new CheckedRecursiveAction() {
1268             protected void realCompute() {
1269                 AsyncFib f = new AsyncFib(8);
1270                 assertSame(f, f.fork());
1271                 helpQuiesce();
1272                 assertEquals(0, getQueuedTaskCount());
1273                 assertEquals(21, f.number);
1274                 checkCompletedNormally(f);
1275             }};
1276         testInvokeOnPool(singletonPool(), a);
1277     }
1278 
1279     /**
1280      * invoke task throws exception when task completes abnormally
1281      */
1282     public void testAbnormalInvokeSingleton() {
1283         RecursiveAction a = new CheckedRecursiveAction() {
1284             protected void realCompute() {
1285                 FailingAsyncFib f = new FailingAsyncFib(8);
1286                 try {
1287                     f.invoke();
1288                     shouldThrow();
1289                 } catch (FJException success) {
1290                     checkCompletedAbnormally(f, success);
1291                 }
1292             }};
1293         testInvokeOnPool(singletonPool(), a);
1294     }
1295 
1296     /**
1297      * quietlyInvoke task returns when task completes abnormally
1298      */
1299     public void testAbnormalQuietlyInvokeSingleton() {
1300         RecursiveAction a = new CheckedRecursiveAction() {
1301             protected void realCompute() {
1302                 FailingAsyncFib f = new FailingAsyncFib(8);
1303                 f.quietlyInvoke();
1304                 assertTrue(f.getException() instanceof FJException);
1305                 checkCompletedAbnormally(f, f.getException());
1306             }};
1307         testInvokeOnPool(singletonPool(), a);
1308     }
1309 
1310     /**
1311      * join of a forked task throws exception when task completes abnormally
1312      */
1313     public void testAbnormalForkJoinSingleton() {
1314         RecursiveAction a = new CheckedRecursiveAction() {
1315             protected void realCompute() {
1316                 FailingAsyncFib f = new FailingAsyncFib(8);
1317                 assertSame(f, f.fork());
1318                 try {
1319                     f.join();
1320                     shouldThrow();
1321                 } catch (FJException success) {
1322                     checkCompletedAbnormally(f, success);
1323                 }
1324             }};
1325         testInvokeOnPool(singletonPool(), a);
1326     }
1327 
1328     /**
1329      * get of a forked task throws exception when task completes abnormally
1330      */
1331     public void testAbnormalForkGetSingleton() {
1332         RecursiveAction a = new CheckedRecursiveAction() {
1333             protected void realCompute() throws Exception {
1334                 FailingAsyncFib f = new FailingAsyncFib(8);
1335                 assertSame(f, f.fork());
1336                 try {
1337                     f.get();
1338                     shouldThrow();
1339                 } catch (ExecutionException success) {
1340                     Throwable cause = success.getCause();
1341                     assertTrue(cause instanceof FJException);
1342                     checkCompletedAbnormally(f, cause);
1343                 }
1344             }};
1345         testInvokeOnPool(singletonPool(), a);
1346     }
1347 
1348     /**
1349      * timed get of a forked task throws exception when task completes abnormally
1350      */
1351     public void testAbnormalForkTimedGetSingleton() {
1352         RecursiveAction a = new CheckedRecursiveAction() {
1353             protected void realCompute() throws Exception {
1354                 FailingAsyncFib f = new FailingAsyncFib(8);
1355                 assertSame(f, f.fork());
1356                 try {
1357                     f.get(LONG_DELAY_MS, MILLISECONDS);
1358                     shouldThrow();
1359                 } catch (ExecutionException success) {
1360                     Throwable cause = success.getCause();
1361                     assertTrue(cause instanceof FJException);
1362                     checkCompletedAbnormally(f, cause);
1363                 }
1364             }};
1365         testInvokeOnPool(singletonPool(), a);
1366     }
1367 
1368     /**
1369      * quietlyJoin of a forked task returns when task completes abnormally
1370      */
1371     public void testAbnormalForkQuietlyJoinSingleton() {
1372         RecursiveAction a = new CheckedRecursiveAction() {
1373             protected void realCompute() {
1374                 FailingAsyncFib f = new FailingAsyncFib(8);
1375                 assertSame(f, f.fork());
1376                 f.quietlyJoin();
1377                 assertTrue(f.getException() instanceof FJException);
1378                 checkCompletedAbnormally(f, f.getException());
1379             }};
1380         testInvokeOnPool(singletonPool(), a);
1381     }
1382 
1383     /**
1384      * invoke task throws exception when task cancelled
1385      */
1386     public void testCancelledInvokeSingleton() {
1387         RecursiveAction a = new CheckedRecursiveAction() {
1388             protected void realCompute() {
1389                 AsyncFib f = new AsyncFib(8);
1390                 assertTrue(f.cancel(true));
1391                 try {
1392                     f.invoke();
1393                     shouldThrow();
1394                 } catch (CancellationException success) {
1395                     checkCancelled(f);
1396                 }
1397             }};
1398         testInvokeOnPool(singletonPool(), a);
1399     }
1400 
1401     /**
1402      * join of a forked task throws exception when task cancelled
1403      */
1404     public void testCancelledForkJoinSingleton() {
1405         RecursiveAction a = new CheckedRecursiveAction() {
1406             protected void realCompute() {
1407                 AsyncFib f = new AsyncFib(8);
1408                 assertTrue(f.cancel(true));
1409                 assertSame(f, f.fork());
1410                 try {
1411                     f.join();
1412                     shouldThrow();
1413                 } catch (CancellationException success) {
1414                     checkCancelled(f);
1415                 }
1416             }};
1417         testInvokeOnPool(singletonPool(), a);
1418     }
1419 
1420     /**
1421      * get of a forked task throws exception when task cancelled
1422      */
1423     public void testCancelledForkGetSingleton() {
1424         RecursiveAction a = new CheckedRecursiveAction() {
1425             protected void realCompute() throws Exception {
1426                 AsyncFib f = new AsyncFib(8);
1427                 assertTrue(f.cancel(true));
1428                 assertSame(f, f.fork());
1429                 try {
1430                     f.get();
1431                     shouldThrow();
1432                 } catch (CancellationException success) {
1433                     checkCancelled(f);
1434                 }
1435             }};
1436         testInvokeOnPool(singletonPool(), a);
1437     }
1438 
1439     /**
1440      * timed get of a forked task throws exception when task cancelled
1441      */
1442     public void testCancelledForkTimedGetSingleton() throws Exception {
1443         RecursiveAction a = new CheckedRecursiveAction() {
1444             protected void realCompute() throws Exception {
1445                 AsyncFib f = new AsyncFib(8);
1446                 assertTrue(f.cancel(true));
1447                 assertSame(f, f.fork());
1448                 try {
1449                     f.get(LONG_DELAY_MS, MILLISECONDS);
1450                     shouldThrow();
1451                 } catch (CancellationException success) {
1452                     checkCancelled(f);
1453                 }
1454             }};
1455         testInvokeOnPool(singletonPool(), a);
1456     }
1457 
1458     /**
1459      * quietlyJoin of a forked task returns when task cancelled
1460      */
1461     public void testCancelledForkQuietlyJoinSingleton() {
1462         RecursiveAction a = new CheckedRecursiveAction() {
1463             protected void realCompute() {
1464                 AsyncFib f = new AsyncFib(8);
1465                 assertTrue(f.cancel(true));
1466                 assertSame(f, f.fork());
1467                 f.quietlyJoin();
1468                 checkCancelled(f);
1469             }};
1470         testInvokeOnPool(singletonPool(), a);
1471     }
1472 
1473     /**
1474      * invoke task throws exception after invoking completeExceptionally
1475      */
1476     public void testCompleteExceptionallySingleton() {
1477         RecursiveAction a = new CheckedRecursiveAction() {
1478             protected void realCompute() {
1479                 AsyncFib f = new AsyncFib(8);
1480                 f.completeExceptionally(new FJException());
1481                 try {
1482                     f.invoke();
1483                     shouldThrow();
1484                 } catch (FJException success) {
1485                     checkCompletedAbnormally(f, success);
1486                 }
1487             }};
1488         testInvokeOnPool(singletonPool(), a);
1489     }
1490 
1491     /**
1492      * invokeAll(t1, t2) invokes all task arguments
1493      */
1494     public void testInvokeAll2Singleton() {
1495         RecursiveAction a = new CheckedRecursiveAction() {
1496             protected void realCompute() {
1497                 AsyncFib f = new AsyncFib(8);
1498                 AsyncFib g = new AsyncFib(9);
1499                 invokeAll(f, g);
1500                 assertEquals(21, f.number);
1501                 assertEquals(34, g.number);
1502                 checkCompletedNormally(f);
1503                 checkCompletedNormally(g);
1504             }};
1505         testInvokeOnPool(singletonPool(), a);
1506     }
1507 
1508     /**
1509      * invokeAll(tasks) with 1 argument invokes task
1510      */
1511     public void testInvokeAll1Singleton() {
1512         RecursiveAction a = new CheckedRecursiveAction() {
1513             protected void realCompute() {
1514                 AsyncFib f = new AsyncFib(8);
1515                 invokeAll(f);
1516                 checkCompletedNormally(f);
1517                 assertEquals(21, f.number);
1518             }};
1519         testInvokeOnPool(singletonPool(), a);
1520     }
1521 
1522     /**
1523      * invokeAll(tasks) with > 2 argument invokes tasks
1524      */
1525     public void testInvokeAll3Singleton() {
1526         RecursiveAction a = new CheckedRecursiveAction() {
1527             protected void realCompute() {
1528                 AsyncFib f = new AsyncFib(8);
1529                 AsyncFib g = new AsyncFib(9);
1530                 AsyncFib h = new AsyncFib(7);
1531                 invokeAll(f, g, h);
1532                 assertEquals(21, f.number);
1533                 assertEquals(34, g.number);
1534                 assertEquals(13, h.number);
1535                 checkCompletedNormally(f);
1536                 checkCompletedNormally(g);
1537                 checkCompletedNormally(h);
1538             }};
1539         testInvokeOnPool(singletonPool(), a);
1540     }
1541 
1542     /**
1543      * invokeAll(collection) invokes all tasks in the collection
1544      */
1545     public void testInvokeAllCollectionSingleton() {
1546         RecursiveAction a = new CheckedRecursiveAction() {
1547             protected void realCompute() {
1548                 AsyncFib f = new AsyncFib(8);
1549                 AsyncFib g = new AsyncFib(9);
1550                 AsyncFib h = new AsyncFib(7);
1551                 HashSet set = new HashSet();
1552                 set.add(f);
1553                 set.add(g);
1554                 set.add(h);
1555                 invokeAll(set);
1556                 assertEquals(21, f.number);
1557                 assertEquals(34, g.number);
1558                 assertEquals(13, h.number);
1559                 checkCompletedNormally(f);
1560                 checkCompletedNormally(g);
1561                 checkCompletedNormally(h);
1562             }};
1563         testInvokeOnPool(singletonPool(), a);
1564     }
1565 
1566     /**
1567      * invokeAll(tasks) with any null task throws NPE
1568      */
1569     public void testInvokeAllNPESingleton() {
1570         RecursiveAction a = new CheckedRecursiveAction() {
1571             protected void realCompute() {
1572                 AsyncFib f = new AsyncFib(8);
1573                 AsyncFib g = new AsyncFib(9);
1574                 AsyncFib h = null;
1575                 try {
1576                     invokeAll(f, g, h);
1577                     shouldThrow();
1578                 } catch (NullPointerException success) {}
1579             }};
1580         testInvokeOnPool(singletonPool(), a);
1581     }
1582 
1583     /**
1584      * invokeAll(t1, t2) throw exception if any task does
1585      */
1586     public void testAbnormalInvokeAll2Singleton() {
1587         RecursiveAction a = new CheckedRecursiveAction() {
1588             protected void realCompute() {
1589                 AsyncFib f = new AsyncFib(8);
1590                 FailingAsyncFib g = new FailingAsyncFib(9);
1591                 ForkJoinTask[] tasks = { f, g };
1592                 shuffle(tasks);
1593                 try {
1594                     invokeAll(tasks);
1595                     shouldThrow();
1596                 } catch (FJException success) {
1597                     checkCompletedAbnormally(g, success);
1598                 }
1599             }};
1600         testInvokeOnPool(singletonPool(), a);
1601     }
1602 
1603     /**
1604      * invokeAll(tasks) with 1 argument throws exception if task does
1605      */
1606     public void testAbnormalInvokeAll1Singleton() {
1607         RecursiveAction a = new CheckedRecursiveAction() {
1608             protected void realCompute() {
1609                 FailingAsyncFib g = new FailingAsyncFib(9);
1610                 try {
1611                     invokeAll(g);
1612                     shouldThrow();
1613                 } catch (FJException success) {
1614                     checkCompletedAbnormally(g, success);
1615                 }
1616             }};
1617         testInvokeOnPool(singletonPool(), a);
1618     }
1619 
1620     /**
1621      * invokeAll(tasks) with > 2 argument throws exception if any task does
1622      */
1623     public void testAbnormalInvokeAll3Singleton() {
1624         RecursiveAction a = new CheckedRecursiveAction() {
1625             protected void realCompute() {
1626                 AsyncFib f = new AsyncFib(8);
1627                 FailingAsyncFib g = new FailingAsyncFib(9);
1628                 AsyncFib h = new AsyncFib(7);
1629                 ForkJoinTask[] tasks = { f, g, h };
1630                 shuffle(tasks);
1631                 try {
1632                     invokeAll(tasks);
1633                     shouldThrow();
1634                 } catch (FJException success) {
1635                     checkCompletedAbnormally(g, success);
1636                 }
1637             }};
1638         testInvokeOnPool(singletonPool(), a);
1639     }
1640 
1641     /**
1642      * invokeAll(collection) throws exception if any task does
1643      */
1644     public void testAbnormalInvokeAllCollectionSingleton() {
1645         RecursiveAction a = new CheckedRecursiveAction() {
1646             protected void realCompute() {
1647                 FailingAsyncFib f = new FailingAsyncFib(8);
1648                 AsyncFib g = new AsyncFib(9);
1649                 AsyncFib h = new AsyncFib(7);
1650                 ForkJoinTask[] tasks = { f, g, h };
1651                 shuffle(tasks);
1652                 try {
1653                     invokeAll(Arrays.asList(tasks));
1654                     shouldThrow();
1655                 } catch (FJException success) {
1656                     checkCompletedAbnormally(f, success);
1657                 }
1658             }};
1659         testInvokeOnPool(singletonPool(), a);
1660     }
1661 
1662     /**
1663      * ForkJoinTask.quietlyComplete returns when task completes
1664      * normally without setting a value. The most recent value
1665      * established by setRawResult(V) (or null by default) is returned
1666      * from invoke.
1667      */
1668     public void testQuietlyComplete() {
1669         RecursiveAction a = new CheckedRecursiveAction() {
1670                 protected void realCompute() {
1671                     AsyncFib f = new AsyncFib(8);
1672                     f.quietlyComplete();
1673                     assertEquals(8, f.number);
1674                     checkCompletedNormally(f);
1675                 }};
1676         testInvokeOnPool(mainPool(), a);
1677     }
1678 
1679     /**
1680      * adapt(runnable).toString() contains toString of wrapped task
1681      */
1682     public void testAdapt_Runnable_toString() {
1683         if (testImplementationDetails) {
1684             Runnable r = () -> {};
1685             ForkJoinTask<?> task = ForkJoinTask.adapt(r);
1686             assertEquals(
1687                 identityString(task) + "[Wrapped task = " + r.toString() + "]",
1688                 task.toString());
1689         }
1690     }
1691 
1692     /**
1693      * adapt(runnable, x).toString() contains toString of wrapped task
1694      */
testAdapt_Runnable_withResult_toString()1695     public void testAdapt_Runnable_withResult_toString() {
1696         if (testImplementationDetails) {
1697             Runnable r = () -> {};
1698             ForkJoinTask<String> task = ForkJoinTask.adapt(r, "");
1699             assertEquals(
1700                 identityString(task) + "[Wrapped task = " + r.toString() + "]",
1701                 task.toString());
1702         }
1703     }
1704 
1705     /**
1706      * adapt(callable).toString() contains toString of wrapped task
1707      */
testAdapt_Callable_toString()1708     public void testAdapt_Callable_toString() {
1709         if (testImplementationDetails) {
1710             Callable<String> c = () -> "";
1711             ForkJoinTask<String> task = ForkJoinTask.adapt(c);
1712             assertEquals(
1713                 identityString(task) + "[Wrapped task = " + c.toString() + "]",
1714                 task.toString());
1715         }
1716     }
1717 }
1718