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