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