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