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  */
      6 
      7 package jsr166;
      8 
      9 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     10 import static java.util.concurrent.TimeUnit.NANOSECONDS;
     11 import static java.util.concurrent.TimeUnit.SECONDS;
     12 
     13 import java.util.ArrayList;
     14 import java.util.HashSet;
     15 import java.util.List;
     16 import java.util.concurrent.BlockingQueue;
     17 import java.util.concurrent.Callable;
     18 import java.util.concurrent.CancellationException;
     19 import java.util.concurrent.CountDownLatch;
     20 import java.util.concurrent.Delayed;
     21 import java.util.concurrent.ExecutionException;
     22 import java.util.concurrent.Executors;
     23 import java.util.concurrent.ExecutorService;
     24 import java.util.concurrent.Future;
     25 import java.util.concurrent.RejectedExecutionException;
     26 import java.util.concurrent.RejectedExecutionHandler;
     27 import java.util.concurrent.RunnableScheduledFuture;
     28 import java.util.concurrent.ScheduledFuture;
     29 import java.util.concurrent.ScheduledThreadPoolExecutor;
     30 import java.util.concurrent.ThreadFactory;
     31 import java.util.concurrent.ThreadPoolExecutor;
     32 import java.util.concurrent.TimeoutException;
     33 import java.util.concurrent.TimeUnit;
     34 import java.util.concurrent.atomic.AtomicBoolean;
     35 import java.util.concurrent.atomic.AtomicInteger;
     36 import java.util.concurrent.atomic.AtomicLong;
     37 
     38 import junit.framework.Test;
     39 import junit.framework.TestSuite;
     40 
     41 public class ScheduledExecutorSubclassTest extends JSR166TestCase {
     42     // android-note: Removed because the CTS runner does a bad job of
     43     // retrying tests that have suite() declarations.
     44     //
     45     // public static void main(String[] args) {
     46     //     main(suite(), args);
     47     // }
     48     // public static Test suite() {
     49     //     return new TestSuite(ScheduledExecutorSubclassTest.class);
     50     // }
     51 
     52     static class CustomTask<V> implements RunnableScheduledFuture<V> {
     53         RunnableScheduledFuture<V> task;
     54         volatile boolean ran;
     55         CustomTask(RunnableScheduledFuture<V> t) { task = t; }
     56         public boolean isPeriodic() { return task.isPeriodic(); }
     57         public void run() {
     58             ran = true;
     59             task.run();
     60         }
     61         public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
     62         public int compareTo(Delayed t) {
     63             return task.compareTo(((CustomTask)t).task);
     64         }
     65         public boolean cancel(boolean mayInterruptIfRunning) {
     66             return task.cancel(mayInterruptIfRunning);
     67         }
     68         public boolean isCancelled() { return task.isCancelled(); }
     69         public boolean isDone() { return task.isDone(); }
     70         public V get() throws InterruptedException, ExecutionException {
     71             V v = task.get();
     72             assertTrue(ran);
     73             return v;
     74         }
     75         public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
     76             V v = task.get(time, unit);
     77             assertTrue(ran);
     78             return v;
     79         }
     80     }
     81 
     82     public class CustomExecutor extends ScheduledThreadPoolExecutor {
     83 
     84         protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
     85             return new CustomTask<V>(task);
     86         }
     87 
     88         protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
     89             return new CustomTask<V>(task);
     90         }
     91         CustomExecutor(int corePoolSize) { super(corePoolSize); }
     92         CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
     93             super(corePoolSize, handler);
     94         }
     95 
     96         CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
     97             super(corePoolSize, threadFactory);
     98         }
     99         CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
    100                        RejectedExecutionHandler handler) {
    101             super(corePoolSize, threadFactory, handler);
    102         }
    103 
    104     }
    105 
    106     /**
    107      * execute successfully executes a runnable
    108      */
    109     public void testExecute() throws InterruptedException {
    110         final CustomExecutor p = new CustomExecutor(1);
    111         try (PoolCleaner cleaner = cleaner(p)) {
    112             final CountDownLatch done = new CountDownLatch(1);
    113             final Runnable task = new CheckedRunnable() {
    114                 public void realRun() { done.countDown(); }};
    115             p.execute(task);
    116             await(done);
    117         }
    118     }
    119 
    120     /**
    121      * delayed schedule of callable successfully executes after delay
    122      */
    123     public void testSchedule1() throws Exception {
    124         final CountDownLatch done = new CountDownLatch(1);
    125         final CustomExecutor p = new CustomExecutor(1);
    126         try (PoolCleaner cleaner = cleaner(p, done)) {
    127             final long startTime = System.nanoTime();
    128             Callable task = new CheckedCallable<Boolean>() {
    129                 public Boolean realCall() {
    130                     done.countDown();
    131                     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    132                     return Boolean.TRUE;
    133                 }};
    134             Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
    135             assertSame(Boolean.TRUE, f.get());
    136             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    137         }
    138     }
    139 
    140     /**
    141      * delayed schedule of runnable successfully executes after delay
    142      */
    143     public void testSchedule3() throws Exception {
    144         final CustomExecutor p = new CustomExecutor(1);
    145         try (PoolCleaner cleaner = cleaner(p)) {
    146             final long startTime = System.nanoTime();
    147             final CountDownLatch done = new CountDownLatch(1);
    148             Runnable task = new CheckedRunnable() {
    149                 public void realRun() {
    150                     done.countDown();
    151                     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    152                 }};
    153             Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
    154             await(done);
    155             assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
    156             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    157         }
    158     }
    159 
    160     /**
    161      * scheduleAtFixedRate executes runnable after given initial delay
    162      */
    163     public void testSchedule4() throws InterruptedException {
    164         final CustomExecutor p = new CustomExecutor(1);
    165         try (PoolCleaner cleaner = cleaner(p)) {
    166             final long startTime = System.nanoTime();
    167             final CountDownLatch done = new CountDownLatch(1);
    168             Runnable task = new CheckedRunnable() {
    169                 public void realRun() {
    170                     done.countDown();
    171                     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    172                 }};
    173             ScheduledFuture f =
    174                 p.scheduleAtFixedRate(task, timeoutMillis(),
    175                                       LONG_DELAY_MS, MILLISECONDS);
    176             await(done);
    177             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    178             f.cancel(true);
    179         }
    180     }
    181 
    182     /**
    183      * scheduleWithFixedDelay executes runnable after given initial delay
    184      */
    185     public void testSchedule5() throws InterruptedException {
    186         final CustomExecutor p = new CustomExecutor(1);
    187         try (PoolCleaner cleaner = cleaner(p)) {
    188             final long startTime = System.nanoTime();
    189             final CountDownLatch done = new CountDownLatch(1);
    190             Runnable task = new CheckedRunnable() {
    191                 public void realRun() {
    192                     done.countDown();
    193                     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    194                 }};
    195             ScheduledFuture f =
    196                 p.scheduleWithFixedDelay(task, timeoutMillis(),
    197                                          LONG_DELAY_MS, MILLISECONDS);
    198             await(done);
    199             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    200             f.cancel(true);
    201         }
    202     }
    203 
    204     static class RunnableCounter implements Runnable {
    205         AtomicInteger count = new AtomicInteger(0);
    206         public void run() { count.getAndIncrement(); }
    207     }
    208 
    209     /**
    210      * scheduleAtFixedRate executes series of tasks at given rate.
    211      * Eventually, it must hold that:
    212      *   cycles - 1 <= elapsedMillis/delay < cycles
    213      */
    214     public void testFixedRateSequence() throws InterruptedException {
    215         final CustomExecutor p = new CustomExecutor(1);
    216         try (PoolCleaner cleaner = cleaner(p)) {
    217             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
    218                 final long startTime = System.nanoTime();
    219                 final int cycles = 8;
    220                 final CountDownLatch done = new CountDownLatch(cycles);
    221                 final Runnable task = new CheckedRunnable() {
    222                     public void realRun() { done.countDown(); }};
    223                 final ScheduledFuture periodicTask =
    224                     p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
    225                 final int totalDelayMillis = (cycles - 1) * delay;
    226                 await(done, totalDelayMillis + LONG_DELAY_MS);
    227                 periodicTask.cancel(true);
    228                 final long elapsedMillis = millisElapsedSince(startTime);
    229                 assertTrue(elapsedMillis >= totalDelayMillis);
    230                 if (elapsedMillis <= cycles * delay)
    231                     return;
    232                 // else retry with longer delay
    233             }
    234             fail("unexpected execution rate");
    235         }
    236     }
    237 
    238     /**
    239      * scheduleWithFixedDelay executes series of tasks with given period.
    240      * Eventually, it must hold that each task starts at least delay and at
    241      * most 2 * delay after the termination of the previous task.
    242      */
    243     public void testFixedDelaySequence() throws InterruptedException {
    244         final CustomExecutor p = new CustomExecutor(1);
    245         try (PoolCleaner cleaner = cleaner(p)) {
    246             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
    247                 final long startTime = System.nanoTime();
    248                 final AtomicLong previous = new AtomicLong(startTime);
    249                 final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
    250                 final int cycles = 8;
    251                 final CountDownLatch done = new CountDownLatch(cycles);
    252                 final int d = delay;
    253                 final Runnable task = new CheckedRunnable() {
    254                     public void realRun() {
    255                         long now = System.nanoTime();
    256                         long elapsedMillis
    257                             = NANOSECONDS.toMillis(now - previous.get());
    258                         if (done.getCount() == cycles) { // first execution
    259                             if (elapsedMillis >= d)
    260                                 tryLongerDelay.set(true);
    261                         } else {
    262                             assertTrue(elapsedMillis >= d);
    263                             if (elapsedMillis >= 2 * d)
    264                                 tryLongerDelay.set(true);
    265                         }
    266                         previous.set(now);
    267                         done.countDown();
    268                     }};
    269                 final ScheduledFuture periodicTask =
    270                     p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
    271                 final int totalDelayMillis = (cycles - 1) * delay;
    272                 await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
    273                 periodicTask.cancel(true);
    274                 final long elapsedMillis = millisElapsedSince(startTime);
    275                 assertTrue(elapsedMillis >= totalDelayMillis);
    276                 if (!tryLongerDelay.get())
    277                     return;
    278                 // else retry with longer delay
    279             }
    280             fail("unexpected execution rate");
    281         }
    282     }
    283 
    284     /**
    285      * execute(null) throws NPE
    286      */
    287     public void testExecuteNull() throws InterruptedException {
    288         final CustomExecutor p = new CustomExecutor(1);
    289         try (PoolCleaner cleaner = cleaner(p)) {
    290             try {
    291                 p.execute(null);
    292                 shouldThrow();
    293             } catch (NullPointerException success) {}
    294         }
    295     }
    296 
    297     /**
    298      * schedule(null) throws NPE
    299      */
    300     public void testScheduleNull() throws InterruptedException {
    301         final CustomExecutor p = new CustomExecutor(1);
    302         try (PoolCleaner cleaner = cleaner(p)) {
    303             try {
    304                 TrackedCallable callable = null;
    305                 Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
    306                 shouldThrow();
    307             } catch (NullPointerException success) {}
    308         }
    309     }
    310 
    311     /**
    312      * execute throws RejectedExecutionException if shutdown
    313      */
    314     public void testSchedule1_RejectedExecutionException() {
    315         final CustomExecutor p = new CustomExecutor(1);
    316         try (PoolCleaner cleaner = cleaner(p)) {
    317             try {
    318                 p.shutdown();
    319                 p.schedule(new NoOpRunnable(),
    320                            MEDIUM_DELAY_MS, MILLISECONDS);
    321                 shouldThrow();
    322             } catch (RejectedExecutionException success) {
    323             } catch (SecurityException ok) {}
    324         }
    325     }
    326 
    327     /**
    328      * schedule throws RejectedExecutionException if shutdown
    329      */
    330     public void testSchedule2_RejectedExecutionException() {
    331         final CustomExecutor p = new CustomExecutor(1);
    332         try (PoolCleaner cleaner = cleaner(p)) {
    333             try {
    334                 p.shutdown();
    335                 p.schedule(new NoOpCallable(),
    336                            MEDIUM_DELAY_MS, MILLISECONDS);
    337                 shouldThrow();
    338             } catch (RejectedExecutionException success) {
    339             } catch (SecurityException ok) {}
    340         }
    341     }
    342 
    343     /**
    344      * schedule callable throws RejectedExecutionException if shutdown
    345      */
    346     public void testSchedule3_RejectedExecutionException() {
    347         final CustomExecutor p = new CustomExecutor(1);
    348         try (PoolCleaner cleaner = cleaner(p)) {
    349             try {
    350                 p.shutdown();
    351                 p.schedule(new NoOpCallable(),
    352                            MEDIUM_DELAY_MS, MILLISECONDS);
    353                 shouldThrow();
    354             } catch (RejectedExecutionException success) {
    355             } catch (SecurityException ok) {}
    356         }
    357     }
    358 
    359     /**
    360      * scheduleAtFixedRate throws RejectedExecutionException if shutdown
    361      */
    362     public void testScheduleAtFixedRate1_RejectedExecutionException() {
    363         final CustomExecutor p = new CustomExecutor(1);
    364         try (PoolCleaner cleaner = cleaner(p)) {
    365             try {
    366                 p.shutdown();
    367                 p.scheduleAtFixedRate(new NoOpRunnable(),
    368                                       MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
    369                 shouldThrow();
    370             } catch (RejectedExecutionException success) {
    371             } catch (SecurityException ok) {}
    372         }
    373     }
    374 
    375     /**
    376      * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
    377      */
    378     public void testScheduleWithFixedDelay1_RejectedExecutionException() {
    379         final CustomExecutor p = new CustomExecutor(1);
    380         try (PoolCleaner cleaner = cleaner(p)) {
    381             try {
    382                 p.shutdown();
    383                 p.scheduleWithFixedDelay(new NoOpRunnable(),
    384                                          MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
    385                 shouldThrow();
    386             } catch (RejectedExecutionException success) {
    387             } catch (SecurityException ok) {}
    388         }
    389     }
    390 
    391     /**
    392      * getActiveCount increases but doesn't overestimate, when a
    393      * thread becomes active
    394      */
    395     public void testGetActiveCount() throws InterruptedException {
    396         final CountDownLatch done = new CountDownLatch(1);
    397         final ThreadPoolExecutor p = new CustomExecutor(2);
    398         try (PoolCleaner cleaner = cleaner(p, done)) {
    399             final CountDownLatch threadStarted = new CountDownLatch(1);
    400             assertEquals(0, p.getActiveCount());
    401             p.execute(new CheckedRunnable() {
    402                 public void realRun() throws InterruptedException {
    403                     threadStarted.countDown();
    404                     assertEquals(1, p.getActiveCount());
    405                     await(done);
    406                 }});
    407             await(threadStarted);
    408             assertEquals(1, p.getActiveCount());
    409         }
    410     }
    411 
    412     /**
    413      * getCompletedTaskCount increases, but doesn't overestimate,
    414      * when tasks complete
    415      */
    416     public void testGetCompletedTaskCount() throws InterruptedException {
    417         final ThreadPoolExecutor p = new CustomExecutor(2);
    418         try (PoolCleaner cleaner = cleaner(p)) {
    419             final CountDownLatch threadStarted = new CountDownLatch(1);
    420             final CountDownLatch threadProceed = new CountDownLatch(1);
    421             final CountDownLatch threadDone = new CountDownLatch(1);
    422             assertEquals(0, p.getCompletedTaskCount());
    423             p.execute(new CheckedRunnable() {
    424                 public void realRun() throws InterruptedException {
    425                     threadStarted.countDown();
    426                     assertEquals(0, p.getCompletedTaskCount());
    427                     threadProceed.await();
    428                     threadDone.countDown();
    429                 }});
    430             await(threadStarted);
    431             assertEquals(0, p.getCompletedTaskCount());
    432             threadProceed.countDown();
    433             threadDone.await();
    434             long startTime = System.nanoTime();
    435             while (p.getCompletedTaskCount() != 1) {
    436                 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
    437                     fail("timed out");
    438                 Thread.yield();
    439             }
    440         }
    441     }
    442 
    443     /**
    444      * getCorePoolSize returns size given in constructor if not otherwise set
    445      */
    446     public void testGetCorePoolSize() {
    447         final CustomExecutor p = new CustomExecutor(1);
    448         try (PoolCleaner cleaner = cleaner(p)) {
    449             assertEquals(1, p.getCorePoolSize());
    450         }
    451     }
    452 
    453     /**
    454      * getLargestPoolSize increases, but doesn't overestimate, when
    455      * multiple threads active
    456      */
    457     public void testGetLargestPoolSize() throws InterruptedException {
    458         final int THREADS = 3;
    459         final CountDownLatch done = new CountDownLatch(1);
    460         final ThreadPoolExecutor p = new CustomExecutor(THREADS);
    461         try (PoolCleaner cleaner = cleaner(p, done)) {
    462             final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
    463             assertEquals(0, p.getLargestPoolSize());
    464             for (int i = 0; i < THREADS; i++)
    465                 p.execute(new CheckedRunnable() {
    466                     public void realRun() throws InterruptedException {
    467                         threadsStarted.countDown();
    468                         await(done);
    469                         assertEquals(THREADS, p.getLargestPoolSize());
    470                     }});
    471             await(threadsStarted);
    472             assertEquals(THREADS, p.getLargestPoolSize());
    473         }
    474         assertEquals(THREADS, p.getLargestPoolSize());
    475     }
    476 
    477     /**
    478      * getPoolSize increases, but doesn't overestimate, when threads
    479      * become active
    480      */
    481     public void testGetPoolSize() throws InterruptedException {
    482         final CountDownLatch done = new CountDownLatch(1);
    483         final ThreadPoolExecutor p = new CustomExecutor(1);
    484         try (PoolCleaner cleaner = cleaner(p, done)) {
    485             final CountDownLatch threadStarted = new CountDownLatch(1);
    486             assertEquals(0, p.getPoolSize());
    487             p.execute(new CheckedRunnable() {
    488                 public void realRun() throws InterruptedException {
    489                     threadStarted.countDown();
    490                     assertEquals(1, p.getPoolSize());
    491                     await(done);
    492                 }});
    493             await(threadStarted);
    494             assertEquals(1, p.getPoolSize());
    495         }
    496     }
    497 
    498     /**
    499      * getTaskCount increases, but doesn't overestimate, when tasks
    500      * submitted
    501      */
    502     public void testGetTaskCount() throws InterruptedException {
    503         final int TASKS = 3;
    504         final CountDownLatch done = new CountDownLatch(1);
    505         final ThreadPoolExecutor p = new CustomExecutor(1);
    506         try (PoolCleaner cleaner = cleaner(p, done)) {
    507             final CountDownLatch threadStarted = new CountDownLatch(1);
    508             assertEquals(0, p.getTaskCount());
    509             assertEquals(0, p.getCompletedTaskCount());
    510             p.execute(new CheckedRunnable() {
    511                 public void realRun() throws InterruptedException {
    512                     threadStarted.countDown();
    513                     await(done);
    514                 }});
    515             await(threadStarted);
    516             assertEquals(1, p.getTaskCount());
    517             assertEquals(0, p.getCompletedTaskCount());
    518             for (int i = 0; i < TASKS; i++) {
    519                 assertEquals(1 + i, p.getTaskCount());
    520                 p.execute(new CheckedRunnable() {
    521                     public void realRun() throws InterruptedException {
    522                         threadStarted.countDown();
    523                         assertEquals(1 + TASKS, p.getTaskCount());
    524                         await(done);
    525                     }});
    526             }
    527             assertEquals(1 + TASKS, p.getTaskCount());
    528             assertEquals(0, p.getCompletedTaskCount());
    529         }
    530         assertEquals(1 + TASKS, p.getTaskCount());
    531         assertEquals(1 + TASKS, p.getCompletedTaskCount());
    532     }
    533 
    534     /**
    535      * getThreadFactory returns factory in constructor if not set
    536      */
    537     public void testGetThreadFactory() {
    538         final ThreadFactory threadFactory = new SimpleThreadFactory();
    539         final CustomExecutor p = new CustomExecutor(1, threadFactory);
    540         try (PoolCleaner cleaner = cleaner(p)) {
    541             assertSame(threadFactory, p.getThreadFactory());
    542         }
    543     }
    544 
    545     /**
    546      * setThreadFactory sets the thread factory returned by getThreadFactory
    547      */
    548     public void testSetThreadFactory() {
    549         final ThreadFactory threadFactory = new SimpleThreadFactory();
    550         final CustomExecutor p = new CustomExecutor(1);
    551         try (PoolCleaner cleaner = cleaner(p)) {
    552             p.setThreadFactory(threadFactory);
    553             assertSame(threadFactory, p.getThreadFactory());
    554         }
    555     }
    556 
    557     /**
    558      * setThreadFactory(null) throws NPE
    559      */
    560     public void testSetThreadFactoryNull() {
    561         final CustomExecutor p = new CustomExecutor(1);
    562         try (PoolCleaner cleaner = cleaner(p)) {
    563             try {
    564                 p.setThreadFactory(null);
    565                 shouldThrow();
    566             } catch (NullPointerException success) {}
    567         }
    568     }
    569 
    570     /**
    571      * isShutdown is false before shutdown, true after
    572      */
    573     public void testIsShutdown() {
    574         final CustomExecutor p = new CustomExecutor(1);
    575         try (PoolCleaner cleaner = cleaner(p)) {
    576             assertFalse(p.isShutdown());
    577             try { p.shutdown(); } catch (SecurityException ok) { return; }
    578             assertTrue(p.isShutdown());
    579         }
    580     }
    581 
    582     /**
    583      * isTerminated is false before termination, true after
    584      */
    585     public void testIsTerminated() throws InterruptedException {
    586         final CountDownLatch done = new CountDownLatch(1);
    587         final ThreadPoolExecutor p = new CustomExecutor(1);
    588         try (PoolCleaner cleaner = cleaner(p)) {
    589             final CountDownLatch threadStarted = new CountDownLatch(1);
    590             p.execute(new CheckedRunnable() {
    591                 public void realRun() throws InterruptedException {
    592                     assertFalse(p.isTerminated());
    593                     threadStarted.countDown();
    594                     await(done);
    595                 }});
    596             await(threadStarted);
    597             assertFalse(p.isTerminated());
    598             assertFalse(p.isTerminating());
    599             done.countDown();
    600             try { p.shutdown(); } catch (SecurityException ok) { return; }
    601             assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    602             assertTrue(p.isTerminated());
    603         }
    604     }
    605 
    606     /**
    607      * isTerminating is not true when running or when terminated
    608      */
    609     public void testIsTerminating() throws InterruptedException {
    610         final CountDownLatch done = new CountDownLatch(1);
    611         final ThreadPoolExecutor p = new CustomExecutor(1);
    612         try (PoolCleaner cleaner = cleaner(p)) {
    613             final CountDownLatch threadStarted = new CountDownLatch(1);
    614             assertFalse(p.isTerminating());
    615             p.execute(new CheckedRunnable() {
    616                 public void realRun() throws InterruptedException {
    617                     assertFalse(p.isTerminating());
    618                     threadStarted.countDown();
    619                     await(done);
    620                 }});
    621             await(threadStarted);
    622             assertFalse(p.isTerminating());
    623             done.countDown();
    624             try { p.shutdown(); } catch (SecurityException ok) { return; }
    625             assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    626             assertTrue(p.isTerminated());
    627             assertFalse(p.isTerminating());
    628         }
    629     }
    630 
    631     /**
    632      * getQueue returns the work queue, which contains queued tasks
    633      */
    634     public void testGetQueue() throws InterruptedException {
    635         final CountDownLatch done = new CountDownLatch(1);
    636         final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
    637         try (PoolCleaner cleaner = cleaner(p, done)) {
    638             final CountDownLatch threadStarted = new CountDownLatch(1);
    639             ScheduledFuture[] tasks = new ScheduledFuture[5];
    640             for (int i = 0; i < tasks.length; i++) {
    641                 Runnable r = new CheckedRunnable() {
    642                     public void realRun() throws InterruptedException {
    643                         threadStarted.countDown();
    644                         await(done);
    645                     }};
    646                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
    647             }
    648             await(threadStarted);
    649             BlockingQueue<Runnable> q = p.getQueue();
    650             assertTrue(q.contains(tasks[tasks.length - 1]));
    651             assertFalse(q.contains(tasks[0]));
    652         }
    653     }
    654 
    655     /**
    656      * remove(task) removes queued task, and fails to remove active task
    657      */
    658     public void testRemove() throws InterruptedException {
    659         final CountDownLatch done = new CountDownLatch(1);
    660         final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
    661         try (PoolCleaner cleaner = cleaner(p, done)) {
    662             ScheduledFuture[] tasks = new ScheduledFuture[5];
    663             final CountDownLatch threadStarted = new CountDownLatch(1);
    664             for (int i = 0; i < tasks.length; i++) {
    665                 Runnable r = new CheckedRunnable() {
    666                     public void realRun() throws InterruptedException {
    667                         threadStarted.countDown();
    668                         await(done);
    669                     }};
    670                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
    671             }
    672             await(threadStarted);
    673             BlockingQueue<Runnable> q = p.getQueue();
    674             assertFalse(p.remove((Runnable)tasks[0]));
    675             assertTrue(q.contains((Runnable)tasks[4]));
    676             assertTrue(q.contains((Runnable)tasks[3]));
    677             assertTrue(p.remove((Runnable)tasks[4]));
    678             assertFalse(p.remove((Runnable)tasks[4]));
    679             assertFalse(q.contains((Runnable)tasks[4]));
    680             assertTrue(q.contains((Runnable)tasks[3]));
    681             assertTrue(p.remove((Runnable)tasks[3]));
    682             assertFalse(q.contains((Runnable)tasks[3]));
    683         }
    684     }
    685 
    686     /**
    687      * purge removes cancelled tasks from the queue
    688      */
    689     public void testPurge() throws InterruptedException {
    690         final ScheduledFuture[] tasks = new ScheduledFuture[5];
    691         final Runnable releaser = new Runnable() { public void run() {
    692             for (ScheduledFuture task : tasks)
    693                 if (task != null) task.cancel(true); }};
    694         final CustomExecutor p = new CustomExecutor(1);
    695         try (PoolCleaner cleaner = cleaner(p, releaser)) {
    696             for (int i = 0; i < tasks.length; i++)
    697                 tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
    698                                       LONG_DELAY_MS, MILLISECONDS);
    699             int max = tasks.length;
    700             if (tasks[4].cancel(true)) --max;
    701             if (tasks[3].cancel(true)) --max;
    702             // There must eventually be an interference-free point at
    703             // which purge will not fail. (At worst, when queue is empty.)
    704             long startTime = System.nanoTime();
    705             do {
    706                 p.purge();
    707                 long count = p.getTaskCount();
    708                 if (count == max)
    709                     return;
    710             } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
    711             fail("Purge failed to remove cancelled tasks");
    712         }
    713     }
    714 
    715     /**
    716      * shutdownNow returns a list containing tasks that were not run,
    717      * and those tasks are drained from the queue
    718      */
    719     public void testShutdownNow() throws InterruptedException {
    720         final int poolSize = 2;
    721         final int count = 5;
    722         final AtomicInteger ran = new AtomicInteger(0);
    723         final CustomExecutor p = new CustomExecutor(poolSize);
    724         final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
    725         Runnable waiter = new CheckedRunnable() { public void realRun() {
    726             threadsStarted.countDown();
    727             try {
    728                 MILLISECONDS.sleep(2 * LONG_DELAY_MS);
    729             } catch (InterruptedException success) {}
    730             ran.getAndIncrement();
    731         }};
    732         for (int i = 0; i < count; i++)
    733             p.execute(waiter);
    734         await(threadsStarted);
    735         assertEquals(poolSize, p.getActiveCount());
    736         assertEquals(0, p.getCompletedTaskCount());
    737         final List<Runnable> queuedTasks;
    738         try {
    739             queuedTasks = p.shutdownNow();
    740         } catch (SecurityException ok) {
    741             return; // Allowed in case test doesn't have privs
    742         }
    743         assertTrue(p.isShutdown());
    744         assertTrue(p.getQueue().isEmpty());
    745         assertEquals(count - poolSize, queuedTasks.size());
    746         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    747         assertTrue(p.isTerminated());
    748         assertEquals(poolSize, ran.get());
    749         assertEquals(poolSize, p.getCompletedTaskCount());
    750     }
    751 
    752     /**
    753      * shutdownNow returns a list containing tasks that were not run,
    754      * and those tasks are drained from the queue
    755      */
    756     public void testShutdownNow_delayedTasks() throws InterruptedException {
    757         final CustomExecutor p = new CustomExecutor(1);
    758         List<ScheduledFuture> tasks = new ArrayList<>();
    759         for (int i = 0; i < 3; i++) {
    760             Runnable r = new NoOpRunnable();
    761             tasks.add(p.schedule(r, 9, SECONDS));
    762             tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
    763             tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
    764         }
    765         if (testImplementationDetails)
    766             assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
    767         final List<Runnable> queuedTasks;
    768         try {
    769             queuedTasks = p.shutdownNow();
    770         } catch (SecurityException ok) {
    771             return; // Allowed in case test doesn't have privs
    772         }
    773         assertTrue(p.isShutdown());
    774         assertTrue(p.getQueue().isEmpty());
    775         if (testImplementationDetails)
    776             assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
    777         assertEquals(tasks.size(), queuedTasks.size());
    778         for (ScheduledFuture task : tasks) {
    779             assertFalse(((CustomTask)task).ran);
    780             assertFalse(task.isDone());
    781             assertFalse(task.isCancelled());
    782         }
    783         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    784         assertTrue(p.isTerminated());
    785     }
    786 
    787     /**
    788      * By default, periodic tasks are cancelled at shutdown.
    789      * By default, delayed tasks keep running after shutdown.
    790      * Check that changing the default values work:
    791      * - setExecuteExistingDelayedTasksAfterShutdownPolicy
    792      * - setContinueExistingPeriodicTasksAfterShutdownPolicy
    793      */
    794     public void testShutdown_cancellation() throws Exception {
    795         Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
    796         for (Boolean policy : allBooleans)
    797     {
    798         final int poolSize = 2;
    799         final CustomExecutor p = new CustomExecutor(poolSize);
    800         final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
    801         final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
    802         final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
    803         if (policy != null) {
    804             p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
    805             p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
    806             p.setRemoveOnCancelPolicy(policy);
    807         }
    808         assertEquals(effectiveDelayedPolicy,
    809                      p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
    810         assertEquals(effectivePeriodicPolicy,
    811                      p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
    812         assertEquals(effectiveRemovePolicy,
    813                      p.getRemoveOnCancelPolicy());
    814         // Strategy: Wedge the pool with poolSize "blocker" threads
    815         final AtomicInteger ran = new AtomicInteger(0);
    816         final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
    817         final CountDownLatch unblock = new CountDownLatch(1);
    818         final CountDownLatch periodicLatch1 = new CountDownLatch(2);
    819         final CountDownLatch periodicLatch2 = new CountDownLatch(2);
    820         Runnable task = new CheckedRunnable() { public void realRun()
    821                                                     throws InterruptedException {
    822             poolBlocked.countDown();
    823             assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
    824             ran.getAndIncrement();
    825         }};
    826         List<Future<?>> blockers = new ArrayList<>();
    827         List<Future<?>> periodics = new ArrayList<>();
    828         List<Future<?>> delayeds = new ArrayList<>();
    829         for (int i = 0; i < poolSize; i++)
    830             blockers.add(p.submit(task));
    831         assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
    832 
    833         periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
    834                                             1, 1, MILLISECONDS));
    835         periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
    836                                                1, 1, MILLISECONDS));
    837         delayeds.add(p.schedule(task, 1, MILLISECONDS));
    838 
    839         assertTrue(p.getQueue().containsAll(periodics));
    840         assertTrue(p.getQueue().containsAll(delayeds));
    841         try { p.shutdown(); } catch (SecurityException ok) { return; }
    842         assertTrue(p.isShutdown());
    843         assertFalse(p.isTerminated());
    844         for (Future<?> periodic : periodics) {
    845             assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
    846             assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
    847         }
    848         for (Future<?> delayed : delayeds) {
    849             assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
    850             assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
    851         }
    852         if (testImplementationDetails) {
    853             assertEquals(effectivePeriodicPolicy,
    854                          p.getQueue().containsAll(periodics));
    855             assertEquals(effectiveDelayedPolicy,
    856                          p.getQueue().containsAll(delayeds));
    857         }
    858         // Release all pool threads
    859         unblock.countDown();
    860 
    861         for (Future<?> delayed : delayeds) {
    862             if (effectiveDelayedPolicy) {
    863                 assertNull(delayed.get());
    864             }
    865         }
    866         if (effectivePeriodicPolicy) {
    867             assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
    868             assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
    869             for (Future<?> periodic : periodics) {
    870                 assertTrue(periodic.cancel(false));
    871                 assertTrue(periodic.isCancelled());
    872                 assertTrue(periodic.isDone());
    873             }
    874         }
    875         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    876         assertTrue(p.isTerminated());
    877         assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
    878     }}
    879 
    880     /**
    881      * completed submit of callable returns result
    882      */
    883     public void testSubmitCallable() throws Exception {
    884         final ExecutorService e = new CustomExecutor(2);
    885         try (PoolCleaner cleaner = cleaner(e)) {
    886             Future<String> future = e.submit(new StringTask());
    887             String result = future.get();
    888             assertSame(TEST_STRING, result);
    889         }
    890     }
    891 
    892     /**
    893      * completed submit of runnable returns successfully
    894      */
    895     public void testSubmitRunnable() throws Exception {
    896         final ExecutorService e = new CustomExecutor(2);
    897         try (PoolCleaner cleaner = cleaner(e)) {
    898             Future<?> future = e.submit(new NoOpRunnable());
    899             future.get();
    900             assertTrue(future.isDone());
    901         }
    902     }
    903 
    904     /**
    905      * completed submit of (runnable, result) returns result
    906      */
    907     public void testSubmitRunnable2() throws Exception {
    908         final ExecutorService e = new CustomExecutor(2);
    909         try (PoolCleaner cleaner = cleaner(e)) {
    910             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
    911             String result = future.get();
    912             assertSame(TEST_STRING, result);
    913         }
    914     }
    915 
    916     /**
    917      * invokeAny(null) throws NPE
    918      */
    919     public void testInvokeAny1() throws Exception {
    920         final ExecutorService e = new CustomExecutor(2);
    921         try (PoolCleaner cleaner = cleaner(e)) {
    922             try {
    923                 e.invokeAny(null);
    924                 shouldThrow();
    925             } catch (NullPointerException success) {}
    926         }
    927     }
    928 
    929     /**
    930      * invokeAny(empty collection) throws IAE
    931      */
    932     public void testInvokeAny2() throws Exception {
    933         final ExecutorService e = new CustomExecutor(2);
    934         try (PoolCleaner cleaner = cleaner(e)) {
    935             try {
    936                 e.invokeAny(new ArrayList<Callable<String>>());
    937                 shouldThrow();
    938             } catch (IllegalArgumentException success) {}
    939         }
    940     }
    941 
    942     /**
    943      * invokeAny(c) throws NPE if c has null elements
    944      */
    945     public void testInvokeAny3() throws Exception {
    946         final CountDownLatch latch = new CountDownLatch(1);
    947         final ExecutorService e = new CustomExecutor(2);
    948         try (PoolCleaner cleaner = cleaner(e)) {
    949             List<Callable<String>> l = new ArrayList<Callable<String>>();
    950             l.add(latchAwaitingStringTask(latch));
    951             l.add(null);
    952             try {
    953                 e.invokeAny(l);
    954                 shouldThrow();
    955             } catch (NullPointerException success) {}
    956             latch.countDown();
    957         }
    958     }
    959 
    960     /**
    961      * invokeAny(c) throws ExecutionException if no task completes
    962      */
    963     public void testInvokeAny4() throws Exception {
    964         final ExecutorService e = new CustomExecutor(2);
    965         try (PoolCleaner cleaner = cleaner(e)) {
    966             List<Callable<String>> l = new ArrayList<Callable<String>>();
    967             l.add(new NPETask());
    968             try {
    969                 e.invokeAny(l);
    970                 shouldThrow();
    971             } catch (ExecutionException success) {
    972                 assertTrue(success.getCause() instanceof NullPointerException);
    973             }
    974         }
    975     }
    976 
    977     /**
    978      * invokeAny(c) returns result of some task
    979      */
    980     public void testInvokeAny5() throws Exception {
    981         final ExecutorService e = new CustomExecutor(2);
    982         try (PoolCleaner cleaner = cleaner(e)) {
    983             List<Callable<String>> l = new ArrayList<Callable<String>>();
    984             l.add(new StringTask());
    985             l.add(new StringTask());
    986             String result = e.invokeAny(l);
    987             assertSame(TEST_STRING, result);
    988         }
    989     }
    990 
    991     /**
    992      * invokeAll(null) throws NPE
    993      */
    994     public void testInvokeAll1() throws Exception {
    995         final ExecutorService e = new CustomExecutor(2);
    996         try (PoolCleaner cleaner = cleaner(e)) {
    997             try {
    998                 e.invokeAll(null);
    999                 shouldThrow();
   1000             } catch (NullPointerException success) {}
   1001         }
   1002     }
   1003 
   1004     /**
   1005      * invokeAll(empty collection) returns empty collection
   1006      */
   1007     public void testInvokeAll2() throws Exception {
   1008         final ExecutorService e = new CustomExecutor(2);
   1009         try (PoolCleaner cleaner = cleaner(e)) {
   1010             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
   1011             assertTrue(r.isEmpty());
   1012         }
   1013     }
   1014 
   1015     /**
   1016      * invokeAll(c) throws NPE if c has null elements
   1017      */
   1018     public void testInvokeAll3() throws Exception {
   1019         final ExecutorService e = new CustomExecutor(2);
   1020         try (PoolCleaner cleaner = cleaner(e)) {
   1021             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1022             l.add(new StringTask());
   1023             l.add(null);
   1024             try {
   1025                 e.invokeAll(l);
   1026                 shouldThrow();
   1027             } catch (NullPointerException success) {}
   1028         }
   1029     }
   1030 
   1031     /**
   1032      * get of invokeAll(c) throws exception on failed task
   1033      */
   1034     public void testInvokeAll4() throws Exception {
   1035         final ExecutorService e = new CustomExecutor(2);
   1036         try (PoolCleaner cleaner = cleaner(e)) {
   1037             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1038             l.add(new NPETask());
   1039             List<Future<String>> futures = e.invokeAll(l);
   1040             assertEquals(1, futures.size());
   1041             try {
   1042                 futures.get(0).get();
   1043                 shouldThrow();
   1044             } catch (ExecutionException success) {
   1045                 assertTrue(success.getCause() instanceof NullPointerException);
   1046             }
   1047         }
   1048     }
   1049 
   1050     /**
   1051      * invokeAll(c) returns results of all completed tasks
   1052      */
   1053     public void testInvokeAll5() throws Exception {
   1054         final ExecutorService e = new CustomExecutor(2);
   1055         try (PoolCleaner cleaner = cleaner(e)) {
   1056             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1057             l.add(new StringTask());
   1058             l.add(new StringTask());
   1059             List<Future<String>> futures = e.invokeAll(l);
   1060             assertEquals(2, futures.size());
   1061             for (Future<String> future : futures)
   1062                 assertSame(TEST_STRING, future.get());
   1063         }
   1064     }
   1065 
   1066     /**
   1067      * timed invokeAny(null) throws NPE
   1068      */
   1069     public void testTimedInvokeAny1() throws Exception {
   1070         final ExecutorService e = new CustomExecutor(2);
   1071         try (PoolCleaner cleaner = cleaner(e)) {
   1072             try {
   1073                 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
   1074                 shouldThrow();
   1075             } catch (NullPointerException success) {}
   1076         }
   1077     }
   1078 
   1079     /**
   1080      * timed invokeAny(,,null) throws NPE
   1081      */
   1082     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
   1083         final ExecutorService e = new CustomExecutor(2);
   1084         try (PoolCleaner cleaner = cleaner(e)) {
   1085             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1086             l.add(new StringTask());
   1087             try {
   1088                 e.invokeAny(l, MEDIUM_DELAY_MS, null);
   1089                 shouldThrow();
   1090             } catch (NullPointerException success) {}
   1091         }
   1092     }
   1093 
   1094     /**
   1095      * timed invokeAny(empty collection) throws IAE
   1096      */
   1097     public void testTimedInvokeAny2() throws Exception {
   1098         final ExecutorService e = new CustomExecutor(2);
   1099         try (PoolCleaner cleaner = cleaner(e)) {
   1100             try {
   1101                 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
   1102                 shouldThrow();
   1103             } catch (IllegalArgumentException success) {}
   1104         }
   1105     }
   1106 
   1107     /**
   1108      * timed invokeAny(c) throws NPE if c has null elements
   1109      */
   1110     public void testTimedInvokeAny3() throws Exception {
   1111         CountDownLatch latch = new CountDownLatch(1);
   1112         final ExecutorService e = new CustomExecutor(2);
   1113         try (PoolCleaner cleaner = cleaner(e)) {
   1114             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1115             l.add(latchAwaitingStringTask(latch));
   1116             l.add(null);
   1117             try {
   1118                 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1119                 shouldThrow();
   1120             } catch (NullPointerException success) {}
   1121             latch.countDown();
   1122         }
   1123     }
   1124 
   1125     /**
   1126      * timed invokeAny(c) throws ExecutionException if no task completes
   1127      */
   1128     public void testTimedInvokeAny4() throws Exception {
   1129         final ExecutorService e = new CustomExecutor(2);
   1130         try (PoolCleaner cleaner = cleaner(e)) {
   1131             long startTime = System.nanoTime();
   1132             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1133             l.add(new NPETask());
   1134             try {
   1135                 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
   1136                 shouldThrow();
   1137             } catch (ExecutionException success) {
   1138                 assertTrue(success.getCause() instanceof NullPointerException);
   1139             }
   1140             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
   1141         }
   1142     }
   1143 
   1144     /**
   1145      * timed invokeAny(c) returns result of some task
   1146      */
   1147     public void testTimedInvokeAny5() throws Exception {
   1148         final ExecutorService e = new CustomExecutor(2);
   1149         try (PoolCleaner cleaner = cleaner(e)) {
   1150             long startTime = System.nanoTime();
   1151             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1152             l.add(new StringTask());
   1153             l.add(new StringTask());
   1154             String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
   1155             assertSame(TEST_STRING, result);
   1156             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
   1157         }
   1158     }
   1159 
   1160     /**
   1161      * timed invokeAll(null) throws NPE
   1162      */
   1163     public void testTimedInvokeAll1() throws Exception {
   1164         final ExecutorService e = new CustomExecutor(2);
   1165         try (PoolCleaner cleaner = cleaner(e)) {
   1166             try {
   1167                 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
   1168                 shouldThrow();
   1169             } catch (NullPointerException success) {}
   1170         }
   1171     }
   1172 
   1173     /**
   1174      * timed invokeAll(,,null) throws NPE
   1175      */
   1176     public void testTimedInvokeAllNullTimeUnit() throws Exception {
   1177         final ExecutorService e = new CustomExecutor(2);
   1178         try (PoolCleaner cleaner = cleaner(e)) {
   1179             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1180             l.add(new StringTask());
   1181             try {
   1182                 e.invokeAll(l, MEDIUM_DELAY_MS, null);
   1183                 shouldThrow();
   1184             } catch (NullPointerException success) {}
   1185         }
   1186     }
   1187 
   1188     /**
   1189      * timed invokeAll(empty collection) returns empty collection
   1190      */
   1191     public void testTimedInvokeAll2() throws Exception {
   1192         final ExecutorService e = new CustomExecutor(2);
   1193         try (PoolCleaner cleaner = cleaner(e)) {
   1194             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
   1195             assertTrue(r.isEmpty());
   1196         }
   1197     }
   1198 
   1199     /**
   1200      * timed invokeAll(c) throws NPE if c has null elements
   1201      */
   1202     public void testTimedInvokeAll3() throws Exception {
   1203         final ExecutorService e = new CustomExecutor(2);
   1204         try (PoolCleaner cleaner = cleaner(e)) {
   1205             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1206             l.add(new StringTask());
   1207             l.add(null);
   1208             try {
   1209                 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1210                 shouldThrow();
   1211             } catch (NullPointerException success) {}
   1212         }
   1213     }
   1214 
   1215     /**
   1216      * get of element of invokeAll(c) throws exception on failed task
   1217      */
   1218     public void testTimedInvokeAll4() throws Exception {
   1219         final ExecutorService e = new CustomExecutor(2);
   1220         try (PoolCleaner cleaner = cleaner(e)) {
   1221             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1222             l.add(new NPETask());
   1223             List<Future<String>> futures =
   1224                 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1225             assertEquals(1, futures.size());
   1226             try {
   1227                 futures.get(0).get();
   1228                 shouldThrow();
   1229             } catch (ExecutionException success) {
   1230                 assertTrue(success.getCause() instanceof NullPointerException);
   1231             }
   1232         }
   1233     }
   1234 
   1235     /**
   1236      * timed invokeAll(c) returns results of all completed tasks
   1237      */
   1238     public void testTimedInvokeAll5() throws Exception {
   1239         final ExecutorService e = new CustomExecutor(2);
   1240         try (PoolCleaner cleaner = cleaner(e)) {
   1241             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1242             l.add(new StringTask());
   1243             l.add(new StringTask());
   1244             List<Future<String>> futures =
   1245                 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
   1246             assertEquals(2, futures.size());
   1247             for (Future<String> future : futures)
   1248                 assertSame(TEST_STRING, future.get());
   1249         }
   1250     }
   1251 
   1252     /**
   1253      * timed invokeAll(c) cancels tasks not completed by timeout
   1254      */
   1255     public void testTimedInvokeAll6() throws Exception {
   1256         for (long timeout = timeoutMillis();;) {
   1257             final CountDownLatch done = new CountDownLatch(1);
   1258             final Callable<String> waiter = new CheckedCallable<String>() {
   1259                 public String realCall() {
   1260                     try { done.await(LONG_DELAY_MS, MILLISECONDS); }
   1261                     catch (InterruptedException ok) {}
   1262                     return "1"; }};
   1263             final ExecutorService p = new CustomExecutor(2);
   1264             try (PoolCleaner cleaner = cleaner(p, done)) {
   1265                 List<Callable<String>> tasks = new ArrayList<>();
   1266                 tasks.add(new StringTask("0"));
   1267                 tasks.add(waiter);
   1268                 tasks.add(new StringTask("2"));
   1269                 long startTime = System.nanoTime();
   1270                 List<Future<String>> futures =
   1271                     p.invokeAll(tasks, timeout, MILLISECONDS);
   1272                 assertEquals(tasks.size(), futures.size());
   1273                 assertTrue(millisElapsedSince(startTime) >= timeout);
   1274                 for (Future future : futures)
   1275                     assertTrue(future.isDone());
   1276                 assertTrue(futures.get(1).isCancelled());
   1277                 try {
   1278                     assertEquals("0", futures.get(0).get());
   1279                     assertEquals("2", futures.get(2).get());
   1280                     break;
   1281                 } catch (CancellationException retryWithLongerTimeout) {
   1282                     timeout *= 2;
   1283                     if (timeout >= LONG_DELAY_MS / 2)
   1284                         fail("expected exactly one task to be cancelled");
   1285                 }
   1286             }
   1287         }
   1288     }
   1289 
   1290 }
   1291