blob: 9e83de2c9234228607318d55c0377e09cd3cdd56 [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 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
Calin Juravle8f0d92b2013-08-01 17:26:00 +010011import static java.util.concurrent.TimeUnit.MILLISECONDS;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010012
13import java.security.PrivilegedAction;
14import java.security.PrivilegedExceptionAction;
15import java.util.ArrayList;
16import java.util.Collections;
17import java.util.List;
18import java.util.concurrent.AbstractExecutorService;
19import java.util.concurrent.ArrayBlockingQueue;
20import java.util.concurrent.Callable;
21import java.util.concurrent.CountDownLatch;
22import java.util.concurrent.ExecutionException;
23import java.util.concurrent.Executors;
24import java.util.concurrent.ExecutorService;
25import java.util.concurrent.Future;
26import java.util.concurrent.ThreadPoolExecutor;
27import java.util.concurrent.TimeUnit;
28import java.util.concurrent.atomic.AtomicBoolean;
29
30import junit.framework.Test;
31import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010032
33public class AbstractExecutorServiceTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010034 // android-note: Removed because the CTS runner does a bad job of
35 // retrying tests that have suite() declarations.
36 //
37 // public static void main(String[] args) {
38 // main(suite(), args);
39 // }
40 // public static Test suite() {
41 // return new TestSuite(...);
42 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010043
44 /**
45 * A no-frills implementation of AbstractExecutorService, designed
46 * to test the submit methods only.
47 */
48 static class DirectExecutorService extends AbstractExecutorService {
49 public void execute(Runnable r) { r.run(); }
50 public void shutdown() { shutdown = true; }
51 public List<Runnable> shutdownNow() {
52 shutdown = true;
53 return Collections.EMPTY_LIST;
54 }
55 public boolean isShutdown() { return shutdown; }
56 public boolean isTerminated() { return isShutdown(); }
57 public boolean awaitTermination(long timeout, TimeUnit unit) {
58 return isShutdown();
59 }
60 private volatile boolean shutdown = false;
61 }
62
63 /**
64 * execute(runnable) runs it to completion
65 */
66 public void testExecuteRunnable() throws Exception {
67 ExecutorService e = new DirectExecutorService();
68 final AtomicBoolean done = new AtomicBoolean(false);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010069 Future<?> future = e.submit(new CheckedRunnable() {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010070 public void realRun() {
71 done.set(true);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010072 }});
Calin Juravle8f0d92b2013-08-01 17:26:00 +010073 assertNull(future.get());
74 assertNull(future.get(0, MILLISECONDS));
75 assertTrue(done.get());
76 assertTrue(future.isDone());
77 assertFalse(future.isCancelled());
78 }
79
80 /**
81 * Completed submit(callable) returns result
82 */
83 public void testSubmitCallable() throws Exception {
84 ExecutorService e = new DirectExecutorService();
85 Future<String> future = e.submit(new StringTask());
86 String result = future.get();
87 assertSame(TEST_STRING, result);
88 }
89
90 /**
91 * Completed submit(runnable) returns successfully
92 */
93 public void testSubmitRunnable() throws Exception {
94 ExecutorService e = new DirectExecutorService();
95 Future<?> future = e.submit(new NoOpRunnable());
96 future.get();
97 assertTrue(future.isDone());
98 }
99
100 /**
101 * Completed submit(runnable, result) returns result
102 */
103 public void testSubmitRunnable2() throws Exception {
104 ExecutorService e = new DirectExecutorService();
105 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
106 String result = future.get();
107 assertSame(TEST_STRING, result);
108 }
109
110 /**
111 * A submitted privileged action runs to completion
112 */
113 public void testSubmitPrivilegedAction() throws Exception {
114 Runnable r = new CheckedRunnable() {
115 public void realRun() throws Exception {
116 ExecutorService e = new DirectExecutorService();
117 Future future = e.submit(Executors.callable(new PrivilegedAction() {
118 public Object run() {
119 return TEST_STRING;
120 }}));
121
122 assertSame(TEST_STRING, future.get());
123 }};
124
125 runWithPermissions(r,
126 new RuntimePermission("getClassLoader"),
127 new RuntimePermission("setContextClassLoader"),
128 new RuntimePermission("modifyThread"));
129 }
130
131 /**
132 * A submitted privileged exception action runs to completion
133 */
134 public void testSubmitPrivilegedExceptionAction() throws Exception {
135 Runnable r = new CheckedRunnable() {
136 public void realRun() throws Exception {
137 ExecutorService e = new DirectExecutorService();
138 Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
139 public Object run() {
140 return TEST_STRING;
141 }}));
142
143 assertSame(TEST_STRING, future.get());
144 }};
145
146 runWithPermissions(r);
147 }
148
149 /**
150 * A submitted failed privileged exception action reports exception
151 */
152 public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
153 Runnable r = new CheckedRunnable() {
154 public void realRun() throws Exception {
155 ExecutorService e = new DirectExecutorService();
156 Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
157 public Object run() throws Exception {
158 throw new IndexOutOfBoundsException();
159 }}));
160
161 try {
162 future.get();
163 shouldThrow();
164 } catch (ExecutionException success) {
165 assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
166 }}};
167
168 runWithPermissions(r);
169 }
170
171 /**
172 * execute(null runnable) throws NPE
173 */
174 public void testExecuteNullRunnable() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100175 ExecutorService e = new DirectExecutorService();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100176 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100177 e.submit((Runnable) null);
178 shouldThrow();
179 } catch (NullPointerException success) {}
180 }
181
182 /**
183 * submit(null callable) throws NPE
184 */
185 public void testSubmitNullCallable() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100186 ExecutorService e = new DirectExecutorService();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100187 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100188 e.submit((Callable) null);
189 shouldThrow();
190 } catch (NullPointerException success) {}
191 }
192
193 /**
194 * submit(callable).get() throws InterruptedException if interrupted
195 */
196 public void testInterruptedSubmit() throws InterruptedException {
197 final CountDownLatch submitted = new CountDownLatch(1);
198 final CountDownLatch quittingTime = new CountDownLatch(1);
199 final ExecutorService p
200 = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS,
201 new ArrayBlockingQueue<Runnable>(10));
202 final Callable<Void> awaiter = new CheckedCallable<Void>() {
203 public Void realCall() throws InterruptedException {
204 quittingTime.await();
205 return null;
206 }};
207 try {
208 Thread t = new Thread(new CheckedInterruptedRunnable() {
209 public void realRun() throws Exception {
210 Future<Void> future = p.submit(awaiter);
211 submitted.countDown();
212 future.get();
213 }});
214 t.start();
215 submitted.await();
216 t.interrupt();
217 t.join();
218 } finally {
219 quittingTime.countDown();
220 joinPool(p);
221 }
222 }
223
224 /**
225 * get of submit(callable) throws ExecutionException if callable
226 * throws exception
227 */
228 public void testSubmitEE() throws InterruptedException {
229 ThreadPoolExecutor p =
230 new ThreadPoolExecutor(1, 1,
231 60, TimeUnit.SECONDS,
232 new ArrayBlockingQueue<Runnable>(10));
233
234 Callable c = new Callable() {
235 public Object call() { throw new ArithmeticException(); }};
236
237 try {
238 p.submit(c).get();
239 shouldThrow();
240 } catch (ExecutionException success) {
241 assertTrue(success.getCause() instanceof ArithmeticException);
242 }
243 joinPool(p);
244 }
245
246 /**
247 * invokeAny(null) throws NPE
248 */
249 public void testInvokeAny1() throws Exception {
250 ExecutorService e = new DirectExecutorService();
251 try {
252 e.invokeAny(null);
253 shouldThrow();
254 } catch (NullPointerException success) {
255 } finally {
256 joinPool(e);
257 }
258 }
259
260 /**
261 * invokeAny(empty collection) throws IAE
262 */
263 public void testInvokeAny2() throws Exception {
264 ExecutorService e = new DirectExecutorService();
265 try {
266 e.invokeAny(new ArrayList<Callable<String>>());
267 shouldThrow();
268 } catch (IllegalArgumentException success) {
269 } finally {
270 joinPool(e);
271 }
272 }
273
274 /**
275 * invokeAny(c) throws NPE if c has null elements
276 */
277 public void testInvokeAny3() throws Exception {
278 ExecutorService e = new DirectExecutorService();
279 List<Callable<Long>> l = new ArrayList<Callable<Long>>();
280 l.add(new Callable<Long>() {
281 public Long call() { throw new ArithmeticException(); }});
282 l.add(null);
283 try {
284 e.invokeAny(l);
285 shouldThrow();
286 } catch (NullPointerException success) {
287 } finally {
288 joinPool(e);
289 }
290 }
291
292 /**
293 * invokeAny(c) throws ExecutionException if no task in c completes
294 */
295 public void testInvokeAny4() throws InterruptedException {
296 ExecutorService e = new DirectExecutorService();
297 List<Callable<String>> l = new ArrayList<Callable<String>>();
298 l.add(new NPETask());
299 try {
300 e.invokeAny(l);
301 shouldThrow();
302 } catch (ExecutionException success) {
303 assertTrue(success.getCause() instanceof NullPointerException);
304 } finally {
305 joinPool(e);
306 }
307 }
308
309 /**
310 * invokeAny(c) returns result of some task in c if at least one completes
311 */
312 public void testInvokeAny5() throws Exception {
313 ExecutorService e = new DirectExecutorService();
314 try {
315 List<Callable<String>> l = new ArrayList<Callable<String>>();
316 l.add(new StringTask());
317 l.add(new StringTask());
318 String result = e.invokeAny(l);
319 assertSame(TEST_STRING, result);
320 } finally {
321 joinPool(e);
322 }
323 }
324
325 /**
326 * invokeAll(null) throws NPE
327 */
328 public void testInvokeAll1() throws InterruptedException {
329 ExecutorService e = new DirectExecutorService();
330 try {
331 e.invokeAll(null);
332 shouldThrow();
333 } catch (NullPointerException success) {
334 } finally {
335 joinPool(e);
336 }
337 }
338
339 /**
340 * invokeAll(empty collection) returns empty collection
341 */
342 public void testInvokeAll2() throws InterruptedException {
343 ExecutorService e = new DirectExecutorService();
344 try {
345 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
346 assertTrue(r.isEmpty());
347 } finally {
348 joinPool(e);
349 }
350 }
351
352 /**
353 * invokeAll(c) throws NPE if c has null elements
354 */
355 public void testInvokeAll3() throws InterruptedException {
356 ExecutorService e = new DirectExecutorService();
357 List<Callable<String>> l = new ArrayList<Callable<String>>();
358 l.add(new StringTask());
359 l.add(null);
360 try {
361 e.invokeAll(l);
362 shouldThrow();
363 } catch (NullPointerException success) {
364 } finally {
365 joinPool(e);
366 }
367 }
368
369 /**
370 * get of returned element of invokeAll(c) throws exception on failed task
371 */
372 public void testInvokeAll4() throws Exception {
373 ExecutorService e = new DirectExecutorService();
374 try {
375 List<Callable<String>> l = new ArrayList<Callable<String>>();
376 l.add(new NPETask());
377 List<Future<String>> futures = e.invokeAll(l);
378 assertEquals(1, futures.size());
379 try {
380 futures.get(0).get();
381 shouldThrow();
382 } catch (ExecutionException success) {
383 assertTrue(success.getCause() instanceof NullPointerException);
384 }
385 } finally {
386 joinPool(e);
387 }
388 }
389
390 /**
391 * invokeAll(c) returns results of all completed tasks in c
392 */
393 public void testInvokeAll5() throws Exception {
394 ExecutorService e = new DirectExecutorService();
395 try {
396 List<Callable<String>> l = new ArrayList<Callable<String>>();
397 l.add(new StringTask());
398 l.add(new StringTask());
399 List<Future<String>> futures = e.invokeAll(l);
400 assertEquals(2, futures.size());
401 for (Future<String> future : futures)
402 assertSame(TEST_STRING, future.get());
403 } finally {
404 joinPool(e);
405 }
406 }
407
408 /**
409 * timed invokeAny(null) throws NPE
410 */
411 public void testTimedInvokeAny1() throws Exception {
412 ExecutorService e = new DirectExecutorService();
413 try {
414 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
415 shouldThrow();
416 } catch (NullPointerException success) {
417 } finally {
418 joinPool(e);
419 }
420 }
421
422 /**
423 * timed invokeAny(null time unit) throws NPE
424 */
425 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
426 ExecutorService e = new DirectExecutorService();
427 List<Callable<String>> l = new ArrayList<Callable<String>>();
428 l.add(new StringTask());
429 try {
430 e.invokeAny(l, MEDIUM_DELAY_MS, null);
431 shouldThrow();
432 } catch (NullPointerException success) {
433 } finally {
434 joinPool(e);
435 }
436 }
437
438 /**
439 * timed invokeAny(empty collection) throws IAE
440 */
441 public void testTimedInvokeAny2() throws Exception {
442 ExecutorService e = new DirectExecutorService();
443 try {
444 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
445 shouldThrow();
446 } catch (IllegalArgumentException success) {
447 } finally {
448 joinPool(e);
449 }
450 }
451
452 /**
453 * timed invokeAny(c) throws NPE if c has null elements
454 */
455 public void testTimedInvokeAny3() throws Exception {
456 ExecutorService e = new DirectExecutorService();
457 List<Callable<Long>> l = new ArrayList<Callable<Long>>();
458 l.add(new Callable<Long>() {
459 public Long call() { throw new ArithmeticException(); }});
460 l.add(null);
461 try {
462 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
463 shouldThrow();
464 } catch (NullPointerException success) {
465 } finally {
466 joinPool(e);
467 }
468 }
469
470 /**
471 * timed invokeAny(c) throws ExecutionException if no task completes
472 */
473 public void testTimedInvokeAny4() throws Exception {
474 ExecutorService e = new DirectExecutorService();
475 List<Callable<String>> l = new ArrayList<Callable<String>>();
476 l.add(new NPETask());
477 try {
478 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
479 shouldThrow();
480 } catch (ExecutionException success) {
481 assertTrue(success.getCause() instanceof NullPointerException);
482 } finally {
483 joinPool(e);
484 }
485 }
486
487 /**
488 * timed invokeAny(c) returns result of some task in c
489 */
490 public void testTimedInvokeAny5() throws Exception {
491 ExecutorService e = new DirectExecutorService();
492 try {
493 List<Callable<String>> l = new ArrayList<Callable<String>>();
494 l.add(new StringTask());
495 l.add(new StringTask());
496 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
497 assertSame(TEST_STRING, result);
498 } finally {
499 joinPool(e);
500 }
501 }
502
503 /**
504 * timed invokeAll(null) throws NPE
505 */
506 public void testTimedInvokeAll1() throws InterruptedException {
507 ExecutorService e = new DirectExecutorService();
508 try {
509 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
510 shouldThrow();
511 } catch (NullPointerException success) {
512 } finally {
513 joinPool(e);
514 }
515 }
516
517 /**
518 * timed invokeAll(null time unit) throws NPE
519 */
520 public void testTimedInvokeAllNullTimeUnit() throws InterruptedException {
521 ExecutorService e = new DirectExecutorService();
522 List<Callable<String>> l = new ArrayList<Callable<String>>();
523 l.add(new StringTask());
524 try {
525 e.invokeAll(l, MEDIUM_DELAY_MS, null);
526 shouldThrow();
527 } catch (NullPointerException success) {
528 } finally {
529 joinPool(e);
530 }
531 }
532
533 /**
534 * timed invokeAll(empty collection) returns empty collection
535 */
536 public void testTimedInvokeAll2() throws InterruptedException {
537 ExecutorService e = new DirectExecutorService();
538 try {
539 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
540 assertTrue(r.isEmpty());
541 } finally {
542 joinPool(e);
543 }
544 }
545
546 /**
547 * timed invokeAll(c) throws NPE if c has null elements
548 */
549 public void testTimedInvokeAll3() throws InterruptedException {
550 ExecutorService e = new DirectExecutorService();
551 List<Callable<String>> l = new ArrayList<Callable<String>>();
552 l.add(new StringTask());
553 l.add(null);
554 try {
555 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
556 shouldThrow();
557 } catch (NullPointerException success) {
558 } finally {
559 joinPool(e);
560 }
561 }
562
563 /**
564 * get of returned element of invokeAll(c) throws exception on failed task
565 */
566 public void testTimedInvokeAll4() throws Exception {
567 ExecutorService e = new DirectExecutorService();
568 try {
569 List<Callable<String>> l = new ArrayList<Callable<String>>();
570 l.add(new NPETask());
571 List<Future<String>> futures =
572 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
573 assertEquals(1, futures.size());
574 try {
575 futures.get(0).get();
576 shouldThrow();
577 } catch (ExecutionException success) {
578 assertTrue(success.getCause() instanceof NullPointerException);
579 }
580 } finally {
581 joinPool(e);
582 }
583 }
584
585 /**
586 * timed invokeAll(c) returns results of all completed tasks in c
587 */
588 public void testTimedInvokeAll5() throws Exception {
589 ExecutorService e = new DirectExecutorService();
590 try {
591 List<Callable<String>> l = new ArrayList<Callable<String>>();
592 l.add(new StringTask());
593 l.add(new StringTask());
594 List<Future<String>> futures =
595 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
596 assertEquals(2, futures.size());
597 for (Future<String> future : futures)
598 assertSame(TEST_STRING, future.get());
599 } finally {
600 joinPool(e);
601 }
602 }
603
604 /**
605 * timed invokeAll cancels tasks not completed by timeout
606 */
607 public void testTimedInvokeAll6() throws InterruptedException {
608 ExecutorService e = new DirectExecutorService();
609 try {
610 List<Callable<String>> l = new ArrayList<Callable<String>>();
611 l.add(new StringTask());
612 l.add(Executors.callable(possiblyInterruptedRunnable(2 * SHORT_DELAY_MS), TEST_STRING));
613 l.add(new StringTask());
614 List<Future<String>> futures =
615 e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
616 assertEquals(l.size(), futures.size());
617 for (Future future : futures)
618 assertTrue(future.isDone());
619 assertFalse(futures.get(0).isCancelled());
620 assertFalse(futures.get(1).isCancelled());
621 assertTrue(futures.get(2).isCancelled());
622 } finally {
623 joinPool(e);
624 }
625 }
626
627}