ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.10
Committed: Sat Feb 7 17:49:11 2015 UTC (9 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +8 -7 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 NullPointerException
725 */
726 public void testInvokeAllNullTask() {
727 RecursiveAction a = new CheckedRecursiveAction() {
728 protected void realCompute() {
729 AsyncFib f = new AsyncFib(8);
730 AsyncFib g = new AsyncFib(9);
731 AsyncFib nul = null;
732 Runnable[] throwingActions = {
733 () -> invokeAll(nul),
734 () -> invokeAll(nul, nul),
735 () -> invokeAll(f, g, nul),
736 () -> invokeAll(f, nul, g),
737 () -> invokeAll(nul, f, g),
738 };
739 assertThrows(NullPointerException.class, throwingActions);
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 * ForkJoinTask.quietlyComplete returns when task completes
1400 * normally without setting a value. The most recent value
1401 * established by setRawResult(V) (or null by default) is returned
1402 * from invoke.
1403 */
1404 public void testQuietlyComplete() {
1405 RecursiveAction a = new CheckedRecursiveAction() {
1406 protected void realCompute() {
1407 AsyncFib f = new AsyncFib(8);
1408 f.quietlyComplete();
1409 assertEquals(8, f.number);
1410 assertTrue(f.isDone());
1411 assertFalse(f.isCancelled());
1412 assertTrue(f.isCompletedNormally());
1413 assertFalse(f.isCompletedAbnormally());
1414 assertNull(f.getException());
1415 }};
1416 testInvokeOnPool(mainPool(), a);
1417 }
1418
1419 }