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