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