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