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