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