Home | History | Annotate | Download | only in concurrent
      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 
     13 package com.google.common.util.concurrent;
     14 
     15 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     16 
     17 import java.security.PrivilegedAction;
     18 import java.security.PrivilegedExceptionAction;
     19 import java.util.ArrayList;
     20 import java.util.Collections;
     21 import java.util.Iterator;
     22 import java.util.List;
     23 import java.util.concurrent.ArrayBlockingQueue;
     24 import java.util.concurrent.Callable;
     25 import java.util.concurrent.CountDownLatch;
     26 import java.util.concurrent.ExecutionException;
     27 import java.util.concurrent.ExecutorService;
     28 import java.util.concurrent.Executors;
     29 import java.util.concurrent.Future;
     30 import java.util.concurrent.ThreadPoolExecutor;
     31 import java.util.concurrent.TimeUnit;
     32 
     33 public 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