ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.33
Committed: Fri Feb 22 19:27:47 2019 UTC (5 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.32: +3 -4 lines
Log Message:
improve assertThrows tests

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
9 import java.util.Arrays;
10 import java.util.concurrent.CountDownLatch;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.ForkJoinPool;
13 import java.util.concurrent.ForkJoinTask;
14 import java.util.concurrent.ForkJoinWorkerThread;
15 import java.util.concurrent.RecursiveAction;
16 import java.util.concurrent.TimeoutException;
17
18 import junit.framework.Test;
19 import junit.framework.TestSuite;
20
21 public class ForkJoinTask8Test extends JSR166TestCase {
22
23 /*
24 * Testing notes: This differs from ForkJoinTaskTest mainly by
25 * defining a version of BinaryAsyncAction that uses JDK8 task
26 * tags for control state, thereby testing getForkJoinTaskTag,
27 * setForkJoinTaskTag, and compareAndSetForkJoinTaskTag across
28 * various contexts. Most of the test methods using it are
29 * otherwise identical, but omitting retest of those dealing with
30 * cancellation, which is not represented in this tag scheme.
31 */
32
33 static final short INITIAL_STATE = -1;
34 static final short COMPLETE_STATE = 0;
35 static final short EXCEPTION_STATE = 1;
36
37 public static void main(String[] args) {
38 main(suite(), args);
39 }
40
41 public static Test suite() {
42 return new TestSuite(ForkJoinTask8Test.class);
43 }
44
45 // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
46 static final int mainPoolSize =
47 Math.max(2, Runtime.getRuntime().availableProcessors());
48
49 private static ForkJoinPool mainPool() {
50 return new ForkJoinPool(mainPoolSize);
51 }
52
53 private static ForkJoinPool singletonPool() {
54 return new ForkJoinPool(1);
55 }
56
57 private static ForkJoinPool asyncSingletonPool() {
58 return new ForkJoinPool(1,
59 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
60 null, true);
61 }
62
63 // Compute fib naively and efficiently
64 final int[] fib;
65 {
66 int[] fib = new int[10];
67 fib[0] = 0;
68 fib[1] = 1;
69 for (int i = 2; i < fib.length; i++)
70 fib[i] = fib[i - 1] + fib[i - 2];
71 this.fib = fib;
72 }
73
74 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
75 try (PoolCleaner cleaner = cleaner(pool)) {
76 assertFalse(a.isDone());
77 assertFalse(a.isCompletedNormally());
78 assertFalse(a.isCompletedAbnormally());
79 assertFalse(a.isCancelled());
80 assertNull(a.getException());
81 assertNull(a.getRawResult());
82
83 assertNull(pool.invoke(a));
84
85 assertTrue(a.isDone());
86 assertTrue(a.isCompletedNormally());
87 assertFalse(a.isCompletedAbnormally());
88 assertFalse(a.isCancelled());
89 assertNull(a.getException());
90 assertNull(a.getRawResult());
91 }
92 }
93
94 void checkNotDone(ForkJoinTask a) {
95 assertFalse(a.isDone());
96 assertFalse(a.isCompletedNormally());
97 assertFalse(a.isCompletedAbnormally());
98 assertFalse(a.isCancelled());
99 assertNull(a.getException());
100 assertNull(a.getRawResult());
101 if (a instanceof BinaryAsyncAction)
102 assertEquals(INITIAL_STATE,
103 ((BinaryAsyncAction)a).getForkJoinTaskTag());
104
105 try {
106 a.get(randomExpiredTimeout(), randomTimeUnit());
107 shouldThrow();
108 } catch (TimeoutException success) {
109 } catch (Throwable fail) { threadUnexpectedException(fail); }
110 }
111
112 <T> void checkCompletedNormally(ForkJoinTask<T> a) {
113 checkCompletedNormally(a, null);
114 }
115
116 <T> void checkCompletedNormally(ForkJoinTask<T> a, T expectedValue) {
117 assertTrue(a.isDone());
118 assertFalse(a.isCancelled());
119 assertTrue(a.isCompletedNormally());
120 assertFalse(a.isCompletedAbnormally());
121 assertNull(a.getException());
122 assertSame(expectedValue, a.getRawResult());
123 if (a instanceof BinaryAsyncAction)
124 assertEquals(COMPLETE_STATE,
125 ((BinaryAsyncAction)a).getForkJoinTaskTag());
126
127 {
128 Thread.currentThread().interrupt();
129 long startTime = System.nanoTime();
130 assertSame(expectedValue, a.join());
131 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
132 Thread.interrupted();
133 }
134
135 {
136 Thread.currentThread().interrupt();
137 long startTime = System.nanoTime();
138 a.quietlyJoin(); // should be no-op
139 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
140 Thread.interrupted();
141 }
142
143 assertFalse(a.cancel(false));
144 assertFalse(a.cancel(true));
145
146 T v1 = null, v2 = null;
147 try {
148 v1 = a.get();
149 v2 = a.get(randomTimeout(), randomTimeUnit());
150 } catch (Throwable fail) { threadUnexpectedException(fail); }
151 assertSame(expectedValue, v1);
152 assertSame(expectedValue, v2);
153 }
154
155 void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
156 assertTrue(a.isDone());
157 assertFalse(a.isCancelled());
158 assertFalse(a.isCompletedNormally());
159 assertTrue(a.isCompletedAbnormally());
160 assertSame(t.getClass(), a.getException().getClass());
161 assertNull(a.getRawResult());
162 assertFalse(a.cancel(false));
163 assertFalse(a.cancel(true));
164 if (a instanceof BinaryAsyncAction)
165 assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() != INITIAL_STATE);
166
167 try {
168 Thread.currentThread().interrupt();
169 a.join();
170 shouldThrow();
171 } catch (Throwable expected) {
172 assertSame(t.getClass(), expected.getClass());
173 }
174 Thread.interrupted();
175
176 {
177 long startTime = System.nanoTime();
178 a.quietlyJoin(); // should be no-op
179 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
180 }
181
182 try {
183 a.get();
184 shouldThrow();
185 } catch (ExecutionException success) {
186 assertSame(t.getClass(), success.getCause().getClass());
187 } catch (Throwable fail) { threadUnexpectedException(fail); }
188
189 try {
190 a.get(randomTimeout(), randomTimeUnit());
191 shouldThrow();
192 } catch (ExecutionException success) {
193 assertSame(t.getClass(), success.getCause().getClass());
194 } catch (Throwable fail) { threadUnexpectedException(fail); }
195 }
196
197 public static final class FJException extends RuntimeException {
198 FJException() { super(); }
199 }
200
201 abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
202
203 private volatile BinaryAsyncAction parent;
204
205 private volatile BinaryAsyncAction sibling;
206
207 protected BinaryAsyncAction() {
208 setForkJoinTaskTag(INITIAL_STATE);
209 }
210
211 public final Void getRawResult() { return null; }
212 protected final void setRawResult(Void mustBeNull) { }
213
214 public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
215 x.parent = y.parent = this;
216 x.sibling = y;
217 y.sibling = x;
218 }
219
220 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
221 if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
222 x.getForkJoinTaskTag() != COMPLETE_STATE ||
223 y.getForkJoinTaskTag() != COMPLETE_STATE) {
224 completeThisExceptionally(new FJException());
225 }
226 }
227
228 protected boolean onException() {
229 return true;
230 }
231
232 public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
233 linkSubtasks(x, y);
234 y.fork();
235 x.fork();
236 }
237
238 private void completeThis() {
239 setForkJoinTaskTag(COMPLETE_STATE);
240 super.complete(null);
241 }
242
243 private void completeThisExceptionally(Throwable ex) {
244 setForkJoinTaskTag(EXCEPTION_STATE);
245 super.completeExceptionally(ex);
246 }
247
248 public boolean cancel(boolean mayInterruptIfRunning) {
249 if (super.cancel(mayInterruptIfRunning)) {
250 completeExceptionally(new FJException());
251 return true;
252 }
253 return false;
254 }
255
256 public final void complete() {
257 BinaryAsyncAction a = this;
258 for (;;) {
259 BinaryAsyncAction s = a.sibling;
260 BinaryAsyncAction p = a.parent;
261 a.sibling = null;
262 a.parent = null;
263 a.completeThis();
264 if (p == null ||
265 p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
266 break;
267 try {
268 p.onComplete(a, s);
269 } catch (Throwable rex) {
270 p.completeExceptionally(rex);
271 return;
272 }
273 a = p;
274 }
275 }
276
277 public final void completeExceptionally(Throwable ex) {
278 for (BinaryAsyncAction a = this;;) {
279 a.completeThisExceptionally(ex);
280 BinaryAsyncAction s = a.sibling;
281 if (s != null && !s.isDone())
282 s.completeExceptionally(ex);
283 if ((a = a.parent) == null)
284 break;
285 }
286 }
287
288 public final BinaryAsyncAction getParent() {
289 return parent;
290 }
291
292 public BinaryAsyncAction getSibling() {
293 return sibling;
294 }
295
296 public void reinitialize() {
297 parent = sibling = null;
298 super.reinitialize();
299 }
300
301 }
302
303 final class AsyncFib extends BinaryAsyncAction {
304 int number;
305 int expectedResult;
306 public AsyncFib(int number) {
307 this.number = number;
308 this.expectedResult = fib[number];
309 }
310
311 public final boolean exec() {
312 try {
313 AsyncFib f = this;
314 int n = f.number;
315 while (n > 1) {
316 AsyncFib p = f;
317 AsyncFib r = new AsyncFib(n - 2);
318 f = new AsyncFib(--n);
319 p.linkSubtasks(r, f);
320 r.fork();
321 }
322 f.complete();
323 }
324 catch (Throwable ex) {
325 compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
326 }
327 if (getForkJoinTaskTag() == EXCEPTION_STATE)
328 throw new FJException();
329 return false;
330 }
331
332 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
333 number = ((AsyncFib)x).number + ((AsyncFib)y).number;
334 super.onComplete(x, y);
335 }
336
337 public void checkCompletedNormally() {
338 assertEquals(expectedResult, number);
339 ForkJoinTask8Test.this.checkCompletedNormally(this);
340 }
341 }
342
343 static final class FailingAsyncFib extends BinaryAsyncAction {
344 int number;
345 public FailingAsyncFib(int n) {
346 this.number = n;
347 }
348
349 public final boolean exec() {
350 try {
351 FailingAsyncFib f = this;
352 int n = f.number;
353 while (n > 1) {
354 FailingAsyncFib p = f;
355 FailingAsyncFib r = new FailingAsyncFib(n - 2);
356 f = new FailingAsyncFib(--n);
357 p.linkSubtasks(r, f);
358 r.fork();
359 }
360 f.complete();
361 }
362 catch (Throwable ex) {
363 compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
364 }
365 if (getForkJoinTaskTag() == EXCEPTION_STATE)
366 throw new FJException();
367 return false;
368 }
369
370 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
371 completeExceptionally(new FJException());
372 }
373 }
374
375 /**
376 * invoke returns when task completes normally.
377 * isCompletedAbnormally and isCancelled return false for normally
378 * completed tasks; getRawResult returns null.
379 */
380 public void testInvoke() {
381 testInvoke(mainPool());
382 }
383 public void testInvoke_Singleton() {
384 testInvoke(singletonPool());
385 }
386 public void testInvoke(ForkJoinPool pool) {
387 RecursiveAction a = new CheckedRecursiveAction() {
388 protected void realCompute() {
389 AsyncFib f = new AsyncFib(8);
390 assertNull(f.invoke());
391 f.checkCompletedNormally();
392 }};
393 testInvokeOnPool(pool, a);
394 }
395
396 /**
397 * quietlyInvoke task returns when task completes normally.
398 * isCompletedAbnormally and isCancelled return false for normally
399 * completed tasks
400 */
401 public void testQuietlyInvoke() {
402 testQuietlyInvoke(mainPool());
403 }
404 public void testQuietlyInvoke_Singleton() {
405 testQuietlyInvoke(singletonPool());
406 }
407 public void testQuietlyInvoke(ForkJoinPool pool) {
408 RecursiveAction a = new CheckedRecursiveAction() {
409 protected void realCompute() {
410 AsyncFib f = new AsyncFib(8);
411 f.quietlyInvoke();
412 f.checkCompletedNormally();
413 }};
414 testInvokeOnPool(pool, a);
415 }
416
417 /**
418 * join of a forked task returns when task completes
419 */
420 public void testForkJoin() {
421 testForkJoin(mainPool());
422 }
423 public void testForkJoin_Singleton() {
424 testForkJoin(singletonPool());
425 }
426 public void testForkJoin(ForkJoinPool pool) {
427 RecursiveAction a = new CheckedRecursiveAction() {
428 protected void realCompute() {
429 AsyncFib f = new AsyncFib(8);
430 assertSame(f, f.fork());
431 assertNull(f.join());
432 f.checkCompletedNormally();
433 }};
434 testInvokeOnPool(pool, a);
435 }
436
437 /**
438 * get of a forked task returns when task completes
439 */
440 public void testForkGet() {
441 testForkGet(mainPool());
442 }
443 public void testForkGet_Singleton() {
444 testForkGet(singletonPool());
445 }
446 public void testForkGet(ForkJoinPool pool) {
447 RecursiveAction a = new CheckedRecursiveAction() {
448 protected void realCompute() throws Exception {
449 AsyncFib f = new AsyncFib(8);
450 assertSame(f, f.fork());
451 assertNull(f.get());
452 f.checkCompletedNormally();
453 }};
454 testInvokeOnPool(pool, a);
455 }
456
457 /**
458 * timed get of a forked task returns when task completes
459 */
460 public void testForkTimedGet() {
461 testForkTimedGet(mainPool());
462 }
463 public void testForkTimedGet_Singleton() {
464 testForkTimedGet(singletonPool());
465 }
466 public void testForkTimedGet(ForkJoinPool pool) {
467 RecursiveAction a = new CheckedRecursiveAction() {
468 protected void realCompute() throws Exception {
469 AsyncFib f = new AsyncFib(8);
470 assertSame(f, f.fork());
471 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
472 f.checkCompletedNormally();
473 }};
474 testInvokeOnPool(pool, a);
475 }
476
477 /**
478 * timed get with null time unit throws NullPointerException
479 */
480 public void testForkTimedGetNullTimeUnit() {
481 testForkTimedGetNullTimeUnit(mainPool());
482 }
483 public void testForkTimedGetNullTimeUnit_Singleton() {
484 testForkTimedGet(singletonPool());
485 }
486 public void testForkTimedGetNullTimeUnit(ForkJoinPool pool) {
487 RecursiveAction a = new CheckedRecursiveAction() {
488 protected void realCompute() throws Exception {
489 AsyncFib f = new AsyncFib(8);
490 assertSame(f, f.fork());
491 try {
492 f.get(randomTimeout(), null);
493 shouldThrow();
494 } catch (NullPointerException success) {}
495 }};
496 testInvokeOnPool(pool, a);
497 }
498
499 /**
500 * quietlyJoin of a forked task returns when task completes
501 */
502 public void testForkQuietlyJoin() {
503 testForkQuietlyJoin(mainPool());
504 }
505 public void testForkQuietlyJoin_Singleton() {
506 testForkQuietlyJoin(singletonPool());
507 }
508 public void testForkQuietlyJoin(ForkJoinPool pool) {
509 RecursiveAction a = new CheckedRecursiveAction() {
510 protected void realCompute() {
511 AsyncFib f = new AsyncFib(8);
512 assertSame(f, f.fork());
513 f.quietlyJoin();
514 f.checkCompletedNormally();
515 }};
516 testInvokeOnPool(pool, a);
517 }
518
519 /**
520 * helpQuiesce returns when tasks are complete.
521 * getQueuedTaskCount returns 0 when quiescent
522 */
523 public void testForkHelpQuiesce() {
524 testForkHelpQuiesce(mainPool());
525 }
526 public void testForkHelpQuiesce_Singleton() {
527 testForkHelpQuiesce(singletonPool());
528 }
529 public void testForkHelpQuiesce(ForkJoinPool pool) {
530 RecursiveAction a = new CheckedRecursiveAction() {
531 protected void realCompute() {
532 AsyncFib f = new AsyncFib(8);
533 assertSame(f, f.fork());
534 helpQuiesce();
535 assertEquals(0, getQueuedTaskCount());
536 f.checkCompletedNormally();
537 }};
538 testInvokeOnPool(pool, a);
539 }
540
541 /**
542 * invoke task throws exception when task completes abnormally
543 */
544 public void testAbnormalInvoke() {
545 testAbnormalInvoke(mainPool());
546 }
547 public void testAbnormalInvoke_Singleton() {
548 testAbnormalInvoke(singletonPool());
549 }
550 public void testAbnormalInvoke(ForkJoinPool pool) {
551 RecursiveAction a = new CheckedRecursiveAction() {
552 protected void realCompute() {
553 FailingAsyncFib f = new FailingAsyncFib(8);
554 try {
555 f.invoke();
556 shouldThrow();
557 } catch (FJException success) {
558 checkCompletedAbnormally(f, success);
559 }
560 }};
561 testInvokeOnPool(pool, a);
562 }
563
564 /**
565 * quietlyInvoke task returns when task completes abnormally
566 */
567 public void testAbnormalQuietlyInvoke() {
568 testAbnormalQuietlyInvoke(mainPool());
569 }
570 public void testAbnormalQuietlyInvoke_Singleton() {
571 testAbnormalQuietlyInvoke(singletonPool());
572 }
573 public void testAbnormalQuietlyInvoke(ForkJoinPool pool) {
574 RecursiveAction a = new CheckedRecursiveAction() {
575 protected void realCompute() {
576 FailingAsyncFib f = new FailingAsyncFib(8);
577 f.quietlyInvoke();
578 assertTrue(f.getException() instanceof FJException);
579 checkCompletedAbnormally(f, f.getException());
580 }};
581 testInvokeOnPool(pool, a);
582 }
583
584 /**
585 * join of a forked task throws exception when task completes abnormally
586 */
587 public void testAbnormalForkJoin() {
588 testAbnormalForkJoin(mainPool());
589 }
590 public void testAbnormalForkJoin_Singleton() {
591 testAbnormalForkJoin(singletonPool());
592 }
593 public void testAbnormalForkJoin(ForkJoinPool pool) {
594 RecursiveAction a = new CheckedRecursiveAction() {
595 protected void realCompute() {
596 FailingAsyncFib f = new FailingAsyncFib(8);
597 assertSame(f, f.fork());
598 try {
599 f.join();
600 shouldThrow();
601 } catch (FJException success) {
602 checkCompletedAbnormally(f, success);
603 }
604 }};
605 testInvokeOnPool(pool, a);
606 }
607
608 /**
609 * get of a forked task throws exception when task completes abnormally
610 */
611 public void testAbnormalForkGet() {
612 testAbnormalForkGet(mainPool());
613 }
614 public void testAbnormalForkGet_Singleton() {
615 testAbnormalForkJoin(singletonPool());
616 }
617 public void testAbnormalForkGet(ForkJoinPool pool) {
618 RecursiveAction a = new CheckedRecursiveAction() {
619 protected void realCompute() throws Exception {
620 FailingAsyncFib f = new FailingAsyncFib(8);
621 assertSame(f, f.fork());
622 try {
623 f.get();
624 shouldThrow();
625 } catch (ExecutionException success) {
626 Throwable cause = success.getCause();
627 assertTrue(cause instanceof FJException);
628 checkCompletedAbnormally(f, cause);
629 }
630 }};
631 testInvokeOnPool(pool, a);
632 }
633
634 /**
635 * timed get of a forked task throws exception when task completes abnormally
636 */
637 public void testAbnormalForkTimedGet() {
638 testAbnormalForkTimedGet(mainPool());
639 }
640 public void testAbnormalForkTimedGet_Singleton() {
641 testAbnormalForkTimedGet(singletonPool());
642 }
643 public void testAbnormalForkTimedGet(ForkJoinPool pool) {
644 RecursiveAction a = new CheckedRecursiveAction() {
645 protected void realCompute() throws Exception {
646 FailingAsyncFib f = new FailingAsyncFib(8);
647 assertSame(f, f.fork());
648 try {
649 f.get(LONG_DELAY_MS, MILLISECONDS);
650 shouldThrow();
651 } catch (ExecutionException success) {
652 Throwable cause = success.getCause();
653 assertTrue(cause instanceof FJException);
654 checkCompletedAbnormally(f, cause);
655 }
656 }};
657 testInvokeOnPool(pool, a);
658 }
659
660 /**
661 * quietlyJoin of a forked task returns when task completes abnormally
662 */
663 public void testAbnormalForkQuietlyJoin() {
664 testAbnormalForkQuietlyJoin(mainPool());
665 }
666 public void testAbnormalForkQuietlyJoin_Singleton() {
667 testAbnormalForkQuietlyJoin(singletonPool());
668 }
669 public void testAbnormalForkQuietlyJoin(ForkJoinPool pool) {
670 RecursiveAction a = new CheckedRecursiveAction() {
671 protected void realCompute() {
672 FailingAsyncFib f = new FailingAsyncFib(8);
673 assertSame(f, f.fork());
674 f.quietlyJoin();
675 assertTrue(f.getException() instanceof FJException);
676 checkCompletedAbnormally(f, f.getException());
677 }};
678 testInvokeOnPool(pool, a);
679 }
680
681 /**
682 * getPool of executing task returns its pool
683 */
684 public void testGetPool() {
685 testGetPool(mainPool());
686 }
687 public void testGetPool_Singleton() {
688 testGetPool(singletonPool());
689 }
690 public void testGetPool(ForkJoinPool pool) {
691 RecursiveAction a = new CheckedRecursiveAction() {
692 protected void realCompute() {
693 assertSame(pool, getPool());
694 }};
695 testInvokeOnPool(pool, a);
696 }
697
698 /**
699 * getPool of non-FJ task returns null
700 */
701 public void testGetPool2() {
702 RecursiveAction a = new CheckedRecursiveAction() {
703 protected void realCompute() {
704 assertNull(getPool());
705 }};
706 assertNull(a.invoke());
707 }
708
709 /**
710 * inForkJoinPool of executing task returns true
711 */
712 public void testInForkJoinPool() {
713 testInForkJoinPool(mainPool());
714 }
715 public void testInForkJoinPool_Singleton() {
716 testInForkJoinPool(singletonPool());
717 }
718 public void testInForkJoinPool(ForkJoinPool pool) {
719 RecursiveAction a = new CheckedRecursiveAction() {
720 protected void realCompute() {
721 assertTrue(inForkJoinPool());
722 }};
723 testInvokeOnPool(pool, a);
724 }
725
726 /**
727 * inForkJoinPool of non-FJ task returns false
728 */
729 public void testInForkJoinPool2() {
730 RecursiveAction a = new CheckedRecursiveAction() {
731 protected void realCompute() {
732 assertFalse(inForkJoinPool());
733 }};
734 assertNull(a.invoke());
735 }
736
737 /**
738 * setRawResult(null) succeeds
739 */
740 public void testSetRawResult() {
741 RecursiveAction a = new CheckedRecursiveAction() {
742 protected void realCompute() {
743 setRawResult(null);
744 assertNull(getRawResult());
745 }};
746 assertNull(a.invoke());
747 }
748
749 /**
750 * invoke task throws exception after invoking completeExceptionally
751 */
752 public void testCompleteExceptionally() {
753 testCompleteExceptionally(mainPool());
754 }
755 public void testCompleteExceptionally_Singleton() {
756 testCompleteExceptionally(singletonPool());
757 }
758 public void testCompleteExceptionally(ForkJoinPool pool) {
759 RecursiveAction a = new CheckedRecursiveAction() {
760 protected void realCompute() {
761 AsyncFib f = new AsyncFib(8);
762 f.completeExceptionally(new FJException());
763 try {
764 f.invoke();
765 shouldThrow();
766 } catch (FJException success) {
767 checkCompletedAbnormally(f, success);
768 }
769 }};
770 testInvokeOnPool(pool, a);
771 }
772
773 /**
774 * invokeAll(tasks) with 1 argument invokes task
775 */
776 public void testInvokeAll1() {
777 testInvokeAll1(mainPool());
778 }
779 public void testInvokeAll1_Singleton() {
780 testInvokeAll1(singletonPool());
781 }
782 public void testInvokeAll1(ForkJoinPool pool) {
783 RecursiveAction a = new CheckedRecursiveAction() {
784 protected void realCompute() {
785 AsyncFib f = new AsyncFib(8);
786 invokeAll(f);
787 f.checkCompletedNormally();
788 }};
789 testInvokeOnPool(pool, a);
790 }
791
792 /**
793 * invokeAll(t1, t2) invokes all task arguments
794 */
795 public void testInvokeAll2() {
796 testInvokeAll2(mainPool());
797 }
798 public void testInvokeAll2_Singleton() {
799 testInvokeAll2(singletonPool());
800 }
801 public void testInvokeAll2(ForkJoinPool pool) {
802 RecursiveAction a = new CheckedRecursiveAction() {
803 protected void realCompute() {
804 AsyncFib[] tasks = {
805 new AsyncFib(8),
806 new AsyncFib(9),
807 };
808 invokeAll(tasks[0], tasks[1]);
809 for (AsyncFib task : tasks) assertTrue(task.isDone());
810 for (AsyncFib task : tasks) task.checkCompletedNormally();
811 }};
812 testInvokeOnPool(pool, a);
813 }
814
815 /**
816 * invokeAll(tasks) with > 2 argument invokes tasks
817 */
818 public void testInvokeAll3() {
819 testInvokeAll3(mainPool());
820 }
821 public void testInvokeAll3_Singleton() {
822 testInvokeAll3(singletonPool());
823 }
824 public void testInvokeAll3(ForkJoinPool pool) {
825 RecursiveAction a = new CheckedRecursiveAction() {
826 protected void realCompute() {
827 AsyncFib[] tasks = {
828 new AsyncFib(8),
829 new AsyncFib(9),
830 new AsyncFib(7),
831 };
832 invokeAll(tasks[0], tasks[1], tasks[2]);
833 for (AsyncFib task : tasks) assertTrue(task.isDone());
834 for (AsyncFib task : tasks) task.checkCompletedNormally();
835 }};
836 testInvokeOnPool(pool, a);
837 }
838
839 /**
840 * invokeAll(collection) invokes all tasks in the collection
841 */
842 public void testInvokeAllCollection() {
843 testInvokeAllCollection(mainPool());
844 }
845 public void testInvokeAllCollection_Singleton() {
846 testInvokeAllCollection(singletonPool());
847 }
848 public void testInvokeAllCollection(ForkJoinPool pool) {
849 RecursiveAction a = new CheckedRecursiveAction() {
850 protected void realCompute() {
851 AsyncFib[] tasks = {
852 new AsyncFib(8),
853 new AsyncFib(9),
854 new AsyncFib(7),
855 };
856 invokeAll(Arrays.asList(tasks));
857 for (AsyncFib task : tasks) assertTrue(task.isDone());
858 for (AsyncFib task : tasks) task.checkCompletedNormally();
859 }};
860 testInvokeOnPool(pool, a);
861 }
862
863 /**
864 * invokeAll(tasks) with any null task throws NullPointerException
865 */
866 public void testInvokeAllNullTask() {
867 testInvokeAllNullTask(mainPool());
868 }
869 public void testInvokeAllNullTask_Singleton() {
870 testInvokeAllNullTask(singletonPool());
871 }
872 public void testInvokeAllNullTask(ForkJoinPool pool) {
873 RecursiveAction a = new CheckedRecursiveAction() {
874 protected void realCompute() {
875 AsyncFib nul = null;
876 assertThrows(
877 NullPointerException.class,
878 () -> invokeAll(nul),
879 () -> invokeAll(nul, nul),
880 () -> invokeAll(new AsyncFib(8), new AsyncFib(9), nul),
881 () -> invokeAll(new AsyncFib(8), nul, new AsyncFib(9)),
882 () -> invokeAll(nul, new AsyncFib(8), new AsyncFib(9)));
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 }