blob: 2c07c2a2f89593115744a526efd26990eac48971 [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
7package jsr166;
8
Narayan Kamath8e9a0e92015-04-28 11:40:00 +01009import static java.util.concurrent.TimeUnit.SECONDS;
10
11import java.util.HashSet;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010012import java.util.concurrent.CancellationException;
13import java.util.concurrent.ExecutionException;
14import java.util.concurrent.ForkJoinPool;
15import java.util.concurrent.ForkJoinTask;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010016import java.util.concurrent.RecursiveTask;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010017import java.util.concurrent.TimeoutException;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010018
19import junit.framework.Test;
20import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010021
22public class RecursiveTaskTest extends JSR166TestCase {
23
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010024 // android-note: Removed because the CTS runner does a bad job of
25 // retrying tests that have suite() declarations.
26 //
27 // public static void main(String[] args) {
28 // main(suite(), args);
29 // }
30 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000031 // return new TestSuite(RecursiveTaskTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010032 // }
33
Calin Juravle8f0d92b2013-08-01 17:26:00 +010034 private static ForkJoinPool mainPool() {
35 return new ForkJoinPool();
36 }
37
38 private static ForkJoinPool singletonPool() {
39 return new ForkJoinPool(1);
40 }
41
42 private static ForkJoinPool asyncSingletonPool() {
43 return new ForkJoinPool(1,
44 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
45 null, true);
46 }
47
48 private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000049 try (PoolCleaner cleaner = cleaner(pool)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010050 checkNotDone(a);
51
52 T result = pool.invoke(a);
53
54 checkCompletedNormally(a, result);
55 return result;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010056 }
57 }
58
59 void checkNotDone(RecursiveTask a) {
60 assertFalse(a.isDone());
61 assertFalse(a.isCompletedNormally());
62 assertFalse(a.isCompletedAbnormally());
63 assertFalse(a.isCancelled());
64 assertNull(a.getException());
65 assertNull(a.getRawResult());
66
67 if (! ForkJoinTask.inForkJoinPool()) {
68 Thread.currentThread().interrupt();
69 try {
70 a.get();
71 shouldThrow();
72 } catch (InterruptedException success) {
73 } catch (Throwable fail) { threadUnexpectedException(fail); }
74
75 Thread.currentThread().interrupt();
76 try {
77 a.get(5L, SECONDS);
78 shouldThrow();
79 } catch (InterruptedException success) {
80 } catch (Throwable fail) { threadUnexpectedException(fail); }
81 }
82
83 try {
84 a.get(0L, SECONDS);
85 shouldThrow();
86 } catch (TimeoutException success) {
87 } catch (Throwable fail) { threadUnexpectedException(fail); }
88 }
89
90 <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
91 assertTrue(a.isDone());
92 assertFalse(a.isCancelled());
93 assertTrue(a.isCompletedNormally());
94 assertFalse(a.isCompletedAbnormally());
95 assertNull(a.getException());
96 assertSame(expected, a.getRawResult());
97 assertSame(expected, a.join());
98 assertFalse(a.cancel(false));
99 assertFalse(a.cancel(true));
100 try {
101 assertSame(expected, a.get());
102 } catch (Throwable fail) { threadUnexpectedException(fail); }
103 try {
104 assertSame(expected, a.get(5L, SECONDS));
105 } catch (Throwable fail) { threadUnexpectedException(fail); }
106 }
107
108 /**
109 * Waits for the task to complete, and checks that when it does,
110 * it will have an Integer result equals to the given int.
111 */
112 void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
113 Integer r = a.join();
114 assertEquals(expected, (int) r);
115 checkCompletedNormally(a, r);
116 }
117
118 /**
119 * Like checkCompletesNormally, but verifies that the task has
120 * already completed.
121 */
122 void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
123 Integer r = a.getRawResult();
124 assertEquals(expected, (int) r);
125 checkCompletedNormally(a, r);
126 }
127
128 void checkCancelled(RecursiveTask a) {
129 assertTrue(a.isDone());
130 assertTrue(a.isCancelled());
131 assertFalse(a.isCompletedNormally());
132 assertTrue(a.isCompletedAbnormally());
133 assertTrue(a.getException() instanceof CancellationException);
134 assertNull(a.getRawResult());
135
136 try {
137 a.join();
138 shouldThrow();
139 } catch (CancellationException success) {
140 } catch (Throwable fail) { threadUnexpectedException(fail); }
141
142 try {
143 a.get();
144 shouldThrow();
145 } catch (CancellationException success) {
146 } catch (Throwable fail) { threadUnexpectedException(fail); }
147
148 try {
149 a.get(5L, SECONDS);
150 shouldThrow();
151 } catch (CancellationException success) {
152 } catch (Throwable fail) { threadUnexpectedException(fail); }
153 }
154
155 void checkCompletedAbnormally(RecursiveTask 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
165 try {
166 a.join();
167 shouldThrow();
168 } catch (Throwable expected) {
169 assertSame(t.getClass(), expected.getClass());
170 }
171
172 try {
173 a.get();
174 shouldThrow();
175 } catch (ExecutionException success) {
176 assertSame(t.getClass(), success.getCause().getClass());
177 } catch (Throwable fail) { threadUnexpectedException(fail); }
178
179 try {
180 a.get(5L, SECONDS);
181 shouldThrow();
182 } catch (ExecutionException success) {
183 assertSame(t.getClass(), success.getCause().getClass());
184 } catch (Throwable fail) { threadUnexpectedException(fail); }
185 }
186
187 public static final class FJException extends RuntimeException {
188 public FJException() { super(); }
189 }
190
191 // An invalid return value for Fib
192 static final Integer NoResult = Integer.valueOf(-17);
193
194 // A simple recursive task for testing
195 final class FibTask extends CheckedRecursiveTask<Integer> {
196 final int number;
197 FibTask(int n) { number = n; }
198 public Integer realCompute() {
199 int n = number;
200 if (n <= 1)
201 return n;
202 FibTask f1 = new FibTask(n - 1);
203 f1.fork();
204 return (new FibTask(n - 2)).compute() + f1.join();
205 }
206
207 public void publicSetRawResult(Integer result) {
208 setRawResult(result);
209 }
210 }
211
212 // A recursive action failing in base case
213 final class FailingFibTask extends RecursiveTask<Integer> {
214 final int number;
215 int result;
216 FailingFibTask(int n) { number = n; }
217 public Integer compute() {
218 int n = number;
219 if (n <= 1)
220 throw new FJException();
221 FailingFibTask f1 = new FailingFibTask(n - 1);
222 f1.fork();
223 return (new FibTask(n - 2)).compute() + f1.join();
224 }
225 }
226
227 /**
228 * invoke returns value when task completes normally.
229 * isCompletedAbnormally and isCancelled return false for normally
230 * completed tasks. getRawResult of a completed non-null task
231 * returns value;
232 */
233 public void testInvoke() {
234 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
235 public Integer realCompute() {
236 FibTask f = new FibTask(8);
237 Integer r = f.invoke();
238 assertEquals(21, (int) r);
239 checkCompletedNormally(f, r);
240 return r;
241 }};
242 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
243 }
244
245 /**
246 * quietlyInvoke task returns when task completes normally.
247 * isCompletedAbnormally and isCancelled return false for normally
248 * completed tasks
249 */
250 public void testQuietlyInvoke() {
251 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
252 public Integer realCompute() {
253 FibTask f = new FibTask(8);
254 f.quietlyInvoke();
255 checkCompletedNormally(f, 21);
256 return NoResult;
257 }};
258 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
259 }
260
261 /**
262 * join of a forked task returns when task completes
263 */
264 public void testForkJoin() {
265 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
266 public Integer realCompute() {
267 FibTask f = new FibTask(8);
268 assertSame(f, f.fork());
269 Integer r = f.join();
270 assertEquals(21, (int) r);
271 checkCompletedNormally(f, r);
272 return r;
273 }};
274 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
275 }
276
277 /**
278 * get of a forked task returns when task completes
279 */
280 public void testForkGet() {
281 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
282 public Integer realCompute() throws Exception {
283 FibTask f = new FibTask(8);
284 assertSame(f, f.fork());
285 Integer r = f.get();
286 assertEquals(21, (int) r);
287 checkCompletedNormally(f, r);
288 return r;
289 }};
290 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
291 }
292
293 /**
294 * timed get of a forked task returns when task completes
295 */
296 public void testForkTimedGet() {
297 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
298 public Integer realCompute() throws Exception {
299 FibTask f = new FibTask(8);
300 assertSame(f, f.fork());
301 Integer r = f.get(5L, SECONDS);
302 assertEquals(21, (int) r);
303 checkCompletedNormally(f, r);
304 return r;
305 }};
306 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
307 }
308
309 /**
310 * quietlyJoin of a forked task returns when task completes
311 */
312 public void testForkQuietlyJoin() {
313 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
314 public Integer realCompute() {
315 FibTask f = new FibTask(8);
316 assertSame(f, f.fork());
317 f.quietlyJoin();
318 Integer r = f.getRawResult();
319 assertEquals(21, (int) r);
320 checkCompletedNormally(f, r);
321 return r;
322 }};
323 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
324 }
325
326 /**
327 * helpQuiesce returns when tasks are complete.
328 * getQueuedTaskCount returns 0 when quiescent
329 */
330 public void testForkHelpQuiesce() {
331 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
332 public Integer realCompute() {
333 FibTask f = new FibTask(8);
334 assertSame(f, f.fork());
335 helpQuiesce();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000336 while (!f.isDone()) // wait out race
337 ;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100338 assertEquals(0, getQueuedTaskCount());
339 checkCompletedNormally(f, 21);
340 return NoResult;
341 }};
342 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
343 }
344
345 /**
346 * invoke task throws exception when task completes abnormally
347 */
348 public void testAbnormalInvoke() {
349 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
350 public Integer realCompute() {
351 FailingFibTask f = new FailingFibTask(8);
352 try {
353 f.invoke();
354 shouldThrow();
355 } catch (FJException success) {
356 checkCompletedAbnormally(f, success);
357 }
358 return NoResult;
359 }};
360 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
361 }
362
363 /**
364 * quietlyInvoke task returns when task completes abnormally
365 */
366 public void testAbnormalQuietlyInvoke() {
367 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
368 public Integer realCompute() {
369 FailingFibTask f = new FailingFibTask(8);
370 f.quietlyInvoke();
371 assertTrue(f.getException() instanceof FJException);
372 checkCompletedAbnormally(f, f.getException());
373 return NoResult;
374 }};
375 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
376 }
377
378 /**
379 * join of a forked task throws exception when task completes abnormally
380 */
381 public void testAbnormalForkJoin() {
382 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
383 public Integer realCompute() {
384 FailingFibTask f = new FailingFibTask(8);
385 assertSame(f, f.fork());
386 try {
387 Integer r = f.join();
388 shouldThrow();
389 } catch (FJException success) {
390 checkCompletedAbnormally(f, success);
391 }
392 return NoResult;
393 }};
394 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
395 }
396
397 /**
398 * get of a forked task throws exception when task completes abnormally
399 */
400 public void testAbnormalForkGet() {
401 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
402 public Integer realCompute() throws Exception {
403 FailingFibTask f = new FailingFibTask(8);
404 assertSame(f, f.fork());
405 try {
406 Integer r = f.get();
407 shouldThrow();
408 } catch (ExecutionException success) {
409 Throwable cause = success.getCause();
410 assertTrue(cause instanceof FJException);
411 checkCompletedAbnormally(f, cause);
412 }
413 return NoResult;
414 }};
415 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
416 }
417
418 /**
419 * timed get of a forked task throws exception when task completes abnormally
420 */
421 public void testAbnormalForkTimedGet() {
422 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
423 public Integer realCompute() throws Exception {
424 FailingFibTask f = new FailingFibTask(8);
425 assertSame(f, f.fork());
426 try {
427 Integer r = f.get(5L, SECONDS);
428 shouldThrow();
429 } catch (ExecutionException success) {
430 Throwable cause = success.getCause();
431 assertTrue(cause instanceof FJException);
432 checkCompletedAbnormally(f, cause);
433 }
434 return NoResult;
435 }};
436 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
437 }
438
439 /**
440 * quietlyJoin of a forked task returns when task completes abnormally
441 */
442 public void testAbnormalForkQuietlyJoin() {
443 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
444 public Integer realCompute() {
445 FailingFibTask f = new FailingFibTask(8);
446 assertSame(f, f.fork());
447 f.quietlyJoin();
448 assertTrue(f.getException() instanceof FJException);
449 checkCompletedAbnormally(f, f.getException());
450 return NoResult;
451 }};
452 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
453 }
454
455 /**
456 * invoke task throws exception when task cancelled
457 */
458 public void testCancelledInvoke() {
459 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
460 public Integer realCompute() {
461 FibTask f = new FibTask(8);
462 assertTrue(f.cancel(true));
463 try {
464 Integer r = f.invoke();
465 shouldThrow();
466 } catch (CancellationException success) {
467 checkCancelled(f);
468 }
469 return NoResult;
470 }};
471 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
472 }
473
474 /**
475 * join of a forked task throws exception when task cancelled
476 */
477 public void testCancelledForkJoin() {
478 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
479 public Integer realCompute() {
480 FibTask f = new FibTask(8);
481 assertTrue(f.cancel(true));
482 assertSame(f, f.fork());
483 try {
484 Integer r = f.join();
485 shouldThrow();
486 } catch (CancellationException success) {
487 checkCancelled(f);
488 }
489 return NoResult;
490 }};
491 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
492 }
493
494 /**
495 * get of a forked task throws exception when task cancelled
496 */
497 public void testCancelledForkGet() {
498 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
499 public Integer realCompute() throws Exception {
500 FibTask f = new FibTask(8);
501 assertTrue(f.cancel(true));
502 assertSame(f, f.fork());
503 try {
504 Integer r = f.get();
505 shouldThrow();
506 } catch (CancellationException success) {
507 checkCancelled(f);
508 }
509 return NoResult;
510 }};
511 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
512 }
513
514 /**
515 * timed get of a forked task throws exception when task cancelled
516 */
517 public void testCancelledForkTimedGet() {
518 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
519 public Integer realCompute() throws Exception {
520 FibTask f = new FibTask(8);
521 assertTrue(f.cancel(true));
522 assertSame(f, f.fork());
523 try {
524 Integer r = f.get(5L, SECONDS);
525 shouldThrow();
526 } catch (CancellationException success) {
527 checkCancelled(f);
528 }
529 return NoResult;
530 }};
531 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
532 }
533
534 /**
535 * quietlyJoin of a forked task returns when task cancelled
536 */
537 public void testCancelledForkQuietlyJoin() {
538 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
539 public Integer realCompute() {
540 FibTask f = new FibTask(8);
541 assertTrue(f.cancel(true));
542 assertSame(f, f.fork());
543 f.quietlyJoin();
544 checkCancelled(f);
545 return NoResult;
546 }};
547 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
548 }
549
550 /**
551 * getPool of executing task returns its pool
552 */
553 public void testGetPool() {
554 final ForkJoinPool mainPool = mainPool();
555 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
556 public Integer realCompute() {
557 assertSame(mainPool, getPool());
558 return NoResult;
559 }};
560 assertSame(NoResult, testInvokeOnPool(mainPool, a));
561 }
562
563 /**
564 * getPool of non-FJ task returns null
565 */
566 public void testGetPool2() {
567 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
568 public Integer realCompute() {
569 assertNull(getPool());
570 return NoResult;
571 }};
572 assertSame(NoResult, a.invoke());
573 }
574
575 /**
576 * inForkJoinPool of executing task returns true
577 */
578 public void testInForkJoinPool() {
579 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
580 public Integer realCompute() {
581 assertTrue(inForkJoinPool());
582 return NoResult;
583 }};
584 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
585 }
586
587 /**
588 * inForkJoinPool of non-FJ task returns false
589 */
590 public void testInForkJoinPool2() {
591 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
592 public Integer realCompute() {
593 assertFalse(inForkJoinPool());
594 return NoResult;
595 }};
596 assertSame(NoResult, a.invoke());
597 }
598
599 /**
600 * The value set by setRawResult is returned by getRawResult
601 */
602 public void testSetRawResult() {
603 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
604 public Integer realCompute() {
605 setRawResult(NoResult);
606 assertSame(NoResult, getRawResult());
607 return NoResult;
608 }
609 };
610 assertSame(NoResult, a.invoke());
611 }
612
613 /**
614 * A reinitialized normally completed task may be re-invoked
615 */
616 public void testReinitialize() {
617 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
618 public Integer realCompute() {
619 FibTask f = new FibTask(8);
620 checkNotDone(f);
621
622 for (int i = 0; i < 3; i++) {
623 Integer r = f.invoke();
624 assertEquals(21, (int) r);
625 checkCompletedNormally(f, r);
626 f.reinitialize();
627 f.publicSetRawResult(null);
628 checkNotDone(f);
629 }
630 return NoResult;
631 }};
632 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
633 }
634
635 /**
636 * A reinitialized abnormally completed task may be re-invoked
637 */
638 public void testReinitializeAbnormal() {
639 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
640 public Integer realCompute() {
641 FailingFibTask f = new FailingFibTask(8);
642 checkNotDone(f);
643
644 for (int i = 0; i < 3; i++) {
645 try {
646 f.invoke();
647 shouldThrow();
648 } catch (FJException success) {
649 checkCompletedAbnormally(f, success);
650 }
651 f.reinitialize();
652 checkNotDone(f);
653 }
654 return NoResult;
655 }};
656 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
657 }
658
659 /**
660 * invoke task throws exception after invoking completeExceptionally
661 */
662 public void testCompleteExceptionally() {
663 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
664 public Integer realCompute() {
665 FibTask f = new FibTask(8);
666 f.completeExceptionally(new FJException());
667 try {
668 Integer r = f.invoke();
669 shouldThrow();
670 } catch (FJException success) {
671 checkCompletedAbnormally(f, success);
672 }
673 return NoResult;
674 }};
675 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
676 }
677
678 /**
679 * invoke task suppresses execution invoking complete
680 */
681 public void testComplete() {
682 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
683 public Integer realCompute() {
684 FibTask f = new FibTask(8);
685 f.complete(NoResult);
686 Integer r = f.invoke();
687 assertSame(NoResult, r);
688 checkCompletedNormally(f, NoResult);
689 return r;
690 }};
691 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
692 }
693
694 /**
695 * invokeAll(t1, t2) invokes all task arguments
696 */
697 public void testInvokeAll2() {
698 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
699 public Integer realCompute() {
700 FibTask f = new FibTask(8);
701 FibTask g = new FibTask(9);
702 invokeAll(f, g);
703 checkCompletedNormally(f, 21);
704 checkCompletedNormally(g, 34);
705 return NoResult;
706 }};
707 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
708 }
709
710 /**
711 * invokeAll(tasks) with 1 argument invokes task
712 */
713 public void testInvokeAll1() {
714 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
715 public Integer realCompute() {
716 FibTask f = new FibTask(8);
717 invokeAll(f);
718 checkCompletedNormally(f, 21);
719 return NoResult;
720 }};
721 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
722 }
723
724 /**
725 * invokeAll(tasks) with > 2 argument invokes tasks
726 */
727 public void testInvokeAll3() {
728 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
729 public Integer realCompute() {
730 FibTask f = new FibTask(8);
731 FibTask g = new FibTask(9);
732 FibTask h = new FibTask(7);
733 invokeAll(f, g, h);
734 assertTrue(f.isDone());
735 assertTrue(g.isDone());
736 assertTrue(h.isDone());
737 checkCompletedNormally(f, 21);
738 checkCompletedNormally(g, 34);
739 checkCompletedNormally(h, 13);
740 return NoResult;
741 }};
742 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
743 }
744
745 /**
746 * invokeAll(collection) invokes all tasks in the collection
747 */
748 public void testInvokeAllCollection() {
749 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
750 public Integer realCompute() {
751 FibTask f = new FibTask(8);
752 FibTask g = new FibTask(9);
753 FibTask h = new FibTask(7);
754 HashSet set = new HashSet();
755 set.add(f);
756 set.add(g);
757 set.add(h);
758 invokeAll(set);
759 assertTrue(f.isDone());
760 assertTrue(g.isDone());
761 assertTrue(h.isDone());
762 checkCompletedNormally(f, 21);
763 checkCompletedNormally(g, 34);
764 checkCompletedNormally(h, 13);
765 return NoResult;
766 }};
767 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
768 }
769
770 /**
771 * invokeAll(tasks) with any null task throws NPE
772 */
773 public void testInvokeAllNPE() {
774 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
775 public Integer realCompute() {
776 FibTask f = new FibTask(8);
777 FibTask g = new FibTask(9);
778 FibTask h = null;
779 try {
780 invokeAll(f, g, h);
781 shouldThrow();
782 } catch (NullPointerException success) {}
783 return NoResult;
784 }};
785 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
786 }
787
788 /**
789 * invokeAll(t1, t2) throw exception if any task does
790 */
791 public void testAbnormalInvokeAll2() {
792 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
793 public Integer realCompute() {
794 FibTask f = new FibTask(8);
795 FailingFibTask g = new FailingFibTask(9);
796 try {
797 invokeAll(f, g);
798 shouldThrow();
799 } catch (FJException success) {
800 checkCompletedAbnormally(g, success);
801 }
802 return NoResult;
803 }};
804 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
805 }
806
807 /**
808 * invokeAll(tasks) with 1 argument throws exception if task does
809 */
810 public void testAbnormalInvokeAll1() {
811 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
812 public Integer realCompute() {
813 FailingFibTask g = new FailingFibTask(9);
814 try {
815 invokeAll(g);
816 shouldThrow();
817 } catch (FJException success) {
818 checkCompletedAbnormally(g, success);
819 }
820 return NoResult;
821 }};
822 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
823 }
824
825 /**
826 * invokeAll(tasks) with > 2 argument throws exception if any task does
827 */
828 public void testAbnormalInvokeAll3() {
829 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
830 public Integer realCompute() {
831 FibTask f = new FibTask(8);
832 FailingFibTask g = new FailingFibTask(9);
833 FibTask h = new FibTask(7);
834 try {
835 invokeAll(f, g, h);
836 shouldThrow();
837 } catch (FJException success) {
838 checkCompletedAbnormally(g, success);
839 }
840 return NoResult;
841 }};
842 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
843 }
844
845 /**
846 * invokeAll(collection) throws exception if any task does
847 */
848 public void testAbnormalInvokeAllCollection() {
849 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
850 public Integer realCompute() {
851 FailingFibTask f = new FailingFibTask(8);
852 FibTask g = new FibTask(9);
853 FibTask h = new FibTask(7);
854 HashSet set = new HashSet();
855 set.add(f);
856 set.add(g);
857 set.add(h);
858 try {
859 invokeAll(set);
860 shouldThrow();
861 } catch (FJException success) {
862 checkCompletedAbnormally(f, success);
863 }
864 return NoResult;
865 }};
866 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
867 }
868
869 /**
870 * tryUnfork returns true for most recent unexecuted task,
871 * and suppresses execution
872 */
873 public void testTryUnfork() {
874 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
875 public Integer realCompute() {
876 FibTask g = new FibTask(9);
877 assertSame(g, g.fork());
878 FibTask f = new FibTask(8);
879 assertSame(f, f.fork());
880 assertTrue(f.tryUnfork());
881 helpQuiesce();
882 checkNotDone(f);
883 checkCompletedNormally(g, 34);
884 return NoResult;
885 }};
886 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
887 }
888
889 /**
890 * getSurplusQueuedTaskCount returns > 0 when
891 * there are more tasks than threads
892 */
893 public void testGetSurplusQueuedTaskCount() {
894 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
895 public Integer realCompute() {
896 FibTask h = new FibTask(7);
897 assertSame(h, h.fork());
898 FibTask g = new FibTask(9);
899 assertSame(g, g.fork());
900 FibTask f = new FibTask(8);
901 assertSame(f, f.fork());
902 assertTrue(getSurplusQueuedTaskCount() > 0);
903 helpQuiesce();
904 assertEquals(0, getSurplusQueuedTaskCount());
905 checkCompletedNormally(f, 21);
906 checkCompletedNormally(g, 34);
907 checkCompletedNormally(h, 13);
908 return NoResult;
909 }};
910 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
911 }
912
913 /**
914 * peekNextLocalTask returns most recent unexecuted task.
915 */
916 public void testPeekNextLocalTask() {
917 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
918 public Integer realCompute() {
919 FibTask g = new FibTask(9);
920 assertSame(g, g.fork());
921 FibTask f = new FibTask(8);
922 assertSame(f, f.fork());
923 assertSame(f, peekNextLocalTask());
924 checkCompletesNormally(f, 21);
925 helpQuiesce();
926 checkCompletedNormally(g, 34);
927 return NoResult;
928 }};
929 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
930 }
931
932 /**
933 * pollNextLocalTask returns most recent unexecuted task
934 * without executing it
935 */
936 public void testPollNextLocalTask() {
937 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
938 public Integer realCompute() {
939 FibTask g = new FibTask(9);
940 assertSame(g, g.fork());
941 FibTask f = new FibTask(8);
942 assertSame(f, f.fork());
943 assertSame(f, pollNextLocalTask());
944 helpQuiesce();
945 checkNotDone(f);
946 checkCompletedNormally(g, 34);
947 return NoResult;
948 }};
949 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
950 }
951
952 /**
953 * pollTask returns an unexecuted task without executing it
954 */
955 public void testPollTask() {
956 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
957 public Integer realCompute() {
958 FibTask g = new FibTask(9);
959 assertSame(g, g.fork());
960 FibTask f = new FibTask(8);
961 assertSame(f, f.fork());
962 assertSame(f, pollTask());
963 helpQuiesce();
964 checkNotDone(f);
965 checkCompletedNormally(g, 34);
966 return NoResult;
967 }};
968 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
969 }
970
971 /**
972 * peekNextLocalTask returns least recent unexecuted task in async mode
973 */
974 public void testPeekNextLocalTaskAsync() {
975 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
976 public Integer realCompute() {
977 FibTask g = new FibTask(9);
978 assertSame(g, g.fork());
979 FibTask f = new FibTask(8);
980 assertSame(f, f.fork());
981 assertSame(g, peekNextLocalTask());
982 assertEquals(21, (int) f.join());
983 helpQuiesce();
984 checkCompletedNormally(f, 21);
985 checkCompletedNormally(g, 34);
986 return NoResult;
987 }};
988 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
989 }
990
991 /**
992 * pollNextLocalTask returns least recent unexecuted task without
993 * executing it, in async mode
994 */
995 public void testPollNextLocalTaskAsync() {
996 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
997 public Integer realCompute() {
998 FibTask g = new FibTask(9);
999 assertSame(g, g.fork());
1000 FibTask f = new FibTask(8);
1001 assertSame(f, f.fork());
1002 assertSame(g, pollNextLocalTask());
1003 helpQuiesce();
1004 checkCompletedNormally(f, 21);
1005 checkNotDone(g);
1006 return NoResult;
1007 }};
1008 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
1009 }
1010
1011 /**
1012 * pollTask returns an unexecuted task without executing it, in
1013 * async mode
1014 */
1015 public void testPollTaskAsync() {
1016 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
1017 public Integer realCompute() {
1018 FibTask g = new FibTask(9);
1019 assertSame(g, g.fork());
1020 FibTask f = new FibTask(8);
1021 assertSame(f, f.fork());
1022 assertSame(g, pollTask());
1023 helpQuiesce();
1024 checkCompletedNormally(f, 21);
1025 checkNotDone(g);
1026 return NoResult;
1027 }};
1028 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
1029 }
1030
1031}