ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.37
Committed: Sun Sep 27 18:50:50 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.36: +3 -1 lines
Log Message:
testShutdownNow: add queue-draining assertions

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