1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  */
  22 
  23 /*
  24  * This file is available under and governed by the GNU General Public
  25  * License version 2 only, as published by the Free Software Foundation.
  26  * However, the following notice accompanied the original version of this
  27  * file:
  28  *
  29  * Written by Doug Lea with assistance from members of JCP JSR-166
  30  * Expert Group and released to the public domain, as explained at
  31  * http://creativecommons.org/publicdomain/zero/1.0/
  32  */
  33 
  34 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  35 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  36 
  37 import java.security.PrivilegedAction;
  38 import java.security.PrivilegedExceptionAction;
  39 import java.util.ArrayList;
  40 import java.util.Collection;
  41 import java.util.Collections;
  42 import java.util.List;
  43 import java.util.concurrent.Callable;
  44 import java.util.concurrent.CountDownLatch;
  45 import java.util.concurrent.ExecutionException;
  46 import java.util.concurrent.Executors;
  47 import java.util.concurrent.ExecutorService;
  48 import java.util.concurrent.ForkJoinPool;
  49 import java.util.concurrent.ForkJoinTask;
  50 import java.util.concurrent.ForkJoinWorkerThread;
  51 import java.util.concurrent.Future;
  52 import java.util.concurrent.RecursiveTask;
  53 import java.util.concurrent.RejectedExecutionException;
  54 import java.util.concurrent.atomic.AtomicBoolean;
  55 import java.util.concurrent.atomic.AtomicInteger;
  56 import java.util.concurrent.locks.ReentrantLock;
  57 
  58 import junit.framework.Test;
  59 import junit.framework.TestSuite;
  60 
  61 public class ForkJoinPoolTest extends JSR166TestCase {
  62     public static void main(String[] args) {
  63         main(suite(), args);
  64     }
  65 
  66     public static Test suite() {
  67         return new TestSuite(ForkJoinPoolTest.class);
  68     }
  69 
  70     /*
  71      * Testing coverage notes:
  72      *
  73      * 1. shutdown and related methods are tested via super.joinPool.
  74      *
  75      * 2. newTaskFor and adapters are tested in submit/invoke tests
  76      *
  77      * 3. We cannot portably test monitoring methods such as
  78      * getStealCount() since they rely ultimately on random task
  79      * stealing that may cause tasks not to be stolen/propagated
  80      * across threads, especially on uniprocessors.
  81      *
  82      * 4. There are no independently testable ForkJoinWorkerThread
  83      * methods, but they are covered here and in task tests.
  84      */
  85 
  86     // Some classes to test extension and factory methods
  87 
  88     static class MyError extends Error {}
  89 
  90     // to test handlers
  91     static class FailingFJWSubclass extends ForkJoinWorkerThread {
  92         public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
  93         protected void onStart() { super.onStart(); throw new MyError(); }
  94     }
  95 
  96     static class FailingThreadFactory
  97             implements ForkJoinPool.ForkJoinWorkerThreadFactory {
  98         final AtomicInteger calls = new AtomicInteger(0);
  99         public ForkJoinWorkerThread newThread(ForkJoinPool p) {
 100             if (calls.incrementAndGet() > 1) return null;
 101             return new FailingFJWSubclass(p);
 102         }
 103     }
 104 
 105     static class SubFJP extends ForkJoinPool { // to expose protected
 106         SubFJP() { super(1); }
 107         public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
 108             return super.drainTasksTo(c);
 109         }
 110         public ForkJoinTask<?> pollSubmission() {
 111             return super.pollSubmission();
 112         }
 113     }
 114 
 115     static class ManagedLocker implements ForkJoinPool.ManagedBlocker {
 116         final ReentrantLock lock;
 117         boolean hasLock = false;
 118         ManagedLocker(ReentrantLock lock) { this.lock = lock; }
 119         public boolean block() {
 120             if (!hasLock)
 121                 lock.lock();
 122             return true;
 123         }
 124         public boolean isReleasable() {
 125             return hasLock || (hasLock = lock.tryLock());
 126         }
 127     }
 128 
 129     // A simple recursive task for testing
 130     static final class FibTask extends RecursiveTask<Integer> {
 131         final int number;
 132         FibTask(int n) { number = n; }
 133         protected Integer compute() {
 134             int n = number;
 135             if (n <= 1)
 136                 return n;
 137             FibTask f1 = new FibTask(n - 1);
 138             f1.fork();
 139             return new FibTask(n - 2).compute() + f1.join();
 140         }
 141     }
 142 
 143     // A failing task for testing
 144     static final class FailingTask extends ForkJoinTask<Void> {
 145         public final Void getRawResult() { return null; }
 146         protected final void setRawResult(Void mustBeNull) { }
 147         protected final boolean exec() { throw new Error(); }
 148         FailingTask() {}
 149     }
 150 
 151     // Fib needlessly using locking to test ManagedBlockers
 152     static final class LockingFibTask extends RecursiveTask<Integer> {
 153         final int number;
 154         final ManagedLocker locker;
 155         final ReentrantLock lock;
 156         LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
 157             number = n;
 158             this.locker = locker;
 159             this.lock = lock;
 160         }
 161         protected Integer compute() {
 162             int n;
 163             LockingFibTask f1 = null;
 164             LockingFibTask f2 = null;
 165             locker.block();
 166             n = number;
 167             if (n > 1) {
 168                 f1 = new LockingFibTask(n - 1, locker, lock);
 169                 f2 = new LockingFibTask(n - 2, locker, lock);
 170             }
 171             lock.unlock();
 172             if (n <= 1)
 173                 return n;
 174             else {
 175                 f1.fork();
 176                 return f2.compute() + f1.join();
 177             }
 178         }
 179     }
 180 
 181     /**
 182      * Successfully constructed pool reports default factory,
 183      * parallelism and async mode policies, no active threads or
 184      * tasks, and quiescent running state.
 185      */
 186     public void testDefaultInitialState() {
 187         ForkJoinPool p = new ForkJoinPool(1);
 188         try (PoolCleaner cleaner = cleaner(p)) {
 189             assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
 190                        p.getFactory());
 191             assertFalse(p.getAsyncMode());
 192             assertEquals(0, p.getActiveThreadCount());
 193             assertEquals(0, p.getStealCount());
 194             assertEquals(0, p.getQueuedTaskCount());
 195             assertEquals(0, p.getQueuedSubmissionCount());
 196             assertFalse(p.hasQueuedSubmissions());
 197             assertFalse(p.isShutdown());
 198             assertFalse(p.isTerminating());
 199             assertFalse(p.isTerminated());
 200         }
 201     }
 202 
 203     /**
 204      * Constructor throws if size argument is less than zero
 205      */
 206     public void testConstructor1() {
 207         try {
 208             new ForkJoinPool(-1);
 209             shouldThrow();
 210         } catch (IllegalArgumentException success) {}
 211     }
 212 
 213     /**
 214      * Constructor throws if factory argument is null
 215      */
 216     public void testConstructor2() {
 217         try {
 218             new ForkJoinPool(1, null, null, false);
 219             shouldThrow();
 220         } catch (NullPointerException success) {}
 221     }
 222 
 223     /**
 224      * getParallelism returns size set in constructor
 225      */
 226     public void testGetParallelism() {
 227         ForkJoinPool p = new ForkJoinPool(1);
 228         try (PoolCleaner cleaner = cleaner(p)) {
 229             assertEquals(1, p.getParallelism());
 230         }
 231     }
 232 
 233     /**
 234      * getPoolSize returns number of started workers.
 235      */
 236     public void testGetPoolSize() {
 237         final CountDownLatch taskStarted = new CountDownLatch(1);
 238         final CountDownLatch done = new CountDownLatch(1);
 239         final ForkJoinPool p = new ForkJoinPool(1);
 240         try (PoolCleaner cleaner = cleaner(p)) {
 241             assertEquals(0, p.getActiveThreadCount());
 242             final Runnable task = new CheckedRunnable() {
 243                 public void realRun() throws InterruptedException {
 244                     taskStarted.countDown();
 245                     assertEquals(1, p.getPoolSize());
 246                     assertEquals(1, p.getActiveThreadCount());
 247                     await(done);
 248                 }};
 249             Future<?> future = p.submit(task);
 250             await(taskStarted);
 251             assertEquals(1, p.getPoolSize());
 252             assertEquals(1, p.getActiveThreadCount());
 253             done.countDown();
 254         }
 255         assertEquals(0, p.getPoolSize());
 256         assertEquals(0, p.getActiveThreadCount());
 257     }
 258 
 259     /**
 260      * awaitTermination on a non-shutdown pool times out
 261      */
 262     public void testAwaitTermination_timesOut() throws InterruptedException {
 263         ForkJoinPool p = new ForkJoinPool(1);
 264         try (PoolCleaner cleaner = cleaner(p)) {
 265             assertFalse(p.isTerminated());
 266             assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
 267             assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
 268             assertFalse(p.awaitTermination(-1L, NANOSECONDS));
 269             assertFalse(p.awaitTermination(-1L, MILLISECONDS));
 270             assertFalse(p.awaitTermination(randomExpiredTimeout(),
 271                                            randomTimeUnit()));
 272             long timeoutNanos = 999999L;
 273             long startTime = System.nanoTime();
 274             assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
 275             assertTrue(System.nanoTime() - startTime >= timeoutNanos);
 276             assertFalse(p.isTerminated());
 277             startTime = System.nanoTime();
 278             long timeoutMillis = timeoutMillis();
 279             assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
 280             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
 281             assertFalse(p.isTerminated());
 282             p.shutdown();
 283             assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
 284             assertTrue(p.isTerminated());
 285         }
 286     }
 287 
 288     /**
 289      * setUncaughtExceptionHandler changes handler for uncaught exceptions.
 290      *
 291      * Additionally tests: Overriding ForkJoinWorkerThread.onStart
 292      * performs its defined action
 293      */
 294     public void testSetUncaughtExceptionHandler() throws InterruptedException {
 295         final CountDownLatch uehInvoked = new CountDownLatch(1);
 296         final Thread.UncaughtExceptionHandler ueh =
 297             new Thread.UncaughtExceptionHandler() {
 298                 public void uncaughtException(Thread t, Throwable e) {
 299                     threadAssertTrue(e instanceof MyError);
 300                     threadAssertTrue(t instanceof FailingFJWSubclass);
 301                     uehInvoked.countDown();
 302                 }};
 303         ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
 304                                           ueh, false);
 305         try (PoolCleaner cleaner = cleaner(p)) {
 306             assertSame(ueh, p.getUncaughtExceptionHandler());
 307             try {
 308                 p.execute(new FibTask(8));
 309                 await(uehInvoked);
 310             } finally {
 311                 p.shutdownNow(); // failure might have prevented processing task
 312             }
 313         }
 314     }
 315 
 316     /**
 317      * After invoking a single task, isQuiescent eventually becomes
 318      * true, at which time queues are empty, threads are not active,
 319      * the task has completed successfully, and construction
 320      * parameters continue to hold
 321      */
 322     public void testIsQuiescent() throws Exception {
 323         ForkJoinPool p = new ForkJoinPool(2);
 324         try (PoolCleaner cleaner = cleaner(p)) {
 325             assertTrue(p.isQuiescent());
 326             long startTime = System.nanoTime();
 327             FibTask f = new FibTask(20);
 328             p.invoke(f);
 329             assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
 330                        p.getFactory());
 331             while (! p.isQuiescent()) {
 332                 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
 333                     throw new AssertionError("timed out");
 334                 assertFalse(p.getAsyncMode());
 335                 assertFalse(p.isShutdown());
 336                 assertFalse(p.isTerminating());
 337                 assertFalse(p.isTerminated());
 338                 Thread.yield();
 339             }
 340 
 341             assertTrue(p.isQuiescent());
 342             assertFalse(p.getAsyncMode());
 343             assertEquals(0, p.getQueuedTaskCount());
 344             assertEquals(0, p.getQueuedSubmissionCount());
 345             assertFalse(p.hasQueuedSubmissions());
 346             while (p.getActiveThreadCount() != 0
 347                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
 348                 Thread.yield();
 349             assertFalse(p.isShutdown());
 350             assertFalse(p.isTerminating());
 351             assertFalse(p.isTerminated());
 352             assertTrue(f.isDone());
 353             assertEquals(6765, (int) f.get());
 354             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
 355         }
 356     }
 357 
 358     /**
 359      * Completed submit(ForkJoinTask) returns result
 360      */
 361     public void testSubmitForkJoinTask() throws Throwable {
 362         ForkJoinPool p = new ForkJoinPool(1);
 363         try (PoolCleaner cleaner = cleaner(p)) {
 364             ForkJoinTask<Integer> f = p.submit(new FibTask(8));
 365             assertEquals(21, (int) f.get());
 366         }
 367     }
 368 
 369     /**
 370      * A task submitted after shutdown is rejected
 371      */
 372     public void testSubmitAfterShutdown() {
 373         ForkJoinPool p = new ForkJoinPool(1);
 374         try (PoolCleaner cleaner = cleaner(p)) {
 375             p.shutdown();
 376             assertTrue(p.isShutdown());
 377             try {
 378                 ForkJoinTask<Integer> f = p.submit(new FibTask(8));
 379                 shouldThrow();
 380             } catch (RejectedExecutionException success) {}
 381         }
 382     }
 383 
 384     /**
 385      * Pool maintains parallelism when using ManagedBlocker
 386      */
 387     public void testBlockingForkJoinTask() throws Throwable {
 388         ForkJoinPool p = new ForkJoinPool(4);
 389         try {
 390             ReentrantLock lock = new ReentrantLock();
 391             ManagedLocker locker = new ManagedLocker(lock);
 392             ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock);
 393             p.execute(f);
 394             assertEquals(6765, (int) f.get());
 395         } finally {
 396             p.shutdownNow(); // don't wait out shutdown
 397         }
 398     }
 399 
 400     /**
 401      * pollSubmission returns unexecuted submitted task, if present
 402      */
 403     public void testPollSubmission() {
 404         final CountDownLatch done = new CountDownLatch(1);
 405         SubFJP p = new SubFJP();
 406         try (PoolCleaner cleaner = cleaner(p)) {
 407             ForkJoinTask a = p.submit(awaiter(done));
 408             ForkJoinTask b = p.submit(awaiter(done));
 409             ForkJoinTask c = p.submit(awaiter(done));
 410             ForkJoinTask r = p.pollSubmission();
 411             assertTrue(r == a || r == b || r == c);
 412             assertFalse(r.isDone());
 413             done.countDown();
 414         }
 415     }
 416 
 417     /**
 418      * drainTasksTo transfers unexecuted submitted tasks, if present
 419      */
 420     public void testDrainTasksTo() {
 421         final CountDownLatch done = new CountDownLatch(1);
 422         SubFJP p = new SubFJP();
 423         try (PoolCleaner cleaner = cleaner(p)) {
 424             ForkJoinTask a = p.submit(awaiter(done));
 425             ForkJoinTask b = p.submit(awaiter(done));
 426             ForkJoinTask c = p.submit(awaiter(done));
 427             ArrayList<ForkJoinTask> al = new ArrayList();
 428             p.drainTasksTo(al);
 429             assertTrue(al.size() > 0);
 430             for (ForkJoinTask r : al) {
 431                 assertTrue(r == a || r == b || r == c);
 432                 assertFalse(r.isDone());
 433             }
 434             done.countDown();
 435         }
 436     }
 437 
 438     // FJ Versions of AbstractExecutorService tests
 439 
 440     /**
 441      * execute(runnable) runs it to completion
 442      */
 443     public void testExecuteRunnable() throws Throwable {
 444         ExecutorService e = new ForkJoinPool(1);
 445         try (PoolCleaner cleaner = cleaner(e)) {
 446             final AtomicBoolean done = new AtomicBoolean(false);
 447             Future<?> future = e.submit(new CheckedRunnable() {
 448                 public void realRun() {
 449                     done.set(true);
 450                 }});
 451             assertNull(future.get());
 452             assertNull(future.get(randomExpiredTimeout(), randomTimeUnit()));
 453             assertTrue(done.get());
 454             assertTrue(future.isDone());
 455             assertFalse(future.isCancelled());
 456         }
 457     }
 458 
 459     /**
 460      * Completed submit(callable) returns result
 461      */
 462     public void testSubmitCallable() throws Throwable {
 463         ExecutorService e = new ForkJoinPool(1);
 464         try (PoolCleaner cleaner = cleaner(e)) {
 465             Future<String> future = e.submit(new StringTask());
 466             assertSame(TEST_STRING, future.get());
 467             assertTrue(future.isDone());
 468             assertFalse(future.isCancelled());
 469         }
 470     }
 471 
 472     /**
 473      * Completed submit(runnable) returns successfully
 474      */
 475     public void testSubmitRunnable() throws Throwable {
 476         ExecutorService e = new ForkJoinPool(1);
 477         try (PoolCleaner cleaner = cleaner(e)) {
 478             Future<?> future = e.submit(new NoOpRunnable());
 479             assertNull(future.get());
 480             assertTrue(future.isDone());
 481             assertFalse(future.isCancelled());
 482         }
 483     }
 484 
 485     /**
 486      * Completed submit(runnable, result) returns result
 487      */
 488     public void testSubmitRunnable2() throws Throwable {
 489         ExecutorService e = new ForkJoinPool(1);
 490         try (PoolCleaner cleaner = cleaner(e)) {
 491             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
 492             assertSame(TEST_STRING, future.get());
 493             assertTrue(future.isDone());
 494             assertFalse(future.isCancelled());
 495         }
 496     }
 497 
 498     /**
 499      * A submitted privileged action runs to completion
 500      */
 501     public void testSubmitPrivilegedAction() throws Exception {
 502         final Callable callable = Executors.callable(new PrivilegedAction() {
 503                 public Object run() { return TEST_STRING; }});
 504         Runnable r = new CheckedRunnable() {
 505         public void realRun() throws Exception {
 506             ExecutorService e = new ForkJoinPool(1);
 507             try (PoolCleaner cleaner = cleaner(e)) {
 508                 Future future = e.submit(callable);
 509                 assertSame(TEST_STRING, future.get());
 510             }
 511         }};
 512 
 513         runWithPermissions(r, new RuntimePermission("modifyThread"));
 514     }
 515 
 516     /**
 517      * A submitted privileged exception action runs to completion
 518      */
 519     public void testSubmitPrivilegedExceptionAction() throws Exception {
 520         final Callable callable =
 521             Executors.callable(new PrivilegedExceptionAction() {
 522                 public Object run() { return TEST_STRING; }});
 523         Runnable r = new CheckedRunnable() {
 524         public void realRun() throws Exception {
 525             ExecutorService e = new ForkJoinPool(1);
 526             try (PoolCleaner cleaner = cleaner(e)) {
 527                 Future future = e.submit(callable);
 528                 assertSame(TEST_STRING, future.get());
 529             }
 530         }};
 531 
 532         runWithPermissions(r, new RuntimePermission("modifyThread"));
 533     }
 534 
 535     /**
 536      * A submitted failed privileged exception action reports exception
 537      */
 538     public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
 539         final Callable callable =
 540             Executors.callable(new PrivilegedExceptionAction() {
 541                 public Object run() { throw new IndexOutOfBoundsException(); }});
 542         Runnable r = new CheckedRunnable() {
 543         public void realRun() throws Exception {
 544             ExecutorService e = new ForkJoinPool(1);
 545             try (PoolCleaner cleaner = cleaner(e)) {
 546                 Future future = e.submit(callable);
 547                 try {
 548                     future.get();
 549                     shouldThrow();
 550                 } catch (ExecutionException success) {
 551                     assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
 552                 }
 553             }
 554         }};
 555 
 556         runWithPermissions(r, new RuntimePermission("modifyThread"));
 557     }
 558 
 559     /**
 560      * execute(null runnable) throws NullPointerException
 561      */
 562     public void testExecuteNullRunnable() {
 563         ExecutorService e = new ForkJoinPool(1);
 564         try (PoolCleaner cleaner = cleaner(e)) {
 565             try {
 566                 Future<?> future = e.submit((Runnable) null);
 567                 shouldThrow();
 568             } catch (NullPointerException success) {}
 569         }
 570     }
 571 
 572     /**
 573      * submit(null callable) throws NullPointerException
 574      */
 575     public void testSubmitNullCallable() {
 576         ExecutorService e = new ForkJoinPool(1);
 577         try (PoolCleaner cleaner = cleaner(e)) {
 578             try {
 579                 Future<String> future = e.submit((Callable) null);
 580                 shouldThrow();
 581             } catch (NullPointerException success) {}
 582         }
 583     }
 584 
 585     /**
 586      * submit(callable).get() throws InterruptedException if interrupted
 587      */
 588     public void testInterruptedSubmit() throws InterruptedException {
 589         final CountDownLatch submitted    = new CountDownLatch(1);
 590         final CountDownLatch quittingTime = new CountDownLatch(1);
 591         final Callable<Void> awaiter = new CheckedCallable<Void>() {
 592             public Void realCall() throws InterruptedException {
 593                 assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
 594                 return null;
 595             }};
 596         final ExecutorService p = new ForkJoinPool(1);
 597         try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
 598             Thread t = new Thread(new CheckedInterruptedRunnable() {
 599                 public void realRun() throws Exception {
 600                     Future<Void> future = p.submit(awaiter);
 601                     submitted.countDown();
 602                     future.get();
 603                 }});
 604             t.start();
 605             await(submitted);
 606             t.interrupt();
 607             awaitTermination(t);
 608         }
 609     }
 610 
 611     /**
 612      * get of submit(callable) throws ExecutionException if callable
 613      * throws exception
 614      */
 615     public void testSubmitEE() throws Throwable {
 616         ForkJoinPool p = new ForkJoinPool(1);
 617         try (PoolCleaner cleaner = cleaner(p)) {
 618             try {
 619                 p.submit(new Callable() {
 620                         public Object call() { throw new ArithmeticException(); }})
 621                     .get();
 622                 shouldThrow();
 623             } catch (ExecutionException success) {
 624                 assertTrue(success.getCause() instanceof ArithmeticException);
 625             }
 626         }
 627     }
 628 
 629     /**
 630      * invokeAny(null) throws NullPointerException
 631      */
 632     public void testInvokeAny1() throws Throwable {
 633         ExecutorService e = new ForkJoinPool(1);
 634         try (PoolCleaner cleaner = cleaner(e)) {
 635             try {
 636                 e.invokeAny(null);
 637                 shouldThrow();
 638             } catch (NullPointerException success) {}
 639         }
 640     }
 641 
 642     /**
 643      * invokeAny(empty collection) throws IllegalArgumentException
 644      */
 645     public void testInvokeAny2() throws Throwable {
 646         ExecutorService e = new ForkJoinPool(1);
 647         try (PoolCleaner cleaner = cleaner(e)) {
 648             try {
 649                 e.invokeAny(new ArrayList<Callable<String>>());
 650                 shouldThrow();
 651             } catch (IllegalArgumentException success) {}
 652         }
 653     }
 654 
 655     /**
 656      * invokeAny(c) throws NullPointerException if c has a single null element
 657      */
 658     public void testInvokeAny3() throws Throwable {
 659         ExecutorService e = new ForkJoinPool(1);
 660         try (PoolCleaner cleaner = cleaner(e)) {
 661             List<Callable<String>> l = new ArrayList<>();
 662             l.add(null);
 663             try {
 664                 e.invokeAny(l);
 665                 shouldThrow();
 666             } catch (NullPointerException success) {}
 667         }
 668     }
 669 
 670     /**
 671      * invokeAny(c) throws NullPointerException if c has null elements
 672      */
 673     public void testInvokeAny4() throws Throwable {
 674         CountDownLatch latch = new CountDownLatch(1);
 675         ExecutorService e = new ForkJoinPool(1);
 676         try (PoolCleaner cleaner = cleaner(e)) {
 677             List<Callable<String>> l = new ArrayList<>();
 678             l.add(latchAwaitingStringTask(latch));
 679             l.add(null);
 680             try {
 681                 e.invokeAny(l);
 682                 shouldThrow();
 683             } catch (NullPointerException success) {}
 684             latch.countDown();
 685         }
 686     }
 687 
 688     /**
 689      * invokeAny(c) throws ExecutionException if no task in c completes
 690      */
 691     public void testInvokeAny5() throws Throwable {
 692         ExecutorService e = new ForkJoinPool(1);
 693         try (PoolCleaner cleaner = cleaner(e)) {
 694             List<Callable<String>> l = new ArrayList<>();
 695             l.add(new NPETask());
 696             try {
 697                 e.invokeAny(l);
 698                 shouldThrow();
 699             } catch (ExecutionException success) {
 700                 assertTrue(success.getCause() instanceof NullPointerException);
 701             }
 702         }
 703     }
 704 
 705     /**
 706      * invokeAny(c) returns result of some task in c if at least one completes
 707      */
 708     public void testInvokeAny6() throws Throwable {
 709         ExecutorService e = new ForkJoinPool(1);
 710         try (PoolCleaner cleaner = cleaner(e)) {
 711             List<Callable<String>> l = new ArrayList<>();
 712             l.add(new StringTask());
 713             l.add(new StringTask());
 714             String result = e.invokeAny(l);
 715             assertSame(TEST_STRING, result);
 716         }
 717     }
 718 
 719     /**
 720      * invokeAll(null) throws NullPointerException
 721      */
 722     public void testInvokeAll1() throws Throwable {
 723         ExecutorService e = new ForkJoinPool(1);
 724         try (PoolCleaner cleaner = cleaner(e)) {
 725             try {
 726                 e.invokeAll(null);
 727                 shouldThrow();
 728             } catch (NullPointerException success) {}
 729         }
 730     }
 731 
 732     /**
 733      * invokeAll(empty collection) returns empty list
 734      */
 735     public void testInvokeAll2() throws InterruptedException {
 736         ExecutorService e = new ForkJoinPool(1);
 737         final Collection<Callable<String>> emptyCollection
 738             = Collections.emptyList();
 739         try (PoolCleaner cleaner = cleaner(e)) {
 740             List<Future<String>> r = e.invokeAll(emptyCollection);
 741             assertTrue(r.isEmpty());
 742         }
 743     }
 744 
 745     /**
 746      * invokeAll(c) throws NullPointerException if c has null elements
 747      */
 748     public void testInvokeAll3() throws InterruptedException {
 749         ExecutorService e = new ForkJoinPool(1);
 750         try (PoolCleaner cleaner = cleaner(e)) {
 751             List<Callable<String>> l = new ArrayList<>();
 752             l.add(new StringTask());
 753             l.add(null);
 754             try {
 755                 e.invokeAll(l);
 756                 shouldThrow();
 757             } catch (NullPointerException success) {}
 758         }
 759     }
 760 
 761     /**
 762      * get of returned element of invokeAll(c) throws
 763      * ExecutionException on failed task
 764      */
 765     public void testInvokeAll4() throws Throwable {
 766         ExecutorService e = new ForkJoinPool(1);
 767         try (PoolCleaner cleaner = cleaner(e)) {
 768             List<Callable<String>> l = new ArrayList<>();
 769             l.add(new NPETask());
 770             List<Future<String>> futures = e.invokeAll(l);
 771             assertEquals(1, futures.size());
 772             try {
 773                 futures.get(0).get();
 774                 shouldThrow();
 775             } catch (ExecutionException success) {
 776                 assertTrue(success.getCause() instanceof NullPointerException);
 777             }
 778         }
 779     }
 780 
 781     /**
 782      * invokeAll(c) returns results of all completed tasks in c
 783      */
 784     public void testInvokeAll5() throws Throwable {
 785         ExecutorService e = new ForkJoinPool(1);
 786         try (PoolCleaner cleaner = cleaner(e)) {
 787             List<Callable<String>> l = new ArrayList<>();
 788             l.add(new StringTask());
 789             l.add(new StringTask());
 790             List<Future<String>> futures = e.invokeAll(l);
 791             assertEquals(2, futures.size());
 792             for (Future<String> future : futures)
 793                 assertSame(TEST_STRING, future.get());
 794         }
 795     }
 796 
 797     /**
 798      * timed invokeAny(null) throws NullPointerException
 799      */
 800     public void testTimedInvokeAny1() throws Throwable {
 801         ExecutorService e = new ForkJoinPool(1);
 802         try (PoolCleaner cleaner = cleaner(e)) {
 803             try {
 804                 e.invokeAny(null, randomTimeout(), randomTimeUnit());
 805                 shouldThrow();
 806             } catch (NullPointerException success) {}
 807         }
 808     }
 809 
 810     /**
 811      * timed invokeAny(null time unit) throws NullPointerException
 812      */
 813     public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
 814         ExecutorService e = new ForkJoinPool(1);
 815         try (PoolCleaner cleaner = cleaner(e)) {
 816             List<Callable<String>> l = new ArrayList<>();
 817             l.add(new StringTask());
 818             try {
 819                 e.invokeAny(l, randomTimeout(), null);
 820                 shouldThrow();
 821             } catch (NullPointerException success) {}
 822         }
 823     }
 824 
 825     /**
 826      * timed invokeAny(empty collection) throws IllegalArgumentException
 827      */
 828     public void testTimedInvokeAny2() throws Throwable {
 829         ExecutorService e = new ForkJoinPool(1);
 830         try (PoolCleaner cleaner = cleaner(e)) {
 831             try {
 832                 e.invokeAny(new ArrayList<Callable<String>>(),
 833                             randomTimeout(), randomTimeUnit());
 834                 shouldThrow();
 835             } catch (IllegalArgumentException success) {}
 836         }
 837     }
 838 
 839     /**
 840      * timed invokeAny(c) throws NullPointerException if c has null elements
 841      */
 842     public void testTimedInvokeAny3() throws Throwable {
 843         CountDownLatch latch = new CountDownLatch(1);
 844         ExecutorService e = new ForkJoinPool(1);
 845         try (PoolCleaner cleaner = cleaner(e)) {
 846             List<Callable<String>> l = new ArrayList<>();
 847             l.add(latchAwaitingStringTask(latch));
 848             l.add(null);
 849             try {
 850                 e.invokeAny(l, randomTimeout(), randomTimeUnit());
 851                 shouldThrow();
 852             } catch (NullPointerException success) {}
 853             latch.countDown();
 854         }
 855     }
 856 
 857     /**
 858      * timed invokeAny(c) throws ExecutionException if no task completes
 859      */
 860     public void testTimedInvokeAny4() throws Throwable {
 861         ExecutorService e = new ForkJoinPool(1);
 862         try (PoolCleaner cleaner = cleaner(e)) {
 863             long startTime = System.nanoTime();
 864             List<Callable<String>> l = new ArrayList<>();
 865             l.add(new NPETask());
 866             try {
 867                 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
 868                 shouldThrow();
 869             } catch (ExecutionException success) {
 870                 assertTrue(success.getCause() instanceof NullPointerException);
 871             }
 872             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
 873         }
 874     }
 875 
 876     /**
 877      * timed invokeAny(c) returns result of some task in c
 878      */
 879     public void testTimedInvokeAny5() throws Throwable {
 880         ExecutorService e = new ForkJoinPool(1);
 881         try (PoolCleaner cleaner = cleaner(e)) {
 882             long startTime = System.nanoTime();
 883             List<Callable<String>> l = new ArrayList<>();
 884             l.add(new StringTask());
 885             l.add(new StringTask());
 886             String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
 887             assertSame(TEST_STRING, result);
 888             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
 889         }
 890     }
 891 
 892     /**
 893      * timed invokeAll(null) throws NullPointerException
 894      */
 895     public void testTimedInvokeAll1() throws Throwable {
 896         ExecutorService e = new ForkJoinPool(1);
 897         try (PoolCleaner cleaner = cleaner(e)) {
 898             try {
 899                 e.invokeAll(null, randomTimeout(), randomTimeUnit());
 900                 shouldThrow();
 901             } catch (NullPointerException success) {}
 902         }
 903     }
 904 
 905     /**
 906      * timed invokeAll(null time unit) throws NullPointerException
 907      */
 908     public void testTimedInvokeAllNullTimeUnit() throws Throwable {
 909         ExecutorService e = new ForkJoinPool(1);
 910         try (PoolCleaner cleaner = cleaner(e)) {
 911             List<Callable<String>> l = new ArrayList<>();
 912             l.add(new StringTask());
 913             try {
 914                 e.invokeAll(l, randomTimeout(), null);
 915                 shouldThrow();
 916             } catch (NullPointerException success) {}
 917         }
 918     }
 919 
 920     /**
 921      * timed invokeAll(empty collection) returns empty list
 922      */
 923     public void testTimedInvokeAll2() throws InterruptedException {
 924         ExecutorService e = new ForkJoinPool(1);
 925         final Collection<Callable<String>> emptyCollection
 926             = Collections.emptyList();
 927         try (PoolCleaner cleaner = cleaner(e)) {
 928             List<Future<String>> r
 929                 = e.invokeAll(emptyCollection,
 930                               randomTimeout(), randomTimeUnit());
 931             assertTrue(r.isEmpty());
 932         }
 933     }
 934 
 935     /**
 936      * timed invokeAll(c) throws NullPointerException if c has null elements
 937      */
 938     public void testTimedInvokeAll3() throws InterruptedException {
 939         ExecutorService e = new ForkJoinPool(1);
 940         try (PoolCleaner cleaner = cleaner(e)) {
 941             List<Callable<String>> l = new ArrayList<>();
 942             l.add(new StringTask());
 943             l.add(null);
 944             try {
 945                 e.invokeAll(l, randomTimeout(), randomTimeUnit());
 946                 shouldThrow();
 947             } catch (NullPointerException success) {}
 948         }
 949     }
 950 
 951     /**
 952      * get of returned element of invokeAll(c) throws exception on failed task
 953      */
 954     public void testTimedInvokeAll4() throws Throwable {
 955         ExecutorService e = new ForkJoinPool(1);
 956         try (PoolCleaner cleaner = cleaner(e)) {
 957             List<Callable<String>> l = new ArrayList<>();
 958             l.add(new NPETask());
 959             List<Future<String>> futures
 960                 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
 961             assertEquals(1, futures.size());
 962             try {
 963                 futures.get(0).get();
 964                 shouldThrow();
 965             } catch (ExecutionException success) {
 966                 assertTrue(success.getCause() instanceof NullPointerException);
 967             }
 968         }
 969     }
 970 
 971     /**
 972      * timed invokeAll(c) returns results of all completed tasks in c
 973      */
 974     public void testTimedInvokeAll5() throws Throwable {
 975         ForkJoinPool e = new ForkJoinPool(1);
 976         try (PoolCleaner cleaner = cleaner(e)) {
 977             List<Callable<String>> l = new ArrayList<>();
 978             l.add(new StringTask());
 979             l.add(new StringTask());
 980             List<Future<String>> futures
 981                 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
 982             assertEquals(2, futures.size());
 983             for (Future<String> future : futures)
 984                 assertSame(TEST_STRING, future.get());
 985         }
 986     }
 987 
 988 }