ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.2
Committed: Mon Jul 22 15:55:43 2013 UTC (10 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +4 -6 lines
Log Message:
whitespace

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 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
184 public static final class FJException extends RuntimeException {
185 FJException() { super(); }
186 }
187
188 abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
189
190 private BinaryAsyncAction parent;
191
192 private BinaryAsyncAction sibling;
193
194 protected BinaryAsyncAction() {
195 setForkJoinTaskTag(INITIAL_STATE);
196 }
197
198 public final Void getRawResult() { return null; }
199 protected final void setRawResult(Void mustBeNull) { }
200
201 public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
202 x.parent = y.parent = this;
203 x.sibling = y;
204 y.sibling = x;
205 }
206
207 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
208 if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
209 x.getForkJoinTaskTag() != COMPLETE_STATE ||
210 y.getForkJoinTaskTag() != COMPLETE_STATE) {
211 completeThisExceptionally(new FJException());
212 }
213 }
214
215 protected boolean onException() {
216 return true;
217 }
218
219 public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
220 linkSubtasks(x, y);
221 y.fork();
222 x.fork();
223 }
224
225 private void completeThis() {
226 setForkJoinTaskTag(COMPLETE_STATE);
227 super.complete(null);
228 }
229
230 private void completeThisExceptionally(Throwable ex) {
231 setForkJoinTaskTag(EXCEPTION_STATE);
232 super.completeExceptionally(ex);
233 }
234
235 public final void complete() {
236 BinaryAsyncAction a = this;
237 for (;;) {
238 BinaryAsyncAction s = a.sibling;
239 BinaryAsyncAction p = a.parent;
240 a.sibling = null;
241 a.parent = null;
242 a.completeThis();
243 if (p == null ||
244 p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
245 break;
246 try {
247 p.onComplete(a, s);
248 } catch (Throwable rex) {
249 p.completeExceptionally(rex);
250 return;
251 }
252 a = p;
253 }
254 }
255
256 public final void completeExceptionally(Throwable ex) {
257 BinaryAsyncAction a = this;
258 while (!a.isCompletedAbnormally()) {
259 a.completeThisExceptionally(ex);
260 BinaryAsyncAction s = a.sibling;
261 if (s != null)
262 s.cancel(false);
263 if (!a.onException() || (a = a.parent) == null)
264 break;
265 }
266 }
267
268 public final BinaryAsyncAction getParent() {
269 return parent;
270 }
271
272 public BinaryAsyncAction getSibling() {
273 return sibling;
274 }
275
276 public void reinitialize() {
277 parent = sibling = null;
278 super.reinitialize();
279 }
280
281
282 }
283
284 static final class AsyncFib extends BinaryAsyncAction {
285 int number;
286 public AsyncFib(int n) {
287 this.number = n;
288 }
289
290 public final boolean exec() {
291 try {
292 AsyncFib f = this;
293 int n = f.number;
294 if (n > 1) {
295 while (n > 1) {
296 AsyncFib p = f;
297 AsyncFib r = new AsyncFib(n - 2);
298 f = new AsyncFib(--n);
299 p.linkSubtasks(r, f);
300 r.fork();
301 }
302 f.number = n;
303 }
304 f.complete();
305 }
306 catch (Throwable ex) {
307 compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
308 }
309 return false;
310 }
311
312 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
313 number = ((AsyncFib)x).number + ((AsyncFib)y).number;
314 super.onComplete(x, y);
315 }
316 }
317
318 static final class FailingAsyncFib extends BinaryAsyncAction {
319 int number;
320 public FailingAsyncFib(int n) {
321 this.number = n;
322 }
323
324 public final boolean exec() {
325 FailingAsyncFib f = this;
326 int n = f.number;
327 if (n > 1) {
328 while (n > 1) {
329 FailingAsyncFib p = f;
330 FailingAsyncFib r = new FailingAsyncFib(n - 2);
331 f = new FailingAsyncFib(--n);
332 p.linkSubtasks(r, f);
333 r.fork();
334 }
335 f.number = n;
336 }
337 f.complete();
338 return false;
339 }
340
341 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
342 completeExceptionally(new FJException());
343 }
344 }
345
346 /**
347 * invoke returns when task completes normally.
348 * isCompletedAbnormally and isCancelled return false for normally
349 * completed tasks; getRawResult returns null.
350 */
351 public void testInvoke() {
352 RecursiveAction a = new CheckedRecursiveAction() {
353 protected void realCompute() {
354 AsyncFib f = new AsyncFib(8);
355 assertNull(f.invoke());
356 assertEquals(21, f.number);
357 checkCompletedNormally(f);
358 }};
359 testInvokeOnPool(mainPool(), a);
360 }
361
362 /**
363 * quietlyInvoke task returns when task completes normally.
364 * isCompletedAbnormally and isCancelled return false for normally
365 * completed tasks
366 */
367 public void testQuietlyInvoke() {
368 RecursiveAction a = new CheckedRecursiveAction() {
369 protected void realCompute() {
370 AsyncFib f = new AsyncFib(8);
371 f.quietlyInvoke();
372 assertEquals(21, f.number);
373 checkCompletedNormally(f);
374 }};
375 testInvokeOnPool(mainPool(), a);
376 }
377
378 /**
379 * join of a forked task returns when task completes
380 */
381 public void testForkJoin() {
382 RecursiveAction a = new CheckedRecursiveAction() {
383 protected void realCompute() {
384 AsyncFib f = new AsyncFib(8);
385 assertSame(f, f.fork());
386 assertNull(f.join());
387 assertEquals(21, f.number);
388 checkCompletedNormally(f);
389 }};
390 testInvokeOnPool(mainPool(), a);
391 }
392
393 /**
394 * get of a forked task returns when task completes
395 */
396 public void testForkGet() {
397 RecursiveAction a = new CheckedRecursiveAction() {
398 protected void realCompute() throws Exception {
399 AsyncFib f = new AsyncFib(8);
400 assertSame(f, f.fork());
401 assertNull(f.get());
402 assertEquals(21, f.number);
403 checkCompletedNormally(f);
404 }};
405 testInvokeOnPool(mainPool(), a);
406 }
407
408 /**
409 * timed get of a forked task returns when task completes
410 */
411 public void testForkTimedGet() {
412 RecursiveAction a = new CheckedRecursiveAction() {
413 protected void realCompute() throws Exception {
414 AsyncFib f = new AsyncFib(8);
415 assertSame(f, f.fork());
416 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
417 assertEquals(21, f.number);
418 checkCompletedNormally(f);
419 }};
420 testInvokeOnPool(mainPool(), a);
421 }
422
423 /**
424 * timed get with null time unit throws NPE
425 */
426 public void testForkTimedGetNPE() {
427 RecursiveAction a = new CheckedRecursiveAction() {
428 protected void realCompute() throws Exception {
429 AsyncFib f = new AsyncFib(8);
430 assertSame(f, f.fork());
431 try {
432 f.get(5L, null);
433 shouldThrow();
434 } catch (NullPointerException success) {}
435 }};
436 testInvokeOnPool(mainPool(), a);
437 }
438
439 /**
440 * quietlyJoin of a forked task returns when task completes
441 */
442 public void testForkQuietlyJoin() {
443 RecursiveAction a = new CheckedRecursiveAction() {
444 protected void realCompute() {
445 AsyncFib f = new AsyncFib(8);
446 assertSame(f, f.fork());
447 f.quietlyJoin();
448 assertEquals(21, f.number);
449 checkCompletedNormally(f);
450 }};
451 testInvokeOnPool(mainPool(), a);
452 }
453
454 /**
455 * helpQuiesce returns when tasks are complete.
456 * getQueuedTaskCount returns 0 when quiescent
457 */
458 public void testForkHelpQuiesce() {
459 RecursiveAction a = new CheckedRecursiveAction() {
460 protected void realCompute() {
461 AsyncFib f = new AsyncFib(8);
462 assertSame(f, f.fork());
463 helpQuiesce();
464 assertEquals(21, f.number);
465 assertEquals(0, getQueuedTaskCount());
466 checkCompletedNormally(f);
467 }};
468 testInvokeOnPool(mainPool(), a);
469 }
470
471 /**
472 * invoke task throws exception when task completes abnormally
473 */
474 public void testAbnormalInvoke() {
475 RecursiveAction a = new CheckedRecursiveAction() {
476 protected void realCompute() {
477 FailingAsyncFib f = new FailingAsyncFib(8);
478 try {
479 f.invoke();
480 shouldThrow();
481 } catch (FJException success) {
482 checkCompletedAbnormally(f, success);
483 }
484 }};
485 testInvokeOnPool(mainPool(), a);
486 }
487
488 /**
489 * quietlyInvoke task returns when task completes abnormally
490 */
491 public void testAbnormalQuietlyInvoke() {
492 RecursiveAction a = new CheckedRecursiveAction() {
493 protected void realCompute() {
494 FailingAsyncFib f = new FailingAsyncFib(8);
495 f.quietlyInvoke();
496 assertTrue(f.getException() instanceof FJException);
497 checkCompletedAbnormally(f, f.getException());
498 }};
499 testInvokeOnPool(mainPool(), a);
500 }
501
502 /**
503 * join of a forked task throws exception when task completes abnormally
504 */
505 public void testAbnormalForkJoin() {
506 RecursiveAction a = new CheckedRecursiveAction() {
507 protected void realCompute() {
508 FailingAsyncFib f = new FailingAsyncFib(8);
509 assertSame(f, f.fork());
510 try {
511 f.join();
512 shouldThrow();
513 } catch (FJException success) {
514 checkCompletedAbnormally(f, success);
515 }
516 }};
517 testInvokeOnPool(mainPool(), a);
518 }
519
520 /**
521 * get of a forked task throws exception when task completes abnormally
522 */
523 public void testAbnormalForkGet() {
524 RecursiveAction a = new CheckedRecursiveAction() {
525 protected void realCompute() throws Exception {
526 FailingAsyncFib f = new FailingAsyncFib(8);
527 assertSame(f, f.fork());
528 try {
529 f.get();
530 shouldThrow();
531 } catch (ExecutionException success) {
532 Throwable cause = success.getCause();
533 assertTrue(cause instanceof FJException);
534 checkCompletedAbnormally(f, cause);
535 }
536 }};
537 testInvokeOnPool(mainPool(), a);
538 }
539
540 /**
541 * timed get of a forked task throws exception when task completes abnormally
542 */
543 public void testAbnormalForkTimedGet() {
544 RecursiveAction a = new CheckedRecursiveAction() {
545 protected void realCompute() throws Exception {
546 FailingAsyncFib f = new FailingAsyncFib(8);
547 assertSame(f, f.fork());
548 try {
549 f.get(LONG_DELAY_MS, MILLISECONDS);
550 shouldThrow();
551 } catch (ExecutionException success) {
552 Throwable cause = success.getCause();
553 assertTrue(cause instanceof FJException);
554 checkCompletedAbnormally(f, cause);
555 }
556 }};
557 testInvokeOnPool(mainPool(), a);
558 }
559
560 /**
561 * quietlyJoin of a forked task returns when task completes abnormally
562 */
563 public void testAbnormalForkQuietlyJoin() {
564 RecursiveAction a = new CheckedRecursiveAction() {
565 protected void realCompute() {
566 FailingAsyncFib f = new FailingAsyncFib(8);
567 assertSame(f, f.fork());
568 f.quietlyJoin();
569 assertTrue(f.getException() instanceof FJException);
570 checkCompletedAbnormally(f, f.getException());
571 }};
572 testInvokeOnPool(mainPool(), a);
573 }
574
575
576 /**
577 * getPool of executing task returns its pool
578 */
579 public void testGetPool() {
580 final ForkJoinPool mainPool = mainPool();
581 RecursiveAction a = new CheckedRecursiveAction() {
582 protected void realCompute() {
583 assertSame(mainPool, getPool());
584 }};
585 testInvokeOnPool(mainPool, a);
586 }
587
588 /**
589 * getPool of non-FJ task returns null
590 */
591 public void testGetPool2() {
592 RecursiveAction a = new CheckedRecursiveAction() {
593 protected void realCompute() {
594 assertNull(getPool());
595 }};
596 assertNull(a.invoke());
597 }
598
599 /**
600 * inForkJoinPool of executing task returns true
601 */
602 public void testInForkJoinPool() {
603 RecursiveAction a = new CheckedRecursiveAction() {
604 protected void realCompute() {
605 assertTrue(inForkJoinPool());
606 }};
607 testInvokeOnPool(mainPool(), a);
608 }
609
610 /**
611 * inForkJoinPool of non-FJ task returns false
612 */
613 public void testInForkJoinPool2() {
614 RecursiveAction a = new CheckedRecursiveAction() {
615 protected void realCompute() {
616 assertFalse(inForkJoinPool());
617 }};
618 assertNull(a.invoke());
619 }
620
621 /**
622 * setRawResult(null) succeeds
623 */
624 public void testSetRawResult() {
625 RecursiveAction a = new CheckedRecursiveAction() {
626 protected void realCompute() {
627 setRawResult(null);
628 assertNull(getRawResult());
629 }};
630 assertNull(a.invoke());
631 }
632
633 /**
634 * invoke task throws exception after invoking completeExceptionally
635 */
636 public void testCompleteExceptionally() {
637 RecursiveAction a = new CheckedRecursiveAction() {
638 protected void realCompute() {
639 AsyncFib f = new AsyncFib(8);
640 f.completeExceptionally(new FJException());
641 try {
642 f.invoke();
643 shouldThrow();
644 } catch (FJException success) {
645 checkCompletedAbnormally(f, success);
646 }
647 }};
648 testInvokeOnPool(mainPool(), a);
649 }
650
651 /**
652 * invokeAll(t1, t2) invokes all task arguments
653 */
654 public void testInvokeAll2() {
655 RecursiveAction a = new CheckedRecursiveAction() {
656 protected void realCompute() {
657 AsyncFib f = new AsyncFib(8);
658 AsyncFib g = new AsyncFib(9);
659 invokeAll(f, g);
660 assertEquals(21, f.number);
661 assertEquals(34, g.number);
662 checkCompletedNormally(f);
663 checkCompletedNormally(g);
664 }};
665 testInvokeOnPool(mainPool(), a);
666 }
667
668 /**
669 * invokeAll(tasks) with 1 argument invokes task
670 */
671 public void testInvokeAll1() {
672 RecursiveAction a = new CheckedRecursiveAction() {
673 protected void realCompute() {
674 AsyncFib f = new AsyncFib(8);
675 invokeAll(f);
676 checkCompletedNormally(f);
677 assertEquals(21, f.number);
678 }};
679 testInvokeOnPool(mainPool(), a);
680 }
681
682 /**
683 * invokeAll(tasks) with > 2 argument invokes tasks
684 */
685 public void testInvokeAll3() {
686 RecursiveAction a = new CheckedRecursiveAction() {
687 protected void realCompute() {
688 AsyncFib f = new AsyncFib(8);
689 AsyncFib g = new AsyncFib(9);
690 AsyncFib h = new AsyncFib(7);
691 invokeAll(f, g, h);
692 assertEquals(21, f.number);
693 assertEquals(34, g.number);
694 assertEquals(13, h.number);
695 checkCompletedNormally(f);
696 checkCompletedNormally(g);
697 checkCompletedNormally(h);
698 }};
699 testInvokeOnPool(mainPool(), a);
700 }
701
702 /**
703 * invokeAll(collection) invokes all tasks in the collection
704 */
705 public void testInvokeAllCollection() {
706 RecursiveAction a = new CheckedRecursiveAction() {
707 protected void realCompute() {
708 AsyncFib f = new AsyncFib(8);
709 AsyncFib g = new AsyncFib(9);
710 AsyncFib h = new AsyncFib(7);
711 HashSet set = new HashSet();
712 set.add(f);
713 set.add(g);
714 set.add(h);
715 invokeAll(set);
716 assertEquals(21, f.number);
717 assertEquals(34, g.number);
718 assertEquals(13, h.number);
719 checkCompletedNormally(f);
720 checkCompletedNormally(g);
721 checkCompletedNormally(h);
722 }};
723 testInvokeOnPool(mainPool(), a);
724 }
725
726 /**
727 * invokeAll(tasks) with any null task throws NPE
728 */
729 public void testInvokeAllNPE() {
730 RecursiveAction a = new CheckedRecursiveAction() {
731 protected void realCompute() {
732 AsyncFib f = new AsyncFib(8);
733 AsyncFib g = new AsyncFib(9);
734 AsyncFib h = null;
735 try {
736 invokeAll(f, g, h);
737 shouldThrow();
738 } catch (NullPointerException success) {}
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 }