ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.28
Committed: Sat Mar 18 20:42:20 2017 UTC (7 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.27: +4 -2 lines
Log Message:
better assertion style

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