ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractExecutorServiceTest.java
Revision: 1.46
Committed: Mon May 29 22:44:26 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.45: +27 -18 lines
Log Message:
more timeout handling rework; remove most uses of MEDIUM_DELAY_MS; randomize timeouts and TimeUnits; write out IAE and ISE

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