ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.68
Committed: Mon May 29 22:44:27 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.67: +30 -21 lines
Log Message:
more timeout handling rework; remove most uses of MEDIUM_DELAY_MS; randomize timeouts and TimeUnits; write out IAE and ISE

File Contents

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