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