blob: e3bb428156b93f46c731c0905d2814b322f915fe [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7package jsr166;
8
Narayan Kamath8e9a0e92015-04-28 11:40:00 +01009import static java.util.concurrent.TimeUnit.MILLISECONDS;
10import static java.util.concurrent.TimeUnit.NANOSECONDS;
11
12import java.security.PrivilegedAction;
13import java.security.PrivilegedExceptionAction;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010014import java.util.ArrayList;
15import java.util.Collection;
16import java.util.List;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010017import java.util.concurrent.Callable;
18import java.util.concurrent.CountDownLatch;
19import java.util.concurrent.ExecutionException;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010020import java.util.concurrent.Executors;
21import java.util.concurrent.ExecutorService;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010022import java.util.concurrent.ForkJoinPool;
23import java.util.concurrent.ForkJoinTask;
24import java.util.concurrent.ForkJoinWorkerThread;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010025import java.util.concurrent.Future;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010026import java.util.concurrent.RecursiveTask;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010027import java.util.concurrent.RejectedExecutionException;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010028import java.util.concurrent.atomic.AtomicBoolean;
29import java.util.concurrent.locks.ReentrantLock;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010030
31import junit.framework.AssertionFailedError;
32import junit.framework.Test;
33import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010034
35public class ForkJoinPoolTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010036 // android-note: Removed because the CTS runner does a bad job of
37 // retrying tests that have suite() declarations.
38 //
39 // public static void main(String[] args) {
40 // main(suite(), args);
41 // }
42 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000043 // return new TestSuite(ForkJoinPoolTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010044 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010045
46 /*
47 * Testing coverage notes:
48 *
49 * 1. shutdown and related methods are tested via super.joinPool.
50 *
51 * 2. newTaskFor and adapters are tested in submit/invoke tests
52 *
53 * 3. We cannot portably test monitoring methods such as
54 * getStealCount() since they rely ultimately on random task
55 * stealing that may cause tasks not to be stolen/propagated
56 * across threads, especially on uniprocessors.
57 *
58 * 4. There are no independently testable ForkJoinWorkerThread
59 * methods, but they are covered here and in task tests.
60 */
61
62 // Some classes to test extension and factory methods
63
64 static class MyHandler implements Thread.UncaughtExceptionHandler {
65 volatile int catches = 0;
66 public void uncaughtException(Thread t, Throwable e) {
67 ++catches;
68 }
69 }
70
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000071 static class MyError extends Error {}
72
Calin Juravle8f0d92b2013-08-01 17:26:00 +010073 // to test handlers
74 static class FailingFJWSubclass extends ForkJoinWorkerThread {
75 public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000076 protected void onStart() { super.onStart(); throw new MyError(); }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010077 }
78
79 static class FailingThreadFactory
80 implements ForkJoinPool.ForkJoinWorkerThreadFactory {
81 volatile int calls = 0;
82 public ForkJoinWorkerThread newThread(ForkJoinPool p) {
83 if (++calls > 1) return null;
84 return new FailingFJWSubclass(p);
85 }
86 }
87
88 static class SubFJP extends ForkJoinPool { // to expose protected
89 SubFJP() { super(1); }
90 public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
91 return super.drainTasksTo(c);
92 }
93 public ForkJoinTask<?> pollSubmission() {
94 return super.pollSubmission();
95 }
96 }
97
98 static class ManagedLocker implements ForkJoinPool.ManagedBlocker {
99 final ReentrantLock lock;
100 boolean hasLock = false;
101 ManagedLocker(ReentrantLock lock) { this.lock = lock; }
102 public boolean block() {
103 if (!hasLock)
104 lock.lock();
105 return true;
106 }
107 public boolean isReleasable() {
108 return hasLock || (hasLock = lock.tryLock());
109 }
110 }
111
112 // A simple recursive task for testing
113 static final class FibTask extends RecursiveTask<Integer> {
114 final int number;
115 FibTask(int n) { number = n; }
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100116 protected Integer compute() {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100117 int n = number;
118 if (n <= 1)
119 return n;
120 FibTask f1 = new FibTask(n - 1);
121 f1.fork();
122 return (new FibTask(n - 2)).compute() + f1.join();
123 }
124 }
125
126 // A failing task for testing
127 static final class FailingTask extends ForkJoinTask<Void> {
128 public final Void getRawResult() { return null; }
129 protected final void setRawResult(Void mustBeNull) { }
130 protected final boolean exec() { throw new Error(); }
131 FailingTask() {}
132 }
133
134 // Fib needlessly using locking to test ManagedBlockers
135 static final class LockingFibTask extends RecursiveTask<Integer> {
136 final int number;
137 final ManagedLocker locker;
138 final ReentrantLock lock;
139 LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
140 number = n;
141 this.locker = locker;
142 this.lock = lock;
143 }
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100144 protected Integer compute() {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100145 int n;
146 LockingFibTask f1 = null;
147 LockingFibTask f2 = null;
148 locker.block();
149 n = number;
150 if (n > 1) {
151 f1 = new LockingFibTask(n - 1, locker, lock);
152 f2 = new LockingFibTask(n - 2, locker, lock);
153 }
154 lock.unlock();
155 if (n <= 1)
156 return n;
157 else {
158 f1.fork();
159 return f2.compute() + f1.join();
160 }
161 }
162 }
163
164 /**
165 * Successfully constructed pool reports default factory,
166 * parallelism and async mode policies, no active threads or
167 * tasks, and quiescent running state.
168 */
169 public void testDefaultInitialState() {
170 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000171 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100172 assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
173 p.getFactory());
174 assertFalse(p.getAsyncMode());
175 assertEquals(0, p.getActiveThreadCount());
176 assertEquals(0, p.getStealCount());
177 assertEquals(0, p.getQueuedTaskCount());
178 assertEquals(0, p.getQueuedSubmissionCount());
179 assertFalse(p.hasQueuedSubmissions());
180 assertFalse(p.isShutdown());
181 assertFalse(p.isTerminating());
182 assertFalse(p.isTerminated());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100183 }
184 }
185
186 /**
187 * Constructor throws if size argument is less than zero
188 */
189 public void testConstructor1() {
190 try {
191 new ForkJoinPool(-1);
192 shouldThrow();
193 } catch (IllegalArgumentException success) {}
194 }
195
196 /**
197 * Constructor throws if factory argument is null
198 */
199 public void testConstructor2() {
200 try {
201 new ForkJoinPool(1, null, null, false);
202 shouldThrow();
203 } catch (NullPointerException success) {}
204 }
205
206 /**
207 * getParallelism returns size set in constructor
208 */
209 public void testGetParallelism() {
210 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000211 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100212 assertEquals(1, p.getParallelism());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100213 }
214 }
215
216 /**
217 * getPoolSize returns number of started workers.
218 */
219 public void testGetPoolSize() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000220 final CountDownLatch taskStarted = new CountDownLatch(1);
221 final CountDownLatch done = new CountDownLatch(1);
222 final ForkJoinPool p = new ForkJoinPool(1);
223 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100224 assertEquals(0, p.getActiveThreadCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000225 final Runnable task = new CheckedRunnable() {
226 public void realRun() throws InterruptedException {
227 taskStarted.countDown();
228 assertEquals(1, p.getPoolSize());
229 assertEquals(1, p.getActiveThreadCount());
230 done.await();
231 }};
232 Future<?> future = p.submit(task);
233 await(taskStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100234 assertEquals(1, p.getPoolSize());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000235 assertEquals(1, p.getActiveThreadCount());
236 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100237 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000238 assertEquals(0, p.getPoolSize());
239 assertEquals(0, p.getActiveThreadCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100240 }
241
242 /**
243 * awaitTermination on a non-shutdown pool times out
244 */
245 public void testAwaitTermination_timesOut() throws InterruptedException {
246 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000247 try (PoolCleaner cleaner = cleaner(p)) {
248 assertFalse(p.isTerminated());
249 assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
250 assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
251 assertFalse(p.awaitTermination(-1L, NANOSECONDS));
252 assertFalse(p.awaitTermination(-1L, MILLISECONDS));
253 assertFalse(p.awaitTermination(0L, NANOSECONDS));
254 assertFalse(p.awaitTermination(0L, MILLISECONDS));
255 long timeoutNanos = 999999L;
256 long startTime = System.nanoTime();
257 assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
258 assertTrue(System.nanoTime() - startTime >= timeoutNanos);
259 assertFalse(p.isTerminated());
260 startTime = System.nanoTime();
261 long timeoutMillis = timeoutMillis();
262 assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
263 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
264 assertFalse(p.isTerminated());
265 p.shutdown();
266 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
267 assertTrue(p.isTerminated());
268 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100269 }
270
271 /**
272 * setUncaughtExceptionHandler changes handler for uncaught exceptions.
273 *
274 * Additionally tests: Overriding ForkJoinWorkerThread.onStart
275 * performs its defined action
276 */
277 public void testSetUncaughtExceptionHandler() throws InterruptedException {
278 final CountDownLatch uehInvoked = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000279 final Thread.UncaughtExceptionHandler ueh =
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100280 new Thread.UncaughtExceptionHandler() {
281 public void uncaughtException(Thread t, Throwable e) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000282 threadAssertTrue(e instanceof MyError);
283 threadAssertTrue(t instanceof FailingFJWSubclass);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100284 uehInvoked.countDown();
285 }};
286 ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000287 ueh, false);
288 try (PoolCleaner cleaner = cleaner(p)) {
289 assertSame(ueh, p.getUncaughtExceptionHandler());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100290 try {
291 p.execute(new FibTask(8));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000292 await(uehInvoked);
293 } finally {
294 p.shutdownNow(); // failure might have prevented processing task
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100295 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100296 }
297 }
298
299 /**
300 * After invoking a single task, isQuiescent eventually becomes
301 * true, at which time queues are empty, threads are not active,
302 * the task has completed successfully, and construction
303 * parameters continue to hold
304 */
305 public void testIsQuiescent() throws Exception {
306 ForkJoinPool p = new ForkJoinPool(2);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000307 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100308 assertTrue(p.isQuiescent());
309 long startTime = System.nanoTime();
310 FibTask f = new FibTask(20);
311 p.invoke(f);
312 assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
313 p.getFactory());
314 while (! p.isQuiescent()) {
315 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
316 throw new AssertionFailedError("timed out");
317 assertFalse(p.getAsyncMode());
318 assertFalse(p.isShutdown());
319 assertFalse(p.isTerminating());
320 assertFalse(p.isTerminated());
321 Thread.yield();
322 }
323
324 assertTrue(p.isQuiescent());
325 assertFalse(p.getAsyncMode());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100326 assertEquals(0, p.getQueuedTaskCount());
327 assertEquals(0, p.getQueuedSubmissionCount());
328 assertFalse(p.hasQueuedSubmissions());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000329 while (p.getActiveThreadCount() != 0
330 && millisElapsedSince(startTime) < LONG_DELAY_MS)
331 Thread.yield();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100332 assertFalse(p.isShutdown());
333 assertFalse(p.isTerminating());
334 assertFalse(p.isTerminated());
335 assertTrue(f.isDone());
336 assertEquals(6765, (int) f.get());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000337 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100338 }
339 }
340
341 /**
342 * Completed submit(ForkJoinTask) returns result
343 */
344 public void testSubmitForkJoinTask() throws Throwable {
345 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000346 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100347 ForkJoinTask<Integer> f = p.submit(new FibTask(8));
348 assertEquals(21, (int) f.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100349 }
350 }
351
352 /**
353 * A task submitted after shutdown is rejected
354 */
355 public void testSubmitAfterShutdown() {
356 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000357 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100358 p.shutdown();
359 assertTrue(p.isShutdown());
360 try {
361 ForkJoinTask<Integer> f = p.submit(new FibTask(8));
362 shouldThrow();
363 } catch (RejectedExecutionException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100364 }
365 }
366
367 /**
368 * Pool maintains parallelism when using ManagedBlocker
369 */
370 public void testBlockingForkJoinTask() throws Throwable {
371 ForkJoinPool p = new ForkJoinPool(4);
372 try {
373 ReentrantLock lock = new ReentrantLock();
374 ManagedLocker locker = new ManagedLocker(lock);
375 ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock);
376 p.execute(f);
377 assertEquals(6765, (int) f.get());
378 } finally {
379 p.shutdownNow(); // don't wait out shutdown
380 }
381 }
382
383 /**
384 * pollSubmission returns unexecuted submitted task, if present
385 */
386 public void testPollSubmission() {
387 final CountDownLatch done = new CountDownLatch(1);
388 SubFJP p = new SubFJP();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000389 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100390 ForkJoinTask a = p.submit(awaiter(done));
391 ForkJoinTask b = p.submit(awaiter(done));
392 ForkJoinTask c = p.submit(awaiter(done));
393 ForkJoinTask r = p.pollSubmission();
394 assertTrue(r == a || r == b || r == c);
395 assertFalse(r.isDone());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100396 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100397 }
398 }
399
400 /**
401 * drainTasksTo transfers unexecuted submitted tasks, if present
402 */
403 public void testDrainTasksTo() {
404 final CountDownLatch done = new CountDownLatch(1);
405 SubFJP p = new SubFJP();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000406 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100407 ForkJoinTask a = p.submit(awaiter(done));
408 ForkJoinTask b = p.submit(awaiter(done));
409 ForkJoinTask c = p.submit(awaiter(done));
410 ArrayList<ForkJoinTask> al = new ArrayList();
411 p.drainTasksTo(al);
412 assertTrue(al.size() > 0);
413 for (ForkJoinTask r : al) {
414 assertTrue(r == a || r == b || r == c);
415 assertFalse(r.isDone());
416 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100417 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100418 }
419 }
420
421 // FJ Versions of AbstractExecutorService tests
422
423 /**
424 * execute(runnable) runs it to completion
425 */
426 public void testExecuteRunnable() throws Throwable {
427 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000428 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100429 final AtomicBoolean done = new AtomicBoolean(false);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100430 Future<?> future = e.submit(new CheckedRunnable() {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100431 public void realRun() {
432 done.set(true);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100433 }});
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100434 assertNull(future.get());
435 assertNull(future.get(0, MILLISECONDS));
436 assertTrue(done.get());
437 assertTrue(future.isDone());
438 assertFalse(future.isCancelled());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100439 }
440 }
441
442 /**
443 * Completed submit(callable) returns result
444 */
445 public void testSubmitCallable() throws Throwable {
446 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000447 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100448 Future<String> future = e.submit(new StringTask());
449 assertSame(TEST_STRING, future.get());
450 assertTrue(future.isDone());
451 assertFalse(future.isCancelled());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100452 }
453 }
454
455 /**
456 * Completed submit(runnable) returns successfully
457 */
458 public void testSubmitRunnable() throws Throwable {
459 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000460 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100461 Future<?> future = e.submit(new NoOpRunnable());
462 assertNull(future.get());
463 assertTrue(future.isDone());
464 assertFalse(future.isCancelled());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100465 }
466 }
467
468 /**
469 * Completed submit(runnable, result) returns result
470 */
471 public void testSubmitRunnable2() throws Throwable {
472 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000473 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100474 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
475 assertSame(TEST_STRING, future.get());
476 assertTrue(future.isDone());
477 assertFalse(future.isCancelled());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100478 }
479 }
480
481 /**
482 * A submitted privileged action runs to completion
483 */
484 public void testSubmitPrivilegedAction() throws Exception {
485 final Callable callable = Executors.callable(new PrivilegedAction() {
486 public Object run() { return TEST_STRING; }});
487 Runnable r = new CheckedRunnable() {
488 public void realRun() throws Exception {
489 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000490 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100491 Future future = e.submit(callable);
492 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100493 }
494 }};
495
496 runWithPermissions(r, new RuntimePermission("modifyThread"));
497 }
498
499 /**
500 * A submitted privileged exception action runs to completion
501 */
502 public void testSubmitPrivilegedExceptionAction() throws Exception {
503 final Callable callable =
504 Executors.callable(new PrivilegedExceptionAction() {
505 public Object run() { return TEST_STRING; }});
506 Runnable r = new CheckedRunnable() {
507 public void realRun() throws Exception {
508 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000509 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100510 Future future = e.submit(callable);
511 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100512 }
513 }};
514
515 runWithPermissions(r, new RuntimePermission("modifyThread"));
516 }
517
518 /**
519 * A submitted failed privileged exception action reports exception
520 */
521 public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
522 final Callable callable =
523 Executors.callable(new PrivilegedExceptionAction() {
524 public Object run() { throw new IndexOutOfBoundsException(); }});
525 Runnable r = new CheckedRunnable() {
526 public void realRun() throws Exception {
527 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000528 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100529 Future future = e.submit(callable);
530 try {
531 future.get();
532 shouldThrow();
533 } catch (ExecutionException success) {
534 assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
535 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100536 }
537 }};
538
539 runWithPermissions(r, new RuntimePermission("modifyThread"));
540 }
541
542 /**
543 * execute(null runnable) throws NullPointerException
544 */
545 public void testExecuteNullRunnable() {
546 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000547 try (PoolCleaner cleaner = cleaner(e)) {
548 try {
549 Future<?> future = e.submit((Runnable) null);
550 shouldThrow();
551 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100552 }
553 }
554
555 /**
556 * submit(null callable) throws NullPointerException
557 */
558 public void testSubmitNullCallable() {
559 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000560 try (PoolCleaner cleaner = cleaner(e)) {
561 try {
562 Future<String> future = e.submit((Callable) null);
563 shouldThrow();
564 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100565 }
566 }
567
568 /**
569 * submit(callable).get() throws InterruptedException if interrupted
570 */
571 public void testInterruptedSubmit() throws InterruptedException {
572 final CountDownLatch submitted = new CountDownLatch(1);
573 final CountDownLatch quittingTime = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100574 final Callable<Void> awaiter = new CheckedCallable<Void>() {
575 public Void realCall() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000576 assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100577 return null;
578 }};
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000579 final ExecutorService p = new ForkJoinPool(1);
580 try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100581 Thread t = new Thread(new CheckedInterruptedRunnable() {
582 public void realRun() throws Exception {
583 Future<Void> future = p.submit(awaiter);
584 submitted.countDown();
585 future.get();
586 }});
587 t.start();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000588 await(submitted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100589 t.interrupt();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000590 awaitTermination(t);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100591 }
592 }
593
594 /**
595 * get of submit(callable) throws ExecutionException if callable
596 * throws exception
597 */
598 public void testSubmitEE() throws Throwable {
599 ForkJoinPool p = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000600 try (PoolCleaner cleaner = cleaner(p)) {
601 try {
602 p.submit(new Callable() {
603 public Object call() { throw new ArithmeticException(); }})
604 .get();
605 shouldThrow();
606 } catch (ExecutionException success) {
607 assertTrue(success.getCause() instanceof ArithmeticException);
608 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100609 }
610 }
611
612 /**
613 * invokeAny(null) throws NullPointerException
614 */
615 public void testInvokeAny1() throws Throwable {
616 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000617 try (PoolCleaner cleaner = cleaner(e)) {
618 try {
619 e.invokeAny(null);
620 shouldThrow();
621 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100622 }
623 }
624
625 /**
626 * invokeAny(empty collection) throws IllegalArgumentException
627 */
628 public void testInvokeAny2() throws Throwable {
629 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000630 try (PoolCleaner cleaner = cleaner(e)) {
631 try {
632 e.invokeAny(new ArrayList<Callable<String>>());
633 shouldThrow();
634 } catch (IllegalArgumentException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100635 }
636 }
637
638 /**
639 * invokeAny(c) throws NullPointerException if c has a single null element
640 */
641 public void testInvokeAny3() throws Throwable {
642 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000643 try (PoolCleaner cleaner = cleaner(e)) {
644 List<Callable<String>> l = new ArrayList<Callable<String>>();
645 l.add(null);
646 try {
647 e.invokeAny(l);
648 shouldThrow();
649 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100650 }
651 }
652
653 /**
654 * invokeAny(c) throws NullPointerException if c has null elements
655 */
656 public void testInvokeAny4() throws Throwable {
657 CountDownLatch latch = new CountDownLatch(1);
658 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000659 try (PoolCleaner cleaner = cleaner(e)) {
660 List<Callable<String>> l = new ArrayList<Callable<String>>();
661 l.add(latchAwaitingStringTask(latch));
662 l.add(null);
663 try {
664 e.invokeAny(l);
665 shouldThrow();
666 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100667 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100668 }
669 }
670
671 /**
672 * invokeAny(c) throws ExecutionException if no task in c completes
673 */
674 public void testInvokeAny5() throws Throwable {
675 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000676 try (PoolCleaner cleaner = cleaner(e)) {
677 List<Callable<String>> l = new ArrayList<Callable<String>>();
678 l.add(new NPETask());
679 try {
680 e.invokeAny(l);
681 shouldThrow();
682 } catch (ExecutionException success) {
683 assertTrue(success.getCause() instanceof NullPointerException);
684 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100685 }
686 }
687
688 /**
689 * invokeAny(c) returns result of some task in c if at least one completes
690 */
691 public void testInvokeAny6() throws Throwable {
692 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000693 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100694 List<Callable<String>> l = new ArrayList<Callable<String>>();
695 l.add(new StringTask());
696 l.add(new StringTask());
697 String result = e.invokeAny(l);
698 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100699 }
700 }
701
702 /**
703 * invokeAll(null) throws NullPointerException
704 */
705 public void testInvokeAll1() throws Throwable {
706 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000707 try (PoolCleaner cleaner = cleaner(e)) {
708 try {
709 e.invokeAll(null);
710 shouldThrow();
711 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100712 }
713 }
714
715 /**
716 * invokeAll(empty collection) returns empty collection
717 */
718 public void testInvokeAll2() throws InterruptedException {
719 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000720 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100721 List<Future<String>> r
722 = e.invokeAll(new ArrayList<Callable<String>>());
723 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100724 }
725 }
726
727 /**
728 * invokeAll(c) throws NullPointerException if c has null elements
729 */
730 public void testInvokeAll3() throws InterruptedException {
731 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000732 try (PoolCleaner cleaner = cleaner(e)) {
733 List<Callable<String>> l = new ArrayList<Callable<String>>();
734 l.add(new StringTask());
735 l.add(null);
736 try {
737 e.invokeAll(l);
738 shouldThrow();
739 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100740 }
741 }
742
743 /**
744 * get of returned element of invokeAll(c) throws
745 * ExecutionException on failed task
746 */
747 public void testInvokeAll4() throws Throwable {
748 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000749 try (PoolCleaner cleaner = cleaner(e)) {
750 List<Callable<String>> l = new ArrayList<Callable<String>>();
751 l.add(new NPETask());
752 List<Future<String>> futures = e.invokeAll(l);
753 assertEquals(1, futures.size());
754 try {
755 futures.get(0).get();
756 shouldThrow();
757 } catch (ExecutionException success) {
758 assertTrue(success.getCause() instanceof NullPointerException);
759 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100760 }
761 }
762
763 /**
764 * invokeAll(c) returns results of all completed tasks in c
765 */
766 public void testInvokeAll5() throws Throwable {
767 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000768 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100769 List<Callable<String>> l = new ArrayList<Callable<String>>();
770 l.add(new StringTask());
771 l.add(new StringTask());
772 List<Future<String>> futures = e.invokeAll(l);
773 assertEquals(2, futures.size());
774 for (Future<String> future : futures)
775 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100776 }
777 }
778
779 /**
780 * timed invokeAny(null) throws NullPointerException
781 */
782 public void testTimedInvokeAny1() throws Throwable {
783 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000784 try (PoolCleaner cleaner = cleaner(e)) {
785 try {
786 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
787 shouldThrow();
788 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100789 }
790 }
791
792 /**
793 * timed invokeAny(null time unit) throws NullPointerException
794 */
795 public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
796 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000797 try (PoolCleaner cleaner = cleaner(e)) {
798 List<Callable<String>> l = new ArrayList<Callable<String>>();
799 l.add(new StringTask());
800 try {
801 e.invokeAny(l, MEDIUM_DELAY_MS, null);
802 shouldThrow();
803 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100804 }
805 }
806
807 /**
808 * timed invokeAny(empty collection) throws IllegalArgumentException
809 */
810 public void testTimedInvokeAny2() throws Throwable {
811 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000812 try (PoolCleaner cleaner = cleaner(e)) {
813 try {
814 e.invokeAny(new ArrayList<Callable<String>>(),
815 MEDIUM_DELAY_MS, MILLISECONDS);
816 shouldThrow();
817 } catch (IllegalArgumentException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100818 }
819 }
820
821 /**
822 * timed invokeAny(c) throws NullPointerException if c has null elements
823 */
824 public void testTimedInvokeAny3() throws Throwable {
825 CountDownLatch latch = new CountDownLatch(1);
826 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000827 try (PoolCleaner cleaner = cleaner(e)) {
828 List<Callable<String>> l = new ArrayList<Callable<String>>();
829 l.add(latchAwaitingStringTask(latch));
830 l.add(null);
831 try {
832 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
833 shouldThrow();
834 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100835 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100836 }
837 }
838
839 /**
840 * timed invokeAny(c) throws ExecutionException if no task completes
841 */
842 public void testTimedInvokeAny4() throws Throwable {
843 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000844 try (PoolCleaner cleaner = cleaner(e)) {
845 long startTime = System.nanoTime();
846 List<Callable<String>> l = new ArrayList<Callable<String>>();
847 l.add(new NPETask());
848 try {
849 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
850 shouldThrow();
851 } catch (ExecutionException success) {
852 assertTrue(success.getCause() instanceof NullPointerException);
853 }
854 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100855 }
856 }
857
858 /**
859 * timed invokeAny(c) returns result of some task in c
860 */
861 public void testTimedInvokeAny5() throws Throwable {
862 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000863 try (PoolCleaner cleaner = cleaner(e)) {
864 long startTime = System.nanoTime();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100865 List<Callable<String>> l = new ArrayList<Callable<String>>();
866 l.add(new StringTask());
867 l.add(new StringTask());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000868 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100869 assertSame(TEST_STRING, result);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000870 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100871 }
872 }
873
874 /**
875 * timed invokeAll(null) throws NullPointerException
876 */
877 public void testTimedInvokeAll1() throws Throwable {
878 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000879 try (PoolCleaner cleaner = cleaner(e)) {
880 try {
881 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
882 shouldThrow();
883 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100884 }
885 }
886
887 /**
888 * timed invokeAll(null time unit) throws NullPointerException
889 */
890 public void testTimedInvokeAllNullTimeUnit() throws Throwable {
891 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000892 try (PoolCleaner cleaner = cleaner(e)) {
893 List<Callable<String>> l = new ArrayList<Callable<String>>();
894 l.add(new StringTask());
895 try {
896 e.invokeAll(l, MEDIUM_DELAY_MS, null);
897 shouldThrow();
898 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100899 }
900 }
901
902 /**
903 * timed invokeAll(empty collection) returns empty collection
904 */
905 public void testTimedInvokeAll2() throws InterruptedException {
906 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000907 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100908 List<Future<String>> r
909 = e.invokeAll(new ArrayList<Callable<String>>(),
910 MEDIUM_DELAY_MS, MILLISECONDS);
911 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100912 }
913 }
914
915 /**
916 * timed invokeAll(c) throws NullPointerException if c has null elements
917 */
918 public void testTimedInvokeAll3() throws InterruptedException {
919 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000920 try (PoolCleaner cleaner = cleaner(e)) {
921 List<Callable<String>> l = new ArrayList<Callable<String>>();
922 l.add(new StringTask());
923 l.add(null);
924 try {
925 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
926 shouldThrow();
927 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100928 }
929 }
930
931 /**
932 * get of returned element of invokeAll(c) throws exception on failed task
933 */
934 public void testTimedInvokeAll4() throws Throwable {
935 ExecutorService e = new ForkJoinPool(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000936 try (PoolCleaner cleaner = cleaner(e)) {
937 List<Callable<String>> l = new ArrayList<Callable<String>>();
938 l.add(new NPETask());
939 List<Future<String>> futures
940 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
941 assertEquals(1, futures.size());
942 try {
943 futures.get(0).get();
944 shouldThrow();
945 } catch (ExecutionException success) {
946 assertTrue(success.getCause() instanceof NullPointerException);
947 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100948 }
949 }
950
951 /**
952 * timed invokeAll(c) returns results of all completed tasks in c
953 */
954 public void testTimedInvokeAll5() throws Throwable {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000955 ForkJoinPool e = new ForkJoinPool(1);
956 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100957 List<Callable<String>> l = new ArrayList<Callable<String>>();
958 l.add(new StringTask());
959 l.add(new StringTask());
960 List<Future<String>> futures
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000961 = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100962 assertEquals(2, futures.size());
963 for (Future<String> future : futures)
964 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100965 }
966 }
967
968}