RecursiveTaskTest.java revision 17486:81e4e95b2288
1228753Smm/* 2228753Smm * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3228753Smm * 4228753Smm * This code is free software; you can redistribute it and/or modify it 5228753Smm * under the terms of the GNU General Public License version 2 only, as 6228753Smm * published by the Free Software Foundation. 7228753Smm * 8228753Smm * This code is distributed in the hope that it will be useful, but WITHOUT 9228753Smm * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10228753Smm * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11228753Smm * version 2 for more details (a copy is included in the LICENSE file that 12228753Smm * accompanied this code). 13228753Smm * 14228753Smm * You should have received a copy of the GNU General Public License version 15228753Smm * 2 along with this work; if not, write to the Free Software Foundation, 16228753Smm * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17228753Smm * 18228753Smm * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19228753Smm * or visit www.oracle.com if you need additional information or have any 20228753Smm * questions. 21228753Smm */ 22228753Smm 23228753Smm/* 24228753Smm * This file is available under and governed by the GNU General Public 25228753Smm * License version 2 only, as published by the Free Software Foundation. 26228753Smm * However, the following notice accompanied the original version of this 27228753Smm * file: 28228753Smm * 29228753Smm * Written by Doug Lea with assistance from members of JCP JSR-166 30228753Smm * Expert Group and released to the public domain, as explained at 31228753Smm * http://creativecommons.org/publicdomain/zero/1.0/ 32228753Smm */ 33228753Smm 34228753Smmimport static java.util.concurrent.TimeUnit.MILLISECONDS; 35228753Smm 36228753Smmimport java.util.HashSet; 37228753Smmimport java.util.concurrent.CancellationException; 38228753Smmimport java.util.concurrent.ExecutionException; 39228753Smmimport java.util.concurrent.ForkJoinPool; 40228753Smmimport java.util.concurrent.ForkJoinTask; 41228753Smmimport java.util.concurrent.RecursiveTask; 42228753Smmimport java.util.concurrent.TimeoutException; 43228753Smm 44228753Smmimport junit.framework.Test; 45228753Smmimport junit.framework.TestSuite; 46248616Smm 47228753Smmpublic class RecursiveTaskTest extends JSR166TestCase { 48228753Smm 49231200Smm public static void main(String[] args) { 50228753Smm main(suite(), args); 51228753Smm } 52228753Smm public static Test suite() { 53231200Smm return new TestSuite(RecursiveTaskTest.class); 54231200Smm } 55231200Smm 56231200Smm private static ForkJoinPool mainPool() { 57231200Smm return new ForkJoinPool(); 58228753Smm } 59228753Smm 60228753Smm private static ForkJoinPool singletonPool() { 61231200Smm return new ForkJoinPool(1); 62248616Smm } 63248616Smm 64228753Smm private static ForkJoinPool asyncSingletonPool() { 65228753Smm return new ForkJoinPool(1, 66228753Smm ForkJoinPool.defaultForkJoinWorkerThreadFactory, 67228753Smm null, true); 68228753Smm } 69248616Smm 70248616Smm private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) { 71248616Smm try (PoolCleaner cleaner = cleaner(pool)) { 72228753Smm checkNotDone(a); 73228753Smm 74228753Smm T result = pool.invoke(a); 75228753Smm 76228753Smm checkCompletedNormally(a, result); 77228753Smm return result; 78228753Smm } 79228753Smm } 80228753Smm 81231200Smm void checkNotDone(RecursiveTask a) { 82228753Smm assertFalse(a.isDone()); 83231200Smm assertFalse(a.isCompletedNormally()); 84231200Smm assertFalse(a.isCompletedAbnormally()); 85228753Smm assertFalse(a.isCancelled()); 86231200Smm assertNull(a.getException()); 87231200Smm assertNull(a.getRawResult()); 88248616Smm 89231200Smm if (! ForkJoinTask.inForkJoinPool()) { 90231200Smm Thread.currentThread().interrupt(); 91248616Smm try { 92228753Smm a.get(); 93228753Smm shouldThrow(); 94228753Smm } catch (InterruptedException success) { 95231200Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 96228753Smm 97228753Smm Thread.currentThread().interrupt(); 98231200Smm try { 99228753Smm a.get(randomTimeout(), randomTimeUnit()); 100228753Smm shouldThrow(); 101231200Smm } catch (InterruptedException success) { 102231200Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 103231200Smm } 104231200Smm 105231200Smm try { 106231200Smm a.get(randomExpiredTimeout(), randomTimeUnit()); 107231200Smm shouldThrow(); 108228753Smm } catch (TimeoutException success) { 109228753Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 110228753Smm } 111231200Smm 112231200Smm <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) { 113231200Smm assertTrue(a.isDone()); 114231200Smm assertFalse(a.isCancelled()); 115231200Smm assertTrue(a.isCompletedNormally()); 116248616Smm assertFalse(a.isCompletedAbnormally()); 117231200Smm assertNull(a.getException()); 118248616Smm assertSame(expected, a.getRawResult()); 119248616Smm assertSame(expected, a.join()); 120228753Smm assertFalse(a.cancel(false)); 121248616Smm assertFalse(a.cancel(true)); 122248616Smm try { 123248616Smm assertSame(expected, a.get()); 124248616Smm assertSame(expected, a.get(randomTimeout(), randomTimeUnit())); 125248616Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 126248616Smm } 127248616Smm 128248616Smm /** 129248616Smm * Waits for the task to complete, and checks that when it does, 130248616Smm * it will have an Integer result equals to the given int. 131248616Smm */ 132248616Smm void checkCompletesNormally(RecursiveTask<Integer> a, int expected) { 133228753Smm Integer r = a.join(); 134228753Smm assertEquals(expected, (int) r); 135248616Smm checkCompletedNormally(a, r); 136248616Smm } 137248616Smm 138248616Smm /** 139248616Smm * Like checkCompletesNormally, but verifies that the task has 140248616Smm * already completed. 141248616Smm */ 142248616Smm void checkCompletedNormally(RecursiveTask<Integer> a, int expected) { 143248616Smm Integer r = a.getRawResult(); 144248616Smm assertEquals(expected, (int) r); 145248616Smm checkCompletedNormally(a, r); 146248616Smm } 147248616Smm 148248616Smm void checkCancelled(RecursiveTask a) { 149248616Smm assertTrue(a.isDone()); 150228753Smm assertTrue(a.isCancelled()); 151248616Smm assertFalse(a.isCompletedNormally()); 152248616Smm assertTrue(a.isCompletedAbnormally()); 153248616Smm assertTrue(a.getException() instanceof CancellationException); 154248616Smm assertNull(a.getRawResult()); 155248616Smm 156248616Smm try { 157248616Smm a.join(); 158248616Smm shouldThrow(); 159248616Smm } catch (CancellationException success) { 160248616Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 161248616Smm 162248616Smm try { 163248616Smm a.get(); 164248616Smm shouldThrow(); 165248616Smm } catch (CancellationException success) { 166248616Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 167248616Smm 168248616Smm try { 169248616Smm a.get(randomTimeout(), randomTimeUnit()); 170248616Smm shouldThrow(); 171248616Smm } catch (CancellationException success) { 172248616Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 173248616Smm } 174248616Smm 175248616Smm void checkCompletedAbnormally(RecursiveTask a, Throwable t) { 176248616Smm assertTrue(a.isDone()); 177248616Smm assertFalse(a.isCancelled()); 178248616Smm assertFalse(a.isCompletedNormally()); 179228753Smm assertTrue(a.isCompletedAbnormally()); 180228753Smm assertSame(t.getClass(), a.getException().getClass()); 181228753Smm assertNull(a.getRawResult()); 182231200Smm assertFalse(a.cancel(false)); 183228753Smm assertFalse(a.cancel(true)); 184231200Smm 185228753Smm try { 186228753Smm a.join(); 187231200Smm shouldThrow(); 188231200Smm } catch (Throwable expected) { 189231200Smm assertSame(t.getClass(), expected.getClass()); 190228753Smm } 191231200Smm 192238856Smm try { 193238856Smm a.get(); 194248616Smm shouldThrow(); 195248616Smm } catch (ExecutionException success) { 196238856Smm assertSame(t.getClass(), success.getCause().getClass()); 197238856Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 198238856Smm 199238856Smm try { 200238856Smm a.get(randomTimeout(), randomTimeUnit()); 201238856Smm shouldThrow(); 202238856Smm } catch (ExecutionException success) { 203231200Smm assertSame(t.getClass(), success.getCause().getClass()); 204231200Smm } catch (Throwable fail) { threadUnexpectedException(fail); } 205231200Smm } 206231200Smm 207231200Smm public static final class FJException extends RuntimeException { 208231200Smm public FJException() { super(); } 209231200Smm } 210228753Smm 211228753Smm /** An invalid return value for Fib. */ 212231200Smm static final Integer NoResult = Integer.valueOf(-17); 213231200Smm 214248616Smm /** A simple recursive task for testing. */ 215228753Smm final class FibTask extends CheckedRecursiveTask<Integer> { 216228753Smm final int number; 217231200Smm FibTask(int n) { number = n; } 218231200Smm public Integer realCompute() { 219231200Smm int n = number; 220231200Smm if (n <= 1) 221248616Smm return n; 222248616Smm FibTask f1 = new FibTask(n - 1); 223248616Smm f1.fork(); 224248616Smm return (new FibTask(n - 2)).compute() + f1.join(); 225248616Smm } 226248616Smm 227248616Smm public void publicSetRawResult(Integer result) { 228248616Smm setRawResult(result); 229231200Smm } 230231200Smm } 231231200Smm 232231200Smm /** A recursive action failing in base case. */ 233228753Smm final class FailingFibTask extends RecursiveTask<Integer> { 234231200Smm final int number; 235228753Smm int result; 236228753Smm FailingFibTask(int n) { number = n; } 237231200Smm public Integer compute() { 238231200Smm int n = number; 239228753Smm if (n <= 1) 240228753Smm throw new FJException(); 241228753Smm FailingFibTask f1 = new FailingFibTask(n - 1); 242228753Smm f1.fork(); 243228753Smm return (new FibTask(n - 2)).compute() + f1.join(); 244228753Smm } 245231200Smm } 246231200Smm 247228753Smm /** 248228753Smm * invoke returns value when task completes normally. 249228753Smm * isCompletedAbnormally and isCancelled return false for normally 250231200Smm * completed tasks. getRawResult of a completed non-null task 251228753Smm * returns value; 252228753Smm */ 253228753Smm public void testInvoke() { 254228753Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 255228753Smm public Integer realCompute() { 256231200Smm FibTask f = new FibTask(8); 257228753Smm Integer r = f.invoke(); 258228753Smm assertEquals(21, (int) r); 259228753Smm checkCompletedNormally(f, r); 260228753Smm return r; 261248616Smm }}; 262248616Smm assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 263228753Smm } 264228753Smm 265231200Smm /** 266228753Smm * quietlyInvoke task returns when task completes normally. 267228753Smm * isCompletedAbnormally and isCancelled return false for normally 268228753Smm * completed tasks 269228753Smm */ 270228753Smm public void testQuietlyInvoke() { 271228753Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 272228753Smm public Integer realCompute() { 273228753Smm FibTask f = new FibTask(8); 274228753Smm f.quietlyInvoke(); 275228753Smm checkCompletedNormally(f, 21); 276228753Smm return NoResult; 277228753Smm }}; 278231200Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 279228753Smm } 280228753Smm 281231200Smm /** 282228753Smm * join of a forked task returns when task completes 283228753Smm */ 284228753Smm public void testForkJoin() { 285248616Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 286231200Smm public Integer realCompute() { 287228753Smm FibTask f = new FibTask(8); 288228753Smm assertSame(f, f.fork()); 289231200Smm Integer r = f.join(); 290248616Smm assertEquals(21, (int) r); 291231200Smm checkCompletedNormally(f, r); 292228753Smm return r; 293228753Smm }}; 294228753Smm assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 295228753Smm } 296228753Smm 297228753Smm /** 298228753Smm * get of a forked task returns when task completes 299228753Smm */ 300228753Smm public void testForkGet() { 301231200Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 302228753Smm public Integer realCompute() throws Exception { 303228753Smm FibTask f = new FibTask(8); 304231200Smm assertSame(f, f.fork()); 305231200Smm Integer r = f.get(); 306228753Smm assertEquals(21, (int) r); 307231200Smm checkCompletedNormally(f, r); 308231200Smm return r; 309231200Smm }}; 310231200Smm assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 311231200Smm } 312231200Smm 313231200Smm /** 314231200Smm * timed get of a forked task returns when task completes 315231200Smm */ 316231200Smm public void testForkTimedGet() { 317238856Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 318238856Smm public Integer realCompute() throws Exception { 319238856Smm FibTask f = new FibTask(8); 320238856Smm assertSame(f, f.fork()); 321238856Smm Integer r = f.get(LONG_DELAY_MS, MILLISECONDS); 322238856Smm assertEquals(21, (int) r); 323238856Smm checkCompletedNormally(f, r); 324238856Smm return r; 325231200Smm }}; 326231200Smm assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 327228753Smm } 328231200Smm 329231200Smm /** 330231200Smm * quietlyJoin of a forked task returns when task completes 331231200Smm */ 332231200Smm public void testForkQuietlyJoin() { 333231200Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 334231200Smm public Integer realCompute() { 335228753Smm FibTask f = new FibTask(8); 336231200Smm assertSame(f, f.fork()); 337231200Smm f.quietlyJoin(); 338228753Smm Integer r = f.getRawResult(); 339228753Smm assertEquals(21, (int) r); 340228753Smm checkCompletedNormally(f, r); 341228753Smm return r; 342228753Smm }}; 343228753Smm assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 344228753Smm } 345228753Smm 346228753Smm /** 347228753Smm * helpQuiesce returns when tasks are complete. 348231200Smm * getQueuedTaskCount returns 0 when quiescent 349231200Smm */ 350228753Smm public void testForkHelpQuiesce() { 351228753Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 352228753Smm public Integer realCompute() { 353228753Smm FibTask f = new FibTask(8); 354231200Smm assertSame(f, f.fork()); 355231200Smm helpQuiesce(); 356231200Smm while (!f.isDone()) // wait out race 357231200Smm ; 358231200Smm assertEquals(0, getQueuedTaskCount()); 359228753Smm checkCompletedNormally(f, 21); 360231200Smm return NoResult; 361248616Smm }}; 362248616Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 363228753Smm } 364228753Smm 365228753Smm /** 366231200Smm * invoke task throws exception when task completes abnormally 367228753Smm */ 368228753Smm public void testAbnormalInvoke() { 369231200Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 370228753Smm public Integer realCompute() { 371228753Smm FailingFibTask f = new FailingFibTask(8); 372228753Smm try { 373228753Smm f.invoke(); 374228753Smm shouldThrow(); 375228753Smm } catch (FJException success) { 376231200Smm checkCompletedAbnormally(f, success); 377228753Smm } 378228753Smm return NoResult; 379228753Smm }}; 380228753Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 381228753Smm } 382228753Smm 383228753Smm /** 384228753Smm * quietlyInvoke task returns when task completes abnormally 385228753Smm */ 386231200Smm public void testAbnormalQuietlyInvoke() { 387228753Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 388228753Smm public Integer realCompute() { 389228753Smm FailingFibTask f = new FailingFibTask(8); 390228753Smm f.quietlyInvoke(); 391228753Smm assertTrue(f.getException() instanceof FJException); 392228753Smm checkCompletedAbnormally(f, f.getException()); 393228753Smm return NoResult; 394228753Smm }}; 395248616Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 396248616Smm } 397248616Smm 398248616Smm /** 399248616Smm * join of a forked task throws exception when task completes abnormally 400248616Smm */ 401248616Smm public void testAbnormalForkJoin() { 402248616Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 403248616Smm public Integer realCompute() { 404248616Smm FailingFibTask f = new FailingFibTask(8); 405248616Smm assertSame(f, f.fork()); 406248616Smm try { 407248616Smm Integer r = f.join(); 408248616Smm shouldThrow(); 409248616Smm } catch (FJException success) { 410248616Smm checkCompletedAbnormally(f, success); 411248616Smm } 412248616Smm return NoResult; 413248616Smm }}; 414248616Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 415248616Smm } 416248616Smm 417248616Smm /** 418248616Smm * get of a forked task throws exception when task completes abnormally 419248616Smm */ 420248616Smm public void testAbnormalForkGet() { 421248616Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 422248616Smm public Integer realCompute() throws Exception { 423248616Smm FailingFibTask f = new FailingFibTask(8); 424248616Smm assertSame(f, f.fork()); 425248616Smm try { 426248616Smm Integer r = f.get(); 427248616Smm shouldThrow(); 428248616Smm } catch (ExecutionException success) { 429248616Smm Throwable cause = success.getCause(); 430248616Smm assertTrue(cause instanceof FJException); 431248616Smm checkCompletedAbnormally(f, cause); 432248616Smm } 433248616Smm return NoResult; 434248616Smm }}; 435248616Smm assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 436248616Smm } 437248616Smm 438248616Smm /** 439248616Smm * timed get of a forked task throws exception when task completes abnormally 440248616Smm */ 441248616Smm public void testAbnormalForkTimedGet() { 442228753Smm RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 443 public Integer realCompute() throws Exception { 444 FailingFibTask f = new FailingFibTask(8); 445 assertSame(f, f.fork()); 446 try { 447 Integer r = f.get(LONG_DELAY_MS, MILLISECONDS); 448 shouldThrow(); 449 } catch (ExecutionException success) { 450 Throwable cause = success.getCause(); 451 assertTrue(cause instanceof FJException); 452 checkCompletedAbnormally(f, cause); 453 } 454 return NoResult; 455 }}; 456 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 457 } 458 459 /** 460 * quietlyJoin of a forked task returns when task completes abnormally 461 */ 462 public void testAbnormalForkQuietlyJoin() { 463 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 464 public Integer realCompute() { 465 FailingFibTask f = new FailingFibTask(8); 466 assertSame(f, f.fork()); 467 f.quietlyJoin(); 468 assertTrue(f.getException() instanceof FJException); 469 checkCompletedAbnormally(f, f.getException()); 470 return NoResult; 471 }}; 472 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 473 } 474 475 /** 476 * invoke task throws exception when task cancelled 477 */ 478 public void testCancelledInvoke() { 479 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 480 public Integer realCompute() { 481 FibTask f = new FibTask(8); 482 assertTrue(f.cancel(true)); 483 try { 484 Integer r = f.invoke(); 485 shouldThrow(); 486 } catch (CancellationException success) { 487 checkCancelled(f); 488 } 489 return NoResult; 490 }}; 491 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 492 } 493 494 /** 495 * join of a forked task throws exception when task cancelled 496 */ 497 public void testCancelledForkJoin() { 498 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 499 public Integer realCompute() { 500 FibTask f = new FibTask(8); 501 assertTrue(f.cancel(true)); 502 assertSame(f, f.fork()); 503 try { 504 Integer r = f.join(); 505 shouldThrow(); 506 } catch (CancellationException success) { 507 checkCancelled(f); 508 } 509 return NoResult; 510 }}; 511 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 512 } 513 514 /** 515 * get of a forked task throws exception when task cancelled 516 */ 517 public void testCancelledForkGet() { 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(); 525 shouldThrow(); 526 } catch (CancellationException success) { 527 checkCancelled(f); 528 } 529 return NoResult; 530 }}; 531 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 532 } 533 534 /** 535 * timed get of a forked task throws exception when task cancelled 536 */ 537 public void testCancelledForkTimedGet() { 538 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 539 public Integer realCompute() throws Exception { 540 FibTask f = new FibTask(8); 541 assertTrue(f.cancel(true)); 542 assertSame(f, f.fork()); 543 try { 544 Integer r = f.get(LONG_DELAY_MS, MILLISECONDS); 545 shouldThrow(); 546 } catch (CancellationException success) { 547 checkCancelled(f); 548 } 549 return NoResult; 550 }}; 551 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 552 } 553 554 /** 555 * quietlyJoin of a forked task returns when task cancelled 556 */ 557 public void testCancelledForkQuietlyJoin() { 558 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 559 public Integer realCompute() { 560 FibTask f = new FibTask(8); 561 assertTrue(f.cancel(true)); 562 assertSame(f, f.fork()); 563 f.quietlyJoin(); 564 checkCancelled(f); 565 return NoResult; 566 }}; 567 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 568 } 569 570 /** 571 * getPool of executing task returns its pool 572 */ 573 public void testGetPool() { 574 final ForkJoinPool mainPool = mainPool(); 575 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 576 public Integer realCompute() { 577 assertSame(mainPool, getPool()); 578 return NoResult; 579 }}; 580 assertSame(NoResult, testInvokeOnPool(mainPool, a)); 581 } 582 583 /** 584 * getPool of non-FJ task returns null 585 */ 586 public void testGetPool2() { 587 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 588 public Integer realCompute() { 589 assertNull(getPool()); 590 return NoResult; 591 }}; 592 assertSame(NoResult, a.invoke()); 593 } 594 595 /** 596 * inForkJoinPool of executing task returns true 597 */ 598 public void testInForkJoinPool() { 599 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 600 public Integer realCompute() { 601 assertTrue(inForkJoinPool()); 602 return NoResult; 603 }}; 604 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 605 } 606 607 /** 608 * inForkJoinPool of non-FJ task returns false 609 */ 610 public void testInForkJoinPool2() { 611 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 612 public Integer realCompute() { 613 assertFalse(inForkJoinPool()); 614 return NoResult; 615 }}; 616 assertSame(NoResult, a.invoke()); 617 } 618 619 /** 620 * The value set by setRawResult is returned by getRawResult 621 */ 622 public void testSetRawResult() { 623 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 624 public Integer realCompute() { 625 setRawResult(NoResult); 626 assertSame(NoResult, getRawResult()); 627 return NoResult; 628 } 629 }; 630 assertSame(NoResult, a.invoke()); 631 } 632 633 /** 634 * A reinitialized normally completed task may be re-invoked 635 */ 636 public void testReinitialize() { 637 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 638 public Integer realCompute() { 639 FibTask f = new FibTask(8); 640 checkNotDone(f); 641 642 for (int i = 0; i < 3; i++) { 643 Integer r = f.invoke(); 644 assertEquals(21, (int) r); 645 checkCompletedNormally(f, r); 646 f.reinitialize(); 647 f.publicSetRawResult(null); 648 checkNotDone(f); 649 } 650 return NoResult; 651 }}; 652 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 653 } 654 655 /** 656 * A reinitialized abnormally completed task may be re-invoked 657 */ 658 public void testReinitializeAbnormal() { 659 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 660 public Integer realCompute() { 661 FailingFibTask f = new FailingFibTask(8); 662 checkNotDone(f); 663 664 for (int i = 0; i < 3; i++) { 665 try { 666 f.invoke(); 667 shouldThrow(); 668 } catch (FJException success) { 669 checkCompletedAbnormally(f, success); 670 } 671 f.reinitialize(); 672 checkNotDone(f); 673 } 674 return NoResult; 675 }}; 676 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 677 } 678 679 /** 680 * invoke task throws exception after invoking completeExceptionally 681 */ 682 public void testCompleteExceptionally() { 683 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 684 public Integer realCompute() { 685 FibTask f = new FibTask(8); 686 f.completeExceptionally(new FJException()); 687 try { 688 Integer r = f.invoke(); 689 shouldThrow(); 690 } catch (FJException success) { 691 checkCompletedAbnormally(f, success); 692 } 693 return NoResult; 694 }}; 695 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 696 } 697 698 /** 699 * invoke task suppresses execution invoking complete 700 */ 701 public void testComplete() { 702 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 703 public Integer realCompute() { 704 FibTask f = new FibTask(8); 705 f.complete(NoResult); 706 Integer r = f.invoke(); 707 assertSame(NoResult, r); 708 checkCompletedNormally(f, NoResult); 709 return r; 710 }}; 711 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 712 } 713 714 /** 715 * invokeAll(t1, t2) invokes all task arguments 716 */ 717 public void testInvokeAll2() { 718 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 719 public Integer realCompute() { 720 FibTask f = new FibTask(8); 721 FibTask g = new FibTask(9); 722 invokeAll(f, g); 723 checkCompletedNormally(f, 21); 724 checkCompletedNormally(g, 34); 725 return NoResult; 726 }}; 727 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 728 } 729 730 /** 731 * invokeAll(tasks) with 1 argument invokes task 732 */ 733 public void testInvokeAll1() { 734 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 735 public Integer realCompute() { 736 FibTask f = new FibTask(8); 737 invokeAll(f); 738 checkCompletedNormally(f, 21); 739 return NoResult; 740 }}; 741 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 742 } 743 744 /** 745 * invokeAll(tasks) with > 2 argument invokes tasks 746 */ 747 public void testInvokeAll3() { 748 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 749 public Integer realCompute() { 750 FibTask f = new FibTask(8); 751 FibTask g = new FibTask(9); 752 FibTask h = new FibTask(7); 753 invokeAll(f, g, h); 754 assertTrue(f.isDone()); 755 assertTrue(g.isDone()); 756 assertTrue(h.isDone()); 757 checkCompletedNormally(f, 21); 758 checkCompletedNormally(g, 34); 759 checkCompletedNormally(h, 13); 760 return NoResult; 761 }}; 762 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 763 } 764 765 /** 766 * invokeAll(collection) invokes all tasks in the collection 767 */ 768 public void testInvokeAllCollection() { 769 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 770 public Integer realCompute() { 771 FibTask f = new FibTask(8); 772 FibTask g = new FibTask(9); 773 FibTask h = new FibTask(7); 774 HashSet set = new HashSet(); 775 set.add(f); 776 set.add(g); 777 set.add(h); 778 invokeAll(set); 779 assertTrue(f.isDone()); 780 assertTrue(g.isDone()); 781 assertTrue(h.isDone()); 782 checkCompletedNormally(f, 21); 783 checkCompletedNormally(g, 34); 784 checkCompletedNormally(h, 13); 785 return NoResult; 786 }}; 787 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 788 } 789 790 /** 791 * invokeAll(tasks) with any null task throws NPE 792 */ 793 public void testInvokeAllNPE() { 794 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 795 public Integer realCompute() { 796 FibTask f = new FibTask(8); 797 FibTask g = new FibTask(9); 798 FibTask h = null; 799 try { 800 invokeAll(f, g, h); 801 shouldThrow(); 802 } catch (NullPointerException success) {} 803 return NoResult; 804 }}; 805 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 806 } 807 808 /** 809 * invokeAll(t1, t2) throw exception if any task does 810 */ 811 public void testAbnormalInvokeAll2() { 812 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 813 public Integer realCompute() { 814 FibTask f = new FibTask(8); 815 FailingFibTask g = new FailingFibTask(9); 816 try { 817 invokeAll(f, g); 818 shouldThrow(); 819 } catch (FJException success) { 820 checkCompletedAbnormally(g, success); 821 } 822 return NoResult; 823 }}; 824 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 825 } 826 827 /** 828 * invokeAll(tasks) with 1 argument throws exception if task does 829 */ 830 public void testAbnormalInvokeAll1() { 831 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 832 public Integer realCompute() { 833 FailingFibTask g = new FailingFibTask(9); 834 try { 835 invokeAll(g); 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(tasks) with > 2 argument throws exception if any task does 847 */ 848 public void testAbnormalInvokeAll3() { 849 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 850 public Integer realCompute() { 851 FibTask f = new FibTask(8); 852 FailingFibTask g = new FailingFibTask(9); 853 FibTask h = new FibTask(7); 854 try { 855 invokeAll(f, g, h); 856 shouldThrow(); 857 } catch (FJException success) { 858 checkCompletedAbnormally(g, success); 859 } 860 return NoResult; 861 }}; 862 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 863 } 864 865 /** 866 * invokeAll(collection) throws exception if any task does 867 */ 868 public void testAbnormalInvokeAllCollection() { 869 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 870 public Integer realCompute() { 871 FailingFibTask f = new FailingFibTask(8); 872 FibTask g = new FibTask(9); 873 FibTask h = new FibTask(7); 874 HashSet set = new HashSet(); 875 set.add(f); 876 set.add(g); 877 set.add(h); 878 try { 879 invokeAll(set); 880 shouldThrow(); 881 } catch (FJException success) { 882 checkCompletedAbnormally(f, success); 883 } 884 return NoResult; 885 }}; 886 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 887 } 888 889 /** 890 * tryUnfork returns true for most recent unexecuted task, 891 * and suppresses execution 892 */ 893 public void testTryUnfork() { 894 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 895 public Integer realCompute() { 896 FibTask g = new FibTask(9); 897 assertSame(g, g.fork()); 898 FibTask f = new FibTask(8); 899 assertSame(f, f.fork()); 900 assertTrue(f.tryUnfork()); 901 helpQuiesce(); 902 checkNotDone(f); 903 checkCompletedNormally(g, 34); 904 return NoResult; 905 }}; 906 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 907 } 908 909 /** 910 * getSurplusQueuedTaskCount returns > 0 when 911 * there are more tasks than threads 912 */ 913 public void testGetSurplusQueuedTaskCount() { 914 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 915 public Integer realCompute() { 916 FibTask h = new FibTask(7); 917 assertSame(h, h.fork()); 918 FibTask g = new FibTask(9); 919 assertSame(g, g.fork()); 920 FibTask f = new FibTask(8); 921 assertSame(f, f.fork()); 922 assertTrue(getSurplusQueuedTaskCount() > 0); 923 helpQuiesce(); 924 assertEquals(0, getSurplusQueuedTaskCount()); 925 checkCompletedNormally(f, 21); 926 checkCompletedNormally(g, 34); 927 checkCompletedNormally(h, 13); 928 return NoResult; 929 }}; 930 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 931 } 932 933 /** 934 * peekNextLocalTask returns most recent unexecuted task. 935 */ 936 public void testPeekNextLocalTask() { 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, peekNextLocalTask()); 944 checkCompletesNormally(f, 21); 945 helpQuiesce(); 946 checkCompletedNormally(g, 34); 947 return NoResult; 948 }}; 949 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 950 } 951 952 /** 953 * pollNextLocalTask returns most recent unexecuted task 954 * without executing it 955 */ 956 public void testPollNextLocalTask() { 957 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 958 public Integer realCompute() { 959 FibTask g = new FibTask(9); 960 assertSame(g, g.fork()); 961 FibTask f = new FibTask(8); 962 assertSame(f, f.fork()); 963 assertSame(f, pollNextLocalTask()); 964 helpQuiesce(); 965 checkNotDone(f); 966 checkCompletedNormally(g, 34); 967 return NoResult; 968 }}; 969 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 970 } 971 972 /** 973 * pollTask returns an unexecuted task without executing it 974 */ 975 public void testPollTask() { 976 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 977 public Integer realCompute() { 978 FibTask g = new FibTask(9); 979 assertSame(g, g.fork()); 980 FibTask f = new FibTask(8); 981 assertSame(f, f.fork()); 982 assertSame(f, pollTask()); 983 helpQuiesce(); 984 checkNotDone(f); 985 checkCompletedNormally(g, 34); 986 return NoResult; 987 }}; 988 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 989 } 990 991 /** 992 * peekNextLocalTask returns least recent unexecuted task in async mode 993 */ 994 public void testPeekNextLocalTaskAsync() { 995 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 996 public Integer realCompute() { 997 FibTask g = new FibTask(9); 998 assertSame(g, g.fork()); 999 FibTask f = new FibTask(8); 1000 assertSame(f, f.fork()); 1001 assertSame(g, peekNextLocalTask()); 1002 assertEquals(21, (int) f.join()); 1003 helpQuiesce(); 1004 checkCompletedNormally(f, 21); 1005 checkCompletedNormally(g, 34); 1006 return NoResult; 1007 }}; 1008 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 1009 } 1010 1011 /** 1012 * pollNextLocalTask returns least recent unexecuted task without 1013 * executing it, in async mode 1014 */ 1015 public void testPollNextLocalTaskAsync() { 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, pollNextLocalTask()); 1023 helpQuiesce(); 1024 checkCompletedNormally(f, 21); 1025 checkNotDone(g); 1026 return NoResult; 1027 }}; 1028 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 1029 } 1030 1031 /** 1032 * pollTask returns an unexecuted task without executing it, in 1033 * async mode 1034 */ 1035 public void testPollTaskAsync() { 1036 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 1037 public Integer realCompute() { 1038 FibTask g = new FibTask(9); 1039 assertSame(g, g.fork()); 1040 FibTask f = new FibTask(8); 1041 assertSame(f, f.fork()); 1042 assertSame(g, pollTask()); 1043 helpQuiesce(); 1044 checkCompletedNormally(f, 21); 1045 checkNotDone(g); 1046 return NoResult; 1047 }}; 1048 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 1049 } 1050 1051} 1052