ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.39
Committed: Mon Sep 28 02:32:57 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.38: +4 -2 lines
Log Message:
use testImplementationDetails

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