ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.38
Committed: Sun Sep 27 20:17:39 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.37: +25 -11 lines
Log Message:
improve tests for shutdownNow

File Contents

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