ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.40
Committed: Mon Sep 28 02:41:29 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.39: +34 -0 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() throws InterruptedException {
714 final int poolSize = 2;
715 final int count = 5;
716 final AtomicInteger ran = new AtomicInteger(0);
717 final CustomExecutor p = new CustomExecutor(poolSize);
718 CountDownLatch threadsStarted = new CountDownLatch(poolSize);
719 CheckedRunnable waiter = new CheckedRunnable() { public void realRun() {
720 threadsStarted.countDown();
721 try {
722 MILLISECONDS.sleep(2 * LONG_DELAY_MS);
723 } catch (InterruptedException success) {}
724 ran.getAndIncrement();
725 }};
726 for (int i = 0; i < count; i++)
727 p.execute(waiter);
728 assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
729 final List<Runnable> queuedTasks;
730 try {
731 queuedTasks = p.shutdownNow();
732 } catch (SecurityException ok) {
733 return; // Allowed in case test doesn't have privs
734 }
735 assertTrue(p.isShutdown());
736 assertTrue(p.getQueue().isEmpty());
737 assertEquals(count - poolSize, queuedTasks.size());
738 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
739 assertTrue(p.isTerminated());
740 assertEquals(poolSize, ran.get());
741 }
742
743 /**
744 * shutdownNow returns a list containing tasks that were not run,
745 * and those tasks are drained from the queue
746 */
747 public void testShutdownNow_delayedTasks() throws InterruptedException {
748 CustomExecutor p = new CustomExecutor(1);
749 List<ScheduledFuture> tasks = new ArrayList<>();
750 for (int i = 0; i < 3; i++) {
751 Runnable r = new NoOpRunnable();
752 tasks.add(p.schedule(r, 9, SECONDS));
753 tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
754 tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
755 }
756 if (testImplementationDetails)
757 assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
758 final List<Runnable> queuedTasks;
759 try {
760 queuedTasks = p.shutdownNow();
761 } catch (SecurityException ok) {
762 return; // Allowed in case test doesn't have privs
763 }
764 assertTrue(p.isShutdown());
765 assertTrue(p.getQueue().isEmpty());
766 if (testImplementationDetails)
767 assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
768 assertEquals(tasks.size(), queuedTasks.size());
769 for (ScheduledFuture task : tasks) {
770 assertFalse(((CustomTask)task).ran);
771 assertFalse(task.isDone());
772 assertFalse(task.isCancelled());
773 }
774 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
775 assertTrue(p.isTerminated());
776 }
777
778 /**
779 * In default setting, shutdown cancels periodic but not delayed
780 * tasks at shutdown
781 */
782 public void testShutdown1() throws InterruptedException {
783 CustomExecutor p = new CustomExecutor(1);
784 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
785 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
786
787 ScheduledFuture[] tasks = new ScheduledFuture[5];
788 for (int i = 0; i < tasks.length; i++)
789 tasks[i] = p.schedule(new NoOpRunnable(),
790 SHORT_DELAY_MS, MILLISECONDS);
791 try { p.shutdown(); } catch (SecurityException ok) { return; }
792 BlockingQueue<Runnable> q = p.getQueue();
793 for (ScheduledFuture task : tasks) {
794 assertFalse(task.isDone());
795 assertFalse(task.isCancelled());
796 assertTrue(q.contains(task));
797 }
798 assertTrue(p.isShutdown());
799 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
800 assertTrue(p.isTerminated());
801 for (ScheduledFuture task : tasks) {
802 assertTrue(task.isDone());
803 assertFalse(task.isCancelled());
804 }
805 }
806
807 /**
808 * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
809 * delayed tasks are cancelled at shutdown
810 */
811 public void testShutdown2() throws InterruptedException {
812 CustomExecutor p = new CustomExecutor(1);
813 p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
814 assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
815 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
816 ScheduledFuture[] tasks = new ScheduledFuture[5];
817 for (int i = 0; i < tasks.length; i++)
818 tasks[i] = p.schedule(new NoOpRunnable(),
819 SHORT_DELAY_MS, MILLISECONDS);
820 BlockingQueue q = p.getQueue();
821 assertEquals(tasks.length, q.size());
822 try { p.shutdown(); } catch (SecurityException ok) { return; }
823 assertTrue(p.isShutdown());
824 assertTrue(q.isEmpty());
825 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
826 assertTrue(p.isTerminated());
827 for (ScheduledFuture task : tasks) {
828 assertTrue(task.isDone());
829 assertTrue(task.isCancelled());
830 }
831 }
832
833 /**
834 * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
835 * periodic tasks are cancelled at shutdown
836 */
837 public void testShutdown3() throws InterruptedException {
838 CustomExecutor p = new CustomExecutor(1);
839 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
840 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
841 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
842 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
843 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
844 long initialDelay = LONG_DELAY_MS;
845 ScheduledFuture task =
846 p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
847 5, MILLISECONDS);
848 try { p.shutdown(); } catch (SecurityException ok) { return; }
849 assertTrue(p.isShutdown());
850 assertTrue(p.getQueue().isEmpty());
851 assertTrue(task.isDone());
852 assertTrue(task.isCancelled());
853 joinPool(p);
854 }
855
856 /**
857 * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
858 * periodic tasks are not cancelled at shutdown
859 */
860 public void testShutdown4() throws InterruptedException {
861 CustomExecutor p = new CustomExecutor(1);
862 final CountDownLatch counter = new CountDownLatch(2);
863 try {
864 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
865 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
866 assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
867 final Runnable r = new CheckedRunnable() {
868 public void realRun() {
869 counter.countDown();
870 }};
871 ScheduledFuture task =
872 p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
873 assertFalse(task.isDone());
874 assertFalse(task.isCancelled());
875 try { p.shutdown(); } catch (SecurityException ok) { return; }
876 assertFalse(task.isCancelled());
877 assertFalse(p.isTerminated());
878 assertTrue(p.isShutdown());
879 assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
880 assertFalse(task.isCancelled());
881 assertTrue(task.cancel(false));
882 assertTrue(task.isDone());
883 assertTrue(task.isCancelled());
884 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
885 assertTrue(p.isTerminated());
886 }
887 finally {
888 joinPool(p);
889 }
890 }
891
892 /**
893 * completed submit of callable returns result
894 */
895 public void testSubmitCallable() throws Exception {
896 ExecutorService e = new CustomExecutor(2);
897 try {
898 Future<String> future = e.submit(new StringTask());
899 String result = future.get();
900 assertSame(TEST_STRING, result);
901 } finally {
902 joinPool(e);
903 }
904 }
905
906 /**
907 * completed submit of runnable returns successfully
908 */
909 public void testSubmitRunnable() throws Exception {
910 ExecutorService e = new CustomExecutor(2);
911 try {
912 Future<?> future = e.submit(new NoOpRunnable());
913 future.get();
914 assertTrue(future.isDone());
915 } finally {
916 joinPool(e);
917 }
918 }
919
920 /**
921 * completed submit of (runnable, result) returns result
922 */
923 public void testSubmitRunnable2() throws Exception {
924 ExecutorService e = new CustomExecutor(2);
925 try {
926 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
927 String result = future.get();
928 assertSame(TEST_STRING, result);
929 } finally {
930 joinPool(e);
931 }
932 }
933
934 /**
935 * invokeAny(null) throws NPE
936 */
937 public void testInvokeAny1() throws Exception {
938 ExecutorService e = new CustomExecutor(2);
939 try {
940 e.invokeAny(null);
941 shouldThrow();
942 } catch (NullPointerException success) {
943 } finally {
944 joinPool(e);
945 }
946 }
947
948 /**
949 * invokeAny(empty collection) throws IAE
950 */
951 public void testInvokeAny2() throws Exception {
952 ExecutorService e = new CustomExecutor(2);
953 try {
954 e.invokeAny(new ArrayList<Callable<String>>());
955 shouldThrow();
956 } catch (IllegalArgumentException success) {
957 } finally {
958 joinPool(e);
959 }
960 }
961
962 /**
963 * invokeAny(c) throws NPE if c has null elements
964 */
965 public void testInvokeAny3() throws Exception {
966 CountDownLatch latch = new CountDownLatch(1);
967 ExecutorService e = new CustomExecutor(2);
968 List<Callable<String>> l = new ArrayList<Callable<String>>();
969 l.add(latchAwaitingStringTask(latch));
970 l.add(null);
971 try {
972 e.invokeAny(l);
973 shouldThrow();
974 } catch (NullPointerException success) {
975 } finally {
976 latch.countDown();
977 joinPool(e);
978 }
979 }
980
981 /**
982 * invokeAny(c) throws ExecutionException if no task completes
983 */
984 public void testInvokeAny4() throws Exception {
985 ExecutorService e = new CustomExecutor(2);
986 List<Callable<String>> l = new ArrayList<Callable<String>>();
987 l.add(new NPETask());
988 try {
989 e.invokeAny(l);
990 shouldThrow();
991 } catch (ExecutionException success) {
992 assertTrue(success.getCause() instanceof NullPointerException);
993 } finally {
994 joinPool(e);
995 }
996 }
997
998 /**
999 * invokeAny(c) returns result of some task
1000 */
1001 public void testInvokeAny5() throws Exception {
1002 ExecutorService e = new CustomExecutor(2);
1003 try {
1004 List<Callable<String>> l = new ArrayList<Callable<String>>();
1005 l.add(new StringTask());
1006 l.add(new StringTask());
1007 String result = e.invokeAny(l);
1008 assertSame(TEST_STRING, result);
1009 } finally {
1010 joinPool(e);
1011 }
1012 }
1013
1014 /**
1015 * invokeAll(null) throws NPE
1016 */
1017 public void testInvokeAll1() throws Exception {
1018 ExecutorService e = new CustomExecutor(2);
1019 try {
1020 e.invokeAll(null);
1021 shouldThrow();
1022 } catch (NullPointerException success) {
1023 } finally {
1024 joinPool(e);
1025 }
1026 }
1027
1028 /**
1029 * invokeAll(empty collection) returns empty collection
1030 */
1031 public void testInvokeAll2() throws Exception {
1032 ExecutorService e = new CustomExecutor(2);
1033 try {
1034 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
1035 assertTrue(r.isEmpty());
1036 } finally {
1037 joinPool(e);
1038 }
1039 }
1040
1041 /**
1042 * invokeAll(c) throws NPE if c has null elements
1043 */
1044 public void testInvokeAll3() throws Exception {
1045 ExecutorService e = new CustomExecutor(2);
1046 List<Callable<String>> l = new ArrayList<Callable<String>>();
1047 l.add(new StringTask());
1048 l.add(null);
1049 try {
1050 e.invokeAll(l);
1051 shouldThrow();
1052 } catch (NullPointerException success) {
1053 } finally {
1054 joinPool(e);
1055 }
1056 }
1057
1058 /**
1059 * get of invokeAll(c) throws exception on failed task
1060 */
1061 public void testInvokeAll4() throws Exception {
1062 ExecutorService e = new CustomExecutor(2);
1063 List<Callable<String>> l = new ArrayList<Callable<String>>();
1064 l.add(new NPETask());
1065 List<Future<String>> futures = e.invokeAll(l);
1066 assertEquals(1, futures.size());
1067 try {
1068 futures.get(0).get();
1069 shouldThrow();
1070 } catch (ExecutionException success) {
1071 assertTrue(success.getCause() instanceof NullPointerException);
1072 } finally {
1073 joinPool(e);
1074 }
1075 }
1076
1077 /**
1078 * invokeAll(c) returns results of all completed tasks
1079 */
1080 public void testInvokeAll5() throws Exception {
1081 ExecutorService e = new CustomExecutor(2);
1082 try {
1083 List<Callable<String>> l = new ArrayList<Callable<String>>();
1084 l.add(new StringTask());
1085 l.add(new StringTask());
1086 List<Future<String>> futures = e.invokeAll(l);
1087 assertEquals(2, futures.size());
1088 for (Future<String> future : futures)
1089 assertSame(TEST_STRING, future.get());
1090 } finally {
1091 joinPool(e);
1092 }
1093 }
1094
1095 /**
1096 * timed invokeAny(null) throws NPE
1097 */
1098 public void testTimedInvokeAny1() throws Exception {
1099 ExecutorService e = new CustomExecutor(2);
1100 try {
1101 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
1102 shouldThrow();
1103 } catch (NullPointerException success) {
1104 } finally {
1105 joinPool(e);
1106 }
1107 }
1108
1109 /**
1110 * timed invokeAny(,,null) throws NPE
1111 */
1112 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1113 ExecutorService e = new CustomExecutor(2);
1114 List<Callable<String>> l = new ArrayList<Callable<String>>();
1115 l.add(new StringTask());
1116 try {
1117 e.invokeAny(l, MEDIUM_DELAY_MS, null);
1118 shouldThrow();
1119 } catch (NullPointerException success) {
1120 } finally {
1121 joinPool(e);
1122 }
1123 }
1124
1125 /**
1126 * timed invokeAny(empty collection) throws IAE
1127 */
1128 public void testTimedInvokeAny2() throws Exception {
1129 ExecutorService e = new CustomExecutor(2);
1130 try {
1131 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1132 shouldThrow();
1133 } catch (IllegalArgumentException success) {
1134 } finally {
1135 joinPool(e);
1136 }
1137 }
1138
1139 /**
1140 * timed invokeAny(c) throws NPE if c has null elements
1141 */
1142 public void testTimedInvokeAny3() throws Exception {
1143 CountDownLatch latch = new CountDownLatch(1);
1144 ExecutorService e = new CustomExecutor(2);
1145 List<Callable<String>> l = new ArrayList<Callable<String>>();
1146 l.add(latchAwaitingStringTask(latch));
1147 l.add(null);
1148 try {
1149 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1150 shouldThrow();
1151 } catch (NullPointerException success) {
1152 } finally {
1153 latch.countDown();
1154 joinPool(e);
1155 }
1156 }
1157
1158 /**
1159 * timed invokeAny(c) throws ExecutionException if no task completes
1160 */
1161 public void testTimedInvokeAny4() throws Exception {
1162 ExecutorService e = new CustomExecutor(2);
1163 List<Callable<String>> l = new ArrayList<Callable<String>>();
1164 l.add(new NPETask());
1165 try {
1166 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1167 shouldThrow();
1168 } catch (ExecutionException success) {
1169 assertTrue(success.getCause() instanceof NullPointerException);
1170 } finally {
1171 joinPool(e);
1172 }
1173 }
1174
1175 /**
1176 * timed invokeAny(c) returns result of some task
1177 */
1178 public void testTimedInvokeAny5() throws Exception {
1179 ExecutorService e = new CustomExecutor(2);
1180 try {
1181 List<Callable<String>> l = new ArrayList<Callable<String>>();
1182 l.add(new StringTask());
1183 l.add(new StringTask());
1184 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1185 assertSame(TEST_STRING, result);
1186 } finally {
1187 joinPool(e);
1188 }
1189 }
1190
1191 /**
1192 * timed invokeAll(null) throws NPE
1193 */
1194 public void testTimedInvokeAll1() throws Exception {
1195 ExecutorService e = new CustomExecutor(2);
1196 try {
1197 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
1198 shouldThrow();
1199 } catch (NullPointerException success) {
1200 } finally {
1201 joinPool(e);
1202 }
1203 }
1204
1205 /**
1206 * timed invokeAll(,,null) throws NPE
1207 */
1208 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1209 ExecutorService e = new CustomExecutor(2);
1210 List<Callable<String>> l = new ArrayList<Callable<String>>();
1211 l.add(new StringTask());
1212 try {
1213 e.invokeAll(l, MEDIUM_DELAY_MS, null);
1214 shouldThrow();
1215 } catch (NullPointerException success) {
1216 } finally {
1217 joinPool(e);
1218 }
1219 }
1220
1221 /**
1222 * timed invokeAll(empty collection) returns empty collection
1223 */
1224 public void testTimedInvokeAll2() throws Exception {
1225 ExecutorService e = new CustomExecutor(2);
1226 try {
1227 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1228 assertTrue(r.isEmpty());
1229 } finally {
1230 joinPool(e);
1231 }
1232 }
1233
1234 /**
1235 * timed invokeAll(c) throws NPE if c has null elements
1236 */
1237 public void testTimedInvokeAll3() throws Exception {
1238 ExecutorService e = new CustomExecutor(2);
1239 List<Callable<String>> l = new ArrayList<Callable<String>>();
1240 l.add(new StringTask());
1241 l.add(null);
1242 try {
1243 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1244 shouldThrow();
1245 } catch (NullPointerException success) {
1246 } finally {
1247 joinPool(e);
1248 }
1249 }
1250
1251 /**
1252 * get of element of invokeAll(c) throws exception on failed task
1253 */
1254 public void testTimedInvokeAll4() throws Exception {
1255 ExecutorService e = new CustomExecutor(2);
1256 List<Callable<String>> l = new ArrayList<Callable<String>>();
1257 l.add(new NPETask());
1258 List<Future<String>> futures =
1259 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1260 assertEquals(1, futures.size());
1261 try {
1262 futures.get(0).get();
1263 shouldThrow();
1264 } catch (ExecutionException success) {
1265 assertTrue(success.getCause() instanceof NullPointerException);
1266 } finally {
1267 joinPool(e);
1268 }
1269 }
1270
1271 /**
1272 * timed invokeAll(c) returns results of all completed tasks
1273 */
1274 public void testTimedInvokeAll5() throws Exception {
1275 ExecutorService e = new CustomExecutor(2);
1276 try {
1277 List<Callable<String>> l = new ArrayList<Callable<String>>();
1278 l.add(new StringTask());
1279 l.add(new StringTask());
1280 List<Future<String>> futures =
1281 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1282 assertEquals(2, futures.size());
1283 for (Future<String> future : futures)
1284 assertSame(TEST_STRING, future.get());
1285 } finally {
1286 joinPool(e);
1287 }
1288 }
1289
1290 /**
1291 * timed invokeAll(c) cancels tasks not completed by timeout
1292 */
1293 public void testTimedInvokeAll6() throws Exception {
1294 ExecutorService e = new CustomExecutor(2);
1295 try {
1296 for (long timeout = timeoutMillis();;) {
1297 List<Callable<String>> tasks = new ArrayList<>();
1298 tasks.add(new StringTask("0"));
1299 tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1300 tasks.add(new StringTask("2"));
1301 long startTime = System.nanoTime();
1302 List<Future<String>> futures =
1303 e.invokeAll(tasks, timeout, MILLISECONDS);
1304 assertEquals(tasks.size(), futures.size());
1305 assertTrue(millisElapsedSince(startTime) >= timeout);
1306 for (Future future : futures)
1307 assertTrue(future.isDone());
1308 assertTrue(futures.get(1).isCancelled());
1309 try {
1310 assertEquals("0", futures.get(0).get());
1311 assertEquals("2", futures.get(2).get());
1312 break;
1313 } catch (CancellationException retryWithLongerTimeout) {
1314 timeout *= 2;
1315 if (timeout >= LONG_DELAY_MS / 2)
1316 fail("expected exactly one task to be cancelled");
1317 }
1318 }
1319 } finally {
1320 joinPool(e);
1321 }
1322 }
1323
1324 }