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