ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractExecutorServiceTest.java
Revision: 1.41
Committed: Mon Oct 5 22:54:45 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.40: +6 -7 lines
Log Message:
improve testInterruptedSubmit

File Contents

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