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 package jsr166; 8 9 import static java.util.concurrent.TimeUnit.SECONDS; 10 11 import java.util.HashSet; 12 import java.util.concurrent.CancellationException; 13 import java.util.concurrent.ExecutionException; 14 import java.util.concurrent.ForkJoinPool; 15 import java.util.concurrent.ForkJoinTask; 16 import java.util.concurrent.RecursiveTask; 17 import java.util.concurrent.TimeoutException; 18 19 import junit.framework.Test; 20 import junit.framework.TestSuite; 21 22 public class RecursiveTaskTest extends JSR166TestCase { 23 24 // 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() { 31 // return new TestSuite(RecursiveTaskTest.class); 32 // } 33 mainPool()34 private static ForkJoinPool mainPool() { 35 return new ForkJoinPool(); 36 } 37 singletonPool()38 private static ForkJoinPool singletonPool() { 39 return new ForkJoinPool(1); 40 } 41 asyncSingletonPool()42 private static ForkJoinPool asyncSingletonPool() { 43 return new ForkJoinPool(1, 44 ForkJoinPool.defaultForkJoinWorkerThreadFactory, 45 null, true); 46 } 47 testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a)48 private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) { 49 try (PoolCleaner cleaner = cleaner(pool)) { 50 checkNotDone(a); 51 52 T result = pool.invoke(a); 53 54 checkCompletedNormally(a, result); 55 return result; 56 } 57 } 58 checkNotDone(RecursiveTask a)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 checkCompletedNormally(RecursiveTask<T> a, T expected)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 */ checkCompletesNormally(RecursiveTask<Integer> a, int expected)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 */ checkCompletedNormally(RecursiveTask<Integer> a, int expected)122 void checkCompletedNormally(RecursiveTask<Integer> a, int expected) { 123 Integer r = a.getRawResult(); 124 assertEquals(expected, (int) r); 125 checkCompletedNormally(a, r); 126 } 127 checkCancelled(RecursiveTask a)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 checkCompletedAbnormally(RecursiveTask a, Throwable t)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 { FJException()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; FibTask(int n)197 FibTask(int n) { number = n; } realCompute()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 publicSetRawResult(Integer result)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; FailingFibTask(int n)216 FailingFibTask(int n) { number = n; } compute()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 */ testInvoke()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 */ testQuietlyInvoke()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 */ testForkJoin()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 */ testForkGet()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 */ testForkTimedGet()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 */ testForkQuietlyJoin()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 */ testForkHelpQuiesce()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(); 336 while (!f.isDone()) // wait out race 337 ; 338 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 */ testAbnormalInvoke()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 */ testAbnormalQuietlyInvoke()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 */ testAbnormalForkJoin()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 */ testAbnormalForkGet()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 */ testAbnormalForkTimedGet()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 */ testAbnormalForkQuietlyJoin()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 */ testCancelledInvoke()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 */ testCancelledForkJoin()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 */ testCancelledForkGet()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 */ testCancelledForkTimedGet()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 */ testCancelledForkQuietlyJoin()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 */ testGetPool()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 */ testGetPool2()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 */ testInForkJoinPool()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 */ testInForkJoinPool2()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 */ testSetRawResult()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 */ testReinitialize()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 */ testReinitializeAbnormal()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 */ testCompleteExceptionally()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 */ testComplete()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 */ testInvokeAll2()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 */ testInvokeAll1()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 */ testInvokeAll3()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 */ testInvokeAllCollection()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 */ testInvokeAllNPE()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 */ testAbnormalInvokeAll2()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 */ testAbnormalInvokeAll1()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 */ testAbnormalInvokeAll3()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 */ testAbnormalInvokeAllCollection()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 */ testTryUnfork()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 */ testGetSurplusQueuedTaskCount()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 */ testPeekNextLocalTask()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 */ testPollNextLocalTask()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 */ testPollTask()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 */ testPeekNextLocalTaskAsync()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 */ testPollNextLocalTaskAsync()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 */ testPollTaskAsync()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 } 1032