ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.1
Committed: Sun Jul 21 22:24:18 2013 UTC (10 years, 9 months ago) by dl
Branch: MAIN
Log Message:
Adapt/incorporate JDK8 tests including suggestions by Eric Wang

File Contents

# Content
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 import java.util.concurrent.ExecutionException;
7 import java.util.concurrent.CancellationException;
8 import java.util.concurrent.ForkJoinPool;
9 import java.util.concurrent.ForkJoinTask;
10 import java.util.concurrent.ForkJoinWorkerThread;
11 import java.util.concurrent.RecursiveAction;
12 import java.util.concurrent.TimeUnit;
13 import java.util.concurrent.TimeoutException;
14 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
15 import static java.util.concurrent.TimeUnit.MILLISECONDS;
16 import static java.util.concurrent.TimeUnit.SECONDS;
17 import java.util.HashSet;
18 import junit.framework.*;
19
20 public class ForkJoinTask8Test extends JSR166TestCase {
21
22 /*
23 * Testing notes: This differs from ForkJoinTaskTest mainly by
24 * defining a version of BinaryAsyncAction that uses JDK8 task
25 * tags for control state, thereby testing getForkJoinTaskTag,
26 * setForkJoinTaskTag, and compareAndSetForkJoinTaskTag across
27 * various contexts. Most of the test methods using it are
28 * otherwise identical, but omitting retest of those dealing with
29 * cancellation, which is not represented in this tag scheme.
30 */
31
32 static final short INITIAL_STATE = -1;
33 static final short COMPLETE_STATE = 0;
34 static final short EXCEPTION_STATE = 1;
35
36
37 public static void main(String[] args) {
38 junit.textui.TestRunner.run(suite());
39 }
40
41 public static Test suite() {
42 return new TestSuite(ForkJoinTask8Test.class);
43 }
44
45 // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
46 static final int mainPoolSize =
47 Math.max(2, Runtime.getRuntime().availableProcessors());
48
49 private static ForkJoinPool mainPool() {
50 return new ForkJoinPool(mainPoolSize);
51 }
52
53 private static ForkJoinPool singletonPool() {
54 return new ForkJoinPool(1);
55 }
56
57 private static ForkJoinPool asyncSingletonPool() {
58 return new ForkJoinPool(1,
59 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
60 null, true);
61 }
62
63 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
64 try {
65 assertFalse(a.isDone());
66 assertFalse(a.isCompletedNormally());
67 assertFalse(a.isCompletedAbnormally());
68 assertFalse(a.isCancelled());
69 assertNull(a.getException());
70 assertNull(a.getRawResult());
71
72 assertNull(pool.invoke(a));
73
74 assertTrue(a.isDone());
75 assertTrue(a.isCompletedNormally());
76 assertFalse(a.isCompletedAbnormally());
77 assertFalse(a.isCancelled());
78 assertNull(a.getException());
79 assertNull(a.getRawResult());
80 } finally {
81 joinPool(pool);
82 }
83 }
84
85 void checkNotDone(ForkJoinTask a) {
86 assertFalse(a.isDone());
87 assertFalse(a.isCompletedNormally());
88 assertFalse(a.isCompletedAbnormally());
89 assertFalse(a.isCancelled());
90 assertNull(a.getException());
91 assertNull(a.getRawResult());
92 if (a instanceof BinaryAsyncAction)
93 assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == INITIAL_STATE);
94
95 try {
96 a.get(0L, SECONDS);
97 shouldThrow();
98 } catch (TimeoutException success) {
99 } catch (Throwable fail) { threadUnexpectedException(fail); }
100 }
101
102 <T> void checkCompletedNormally(ForkJoinTask<T> a) {
103 checkCompletedNormally(a, null);
104 }
105
106 <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
107 assertTrue(a.isDone());
108 assertFalse(a.isCancelled());
109 assertTrue(a.isCompletedNormally());
110 assertFalse(a.isCompletedAbnormally());
111 assertNull(a.getException());
112 assertSame(expected, a.getRawResult());
113 if (a instanceof BinaryAsyncAction)
114 assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == COMPLETE_STATE);
115
116 {
117 Thread.currentThread().interrupt();
118 long t0 = System.nanoTime();
119 assertSame(expected, a.join());
120 assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
121 Thread.interrupted();
122 }
123
124 {
125 Thread.currentThread().interrupt();
126 long t0 = System.nanoTime();
127 a.quietlyJoin(); // should be no-op
128 assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
129 Thread.interrupted();
130 }
131
132 assertFalse(a.cancel(false));
133 assertFalse(a.cancel(true));
134 try {
135 assertSame(expected, a.get());
136 } catch (Throwable fail) { threadUnexpectedException(fail); }
137 try {
138 assertSame(expected, a.get(5L, SECONDS));
139 } catch (Throwable fail) { threadUnexpectedException(fail); }
140 }
141
142 void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
143 assertTrue(a.isDone());
144 assertFalse(a.isCancelled());
145 assertFalse(a.isCompletedNormally());
146 assertTrue(a.isCompletedAbnormally());
147 assertSame(t.getClass(), a.getException().getClass());
148 assertNull(a.getRawResult());
149 assertFalse(a.cancel(false));
150 assertFalse(a.cancel(true));
151 if (a instanceof BinaryAsyncAction)
152 assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() != INITIAL_STATE);
153
154 try {
155 Thread.currentThread().interrupt();
156 a.join();
157 shouldThrow();
158 } catch (Throwable expected) {
159 assertSame(t.getClass(), expected.getClass());
160 }
161 Thread.interrupted();
162
163 {
164 long t0 = System.nanoTime();
165 a.quietlyJoin(); // should be no-op
166 assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
167 }
168
169 try {
170 a.get();
171 shouldThrow();
172 } catch (ExecutionException success) {
173 assertSame(t.getClass(), success.getCause().getClass());
174 } catch (Throwable fail) { threadUnexpectedException(fail); }
175
176 try {
177 a.get(5L, SECONDS);
178 shouldThrow();
179 } catch (ExecutionException success) {
180 assertSame(t.getClass(), success.getCause().getClass());
181 } catch (Throwable fail) { threadUnexpectedException(fail); }
182 }
183
184
185 public static final class FJException extends RuntimeException {
186 FJException() { super(); }
187 }
188
189 abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
190
191 private BinaryAsyncAction parent;
192
193 private BinaryAsyncAction sibling;
194
195 protected BinaryAsyncAction() {
196 setForkJoinTaskTag(INITIAL_STATE);
197 }
198
199 public final Void getRawResult() { return null; }
200 protected final void setRawResult(Void mustBeNull) { }
201
202 public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
203 x.parent = y.parent = this;
204 x.sibling = y;
205 y.sibling = x;
206 }
207
208 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
209 if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
210 x.getForkJoinTaskTag() != COMPLETE_STATE ||
211 y.getForkJoinTaskTag() != COMPLETE_STATE) {
212 completeThisExceptionally(new FJException());
213 }
214 }
215
216 protected boolean onException() {
217 return true;
218 }
219
220 public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
221 linkSubtasks(x, y);
222 y.fork();
223 x.fork();
224 }
225
226 private void completeThis() {
227 setForkJoinTaskTag(COMPLETE_STATE);
228 super.complete(null);
229 }
230
231 private void completeThisExceptionally(Throwable ex) {
232 setForkJoinTaskTag(EXCEPTION_STATE);
233 super.completeExceptionally(ex);
234 }
235
236 public final void complete() {
237 BinaryAsyncAction a = this;
238 for (;;) {
239 BinaryAsyncAction s = a.sibling;
240 BinaryAsyncAction p = a.parent;
241 a.sibling = null;
242 a.parent = null;
243 a.completeThis();
244 if (p == null ||
245 p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
246 break;
247 try {
248 p.onComplete(a, s);
249 } catch (Throwable rex) {
250 p.completeExceptionally(rex);
251 return;
252 }
253 a = p;
254 }
255 }
256
257 public final void completeExceptionally(Throwable ex) {
258 BinaryAsyncAction a = this;
259 while (!a.isCompletedAbnormally()) {
260 a.completeThisExceptionally(ex);
261 BinaryAsyncAction s = a.sibling;
262 if (s != null)
263 s.cancel(false);
264 if (!a.onException() || (a = a.parent) == null)
265 break;
266 }
267 }
268
269 public final BinaryAsyncAction getParent() {
270 return parent;
271 }
272
273 public BinaryAsyncAction getSibling() {
274 return sibling;
275 }
276
277 public void reinitialize() {
278 parent = sibling = null;
279 super.reinitialize();
280 }
281
282
283 }
284
285 static final class AsyncFib extends BinaryAsyncAction {
286 int number;
287 public AsyncFib(int n) {
288 this.number = n;
289 }
290
291 public final boolean exec() {
292 try {
293 AsyncFib f = this;
294 int n = f.number;
295 if (n > 1) {
296 while (n > 1) {
297 AsyncFib p = f;
298 AsyncFib r = new AsyncFib(n - 2);
299 f = new AsyncFib(--n);
300 p.linkSubtasks(r, f);
301 r.fork();
302 }
303 f.number = n;
304 }
305 f.complete();
306 }
307 catch(Throwable ex) {
308 compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
309 }
310 return false;
311 }
312
313 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
314 number = ((AsyncFib)x).number + ((AsyncFib)y).number;
315 super.onComplete(x, y);
316 }
317 }
318
319 static final class FailingAsyncFib extends BinaryAsyncAction {
320 int number;
321 public FailingAsyncFib(int n) {
322 this.number = n;
323 }
324
325 public final boolean exec() {
326 FailingAsyncFib f = this;
327 int n = f.number;
328 if (n > 1) {
329 while (n > 1) {
330 FailingAsyncFib p = f;
331 FailingAsyncFib r = new FailingAsyncFib(n - 2);
332 f = new FailingAsyncFib(--n);
333 p.linkSubtasks(r, f);
334 r.fork();
335 }
336 f.number = n;
337 }
338 f.complete();
339 return false;
340 }
341
342 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
343 completeExceptionally(new FJException());
344 }
345 }
346
347 /**
348 * invoke returns when task completes normally.
349 * isCompletedAbnormally and isCancelled return false for normally
350 * completed tasks; getRawResult returns null.
351 */
352 public void testInvoke() {
353 RecursiveAction a = new CheckedRecursiveAction() {
354 protected void realCompute() {
355 AsyncFib f = new AsyncFib(8);
356 assertNull(f.invoke());
357 assertEquals(21, f.number);
358 checkCompletedNormally(f);
359 }};
360 testInvokeOnPool(mainPool(), a);
361 }
362
363 /**
364 * quietlyInvoke task returns when task completes normally.
365 * isCompletedAbnormally and isCancelled return false for normally
366 * completed tasks
367 */
368 public void testQuietlyInvoke() {
369 RecursiveAction a = new CheckedRecursiveAction() {
370 protected void realCompute() {
371 AsyncFib f = new AsyncFib(8);
372 f.quietlyInvoke();
373 assertEquals(21, f.number);
374 checkCompletedNormally(f);
375 }};
376 testInvokeOnPool(mainPool(), a);
377 }
378
379 /**
380 * join of a forked task returns when task completes
381 */
382 public void testForkJoin() {
383 RecursiveAction a = new CheckedRecursiveAction() {
384 protected void realCompute() {
385 AsyncFib f = new AsyncFib(8);
386 assertSame(f, f.fork());
387 assertNull(f.join());
388 assertEquals(21, f.number);
389 checkCompletedNormally(f);
390 }};
391 testInvokeOnPool(mainPool(), a);
392 }
393
394 /**
395 * get of a forked task returns when task completes
396 */
397 public void testForkGet() {
398 RecursiveAction a = new CheckedRecursiveAction() {
399 protected void realCompute() throws Exception {
400 AsyncFib f = new AsyncFib(8);
401 assertSame(f, f.fork());
402 assertNull(f.get());
403 assertEquals(21, f.number);
404 checkCompletedNormally(f);
405 }};
406 testInvokeOnPool(mainPool(), a);
407 }
408
409 /**
410 * timed get of a forked task returns when task completes
411 */
412 public void testForkTimedGet() {
413 RecursiveAction a = new CheckedRecursiveAction() {
414 protected void realCompute() throws Exception {
415 AsyncFib f = new AsyncFib(8);
416 assertSame(f, f.fork());
417 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
418 assertEquals(21, f.number);
419 checkCompletedNormally(f);
420 }};
421 testInvokeOnPool(mainPool(), a);
422 }
423
424 /**
425 * timed get with null time unit throws NPE
426 */
427 public void testForkTimedGetNPE() {
428 RecursiveAction a = new CheckedRecursiveAction() {
429 protected void realCompute() throws Exception {
430 AsyncFib f = new AsyncFib(8);
431 assertSame(f, f.fork());
432 try {
433 f.get(5L, null);
434 shouldThrow();
435 } catch (NullPointerException success) {}
436 }};
437 testInvokeOnPool(mainPool(), a);
438 }
439
440 /**
441 * quietlyJoin of a forked task returns when task completes
442 */
443 public void testForkQuietlyJoin() {
444 RecursiveAction a = new CheckedRecursiveAction() {
445 protected void realCompute() {
446 AsyncFib f = new AsyncFib(8);
447 assertSame(f, f.fork());
448 f.quietlyJoin();
449 assertEquals(21, f.number);
450 checkCompletedNormally(f);
451 }};
452 testInvokeOnPool(mainPool(), a);
453 }
454
455 /**
456 * helpQuiesce returns when tasks are complete.
457 * getQueuedTaskCount returns 0 when quiescent
458 */
459 public void testForkHelpQuiesce() {
460 RecursiveAction a = new CheckedRecursiveAction() {
461 protected void realCompute() {
462 AsyncFib f = new AsyncFib(8);
463 assertSame(f, f.fork());
464 helpQuiesce();
465 assertEquals(21, f.number);
466 assertEquals(0, getQueuedTaskCount());
467 checkCompletedNormally(f);
468 }};
469 testInvokeOnPool(mainPool(), a);
470 }
471
472 /**
473 * invoke task throws exception when task completes abnormally
474 */
475 public void testAbnormalInvoke() {
476 RecursiveAction a = new CheckedRecursiveAction() {
477 protected void realCompute() {
478 FailingAsyncFib f = new FailingAsyncFib(8);
479 try {
480 f.invoke();
481 shouldThrow();
482 } catch (FJException success) {
483 checkCompletedAbnormally(f, success);
484 }
485 }};
486 testInvokeOnPool(mainPool(), a);
487 }
488
489 /**
490 * quietlyInvoke task returns when task completes abnormally
491 */
492 public void testAbnormalQuietlyInvoke() {
493 RecursiveAction a = new CheckedRecursiveAction() {
494 protected void realCompute() {
495 FailingAsyncFib f = new FailingAsyncFib(8);
496 f.quietlyInvoke();
497 assertTrue(f.getException() instanceof FJException);
498 checkCompletedAbnormally(f, f.getException());
499 }};
500 testInvokeOnPool(mainPool(), a);
501 }
502
503 /**
504 * join of a forked task throws exception when task completes abnormally
505 */
506 public void testAbnormalForkJoin() {
507 RecursiveAction a = new CheckedRecursiveAction() {
508 protected void realCompute() {
509 FailingAsyncFib f = new FailingAsyncFib(8);
510 assertSame(f, f.fork());
511 try {
512 f.join();
513 shouldThrow();
514 } catch (FJException success) {
515 checkCompletedAbnormally(f, success);
516 }
517 }};
518 testInvokeOnPool(mainPool(), a);
519 }
520
521 /**
522 * get of a forked task throws exception when task completes abnormally
523 */
524 public void testAbnormalForkGet() {
525 RecursiveAction a = new CheckedRecursiveAction() {
526 protected void realCompute() throws Exception {
527 FailingAsyncFib f = new FailingAsyncFib(8);
528 assertSame(f, f.fork());
529 try {
530 f.get();
531 shouldThrow();
532 } catch (ExecutionException success) {
533 Throwable cause = success.getCause();
534 assertTrue(cause instanceof FJException);
535 checkCompletedAbnormally(f, cause);
536 }
537 }};
538 testInvokeOnPool(mainPool(), a);
539 }
540
541 /**
542 * timed get of a forked task throws exception when task completes abnormally
543 */
544 public void testAbnormalForkTimedGet() {
545 RecursiveAction a = new CheckedRecursiveAction() {
546 protected void realCompute() throws Exception {
547 FailingAsyncFib f = new FailingAsyncFib(8);
548 assertSame(f, f.fork());
549 try {
550 f.get(LONG_DELAY_MS, MILLISECONDS);
551 shouldThrow();
552 } catch (ExecutionException success) {
553 Throwable cause = success.getCause();
554 assertTrue(cause instanceof FJException);
555 checkCompletedAbnormally(f, cause);
556 }
557 }};
558 testInvokeOnPool(mainPool(), a);
559 }
560
561 /**
562 * quietlyJoin of a forked task returns when task completes abnormally
563 */
564 public void testAbnormalForkQuietlyJoin() {
565 RecursiveAction a = new CheckedRecursiveAction() {
566 protected void realCompute() {
567 FailingAsyncFib f = new FailingAsyncFib(8);
568 assertSame(f, f.fork());
569 f.quietlyJoin();
570 assertTrue(f.getException() instanceof FJException);
571 checkCompletedAbnormally(f, f.getException());
572 }};
573 testInvokeOnPool(mainPool(), a);
574 }
575
576
577 /**
578 * getPool of executing task returns its pool
579 */
580 public void testGetPool() {
581 final ForkJoinPool mainPool = mainPool();
582 RecursiveAction a = new CheckedRecursiveAction() {
583 protected void realCompute() {
584 assertSame(mainPool, getPool());
585 }};
586 testInvokeOnPool(mainPool, a);
587 }
588
589 /**
590 * getPool of non-FJ task returns null
591 */
592 public void testGetPool2() {
593 RecursiveAction a = new CheckedRecursiveAction() {
594 protected void realCompute() {
595 assertNull(getPool());
596 }};
597 assertNull(a.invoke());
598 }
599
600 /**
601 * inForkJoinPool of executing task returns true
602 */
603 public void testInForkJoinPool() {
604 RecursiveAction a = new CheckedRecursiveAction() {
605 protected void realCompute() {
606 assertTrue(inForkJoinPool());
607 }};
608 testInvokeOnPool(mainPool(), a);
609 }
610
611 /**
612 * inForkJoinPool of non-FJ task returns false
613 */
614 public void testInForkJoinPool2() {
615 RecursiveAction a = new CheckedRecursiveAction() {
616 protected void realCompute() {
617 assertFalse(inForkJoinPool());
618 }};
619 assertNull(a.invoke());
620 }
621
622 /**
623 * setRawResult(null) succeeds
624 */
625 public void testSetRawResult() {
626 RecursiveAction a = new CheckedRecursiveAction() {
627 protected void realCompute() {
628 setRawResult(null);
629 assertNull(getRawResult());
630 }};
631 assertNull(a.invoke());
632 }
633
634 /**
635 * invoke task throws exception after invoking completeExceptionally
636 */
637 public void testCompleteExceptionally() {
638 RecursiveAction a = new CheckedRecursiveAction() {
639 protected void realCompute() {
640 AsyncFib f = new AsyncFib(8);
641 f.completeExceptionally(new FJException());
642 try {
643 f.invoke();
644 shouldThrow();
645 } catch (FJException success) {
646 checkCompletedAbnormally(f, success);
647 }
648 }};
649 testInvokeOnPool(mainPool(), a);
650 }
651
652 /**
653 * invokeAll(t1, t2) invokes all task arguments
654 */
655 public void testInvokeAll2() {
656 RecursiveAction a = new CheckedRecursiveAction() {
657 protected void realCompute() {
658 AsyncFib f = new AsyncFib(8);
659 AsyncFib g = new AsyncFib(9);
660 invokeAll(f, g);
661 assertEquals(21, f.number);
662 assertEquals(34, g.number);
663 checkCompletedNormally(f);
664 checkCompletedNormally(g);
665 }};
666 testInvokeOnPool(mainPool(), a);
667 }
668
669 /**
670 * invokeAll(tasks) with 1 argument invokes task
671 */
672 public void testInvokeAll1() {
673 RecursiveAction a = new CheckedRecursiveAction() {
674 protected void realCompute() {
675 AsyncFib f = new AsyncFib(8);
676 invokeAll(f);
677 checkCompletedNormally(f);
678 assertEquals(21, f.number);
679 }};
680 testInvokeOnPool(mainPool(), a);
681 }
682
683 /**
684 * invokeAll(tasks) with > 2 argument invokes tasks
685 */
686 public void testInvokeAll3() {
687 RecursiveAction a = new CheckedRecursiveAction() {
688 protected void realCompute() {
689 AsyncFib f = new AsyncFib(8);
690 AsyncFib g = new AsyncFib(9);
691 AsyncFib h = new AsyncFib(7);
692 invokeAll(f, g, h);
693 assertEquals(21, f.number);
694 assertEquals(34, g.number);
695 assertEquals(13, h.number);
696 checkCompletedNormally(f);
697 checkCompletedNormally(g);
698 checkCompletedNormally(h);
699 }};
700 testInvokeOnPool(mainPool(), a);
701 }
702
703 /**
704 * invokeAll(collection) invokes all tasks in the collection
705 */
706 public void testInvokeAllCollection() {
707 RecursiveAction a = new CheckedRecursiveAction() {
708 protected void realCompute() {
709 AsyncFib f = new AsyncFib(8);
710 AsyncFib g = new AsyncFib(9);
711 AsyncFib h = new AsyncFib(7);
712 HashSet set = new HashSet();
713 set.add(f);
714 set.add(g);
715 set.add(h);
716 invokeAll(set);
717 assertEquals(21, f.number);
718 assertEquals(34, g.number);
719 assertEquals(13, h.number);
720 checkCompletedNormally(f);
721 checkCompletedNormally(g);
722 checkCompletedNormally(h);
723 }};
724 testInvokeOnPool(mainPool(), a);
725 }
726
727 /**
728 * invokeAll(tasks) with any null task throws NPE
729 */
730 public void testInvokeAllNPE() {
731 RecursiveAction a = new CheckedRecursiveAction() {
732 protected void realCompute() {
733 AsyncFib f = new AsyncFib(8);
734 AsyncFib g = new AsyncFib(9);
735 AsyncFib h = null;
736 try {
737 invokeAll(f, g, h);
738 shouldThrow();
739 } catch (NullPointerException success) {}
740 }};
741 testInvokeOnPool(mainPool(), a);
742 }
743
744 /**
745 * invokeAll(t1, t2) throw exception if any task does
746 */
747 public void testAbnormalInvokeAll2() {
748 RecursiveAction a = new CheckedRecursiveAction() {
749 protected void realCompute() {
750 AsyncFib f = new AsyncFib(8);
751 FailingAsyncFib g = new FailingAsyncFib(9);
752 try {
753 invokeAll(f, g);
754 shouldThrow();
755 } catch (FJException success) {
756 checkCompletedAbnormally(g, success);
757 }
758 }};
759 testInvokeOnPool(mainPool(), a);
760 }
761
762 /**
763 * invokeAll(tasks) with 1 argument throws exception if task does
764 */
765 public void testAbnormalInvokeAll1() {
766 RecursiveAction a = new CheckedRecursiveAction() {
767 protected void realCompute() {
768 FailingAsyncFib g = new FailingAsyncFib(9);
769 try {
770 invokeAll(g);
771 shouldThrow();
772 } catch (FJException success) {
773 checkCompletedAbnormally(g, success);
774 }
775 }};
776 testInvokeOnPool(mainPool(), a);
777 }
778
779 /**
780 * invokeAll(tasks) with > 2 argument throws exception if any task does
781 */
782 public void testAbnormalInvokeAll3() {
783 RecursiveAction a = new CheckedRecursiveAction() {
784 protected void realCompute() {
785 AsyncFib f = new AsyncFib(8);
786 FailingAsyncFib g = new FailingAsyncFib(9);
787 AsyncFib h = new AsyncFib(7);
788 try {
789 invokeAll(f, g, h);
790 shouldThrow();
791 } catch (FJException success) {
792 checkCompletedAbnormally(g, success);
793 }
794 }};
795 testInvokeOnPool(mainPool(), a);
796 }
797
798 /**
799 * invokeAll(collection) throws exception if any task does
800 */
801 public void testAbnormalInvokeAllCollection() {
802 RecursiveAction a = new CheckedRecursiveAction() {
803 protected void realCompute() {
804 FailingAsyncFib f = new FailingAsyncFib(8);
805 AsyncFib g = new AsyncFib(9);
806 AsyncFib h = new AsyncFib(7);
807 HashSet set = new HashSet();
808 set.add(f);
809 set.add(g);
810 set.add(h);
811 try {
812 invokeAll(set);
813 shouldThrow();
814 } catch (FJException success) {
815 checkCompletedAbnormally(f, success);
816 }
817 }};
818 testInvokeOnPool(mainPool(), a);
819 }
820
821 /**
822 * tryUnfork returns true for most recent unexecuted task,
823 * and suppresses execution
824 */
825 public void testTryUnfork() {
826 RecursiveAction a = new CheckedRecursiveAction() {
827 protected void realCompute() {
828 AsyncFib g = new AsyncFib(9);
829 assertSame(g, g.fork());
830 AsyncFib f = new AsyncFib(8);
831 assertSame(f, f.fork());
832 assertTrue(f.tryUnfork());
833 helpQuiesce();
834 checkNotDone(f);
835 checkCompletedNormally(g);
836 }};
837 testInvokeOnPool(singletonPool(), a);
838 }
839
840 /**
841 * getSurplusQueuedTaskCount returns > 0 when
842 * there are more tasks than threads
843 */
844 public void testGetSurplusQueuedTaskCount() {
845 RecursiveAction a = new CheckedRecursiveAction() {
846 protected void realCompute() {
847 AsyncFib h = new AsyncFib(7);
848 assertSame(h, h.fork());
849 AsyncFib g = new AsyncFib(9);
850 assertSame(g, g.fork());
851 AsyncFib f = new AsyncFib(8);
852 assertSame(f, f.fork());
853 assertTrue(getSurplusQueuedTaskCount() > 0);
854 helpQuiesce();
855 assertEquals(0, getSurplusQueuedTaskCount());
856 checkCompletedNormally(f);
857 checkCompletedNormally(g);
858 checkCompletedNormally(h);
859 }};
860 testInvokeOnPool(singletonPool(), a);
861 }
862
863 /**
864 * peekNextLocalTask returns most recent unexecuted task.
865 */
866 public void testPeekNextLocalTask() {
867 RecursiveAction a = new CheckedRecursiveAction() {
868 protected void realCompute() {
869 AsyncFib g = new AsyncFib(9);
870 assertSame(g, g.fork());
871 AsyncFib f = new AsyncFib(8);
872 assertSame(f, f.fork());
873 assertSame(f, peekNextLocalTask());
874 assertNull(f.join());
875 checkCompletedNormally(f);
876 helpQuiesce();
877 checkCompletedNormally(g);
878 }};
879 testInvokeOnPool(singletonPool(), a);
880 }
881
882 /**
883 * pollNextLocalTask returns most recent unexecuted task without
884 * executing it
885 */
886 public void testPollNextLocalTask() {
887 RecursiveAction a = new CheckedRecursiveAction() {
888 protected void realCompute() {
889 AsyncFib g = new AsyncFib(9);
890 assertSame(g, g.fork());
891 AsyncFib f = new AsyncFib(8);
892 assertSame(f, f.fork());
893 assertSame(f, pollNextLocalTask());
894 helpQuiesce();
895 checkNotDone(f);
896 assertEquals(34, g.number);
897 checkCompletedNormally(g);
898 }};
899 testInvokeOnPool(singletonPool(), a);
900 }
901
902 /**
903 * pollTask returns an unexecuted task without executing it
904 */
905 public void testPollTask() {
906 RecursiveAction a = new CheckedRecursiveAction() {
907 protected void realCompute() {
908 AsyncFib g = new AsyncFib(9);
909 assertSame(g, g.fork());
910 AsyncFib f = new AsyncFib(8);
911 assertSame(f, f.fork());
912 assertSame(f, pollTask());
913 helpQuiesce();
914 checkNotDone(f);
915 checkCompletedNormally(g);
916 }};
917 testInvokeOnPool(singletonPool(), a);
918 }
919
920 /**
921 * peekNextLocalTask returns least recent unexecuted task in async mode
922 */
923 public void testPeekNextLocalTaskAsync() {
924 RecursiveAction a = new CheckedRecursiveAction() {
925 protected void realCompute() {
926 AsyncFib g = new AsyncFib(9);
927 assertSame(g, g.fork());
928 AsyncFib f = new AsyncFib(8);
929 assertSame(f, f.fork());
930 assertSame(g, peekNextLocalTask());
931 assertNull(f.join());
932 helpQuiesce();
933 checkCompletedNormally(f);
934 assertEquals(34, g.number);
935 checkCompletedNormally(g);
936 }};
937 testInvokeOnPool(asyncSingletonPool(), a);
938 }
939
940 /**
941 * pollNextLocalTask returns least recent unexecuted task without
942 * executing it, in async mode
943 */
944 public void testPollNextLocalTaskAsync() {
945 RecursiveAction a = new CheckedRecursiveAction() {
946 protected void realCompute() {
947 AsyncFib g = new AsyncFib(9);
948 assertSame(g, g.fork());
949 AsyncFib f = new AsyncFib(8);
950 assertSame(f, f.fork());
951 assertSame(g, pollNextLocalTask());
952 helpQuiesce();
953 assertEquals(21, f.number);
954 checkCompletedNormally(f);
955 checkNotDone(g);
956 }};
957 testInvokeOnPool(asyncSingletonPool(), a);
958 }
959
960 /**
961 * pollTask returns an unexecuted task without executing it, in
962 * async mode
963 */
964 public void testPollTaskAsync() {
965 RecursiveAction a = new CheckedRecursiveAction() {
966 protected void realCompute() {
967 AsyncFib g = new AsyncFib(9);
968 assertSame(g, g.fork());
969 AsyncFib f = new AsyncFib(8);
970 assertSame(f, f.fork());
971 assertSame(g, pollTask());
972 helpQuiesce();
973 assertEquals(21, f.number);
974 checkCompletedNormally(f);
975 checkNotDone(g);
976 }};
977 testInvokeOnPool(asyncSingletonPool(), a);
978 }
979
980 // versions for singleton pools
981
982 /**
983 * invoke returns when task completes normally.
984 * isCompletedAbnormally and isCancelled return false for normally
985 * completed tasks; getRawResult returns null.
986 */
987 public void testInvokeSingleton() {
988 RecursiveAction a = new CheckedRecursiveAction() {
989 protected void realCompute() {
990 AsyncFib f = new AsyncFib(8);
991 assertNull(f.invoke());
992 assertEquals(21, f.number);
993 checkCompletedNormally(f);
994 }};
995 testInvokeOnPool(singletonPool(), a);
996 }
997
998 /**
999 * quietlyInvoke task returns when task completes normally.
1000 * isCompletedAbnormally and isCancelled return false for normally
1001 * completed tasks
1002 */
1003 public void testQuietlyInvokeSingleton() {
1004 RecursiveAction a = new CheckedRecursiveAction() {
1005 protected void realCompute() {
1006 AsyncFib f = new AsyncFib(8);
1007 f.quietlyInvoke();
1008 assertEquals(21, f.number);
1009 checkCompletedNormally(f);
1010 }};
1011 testInvokeOnPool(singletonPool(), a);
1012 }
1013
1014 /**
1015 * join of a forked task returns when task completes
1016 */
1017 public void testForkJoinSingleton() {
1018 RecursiveAction a = new CheckedRecursiveAction() {
1019 protected void realCompute() {
1020 AsyncFib f = new AsyncFib(8);
1021 assertSame(f, f.fork());
1022 assertNull(f.join());
1023 assertEquals(21, f.number);
1024 checkCompletedNormally(f);
1025 }};
1026 testInvokeOnPool(singletonPool(), a);
1027 }
1028
1029 /**
1030 * get of a forked task returns when task completes
1031 */
1032 public void testForkGetSingleton() {
1033 RecursiveAction a = new CheckedRecursiveAction() {
1034 protected void realCompute() throws Exception {
1035 AsyncFib f = new AsyncFib(8);
1036 assertSame(f, f.fork());
1037 assertNull(f.get());
1038 assertEquals(21, f.number);
1039 checkCompletedNormally(f);
1040 }};
1041 testInvokeOnPool(singletonPool(), a);
1042 }
1043
1044 /**
1045 * timed get of a forked task returns when task completes
1046 */
1047 public void testForkTimedGetSingleton() {
1048 RecursiveAction a = new CheckedRecursiveAction() {
1049 protected void realCompute() throws Exception {
1050 AsyncFib f = new AsyncFib(8);
1051 assertSame(f, f.fork());
1052 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
1053 assertEquals(21, f.number);
1054 checkCompletedNormally(f);
1055 }};
1056 testInvokeOnPool(singletonPool(), a);
1057 }
1058
1059 /**
1060 * timed get with null time unit throws NPE
1061 */
1062 public void testForkTimedGetNPESingleton() {
1063 RecursiveAction a = new CheckedRecursiveAction() {
1064 protected void realCompute() throws Exception {
1065 AsyncFib f = new AsyncFib(8);
1066 assertSame(f, f.fork());
1067 try {
1068 f.get(5L, null);
1069 shouldThrow();
1070 } catch (NullPointerException success) {}
1071 }};
1072 testInvokeOnPool(singletonPool(), a);
1073 }
1074
1075 /**
1076 * quietlyJoin of a forked task returns when task completes
1077 */
1078 public void testForkQuietlyJoinSingleton() {
1079 RecursiveAction a = new CheckedRecursiveAction() {
1080 protected void realCompute() {
1081 AsyncFib f = new AsyncFib(8);
1082 assertSame(f, f.fork());
1083 f.quietlyJoin();
1084 assertEquals(21, f.number);
1085 checkCompletedNormally(f);
1086 }};
1087 testInvokeOnPool(singletonPool(), a);
1088 }
1089
1090 /**
1091 * helpQuiesce returns when tasks are complete.
1092 * getQueuedTaskCount returns 0 when quiescent
1093 */
1094 public void testForkHelpQuiesceSingleton() {
1095 RecursiveAction a = new CheckedRecursiveAction() {
1096 protected void realCompute() {
1097 AsyncFib f = new AsyncFib(8);
1098 assertSame(f, f.fork());
1099 helpQuiesce();
1100 assertEquals(0, getQueuedTaskCount());
1101 assertEquals(21, f.number);
1102 checkCompletedNormally(f);
1103 }};
1104 testInvokeOnPool(singletonPool(), a);
1105 }
1106
1107 /**
1108 * invoke task throws exception when task completes abnormally
1109 */
1110 public void testAbnormalInvokeSingleton() {
1111 RecursiveAction a = new CheckedRecursiveAction() {
1112 protected void realCompute() {
1113 FailingAsyncFib f = new FailingAsyncFib(8);
1114 try {
1115 f.invoke();
1116 shouldThrow();
1117 } catch (FJException success) {
1118 checkCompletedAbnormally(f, success);
1119 }
1120 }};
1121 testInvokeOnPool(singletonPool(), a);
1122 }
1123
1124 /**
1125 * quietlyInvoke task returns when task completes abnormally
1126 */
1127 public void testAbnormalQuietlyInvokeSingleton() {
1128 RecursiveAction a = new CheckedRecursiveAction() {
1129 protected void realCompute() {
1130 FailingAsyncFib f = new FailingAsyncFib(8);
1131 f.quietlyInvoke();
1132 assertTrue(f.getException() instanceof FJException);
1133 checkCompletedAbnormally(f, f.getException());
1134 }};
1135 testInvokeOnPool(singletonPool(), a);
1136 }
1137
1138 /**
1139 * join of a forked task throws exception when task completes abnormally
1140 */
1141 public void testAbnormalForkJoinSingleton() {
1142 RecursiveAction a = new CheckedRecursiveAction() {
1143 protected void realCompute() {
1144 FailingAsyncFib f = new FailingAsyncFib(8);
1145 assertSame(f, f.fork());
1146 try {
1147 f.join();
1148 shouldThrow();
1149 } catch (FJException success) {
1150 checkCompletedAbnormally(f, success);
1151 }
1152 }};
1153 testInvokeOnPool(singletonPool(), a);
1154 }
1155
1156 /**
1157 * get of a forked task throws exception when task completes abnormally
1158 */
1159 public void testAbnormalForkGetSingleton() {
1160 RecursiveAction a = new CheckedRecursiveAction() {
1161 protected void realCompute() throws Exception {
1162 FailingAsyncFib f = new FailingAsyncFib(8);
1163 assertSame(f, f.fork());
1164 try {
1165 f.get();
1166 shouldThrow();
1167 } catch (ExecutionException success) {
1168 Throwable cause = success.getCause();
1169 assertTrue(cause instanceof FJException);
1170 checkCompletedAbnormally(f, cause);
1171 }
1172 }};
1173 testInvokeOnPool(singletonPool(), a);
1174 }
1175
1176 /**
1177 * timed get of a forked task throws exception when task completes abnormally
1178 */
1179 public void testAbnormalForkTimedGetSingleton() {
1180 RecursiveAction a = new CheckedRecursiveAction() {
1181 protected void realCompute() throws Exception {
1182 FailingAsyncFib f = new FailingAsyncFib(8);
1183 assertSame(f, f.fork());
1184 try {
1185 f.get(LONG_DELAY_MS, MILLISECONDS);
1186 shouldThrow();
1187 } catch (ExecutionException success) {
1188 Throwable cause = success.getCause();
1189 assertTrue(cause instanceof FJException);
1190 checkCompletedAbnormally(f, cause);
1191 }
1192 }};
1193 testInvokeOnPool(singletonPool(), a);
1194 }
1195
1196 /**
1197 * quietlyJoin of a forked task returns when task completes abnormally
1198 */
1199 public void testAbnormalForkQuietlyJoinSingleton() {
1200 RecursiveAction a = new CheckedRecursiveAction() {
1201 protected void realCompute() {
1202 FailingAsyncFib f = new FailingAsyncFib(8);
1203 assertSame(f, f.fork());
1204 f.quietlyJoin();
1205 assertTrue(f.getException() instanceof FJException);
1206 checkCompletedAbnormally(f, f.getException());
1207 }};
1208 testInvokeOnPool(singletonPool(), a);
1209 }
1210
1211 /**
1212 * invoke task throws exception after invoking completeExceptionally
1213 */
1214 public void testCompleteExceptionallySingleton() {
1215 RecursiveAction a = new CheckedRecursiveAction() {
1216 protected void realCompute() {
1217 AsyncFib f = new AsyncFib(8);
1218 f.completeExceptionally(new FJException());
1219 try {
1220 f.invoke();
1221 shouldThrow();
1222 } catch (FJException success) {
1223 checkCompletedAbnormally(f, success);
1224 }
1225 }};
1226 testInvokeOnPool(singletonPool(), a);
1227 }
1228
1229 /**
1230 * invokeAll(t1, t2) invokes all task arguments
1231 */
1232 public void testInvokeAll2Singleton() {
1233 RecursiveAction a = new CheckedRecursiveAction() {
1234 protected void realCompute() {
1235 AsyncFib f = new AsyncFib(8);
1236 AsyncFib g = new AsyncFib(9);
1237 invokeAll(f, g);
1238 assertEquals(21, f.number);
1239 assertEquals(34, g.number);
1240 checkCompletedNormally(f);
1241 checkCompletedNormally(g);
1242 }};
1243 testInvokeOnPool(singletonPool(), a);
1244 }
1245
1246 /**
1247 * invokeAll(tasks) with 1 argument invokes task
1248 */
1249 public void testInvokeAll1Singleton() {
1250 RecursiveAction a = new CheckedRecursiveAction() {
1251 protected void realCompute() {
1252 AsyncFib f = new AsyncFib(8);
1253 invokeAll(f);
1254 checkCompletedNormally(f);
1255 assertEquals(21, f.number);
1256 }};
1257 testInvokeOnPool(singletonPool(), a);
1258 }
1259
1260 /**
1261 * invokeAll(tasks) with > 2 argument invokes tasks
1262 */
1263 public void testInvokeAll3Singleton() {
1264 RecursiveAction a = new CheckedRecursiveAction() {
1265 protected void realCompute() {
1266 AsyncFib f = new AsyncFib(8);
1267 AsyncFib g = new AsyncFib(9);
1268 AsyncFib h = new AsyncFib(7);
1269 invokeAll(f, g, h);
1270 assertEquals(21, f.number);
1271 assertEquals(34, g.number);
1272 assertEquals(13, h.number);
1273 checkCompletedNormally(f);
1274 checkCompletedNormally(g);
1275 checkCompletedNormally(h);
1276 }};
1277 testInvokeOnPool(singletonPool(), a);
1278 }
1279
1280 /**
1281 * invokeAll(collection) invokes all tasks in the collection
1282 */
1283 public void testInvokeAllCollectionSingleton() {
1284 RecursiveAction a = new CheckedRecursiveAction() {
1285 protected void realCompute() {
1286 AsyncFib f = new AsyncFib(8);
1287 AsyncFib g = new AsyncFib(9);
1288 AsyncFib h = new AsyncFib(7);
1289 HashSet set = new HashSet();
1290 set.add(f);
1291 set.add(g);
1292 set.add(h);
1293 invokeAll(set);
1294 assertEquals(21, f.number);
1295 assertEquals(34, g.number);
1296 assertEquals(13, h.number);
1297 checkCompletedNormally(f);
1298 checkCompletedNormally(g);
1299 checkCompletedNormally(h);
1300 }};
1301 testInvokeOnPool(singletonPool(), a);
1302 }
1303
1304 /**
1305 * invokeAll(tasks) with any null task throws NPE
1306 */
1307 public void testInvokeAllNPESingleton() {
1308 RecursiveAction a = new CheckedRecursiveAction() {
1309 protected void realCompute() {
1310 AsyncFib f = new AsyncFib(8);
1311 AsyncFib g = new AsyncFib(9);
1312 AsyncFib h = null;
1313 try {
1314 invokeAll(f, g, h);
1315 shouldThrow();
1316 } catch (NullPointerException success) {}
1317 }};
1318 testInvokeOnPool(singletonPool(), a);
1319 }
1320
1321 /**
1322 * invokeAll(t1, t2) throw exception if any task does
1323 */
1324 public void testAbnormalInvokeAll2Singleton() {
1325 RecursiveAction a = new CheckedRecursiveAction() {
1326 protected void realCompute() {
1327 AsyncFib f = new AsyncFib(8);
1328 FailingAsyncFib g = new FailingAsyncFib(9);
1329 try {
1330 invokeAll(f, g);
1331 shouldThrow();
1332 } catch (FJException success) {
1333 checkCompletedAbnormally(g, success);
1334 }
1335 }};
1336 testInvokeOnPool(singletonPool(), a);
1337 }
1338
1339 /**
1340 * invokeAll(tasks) with 1 argument throws exception if task does
1341 */
1342 public void testAbnormalInvokeAll1Singleton() {
1343 RecursiveAction a = new CheckedRecursiveAction() {
1344 protected void realCompute() {
1345 FailingAsyncFib g = new FailingAsyncFib(9);
1346 try {
1347 invokeAll(g);
1348 shouldThrow();
1349 } catch (FJException success) {
1350 checkCompletedAbnormally(g, success);
1351 }
1352 }};
1353 testInvokeOnPool(singletonPool(), a);
1354 }
1355
1356 /**
1357 * invokeAll(tasks) with > 2 argument throws exception if any task does
1358 */
1359 public void testAbnormalInvokeAll3Singleton() {
1360 RecursiveAction a = new CheckedRecursiveAction() {
1361 protected void realCompute() {
1362 AsyncFib f = new AsyncFib(8);
1363 FailingAsyncFib g = new FailingAsyncFib(9);
1364 AsyncFib h = new AsyncFib(7);
1365 try {
1366 invokeAll(f, g, h);
1367 shouldThrow();
1368 } catch (FJException success) {
1369 checkCompletedAbnormally(g, success);
1370 }
1371 }};
1372 testInvokeOnPool(singletonPool(), a);
1373 }
1374
1375 /**
1376 * invokeAll(collection) throws exception if any task does
1377 */
1378 public void testAbnormalInvokeAllCollectionSingleton() {
1379 RecursiveAction a = new CheckedRecursiveAction() {
1380 protected void realCompute() {
1381 FailingAsyncFib f = new FailingAsyncFib(8);
1382 AsyncFib g = new AsyncFib(9);
1383 AsyncFib h = new AsyncFib(7);
1384 HashSet set = new HashSet();
1385 set.add(f);
1386 set.add(g);
1387 set.add(h);
1388 try {
1389 invokeAll(set);
1390 shouldThrow();
1391 } catch (FJException success) {
1392 checkCompletedAbnormally(f, success);
1393 }
1394 }};
1395 testInvokeOnPool(singletonPool(), a);
1396 }
1397
1398
1399 /**
1400 * ForkJoinTask.quietlyComplete returns when task completes
1401 * normally without setting a value. The most recent value
1402 * established by setRawResult(V) (or null by default) is returned
1403 * from invoke.
1404 */
1405 public void testQuietlyComplete() {
1406 RecursiveAction a = new CheckedRecursiveAction() {
1407 protected void realCompute() {
1408 AsyncFib f = new AsyncFib(8);
1409 f.quietlyComplete();
1410 assertEquals(8, f.number);
1411 assertTrue(f.isDone());
1412 assertFalse(f.isCancelled());
1413 assertTrue(f.isCompletedNormally());
1414 assertFalse(f.isCompletedAbnormally());
1415 assertNull(f.getException());
1416 }};
1417 testInvokeOnPool(mainPool(), a);
1418 }
1419
1420 }