ForkJoinTaskTest.java revision 15352:d5c70818cd8a
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
34import static java.util.concurrent.TimeUnit.MILLISECONDS;
35import static java.util.concurrent.TimeUnit.SECONDS;
36
37import java.util.Arrays;
38import java.util.Collections;
39import java.util.HashSet;
40import java.util.List;
41import java.util.concurrent.CancellationException;
42import java.util.concurrent.ExecutionException;
43import java.util.concurrent.ForkJoinPool;
44import java.util.concurrent.ForkJoinTask;
45import java.util.concurrent.RecursiveAction;
46import java.util.concurrent.TimeoutException;
47import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
48
49import junit.framework.Test;
50import junit.framework.TestSuite;
51
52public class ForkJoinTaskTest extends JSR166TestCase {
53
54    public static void main(String[] args) {
55        main(suite(), args);
56    }
57
58    public static Test suite() {
59        return new TestSuite(ForkJoinTaskTest.class);
60    }
61
62    // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
63    static final int mainPoolSize =
64        Math.max(2, Runtime.getRuntime().availableProcessors());
65
66    private static ForkJoinPool mainPool() {
67        return new ForkJoinPool(mainPoolSize);
68    }
69
70    private static ForkJoinPool singletonPool() {
71        return new ForkJoinPool(1);
72    }
73
74    private static ForkJoinPool asyncSingletonPool() {
75        return new ForkJoinPool(1,
76                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
77                                null, true);
78    }
79
80    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
81        try (PoolCleaner cleaner = cleaner(pool)) {
82            assertFalse(a.isDone());
83            assertFalse(a.isCompletedNormally());
84            assertFalse(a.isCompletedAbnormally());
85            assertFalse(a.isCancelled());
86            assertNull(a.getException());
87            assertNull(a.getRawResult());
88
89            assertNull(pool.invoke(a));
90
91            assertTrue(a.isDone());
92            assertTrue(a.isCompletedNormally());
93            assertFalse(a.isCompletedAbnormally());
94            assertFalse(a.isCancelled());
95            assertNull(a.getException());
96            assertNull(a.getRawResult());
97        }
98    }
99
100    void checkNotDone(ForkJoinTask a) {
101        assertFalse(a.isDone());
102        assertFalse(a.isCompletedNormally());
103        assertFalse(a.isCompletedAbnormally());
104        assertFalse(a.isCancelled());
105        assertNull(a.getException());
106        assertNull(a.getRawResult());
107
108        try {
109            a.get(0L, SECONDS);
110            shouldThrow();
111        } catch (TimeoutException success) {
112        } catch (Throwable fail) { threadUnexpectedException(fail); }
113    }
114
115    <T> void checkCompletedNormally(ForkJoinTask<T> a) {
116        checkCompletedNormally(a, null);
117    }
118
119    <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
120        assertTrue(a.isDone());
121        assertFalse(a.isCancelled());
122        assertTrue(a.isCompletedNormally());
123        assertFalse(a.isCompletedAbnormally());
124        assertNull(a.getException());
125        assertSame(expected, a.getRawResult());
126
127        {
128            Thread.currentThread().interrupt();
129            long startTime = System.nanoTime();
130            assertSame(expected, a.join());
131            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
132            Thread.interrupted();
133        }
134
135        {
136            Thread.currentThread().interrupt();
137            long startTime = System.nanoTime();
138            a.quietlyJoin();        // should be no-op
139            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
140            Thread.interrupted();
141        }
142
143        assertFalse(a.cancel(false));
144        assertFalse(a.cancel(true));
145        try {
146            assertSame(expected, a.get());
147        } catch (Throwable fail) { threadUnexpectedException(fail); }
148        try {
149            assertSame(expected, a.get(5L, SECONDS));
150        } catch (Throwable fail) { threadUnexpectedException(fail); }
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) < SMALL_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(5L, SECONDS);
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) < SMALL_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(5L, SECONDS);
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(5L, 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(5L, 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