blob: 194dd58d0fafc632bfe1c349fb77acd48e166223 [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
7package jsr166;
8
Calin Juravle8f0d92b2013-08-01 17:26:00 +01009import static java.util.concurrent.TimeUnit.MILLISECONDS;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000010import static java.util.concurrent.TimeUnit.NANOSECONDS;
11import static java.util.concurrent.TimeUnit.SECONDS;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010012
13import java.util.ArrayList;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000014import java.util.HashSet;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010015import java.util.List;
16import java.util.concurrent.BlockingQueue;
17import java.util.concurrent.Callable;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000018import java.util.concurrent.CancellationException;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010019import java.util.concurrent.CountDownLatch;
20import java.util.concurrent.Delayed;
21import java.util.concurrent.ExecutionException;
22import java.util.concurrent.Executors;
23import java.util.concurrent.ExecutorService;
24import java.util.concurrent.Future;
25import java.util.concurrent.RejectedExecutionException;
26import java.util.concurrent.RejectedExecutionHandler;
27import java.util.concurrent.RunnableScheduledFuture;
28import java.util.concurrent.ScheduledFuture;
29import java.util.concurrent.ScheduledThreadPoolExecutor;
30import java.util.concurrent.ThreadFactory;
31import java.util.concurrent.ThreadPoolExecutor;
32import java.util.concurrent.TimeoutException;
33import java.util.concurrent.TimeUnit;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000034import java.util.concurrent.atomic.AtomicBoolean;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010035import java.util.concurrent.atomic.AtomicInteger;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000036import java.util.concurrent.atomic.AtomicLong;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010037
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010038import junit.framework.Test;
39import junit.framework.TestSuite;
40
Calin Juravle8f0d92b2013-08-01 17:26:00 +010041public class ScheduledExecutorSubclassTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010042 // android-note: Removed because the CTS runner does a bad job of
43 // retrying tests that have suite() declarations.
44 //
45 // public static void main(String[] args) {
46 // main(suite(), args);
47 // }
48 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000049 // return new TestSuite(ScheduledExecutorSubclassTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010050 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010051
52 static class CustomTask<V> implements RunnableScheduledFuture<V> {
53 RunnableScheduledFuture<V> task;
54 volatile boolean ran;
55 CustomTask(RunnableScheduledFuture<V> t) { task = t; }
56 public boolean isPeriodic() { return task.isPeriodic(); }
57 public void run() {
58 ran = true;
59 task.run();
60 }
61 public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
62 public int compareTo(Delayed t) {
63 return task.compareTo(((CustomTask)t).task);
64 }
65 public boolean cancel(boolean mayInterruptIfRunning) {
66 return task.cancel(mayInterruptIfRunning);
67 }
68 public boolean isCancelled() { return task.isCancelled(); }
69 public boolean isDone() { return task.isDone(); }
70 public V get() throws InterruptedException, ExecutionException {
71 V v = task.get();
72 assertTrue(ran);
73 return v;
74 }
75 public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
76 V v = task.get(time, unit);
77 assertTrue(ran);
78 return v;
79 }
80 }
81
82 public class CustomExecutor extends ScheduledThreadPoolExecutor {
83
84 protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
85 return new CustomTask<V>(task);
86 }
87
88 protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
89 return new CustomTask<V>(task);
90 }
91 CustomExecutor(int corePoolSize) { super(corePoolSize); }
92 CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
93 super(corePoolSize, handler);
94 }
95
96 CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
97 super(corePoolSize, threadFactory);
98 }
99 CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
100 RejectedExecutionHandler handler) {
101 super(corePoolSize, threadFactory, handler);
102 }
103
104 }
105
106 /**
107 * execute successfully executes a runnable
108 */
109 public void testExecute() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000110 final CustomExecutor p = new CustomExecutor(1);
111 try (PoolCleaner cleaner = cleaner(p)) {
112 final CountDownLatch done = new CountDownLatch(1);
113 final Runnable task = new CheckedRunnable() {
114 public void realRun() { done.countDown(); }};
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100115 p.execute(task);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000116 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100117 }
118 }
119
120 /**
121 * delayed schedule of callable successfully executes after delay
122 */
123 public void testSchedule1() throws Exception {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100124 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000125 final CustomExecutor p = new CustomExecutor(1);
126 try (PoolCleaner cleaner = cleaner(p, done)) {
127 final long startTime = System.nanoTime();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100128 Callable task = new CheckedCallable<Boolean>() {
129 public Boolean realCall() {
130 done.countDown();
131 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
132 return Boolean.TRUE;
133 }};
134 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
135 assertSame(Boolean.TRUE, f.get());
136 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100137 }
138 }
139
140 /**
141 * delayed schedule of runnable successfully executes after delay
142 */
143 public void testSchedule3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000144 final CustomExecutor p = new CustomExecutor(1);
145 try (PoolCleaner cleaner = cleaner(p)) {
146 final long startTime = System.nanoTime();
147 final CountDownLatch done = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100148 Runnable task = new CheckedRunnable() {
149 public void realRun() {
150 done.countDown();
151 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
152 }};
153 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
154 await(done);
155 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
156 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100157 }
158 }
159
160 /**
161 * scheduleAtFixedRate executes runnable after given initial delay
162 */
163 public void testSchedule4() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000164 final CustomExecutor p = new CustomExecutor(1);
165 try (PoolCleaner cleaner = cleaner(p)) {
166 final long startTime = System.nanoTime();
167 final CountDownLatch done = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100168 Runnable task = new CheckedRunnable() {
169 public void realRun() {
170 done.countDown();
171 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
172 }};
173 ScheduledFuture f =
174 p.scheduleAtFixedRate(task, timeoutMillis(),
175 LONG_DELAY_MS, MILLISECONDS);
176 await(done);
177 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
178 f.cancel(true);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100179 }
180 }
181
182 /**
183 * scheduleWithFixedDelay executes runnable after given initial delay
184 */
185 public void testSchedule5() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000186 final CustomExecutor p = new CustomExecutor(1);
187 try (PoolCleaner cleaner = cleaner(p)) {
188 final long startTime = System.nanoTime();
189 final CountDownLatch done = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100190 Runnable task = new CheckedRunnable() {
191 public void realRun() {
192 done.countDown();
193 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
194 }};
195 ScheduledFuture f =
196 p.scheduleWithFixedDelay(task, timeoutMillis(),
197 LONG_DELAY_MS, MILLISECONDS);
198 await(done);
199 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
200 f.cancel(true);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100201 }
202 }
203
204 static class RunnableCounter implements Runnable {
205 AtomicInteger count = new AtomicInteger(0);
206 public void run() { count.getAndIncrement(); }
207 }
208
209 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000210 * scheduleAtFixedRate executes series of tasks at given rate.
211 * Eventually, it must hold that:
212 * cycles - 1 <= elapsedMillis/delay < cycles
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100213 */
214 public void testFixedRateSequence() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000215 final CustomExecutor p = new CustomExecutor(1);
216 try (PoolCleaner cleaner = cleaner(p)) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100217 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000218 final long startTime = System.nanoTime();
219 final int cycles = 8;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100220 final CountDownLatch done = new CountDownLatch(cycles);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000221 final Runnable task = new CheckedRunnable() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100222 public void realRun() { done.countDown(); }};
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000223 final ScheduledFuture periodicTask =
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100224 p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000225 final int totalDelayMillis = (cycles - 1) * delay;
226 await(done, totalDelayMillis + LONG_DELAY_MS);
227 periodicTask.cancel(true);
228 final long elapsedMillis = millisElapsedSince(startTime);
229 assertTrue(elapsedMillis >= totalDelayMillis);
230 if (elapsedMillis <= cycles * delay)
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100231 return;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000232 // else retry with longer delay
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100233 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000234 fail("unexpected execution rate");
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100235 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100236 }
237
238 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000239 * scheduleWithFixedDelay executes series of tasks with given period.
240 * Eventually, it must hold that each task starts at least delay and at
241 * most 2 * delay after the termination of the previous task.
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100242 */
243 public void testFixedDelaySequence() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000244 final CustomExecutor p = new CustomExecutor(1);
245 try (PoolCleaner cleaner = cleaner(p)) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100246 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000247 final long startTime = System.nanoTime();
248 final AtomicLong previous = new AtomicLong(startTime);
249 final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
250 final int cycles = 8;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100251 final CountDownLatch done = new CountDownLatch(cycles);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000252 final int d = delay;
253 final Runnable task = new CheckedRunnable() {
254 public void realRun() {
255 long now = System.nanoTime();
256 long elapsedMillis
257 = NANOSECONDS.toMillis(now - previous.get());
258 if (done.getCount() == cycles) { // first execution
259 if (elapsedMillis >= d)
260 tryLongerDelay.set(true);
261 } else {
262 assertTrue(elapsedMillis >= d);
263 if (elapsedMillis >= 2 * d)
264 tryLongerDelay.set(true);
265 }
266 previous.set(now);
267 done.countDown();
268 }};
269 final ScheduledFuture periodicTask =
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100270 p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000271 final int totalDelayMillis = (cycles - 1) * delay;
272 await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
273 periodicTask.cancel(true);
274 final long elapsedMillis = millisElapsedSince(startTime);
275 assertTrue(elapsedMillis >= totalDelayMillis);
276 if (!tryLongerDelay.get())
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100277 return;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000278 // else retry with longer delay
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100279 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000280 fail("unexpected execution rate");
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100281 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100282 }
283
284 /**
285 * execute(null) throws NPE
286 */
287 public void testExecuteNull() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000288 final CustomExecutor p = new CustomExecutor(1);
289 try (PoolCleaner cleaner = cleaner(p)) {
290 try {
291 p.execute(null);
292 shouldThrow();
293 } catch (NullPointerException success) {}
294 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100295 }
296
297 /**
298 * schedule(null) throws NPE
299 */
300 public void testScheduleNull() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000301 final CustomExecutor p = new CustomExecutor(1);
302 try (PoolCleaner cleaner = cleaner(p)) {
303 try {
304 TrackedCallable callable = null;
305 Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
306 shouldThrow();
307 } catch (NullPointerException success) {}
308 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100309 }
310
311 /**
312 * execute throws RejectedExecutionException if shutdown
313 */
314 public void testSchedule1_RejectedExecutionException() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000315 final CustomExecutor p = new CustomExecutor(1);
316 try (PoolCleaner cleaner = cleaner(p)) {
317 try {
318 p.shutdown();
319 p.schedule(new NoOpRunnable(),
320 MEDIUM_DELAY_MS, MILLISECONDS);
321 shouldThrow();
322 } catch (RejectedExecutionException success) {
323 } catch (SecurityException ok) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100324 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100325 }
326
327 /**
328 * schedule throws RejectedExecutionException if shutdown
329 */
330 public void testSchedule2_RejectedExecutionException() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000331 final CustomExecutor p = new CustomExecutor(1);
332 try (PoolCleaner cleaner = cleaner(p)) {
333 try {
334 p.shutdown();
335 p.schedule(new NoOpCallable(),
336 MEDIUM_DELAY_MS, MILLISECONDS);
337 shouldThrow();
338 } catch (RejectedExecutionException success) {
339 } catch (SecurityException ok) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100340 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100341 }
342
343 /**
344 * schedule callable throws RejectedExecutionException if shutdown
345 */
346 public void testSchedule3_RejectedExecutionException() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000347 final CustomExecutor p = new CustomExecutor(1);
348 try (PoolCleaner cleaner = cleaner(p)) {
349 try {
350 p.shutdown();
351 p.schedule(new NoOpCallable(),
352 MEDIUM_DELAY_MS, MILLISECONDS);
353 shouldThrow();
354 } catch (RejectedExecutionException success) {
355 } catch (SecurityException ok) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100356 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100357 }
358
359 /**
360 * scheduleAtFixedRate throws RejectedExecutionException if shutdown
361 */
362 public void testScheduleAtFixedRate1_RejectedExecutionException() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000363 final CustomExecutor p = new CustomExecutor(1);
364 try (PoolCleaner cleaner = cleaner(p)) {
365 try {
366 p.shutdown();
367 p.scheduleAtFixedRate(new NoOpRunnable(),
368 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
369 shouldThrow();
370 } catch (RejectedExecutionException success) {
371 } catch (SecurityException ok) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100372 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100373 }
374
375 /**
376 * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
377 */
378 public void testScheduleWithFixedDelay1_RejectedExecutionException() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000379 final CustomExecutor p = new CustomExecutor(1);
380 try (PoolCleaner cleaner = cleaner(p)) {
381 try {
382 p.shutdown();
383 p.scheduleWithFixedDelay(new NoOpRunnable(),
384 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
385 shouldThrow();
386 } catch (RejectedExecutionException success) {
387 } catch (SecurityException ok) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100388 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100389 }
390
391 /**
392 * getActiveCount increases but doesn't overestimate, when a
393 * thread becomes active
394 */
395 public void testGetActiveCount() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000396 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000397 final ThreadPoolExecutor p = new CustomExecutor(2);
398 try (PoolCleaner cleaner = cleaner(p, done)) {
399 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100400 assertEquals(0, p.getActiveCount());
401 p.execute(new CheckedRunnable() {
402 public void realRun() throws InterruptedException {
403 threadStarted.countDown();
404 assertEquals(1, p.getActiveCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000405 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100406 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000407 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100408 assertEquals(1, p.getActiveCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100409 }
410 }
411
412 /**
413 * getCompletedTaskCount increases, but doesn't overestimate,
414 * when tasks complete
415 */
416 public void testGetCompletedTaskCount() throws InterruptedException {
417 final ThreadPoolExecutor p = new CustomExecutor(2);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000418 try (PoolCleaner cleaner = cleaner(p)) {
419 final CountDownLatch threadStarted = new CountDownLatch(1);
420 final CountDownLatch threadProceed = new CountDownLatch(1);
421 final CountDownLatch threadDone = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100422 assertEquals(0, p.getCompletedTaskCount());
423 p.execute(new CheckedRunnable() {
424 public void realRun() throws InterruptedException {
425 threadStarted.countDown();
426 assertEquals(0, p.getCompletedTaskCount());
427 threadProceed.await();
428 threadDone.countDown();
429 }});
430 await(threadStarted);
431 assertEquals(0, p.getCompletedTaskCount());
432 threadProceed.countDown();
433 threadDone.await();
434 long startTime = System.nanoTime();
435 while (p.getCompletedTaskCount() != 1) {
436 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
437 fail("timed out");
438 Thread.yield();
439 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100440 }
441 }
442
443 /**
444 * getCorePoolSize returns size given in constructor if not otherwise set
445 */
446 public void testGetCorePoolSize() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000447 final CustomExecutor p = new CustomExecutor(1);
448 try (PoolCleaner cleaner = cleaner(p)) {
449 assertEquals(1, p.getCorePoolSize());
450 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100451 }
452
453 /**
454 * getLargestPoolSize increases, but doesn't overestimate, when
455 * multiple threads active
456 */
457 public void testGetLargestPoolSize() throws InterruptedException {
458 final int THREADS = 3;
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000459 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000460 final ThreadPoolExecutor p = new CustomExecutor(THREADS);
461 try (PoolCleaner cleaner = cleaner(p, done)) {
462 final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100463 assertEquals(0, p.getLargestPoolSize());
464 for (int i = 0; i < THREADS; i++)
465 p.execute(new CheckedRunnable() {
466 public void realRun() throws InterruptedException {
467 threadsStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000468 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100469 assertEquals(THREADS, p.getLargestPoolSize());
470 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000471 await(threadsStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100472 assertEquals(THREADS, p.getLargestPoolSize());
473 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000474 assertEquals(THREADS, p.getLargestPoolSize());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100475 }
476
477 /**
478 * getPoolSize increases, but doesn't overestimate, when threads
479 * become active
480 */
481 public void testGetPoolSize() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000482 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000483 final ThreadPoolExecutor p = new CustomExecutor(1);
484 try (PoolCleaner cleaner = cleaner(p, done)) {
485 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100486 assertEquals(0, p.getPoolSize());
487 p.execute(new CheckedRunnable() {
488 public void realRun() throws InterruptedException {
489 threadStarted.countDown();
490 assertEquals(1, p.getPoolSize());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000491 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100492 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000493 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100494 assertEquals(1, p.getPoolSize());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100495 }
496 }
497
498 /**
499 * getTaskCount increases, but doesn't overestimate, when tasks
500 * submitted
501 */
502 public void testGetTaskCount() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000503 final int TASKS = 3;
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000504 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000505 final ThreadPoolExecutor p = new CustomExecutor(1);
506 try (PoolCleaner cleaner = cleaner(p, done)) {
507 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100508 assertEquals(0, p.getTaskCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000509 assertEquals(0, p.getCompletedTaskCount());
510 p.execute(new CheckedRunnable() {
511 public void realRun() throws InterruptedException {
512 threadStarted.countDown();
513 await(done);
514 }});
515 await(threadStarted);
516 assertEquals(1, p.getTaskCount());
517 assertEquals(0, p.getCompletedTaskCount());
518 for (int i = 0; i < TASKS; i++) {
519 assertEquals(1 + i, p.getTaskCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100520 p.execute(new CheckedRunnable() {
521 public void realRun() throws InterruptedException {
522 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000523 assertEquals(1 + TASKS, p.getTaskCount());
524 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100525 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000526 }
527 assertEquals(1 + TASKS, p.getTaskCount());
528 assertEquals(0, p.getCompletedTaskCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100529 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000530 assertEquals(1 + TASKS, p.getTaskCount());
531 assertEquals(1 + TASKS, p.getCompletedTaskCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100532 }
533
534 /**
535 * getThreadFactory returns factory in constructor if not set
536 */
537 public void testGetThreadFactory() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000538 final ThreadFactory threadFactory = new SimpleThreadFactory();
539 final CustomExecutor p = new CustomExecutor(1, threadFactory);
540 try (PoolCleaner cleaner = cleaner(p)) {
541 assertSame(threadFactory, p.getThreadFactory());
542 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100543 }
544
545 /**
546 * setThreadFactory sets the thread factory returned by getThreadFactory
547 */
548 public void testSetThreadFactory() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000549 final ThreadFactory threadFactory = new SimpleThreadFactory();
550 final CustomExecutor p = new CustomExecutor(1);
551 try (PoolCleaner cleaner = cleaner(p)) {
552 p.setThreadFactory(threadFactory);
553 assertSame(threadFactory, p.getThreadFactory());
554 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100555 }
556
557 /**
558 * setThreadFactory(null) throws NPE
559 */
560 public void testSetThreadFactoryNull() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000561 final CustomExecutor p = new CustomExecutor(1);
562 try (PoolCleaner cleaner = cleaner(p)) {
563 try {
564 p.setThreadFactory(null);
565 shouldThrow();
566 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100567 }
568 }
569
570 /**
571 * isShutdown is false before shutdown, true after
572 */
573 public void testIsShutdown() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000574 final CustomExecutor p = new CustomExecutor(1);
575 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100576 assertFalse(p.isShutdown());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000577 try { p.shutdown(); } catch (SecurityException ok) { return; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000578 assertTrue(p.isShutdown());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000579 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100580 }
581
582 /**
583 * isTerminated is false before termination, true after
584 */
585 public void testIsTerminated() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000586 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000587 final ThreadPoolExecutor p = new CustomExecutor(1);
588 try (PoolCleaner cleaner = cleaner(p)) {
589 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100590 p.execute(new CheckedRunnable() {
591 public void realRun() throws InterruptedException {
592 assertFalse(p.isTerminated());
593 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000594 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100595 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000596 await(threadStarted);
597 assertFalse(p.isTerminated());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100598 assertFalse(p.isTerminating());
599 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100600 try { p.shutdown(); } catch (SecurityException ok) { return; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000601 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
602 assertTrue(p.isTerminated());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100603 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100604 }
605
606 /**
607 * isTerminating is not true when running or when terminated
608 */
609 public void testIsTerminating() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000610 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000611 final ThreadPoolExecutor p = new CustomExecutor(1);
612 try (PoolCleaner cleaner = cleaner(p)) {
613 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100614 assertFalse(p.isTerminating());
615 p.execute(new CheckedRunnable() {
616 public void realRun() throws InterruptedException {
617 assertFalse(p.isTerminating());
618 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000619 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100620 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000621 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100622 assertFalse(p.isTerminating());
623 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100624 try { p.shutdown(); } catch (SecurityException ok) { return; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000625 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
626 assertTrue(p.isTerminated());
627 assertFalse(p.isTerminating());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100628 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100629 }
630
631 /**
632 * getQueue returns the work queue, which contains queued tasks
633 */
634 public void testGetQueue() throws InterruptedException {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100635 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000636 final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
637 try (PoolCleaner cleaner = cleaner(p, done)) {
638 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100639 ScheduledFuture[] tasks = new ScheduledFuture[5];
640 for (int i = 0; i < tasks.length; i++) {
641 Runnable r = new CheckedRunnable() {
642 public void realRun() throws InterruptedException {
643 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000644 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100645 }};
646 tasks[i] = p.schedule(r, 1, MILLISECONDS);
647 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000648 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100649 BlockingQueue<Runnable> q = p.getQueue();
650 assertTrue(q.contains(tasks[tasks.length - 1]));
651 assertFalse(q.contains(tasks[0]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100652 }
653 }
654
655 /**
656 * remove(task) removes queued task, and fails to remove active task
657 */
658 public void testRemove() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000659 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000660 final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
661 try (PoolCleaner cleaner = cleaner(p, done)) {
662 ScheduledFuture[] tasks = new ScheduledFuture[5];
663 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100664 for (int i = 0; i < tasks.length; i++) {
665 Runnable r = new CheckedRunnable() {
666 public void realRun() throws InterruptedException {
667 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000668 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100669 }};
670 tasks[i] = p.schedule(r, 1, MILLISECONDS);
671 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000672 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100673 BlockingQueue<Runnable> q = p.getQueue();
674 assertFalse(p.remove((Runnable)tasks[0]));
675 assertTrue(q.contains((Runnable)tasks[4]));
676 assertTrue(q.contains((Runnable)tasks[3]));
677 assertTrue(p.remove((Runnable)tasks[4]));
678 assertFalse(p.remove((Runnable)tasks[4]));
679 assertFalse(q.contains((Runnable)tasks[4]));
680 assertTrue(q.contains((Runnable)tasks[3]));
681 assertTrue(p.remove((Runnable)tasks[3]));
682 assertFalse(q.contains((Runnable)tasks[3]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100683 }
684 }
685
686 /**
687 * purge removes cancelled tasks from the queue
688 */
689 public void testPurge() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000690 final ScheduledFuture[] tasks = new ScheduledFuture[5];
691 final Runnable releaser = new Runnable() { public void run() {
692 for (ScheduledFuture task : tasks)
693 if (task != null) task.cancel(true); }};
694 final CustomExecutor p = new CustomExecutor(1);
695 try (PoolCleaner cleaner = cleaner(p, releaser)) {
696 for (int i = 0; i < tasks.length; i++)
697 tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
698 LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100699 int max = tasks.length;
700 if (tasks[4].cancel(true)) --max;
701 if (tasks[3].cancel(true)) --max;
702 // There must eventually be an interference-free point at
703 // which purge will not fail. (At worst, when queue is empty.)
704 long startTime = System.nanoTime();
705 do {
706 p.purge();
707 long count = p.getTaskCount();
708 if (count == max)
709 return;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000710 } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100711 fail("Purge failed to remove cancelled tasks");
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100712 }
713 }
714
715 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000716 * shutdownNow returns a list containing tasks that were not run,
717 * and those tasks are drained from the queue
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100718 */
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000719 public void testShutdownNow() throws InterruptedException {
720 final int poolSize = 2;
721 final int count = 5;
722 final AtomicInteger ran = new AtomicInteger(0);
723 final CustomExecutor p = new CustomExecutor(poolSize);
724 final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
725 Runnable waiter = new CheckedRunnable() { public void realRun() {
726 threadsStarted.countDown();
727 try {
728 MILLISECONDS.sleep(2 * LONG_DELAY_MS);
729 } catch (InterruptedException success) {}
730 ran.getAndIncrement();
731 }};
732 for (int i = 0; i < count; i++)
733 p.execute(waiter);
734 await(threadsStarted);
735 assertEquals(poolSize, p.getActiveCount());
736 assertEquals(0, p.getCompletedTaskCount());
737 final List<Runnable> queuedTasks;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100738 try {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000739 queuedTasks = p.shutdownNow();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100740 } catch (SecurityException ok) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000741 return; // Allowed in case test doesn't have privs
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100742 }
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000743 assertTrue(p.isShutdown());
744 assertTrue(p.getQueue().isEmpty());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000745 assertEquals(count - poolSize, queuedTasks.size());
746 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
747 assertTrue(p.isTerminated());
748 assertEquals(poolSize, ran.get());
749 assertEquals(poolSize, p.getCompletedTaskCount());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000750 }
751
752 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000753 * shutdownNow returns a list containing tasks that were not run,
754 * and those tasks are drained from the queue
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000755 */
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000756 public void testShutdownNow_delayedTasks() throws InterruptedException {
757 final CustomExecutor p = new CustomExecutor(1);
758 List<ScheduledFuture> tasks = new ArrayList<>();
759 for (int i = 0; i < 3; i++) {
760 Runnable r = new NoOpRunnable();
761 tasks.add(p.schedule(r, 9, SECONDS));
762 tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
763 tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
764 }
765 if (testImplementationDetails)
766 assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
767 final List<Runnable> queuedTasks;
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000768 try {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000769 queuedTasks = p.shutdownNow();
770 } catch (SecurityException ok) {
771 return; // Allowed in case test doesn't have privs
772 }
773 assertTrue(p.isShutdown());
774 assertTrue(p.getQueue().isEmpty());
775 if (testImplementationDetails)
776 assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
777 assertEquals(tasks.size(), queuedTasks.size());
778 for (ScheduledFuture task : tasks) {
779 assertFalse(((CustomTask)task).ran);
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000780 assertFalse(task.isDone());
781 assertFalse(task.isCancelled());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000782 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000783 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
784 assertTrue(p.isTerminated());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000785 }
Przemyslaw Szczepaniak5328e072016-03-11 15:59:10 +0000786
787 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000788 * By default, periodic tasks are cancelled at shutdown.
789 * By default, delayed tasks keep running after shutdown.
790 * Check that changing the default values work:
791 * - setExecuteExistingDelayedTasksAfterShutdownPolicy
792 * - setContinueExistingPeriodicTasksAfterShutdownPolicy
793 */
794 public void testShutdown_cancellation() throws Exception {
795 Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
796 for (Boolean policy : allBooleans)
797 {
798 final int poolSize = 2;
799 final CustomExecutor p = new CustomExecutor(poolSize);
800 final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
801 final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
802 final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
803 if (policy != null) {
804 p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
805 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
806 p.setRemoveOnCancelPolicy(policy);
807 }
808 assertEquals(effectiveDelayedPolicy,
809 p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
810 assertEquals(effectivePeriodicPolicy,
811 p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
812 assertEquals(effectiveRemovePolicy,
813 p.getRemoveOnCancelPolicy());
814 // Strategy: Wedge the pool with poolSize "blocker" threads
815 final AtomicInteger ran = new AtomicInteger(0);
816 final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
817 final CountDownLatch unblock = new CountDownLatch(1);
818 final CountDownLatch periodicLatch1 = new CountDownLatch(2);
819 final CountDownLatch periodicLatch2 = new CountDownLatch(2);
820 Runnable task = new CheckedRunnable() { public void realRun()
821 throws InterruptedException {
822 poolBlocked.countDown();
823 assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
824 ran.getAndIncrement();
825 }};
826 List<Future<?>> blockers = new ArrayList<>();
827 List<Future<?>> periodics = new ArrayList<>();
828 List<Future<?>> delayeds = new ArrayList<>();
829 for (int i = 0; i < poolSize; i++)
830 blockers.add(p.submit(task));
831 assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
832
833 periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
834 1, 1, MILLISECONDS));
835 periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
836 1, 1, MILLISECONDS));
837 delayeds.add(p.schedule(task, 1, MILLISECONDS));
838
839 assertTrue(p.getQueue().containsAll(periodics));
840 assertTrue(p.getQueue().containsAll(delayeds));
841 try { p.shutdown(); } catch (SecurityException ok) { return; }
842 assertTrue(p.isShutdown());
843 assertFalse(p.isTerminated());
844 for (Future<?> periodic : periodics) {
845 assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
846 assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
847 }
848 for (Future<?> delayed : delayeds) {
849 assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
850 assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
851 }
852 if (testImplementationDetails) {
853 assertEquals(effectivePeriodicPolicy,
854 p.getQueue().containsAll(periodics));
855 assertEquals(effectiveDelayedPolicy,
856 p.getQueue().containsAll(delayeds));
857 }
858 // Release all pool threads
859 unblock.countDown();
860
861 for (Future<?> delayed : delayeds) {
862 if (effectiveDelayedPolicy) {
863 assertNull(delayed.get());
864 }
865 }
866 if (effectivePeriodicPolicy) {
867 assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
868 assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
869 for (Future<?> periodic : periodics) {
870 assertTrue(periodic.cancel(false));
871 assertTrue(periodic.isCancelled());
872 assertTrue(periodic.isDone());
873 }
874 }
875 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
876 assertTrue(p.isTerminated());
877 assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
878 }}
879
880 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100881 * completed submit of callable returns result
882 */
883 public void testSubmitCallable() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000884 final ExecutorService e = new CustomExecutor(2);
885 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100886 Future<String> future = e.submit(new StringTask());
887 String result = future.get();
888 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100889 }
890 }
891
892 /**
893 * completed submit of runnable returns successfully
894 */
895 public void testSubmitRunnable() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000896 final ExecutorService e = new CustomExecutor(2);
897 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100898 Future<?> future = e.submit(new NoOpRunnable());
899 future.get();
900 assertTrue(future.isDone());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100901 }
902 }
903
904 /**
905 * completed submit of (runnable, result) returns result
906 */
907 public void testSubmitRunnable2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000908 final ExecutorService e = new CustomExecutor(2);
909 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100910 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
911 String result = future.get();
912 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100913 }
914 }
915
916 /**
917 * invokeAny(null) throws NPE
918 */
919 public void testInvokeAny1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000920 final ExecutorService e = new CustomExecutor(2);
921 try (PoolCleaner cleaner = cleaner(e)) {
922 try {
923 e.invokeAny(null);
924 shouldThrow();
925 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100926 }
927 }
928
929 /**
930 * invokeAny(empty collection) throws IAE
931 */
932 public void testInvokeAny2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000933 final ExecutorService e = new CustomExecutor(2);
934 try (PoolCleaner cleaner = cleaner(e)) {
935 try {
936 e.invokeAny(new ArrayList<Callable<String>>());
937 shouldThrow();
938 } catch (IllegalArgumentException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100939 }
940 }
941
942 /**
943 * invokeAny(c) throws NPE if c has null elements
944 */
945 public void testInvokeAny3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000946 final CountDownLatch latch = new CountDownLatch(1);
947 final ExecutorService e = new CustomExecutor(2);
948 try (PoolCleaner cleaner = cleaner(e)) {
949 List<Callable<String>> l = new ArrayList<Callable<String>>();
950 l.add(latchAwaitingStringTask(latch));
951 l.add(null);
952 try {
953 e.invokeAny(l);
954 shouldThrow();
955 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100956 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100957 }
958 }
959
960 /**
961 * invokeAny(c) throws ExecutionException if no task completes
962 */
963 public void testInvokeAny4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000964 final ExecutorService e = new CustomExecutor(2);
965 try (PoolCleaner cleaner = cleaner(e)) {
966 List<Callable<String>> l = new ArrayList<Callable<String>>();
967 l.add(new NPETask());
968 try {
969 e.invokeAny(l);
970 shouldThrow();
971 } catch (ExecutionException success) {
972 assertTrue(success.getCause() instanceof NullPointerException);
973 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100974 }
975 }
976
977 /**
978 * invokeAny(c) returns result of some task
979 */
980 public void testInvokeAny5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000981 final ExecutorService e = new CustomExecutor(2);
982 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100983 List<Callable<String>> l = new ArrayList<Callable<String>>();
984 l.add(new StringTask());
985 l.add(new StringTask());
986 String result = e.invokeAny(l);
987 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100988 }
989 }
990
991 /**
992 * invokeAll(null) throws NPE
993 */
994 public void testInvokeAll1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000995 final ExecutorService e = new CustomExecutor(2);
996 try (PoolCleaner cleaner = cleaner(e)) {
997 try {
998 e.invokeAll(null);
999 shouldThrow();
1000 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001001 }
1002 }
1003
1004 /**
1005 * invokeAll(empty collection) returns empty collection
1006 */
1007 public void testInvokeAll2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001008 final ExecutorService e = new CustomExecutor(2);
1009 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001010 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
1011 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001012 }
1013 }
1014
1015 /**
1016 * invokeAll(c) throws NPE if c has null elements
1017 */
1018 public void testInvokeAll3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001019 final ExecutorService e = new CustomExecutor(2);
1020 try (PoolCleaner cleaner = cleaner(e)) {
1021 List<Callable<String>> l = new ArrayList<Callable<String>>();
1022 l.add(new StringTask());
1023 l.add(null);
1024 try {
1025 e.invokeAll(l);
1026 shouldThrow();
1027 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001028 }
1029 }
1030
1031 /**
1032 * get of invokeAll(c) throws exception on failed task
1033 */
1034 public void testInvokeAll4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001035 final ExecutorService e = new CustomExecutor(2);
1036 try (PoolCleaner cleaner = cleaner(e)) {
1037 List<Callable<String>> l = new ArrayList<Callable<String>>();
1038 l.add(new NPETask());
1039 List<Future<String>> futures = e.invokeAll(l);
1040 assertEquals(1, futures.size());
1041 try {
1042 futures.get(0).get();
1043 shouldThrow();
1044 } catch (ExecutionException success) {
1045 assertTrue(success.getCause() instanceof NullPointerException);
1046 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001047 }
1048 }
1049
1050 /**
1051 * invokeAll(c) returns results of all completed tasks
1052 */
1053 public void testInvokeAll5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001054 final ExecutorService e = new CustomExecutor(2);
1055 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001056 List<Callable<String>> l = new ArrayList<Callable<String>>();
1057 l.add(new StringTask());
1058 l.add(new StringTask());
1059 List<Future<String>> futures = e.invokeAll(l);
1060 assertEquals(2, futures.size());
1061 for (Future<String> future : futures)
1062 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001063 }
1064 }
1065
1066 /**
1067 * timed invokeAny(null) throws NPE
1068 */
1069 public void testTimedInvokeAny1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001070 final ExecutorService e = new CustomExecutor(2);
1071 try (PoolCleaner cleaner = cleaner(e)) {
1072 try {
1073 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
1074 shouldThrow();
1075 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001076 }
1077 }
1078
1079 /**
1080 * timed invokeAny(,,null) throws NPE
1081 */
1082 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001083 final ExecutorService e = new CustomExecutor(2);
1084 try (PoolCleaner cleaner = cleaner(e)) {
1085 List<Callable<String>> l = new ArrayList<Callable<String>>();
1086 l.add(new StringTask());
1087 try {
1088 e.invokeAny(l, MEDIUM_DELAY_MS, null);
1089 shouldThrow();
1090 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001091 }
1092 }
1093
1094 /**
1095 * timed invokeAny(empty collection) throws IAE
1096 */
1097 public void testTimedInvokeAny2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001098 final ExecutorService e = new CustomExecutor(2);
1099 try (PoolCleaner cleaner = cleaner(e)) {
1100 try {
1101 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1102 shouldThrow();
1103 } catch (IllegalArgumentException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001104 }
1105 }
1106
1107 /**
1108 * timed invokeAny(c) throws NPE if c has null elements
1109 */
1110 public void testTimedInvokeAny3() throws Exception {
1111 CountDownLatch latch = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001112 final ExecutorService e = new CustomExecutor(2);
1113 try (PoolCleaner cleaner = cleaner(e)) {
1114 List<Callable<String>> l = new ArrayList<Callable<String>>();
1115 l.add(latchAwaitingStringTask(latch));
1116 l.add(null);
1117 try {
1118 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1119 shouldThrow();
1120 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001121 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001122 }
1123 }
1124
1125 /**
1126 * timed invokeAny(c) throws ExecutionException if no task completes
1127 */
1128 public void testTimedInvokeAny4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001129 final ExecutorService e = new CustomExecutor(2);
1130 try (PoolCleaner cleaner = cleaner(e)) {
1131 long startTime = System.nanoTime();
1132 List<Callable<String>> l = new ArrayList<Callable<String>>();
1133 l.add(new NPETask());
1134 try {
1135 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1136 shouldThrow();
1137 } catch (ExecutionException success) {
1138 assertTrue(success.getCause() instanceof NullPointerException);
1139 }
1140 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001141 }
1142 }
1143
1144 /**
1145 * timed invokeAny(c) returns result of some task
1146 */
1147 public void testTimedInvokeAny5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001148 final ExecutorService e = new CustomExecutor(2);
1149 try (PoolCleaner cleaner = cleaner(e)) {
1150 long startTime = System.nanoTime();
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001151 List<Callable<String>> l = new ArrayList<Callable<String>>();
1152 l.add(new StringTask());
1153 l.add(new StringTask());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001154 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001155 assertSame(TEST_STRING, result);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001156 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001157 }
1158 }
1159
1160 /**
1161 * timed invokeAll(null) throws NPE
1162 */
1163 public void testTimedInvokeAll1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001164 final ExecutorService e = new CustomExecutor(2);
1165 try (PoolCleaner cleaner = cleaner(e)) {
1166 try {
1167 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
1168 shouldThrow();
1169 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001170 }
1171 }
1172
1173 /**
1174 * timed invokeAll(,,null) throws NPE
1175 */
1176 public void testTimedInvokeAllNullTimeUnit() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001177 final ExecutorService e = new CustomExecutor(2);
1178 try (PoolCleaner cleaner = cleaner(e)) {
1179 List<Callable<String>> l = new ArrayList<Callable<String>>();
1180 l.add(new StringTask());
1181 try {
1182 e.invokeAll(l, MEDIUM_DELAY_MS, null);
1183 shouldThrow();
1184 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001185 }
1186 }
1187
1188 /**
1189 * timed invokeAll(empty collection) returns empty collection
1190 */
1191 public void testTimedInvokeAll2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001192 final ExecutorService e = new CustomExecutor(2);
1193 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001194 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1195 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001196 }
1197 }
1198
1199 /**
1200 * timed invokeAll(c) throws NPE if c has null elements
1201 */
1202 public void testTimedInvokeAll3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001203 final ExecutorService e = new CustomExecutor(2);
1204 try (PoolCleaner cleaner = cleaner(e)) {
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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001212 }
1213 }
1214
1215 /**
1216 * get of element of invokeAll(c) throws exception on failed task
1217 */
1218 public void testTimedInvokeAll4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001219 final ExecutorService e = new CustomExecutor(2);
1220 try (PoolCleaner cleaner = cleaner(e)) {
1221 List<Callable<String>> l = new ArrayList<Callable<String>>();
1222 l.add(new NPETask());
1223 List<Future<String>> futures =
1224 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1225 assertEquals(1, futures.size());
1226 try {
1227 futures.get(0).get();
1228 shouldThrow();
1229 } catch (ExecutionException success) {
1230 assertTrue(success.getCause() instanceof NullPointerException);
1231 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001232 }
1233 }
1234
1235 /**
1236 * timed invokeAll(c) returns results of all completed tasks
1237 */
1238 public void testTimedInvokeAll5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001239 final ExecutorService e = new CustomExecutor(2);
1240 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001241 List<Callable<String>> l = new ArrayList<Callable<String>>();
1242 l.add(new StringTask());
1243 l.add(new StringTask());
1244 List<Future<String>> futures =
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001245 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001246 assertEquals(2, futures.size());
1247 for (Future<String> future : futures)
1248 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001249 }
1250 }
1251
1252 /**
1253 * timed invokeAll(c) cancels tasks not completed by timeout
1254 */
1255 public void testTimedInvokeAll6() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001256 for (long timeout = timeoutMillis();;) {
1257 final CountDownLatch done = new CountDownLatch(1);
1258 final Callable<String> waiter = new CheckedCallable<String>() {
1259 public String realCall() {
1260 try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1261 catch (InterruptedException ok) {}
1262 return "1"; }};
1263 final ExecutorService p = new CustomExecutor(2);
1264 try (PoolCleaner cleaner = cleaner(p, done)) {
1265 List<Callable<String>> tasks = new ArrayList<>();
1266 tasks.add(new StringTask("0"));
1267 tasks.add(waiter);
1268 tasks.add(new StringTask("2"));
1269 long startTime = System.nanoTime();
1270 List<Future<String>> futures =
1271 p.invokeAll(tasks, timeout, MILLISECONDS);
1272 assertEquals(tasks.size(), futures.size());
1273 assertTrue(millisElapsedSince(startTime) >= timeout);
1274 for (Future future : futures)
1275 assertTrue(future.isDone());
1276 assertTrue(futures.get(1).isCancelled());
1277 try {
1278 assertEquals("0", futures.get(0).get());
1279 assertEquals("2", futures.get(2).get());
1280 break;
1281 } catch (CancellationException retryWithLongerTimeout) {
1282 timeout *= 2;
1283 if (timeout >= LONG_DELAY_MS / 2)
1284 fail("expected exactly one task to be cancelled");
1285 }
1286 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001287 }
1288 }
1289
1290}