ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.9
Committed: Sat Feb 7 17:43:38 2015 UTC (9 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +7 -4 lines
Log Message:
improve testInvokeAllNPE

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