blob: 44d12b3478d743a4c97ddbb154ef381456e00641 [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 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010011import static java.util.concurrent.TimeUnit.MILLISECONDS;
12import static java.util.concurrent.TimeUnit.NANOSECONDS;
13import static java.util.concurrent.TimeUnit.SECONDS;
14
15import java.util.ArrayList;
16import java.util.List;
17import java.util.NoSuchElementException;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010018import java.util.concurrent.Callable;
19import java.util.concurrent.CancellationException;
20import java.util.concurrent.CountDownLatch;
21import java.util.concurrent.ExecutionException;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010022import java.util.concurrent.Executors;
23import java.util.concurrent.ExecutorService;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010024import java.util.concurrent.Future;
25import java.util.concurrent.FutureTask;
26import java.util.concurrent.TimeoutException;
27import java.util.concurrent.atomic.AtomicInteger;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010028
29import junit.framework.Test;
30import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010031
32public class FutureTaskTest extends JSR166TestCase {
33
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010034 // android-note: Removed because the CTS runner does a bad job of
35 // retrying tests that have suite() declarations.
36 //
37 // public static void main(String[] args) {
38 // main(suite(), args);
39 // }
40 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000041 // return new TestSuite(FutureTaskTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010042 // }
43
Calin Juravle8f0d92b2013-08-01 17:26:00 +010044 void checkIsDone(Future<?> f) {
45 assertTrue(f.isDone());
46 assertFalse(f.cancel(false));
47 assertFalse(f.cancel(true));
48 if (f instanceof PublicFutureTask) {
49 PublicFutureTask pf = (PublicFutureTask) f;
50 assertEquals(1, pf.doneCount());
51 assertFalse(pf.runAndReset());
52 assertEquals(1, pf.doneCount());
53 Object r = null; Object exInfo = null;
54 try {
55 r = f.get();
56 } catch (CancellationException t) {
57 exInfo = CancellationException.class;
58 } catch (ExecutionException t) {
59 exInfo = t.getCause();
60 } catch (Throwable t) {
61 threadUnexpectedException(t);
62 }
63
64 // Check that run and runAndReset have no effect.
65 int savedRunCount = pf.runCount();
66 pf.run();
67 pf.runAndReset();
68 assertEquals(savedRunCount, pf.runCount());
69 try {
70 assertSame(r, f.get());
71 } catch (CancellationException t) {
72 assertSame(exInfo, CancellationException.class);
73 } catch (ExecutionException t) {
74 assertSame(exInfo, t.getCause());
75 } catch (Throwable t) {
76 threadUnexpectedException(t);
77 }
78 assertTrue(f.isDone());
79 }
80 }
81
82 void checkNotDone(Future<?> f) {
83 assertFalse(f.isDone());
84 assertFalse(f.isCancelled());
85 if (f instanceof PublicFutureTask) {
86 PublicFutureTask pf = (PublicFutureTask) f;
87 assertEquals(0, pf.doneCount());
88 assertEquals(0, pf.setCount());
89 assertEquals(0, pf.setExceptionCount());
90 }
91 }
92
93 void checkIsRunning(Future<?> f) {
94 checkNotDone(f);
95 if (f instanceof FutureTask) {
96 FutureTask ft = (FutureTask<?>) f;
97 // Check that run methods do nothing
98 ft.run();
99 if (f instanceof PublicFutureTask) {
100 PublicFutureTask pf = (PublicFutureTask) f;
101 int savedRunCount = pf.runCount();
102 pf.run();
103 assertFalse(pf.runAndReset());
104 assertEquals(savedRunCount, pf.runCount());
105 }
106 checkNotDone(f);
107 }
108 }
109
110 <T> void checkCompletedNormally(Future<T> f, T expected) {
111 checkIsDone(f);
112 assertFalse(f.isCancelled());
113
114 try {
115 assertSame(expected, f.get());
116 } catch (Throwable fail) { threadUnexpectedException(fail); }
117 try {
118 assertSame(expected, f.get(5L, SECONDS));
119 } catch (Throwable fail) { threadUnexpectedException(fail); }
120 }
121
122 void checkCancelled(Future<?> f) {
123 checkIsDone(f);
124 assertTrue(f.isCancelled());
125
126 try {
127 f.get();
128 shouldThrow();
129 } catch (CancellationException success) {
130 } catch (Throwable fail) { threadUnexpectedException(fail); }
131
132 try {
133 f.get(5L, SECONDS);
134 shouldThrow();
135 } catch (CancellationException success) {
136 } catch (Throwable fail) { threadUnexpectedException(fail); }
137 }
138
139 void tryToConfuseDoneTask(PublicFutureTask pf) {
140 pf.set(new Object());
141 pf.setException(new Error());
142 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100143 pf.cancel(mayInterruptIfRunning);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100144 }
145 }
146
147 void checkCompletedAbnormally(Future<?> f, Throwable t) {
148 checkIsDone(f);
149 assertFalse(f.isCancelled());
150
151 try {
152 f.get();
153 shouldThrow();
154 } catch (ExecutionException success) {
155 assertSame(t, success.getCause());
156 } catch (Throwable fail) { threadUnexpectedException(fail); }
157
158 try {
159 f.get(5L, SECONDS);
160 shouldThrow();
161 } catch (ExecutionException success) {
162 assertSame(t, success.getCause());
163 } catch (Throwable fail) { threadUnexpectedException(fail); }
164 }
165
166 /**
167 * Subclass to expose protected methods
168 */
169 static class PublicFutureTask extends FutureTask {
170 private final AtomicInteger runCount;
171 private final AtomicInteger doneCount = new AtomicInteger(0);
172 private final AtomicInteger runAndResetCount = new AtomicInteger(0);
173 private final AtomicInteger setCount = new AtomicInteger(0);
174 private final AtomicInteger setExceptionCount = new AtomicInteger(0);
175 public int runCount() { return runCount.get(); }
176 public int doneCount() { return doneCount.get(); }
177 public int runAndResetCount() { return runAndResetCount.get(); }
178 public int setCount() { return setCount.get(); }
179 public int setExceptionCount() { return setExceptionCount.get(); }
180
181 PublicFutureTask(Runnable runnable) {
182 this(runnable, seven);
183 }
184 PublicFutureTask(Runnable runnable, Object result) {
185 this(runnable, result, new AtomicInteger(0));
186 }
187 private PublicFutureTask(final Runnable runnable, Object result,
188 final AtomicInteger runCount) {
189 super(new Runnable() {
190 public void run() {
191 runCount.getAndIncrement();
192 runnable.run();
193 }}, result);
194 this.runCount = runCount;
195 }
196 PublicFutureTask(Callable callable) {
197 this(callable, new AtomicInteger(0));
198 }
199 private PublicFutureTask(final Callable callable,
200 final AtomicInteger runCount) {
201 super(new Callable() {
202 public Object call() throws Exception {
203 runCount.getAndIncrement();
204 return callable.call();
205 }});
206 this.runCount = runCount;
207 }
208 @Override public void done() {
209 assertTrue(isDone());
210 doneCount.incrementAndGet();
211 super.done();
212 }
213 @Override public boolean runAndReset() {
214 runAndResetCount.incrementAndGet();
215 return super.runAndReset();
216 }
217 @Override public void set(Object x) {
218 setCount.incrementAndGet();
219 super.set(x);
220 }
221 @Override public void setException(Throwable t) {
222 setExceptionCount.incrementAndGet();
223 super.setException(t);
224 }
225 }
226
227 class Counter extends CheckedRunnable {
228 final AtomicInteger count = new AtomicInteger(0);
229 public int get() { return count.get(); }
230 public void realRun() {
231 count.getAndIncrement();
232 }
233 }
234
235 /**
236 * creating a future with a null callable throws NullPointerException
237 */
238 public void testConstructor() {
239 try {
240 new FutureTask(null);
241 shouldThrow();
242 } catch (NullPointerException success) {}
243 }
244
245 /**
246 * creating a future with null runnable throws NullPointerException
247 */
248 public void testConstructor2() {
249 try {
250 new FutureTask(null, Boolean.TRUE);
251 shouldThrow();
252 } catch (NullPointerException success) {}
253 }
254
255 /**
256 * isDone is true when a task completes
257 */
258 public void testIsDone() {
259 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
260 assertFalse(task.isDone());
261 task.run();
262 assertTrue(task.isDone());
263 checkCompletedNormally(task, Boolean.TRUE);
264 assertEquals(1, task.runCount());
265 }
266
267 /**
268 * runAndReset of a non-cancelled task succeeds
269 */
270 public void testRunAndReset() {
271 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
272 for (int i = 0; i < 3; i++) {
273 assertTrue(task.runAndReset());
274 checkNotDone(task);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000275 assertEquals(i + 1, task.runCount());
276 assertEquals(i + 1, task.runAndResetCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100277 assertEquals(0, task.setCount());
278 assertEquals(0, task.setExceptionCount());
279 }
280 }
281
282 /**
283 * runAndReset after cancellation fails
284 */
285 public void testRunAndResetAfterCancel() {
286 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
287 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
288 assertTrue(task.cancel(mayInterruptIfRunning));
289 for (int i = 0; i < 3; i++) {
290 assertFalse(task.runAndReset());
291 assertEquals(0, task.runCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000292 assertEquals(i + 1, task.runAndResetCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100293 assertEquals(0, task.setCount());
294 assertEquals(0, task.setExceptionCount());
295 }
296 tryToConfuseDoneTask(task);
297 checkCancelled(task);
298 }
299 }
300
301 /**
302 * setting value causes get to return it
303 */
304 public void testSet() throws Exception {
305 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
306 task.set(one);
307 for (int i = 0; i < 3; i++) {
308 assertSame(one, task.get());
309 assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
310 assertEquals(1, task.setCount());
311 }
312 tryToConfuseDoneTask(task);
313 checkCompletedNormally(task, one);
314 assertEquals(0, task.runCount());
315 }
316
317 /**
318 * setException causes get to throw ExecutionException
319 */
320 public void testSetException_get() throws Exception {
321 Exception nse = new NoSuchElementException();
322 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
323 task.setException(nse);
324
325 try {
326 task.get();
327 shouldThrow();
328 } catch (ExecutionException success) {
329 assertSame(nse, success.getCause());
330 checkCompletedAbnormally(task, nse);
331 }
332
333 try {
334 task.get(LONG_DELAY_MS, MILLISECONDS);
335 shouldThrow();
336 } catch (ExecutionException success) {
337 assertSame(nse, success.getCause());
338 checkCompletedAbnormally(task, nse);
339 }
340
341 assertEquals(1, task.setExceptionCount());
342 assertEquals(0, task.setCount());
343 tryToConfuseDoneTask(task);
344 checkCompletedAbnormally(task, nse);
345 assertEquals(0, task.runCount());
346 }
347
348 /**
349 * cancel(false) before run succeeds
350 */
351 public void testCancelBeforeRun() {
352 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
353 assertTrue(task.cancel(false));
354 task.run();
355 assertEquals(0, task.runCount());
356 assertEquals(0, task.setCount());
357 assertEquals(0, task.setExceptionCount());
358 assertTrue(task.isCancelled());
359 assertTrue(task.isDone());
360 tryToConfuseDoneTask(task);
361 assertEquals(0, task.runCount());
362 checkCancelled(task);
363 }
364
365 /**
366 * cancel(true) before run succeeds
367 */
368 public void testCancelBeforeRun2() {
369 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
370 assertTrue(task.cancel(true));
371 task.run();
372 assertEquals(0, task.runCount());
373 assertEquals(0, task.setCount());
374 assertEquals(0, task.setExceptionCount());
375 assertTrue(task.isCancelled());
376 assertTrue(task.isDone());
377 tryToConfuseDoneTask(task);
378 assertEquals(0, task.runCount());
379 checkCancelled(task);
380 }
381
382 /**
383 * cancel(false) of a completed task fails
384 */
385 public void testCancelAfterRun() {
386 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
387 task.run();
388 assertFalse(task.cancel(false));
389 assertEquals(1, task.runCount());
390 assertEquals(1, task.setCount());
391 assertEquals(0, task.setExceptionCount());
392 tryToConfuseDoneTask(task);
393 checkCompletedNormally(task, Boolean.TRUE);
394 assertEquals(1, task.runCount());
395 }
396
397 /**
398 * cancel(true) of a completed task fails
399 */
400 public void testCancelAfterRun2() {
401 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
402 task.run();
403 assertFalse(task.cancel(true));
404 assertEquals(1, task.runCount());
405 assertEquals(1, task.setCount());
406 assertEquals(0, task.setExceptionCount());
407 tryToConfuseDoneTask(task);
408 checkCompletedNormally(task, Boolean.TRUE);
409 assertEquals(1, task.runCount());
410 }
411
412 /**
413 * cancel(true) interrupts a running task that subsequently succeeds
414 */
415 public void testCancelInterrupt() {
416 final CountDownLatch pleaseCancel = new CountDownLatch(1);
417 final PublicFutureTask task =
418 new PublicFutureTask(new CheckedRunnable() {
419 public void realRun() {
420 pleaseCancel.countDown();
421 try {
422 delay(LONG_DELAY_MS);
423 shouldThrow();
424 } catch (InterruptedException success) {}
425 }});
426
427 Thread t = newStartedThread(task);
428 await(pleaseCancel);
429 assertTrue(task.cancel(true));
430 assertTrue(task.isCancelled());
431 assertTrue(task.isDone());
432 awaitTermination(t);
433 assertEquals(1, task.runCount());
434 assertEquals(1, task.setCount());
435 assertEquals(0, task.setExceptionCount());
436 tryToConfuseDoneTask(task);
437 checkCancelled(task);
438 }
439
440 /**
441 * cancel(true) tries to interrupt a running task, but
442 * Thread.interrupt throws (simulating a restrictive security
443 * manager)
444 */
445 public void testCancelInterrupt_ThrowsSecurityException() {
446 final CountDownLatch pleaseCancel = new CountDownLatch(1);
447 final CountDownLatch cancelled = new CountDownLatch(1);
448 final PublicFutureTask task =
449 new PublicFutureTask(new CheckedRunnable() {
450 public void realRun() {
451 pleaseCancel.countDown();
452 await(cancelled);
453 assertFalse(Thread.interrupted());
454 }});
455
456 final Thread t = new Thread(task) {
457 // Simulate a restrictive security manager.
458 @Override public void interrupt() {
459 throw new SecurityException();
460 }};
461 t.setDaemon(true);
462 t.start();
463
464 await(pleaseCancel);
465 try {
466 task.cancel(true);
467 shouldThrow();
468 } catch (SecurityException expected) {}
469
470 // We failed to deliver the interrupt, but the world retains
471 // its sanity, as if we had done task.cancel(false)
472 assertTrue(task.isCancelled());
473 assertTrue(task.isDone());
474 assertEquals(1, task.runCount());
475 assertEquals(1, task.doneCount());
476 assertEquals(0, task.setCount());
477 assertEquals(0, task.setExceptionCount());
478 cancelled.countDown();
479 awaitTermination(t);
480 assertEquals(1, task.setCount());
481 assertEquals(0, task.setExceptionCount());
482 tryToConfuseDoneTask(task);
483 checkCancelled(task);
484 }
485
486 /**
487 * cancel(true) interrupts a running task that subsequently throws
488 */
489 public void testCancelInterrupt_taskFails() {
490 final CountDownLatch pleaseCancel = new CountDownLatch(1);
491 final PublicFutureTask task =
492 new PublicFutureTask(new Runnable() {
493 public void run() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100494 pleaseCancel.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100495 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100496 delay(LONG_DELAY_MS);
497 threadShouldThrow();
498 } catch (InterruptedException success) {
499 } catch (Throwable t) { threadUnexpectedException(t); }
500 throw new RuntimeException();
501 }});
502
503 Thread t = newStartedThread(task);
504 await(pleaseCancel);
505 assertTrue(task.cancel(true));
506 assertTrue(task.isCancelled());
507 awaitTermination(t);
508 assertEquals(1, task.runCount());
509 assertEquals(0, task.setCount());
510 assertEquals(1, task.setExceptionCount());
511 tryToConfuseDoneTask(task);
512 checkCancelled(task);
513 }
514
515 /**
516 * cancel(false) does not interrupt a running task
517 */
518 public void testCancelNoInterrupt() {
519 final CountDownLatch pleaseCancel = new CountDownLatch(1);
520 final CountDownLatch cancelled = new CountDownLatch(1);
521 final PublicFutureTask task =
522 new PublicFutureTask(new CheckedCallable<Boolean>() {
523 public Boolean realCall() {
524 pleaseCancel.countDown();
525 await(cancelled);
526 assertFalse(Thread.interrupted());
527 return Boolean.TRUE;
528 }});
529
530 Thread t = newStartedThread(task);
531 await(pleaseCancel);
532 assertTrue(task.cancel(false));
533 assertTrue(task.isCancelled());
534 cancelled.countDown();
535 awaitTermination(t);
536 assertEquals(1, task.runCount());
537 assertEquals(1, task.setCount());
538 assertEquals(0, task.setExceptionCount());
539 tryToConfuseDoneTask(task);
540 checkCancelled(task);
541 }
542
543 /**
544 * run in one thread causes get in another thread to retrieve value
545 */
546 public void testGetRun() {
547 final CountDownLatch pleaseRun = new CountDownLatch(2);
548
549 final PublicFutureTask task =
550 new PublicFutureTask(new CheckedCallable<Object>() {
551 public Object realCall() {
552 return two;
553 }});
554
555 Thread t1 = newStartedThread(new CheckedRunnable() {
556 public void realRun() throws Exception {
557 pleaseRun.countDown();
558 assertSame(two, task.get());
559 }});
560
561 Thread t2 = newStartedThread(new CheckedRunnable() {
562 public void realRun() throws Exception {
563 pleaseRun.countDown();
564 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
565 }});
566
567 await(pleaseRun);
568 checkNotDone(task);
569 assertTrue(t1.isAlive());
570 assertTrue(t2.isAlive());
571 task.run();
572 checkCompletedNormally(task, two);
573 assertEquals(1, task.runCount());
574 assertEquals(1, task.setCount());
575 assertEquals(0, task.setExceptionCount());
576 awaitTermination(t1);
577 awaitTermination(t2);
578 tryToConfuseDoneTask(task);
579 checkCompletedNormally(task, two);
580 }
581
582 /**
583 * set in one thread causes get in another thread to retrieve value
584 */
585 public void testGetSet() {
586 final CountDownLatch pleaseSet = new CountDownLatch(2);
587
588 final PublicFutureTask task =
589 new PublicFutureTask(new CheckedCallable<Object>() {
590 public Object realCall() throws InterruptedException {
591 return two;
592 }});
593
594 Thread t1 = newStartedThread(new CheckedRunnable() {
595 public void realRun() throws Exception {
596 pleaseSet.countDown();
597 assertSame(two, task.get());
598 }});
599
600 Thread t2 = newStartedThread(new CheckedRunnable() {
601 public void realRun() throws Exception {
602 pleaseSet.countDown();
603 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
604 }});
605
606 await(pleaseSet);
607 checkNotDone(task);
608 assertTrue(t1.isAlive());
609 assertTrue(t2.isAlive());
610 task.set(two);
611 assertEquals(0, task.runCount());
612 assertEquals(1, task.setCount());
613 assertEquals(0, task.setExceptionCount());
614 tryToConfuseDoneTask(task);
615 checkCompletedNormally(task, two);
616 awaitTermination(t1);
617 awaitTermination(t2);
618 }
619
620 /**
621 * Cancelling a task causes timed get in another thread to throw
622 * CancellationException
623 */
624 public void testTimedGet_Cancellation() {
625 testTimedGet_Cancellation(false);
626 }
627 public void testTimedGet_Cancellation_interrupt() {
628 testTimedGet_Cancellation(true);
629 }
630 public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
631 final CountDownLatch pleaseCancel = new CountDownLatch(3);
632 final CountDownLatch cancelled = new CountDownLatch(1);
633 final Callable<Object> callable =
634 new CheckedCallable<Object>() {
635 public Object realCall() throws InterruptedException {
636 pleaseCancel.countDown();
637 if (mayInterruptIfRunning) {
638 try {
639 delay(2*LONG_DELAY_MS);
640 } catch (InterruptedException success) {}
641 } else {
642 await(cancelled);
643 }
644 return two;
645 }};
646 final PublicFutureTask task = new PublicFutureTask(callable);
647
648 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
649 public void realRun() throws Exception {
650 pleaseCancel.countDown();
651 task.get();
652 }};
653 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
654 public void realRun() throws Exception {
655 pleaseCancel.countDown();
656 task.get(2*LONG_DELAY_MS, MILLISECONDS);
657 }};
658 t1.start();
659 t2.start();
660 Thread t3 = newStartedThread(task);
661 await(pleaseCancel);
662 checkIsRunning(task);
663 task.cancel(mayInterruptIfRunning);
664 checkCancelled(task);
665 awaitTermination(t1);
666 awaitTermination(t2);
667 cancelled.countDown();
668 awaitTermination(t3);
669 assertEquals(1, task.runCount());
670 assertEquals(1, task.setCount());
671 assertEquals(0, task.setExceptionCount());
672 tryToConfuseDoneTask(task);
673 checkCancelled(task);
674 }
675
676 /**
677 * A runtime exception in task causes get to throw ExecutionException
678 */
679 public void testGet_ExecutionException() throws InterruptedException {
680 final ArithmeticException e = new ArithmeticException();
681 final PublicFutureTask task = new PublicFutureTask(new Callable() {
682 public Object call() {
683 throw e;
684 }});
685
686 task.run();
687 assertEquals(1, task.runCount());
688 assertEquals(0, task.setCount());
689 assertEquals(1, task.setExceptionCount());
690 try {
691 task.get();
692 shouldThrow();
693 } catch (ExecutionException success) {
694 assertSame(e, success.getCause());
695 tryToConfuseDoneTask(task);
696 checkCompletedAbnormally(task, success.getCause());
697 }
698 }
699
700 /**
701 * A runtime exception in task causes timed get to throw ExecutionException
702 */
703 public void testTimedGet_ExecutionException2() throws Exception {
704 final ArithmeticException e = new ArithmeticException();
705 final PublicFutureTask task = new PublicFutureTask(new Callable() {
706 public Object call() {
707 throw e;
708 }});
709
710 task.run();
711 try {
712 task.get(LONG_DELAY_MS, MILLISECONDS);
713 shouldThrow();
714 } catch (ExecutionException success) {
715 assertSame(e, success.getCause());
716 tryToConfuseDoneTask(task);
717 checkCompletedAbnormally(task, success.getCause());
718 }
719 }
720
721 /**
722 * get is interruptible
723 */
724 public void testGet_interruptible() {
725 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
726 final FutureTask task = new FutureTask(new NoOpCallable());
727 Thread t = newStartedThread(new CheckedRunnable() {
728 public void realRun() throws Exception {
729 Thread.currentThread().interrupt();
730 try {
731 task.get();
732 shouldThrow();
733 } catch (InterruptedException success) {}
734 assertFalse(Thread.interrupted());
735
736 pleaseInterrupt.countDown();
737 try {
738 task.get();
739 shouldThrow();
740 } catch (InterruptedException success) {}
741 assertFalse(Thread.interrupted());
742 }});
743
744 await(pleaseInterrupt);
745 t.interrupt();
746 awaitTermination(t);
747 checkNotDone(task);
748 }
749
750 /**
751 * timed get is interruptible
752 */
753 public void testTimedGet_interruptible() {
754 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
755 final FutureTask task = new FutureTask(new NoOpCallable());
756 Thread t = newStartedThread(new CheckedRunnable() {
757 public void realRun() throws Exception {
758 Thread.currentThread().interrupt();
759 try {
760 task.get(2*LONG_DELAY_MS, MILLISECONDS);
761 shouldThrow();
762 } catch (InterruptedException success) {}
763 assertFalse(Thread.interrupted());
764
765 pleaseInterrupt.countDown();
766 try {
767 task.get(2*LONG_DELAY_MS, MILLISECONDS);
768 shouldThrow();
769 } catch (InterruptedException success) {}
770 assertFalse(Thread.interrupted());
771 }});
772
773 await(pleaseInterrupt);
774 t.interrupt();
775 awaitTermination(t);
776 checkNotDone(task);
777 }
778
779 /**
780 * A timed out timed get throws TimeoutException
781 */
782 public void testGet_TimeoutException() throws Exception {
783 FutureTask task = new FutureTask(new NoOpCallable());
784 long startTime = System.nanoTime();
785 try {
786 task.get(timeoutMillis(), MILLISECONDS);
787 shouldThrow();
788 } catch (TimeoutException success) {
789 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
790 }
791 }
792
793 /**
794 * timed get with null TimeUnit throws NullPointerException
795 */
796 public void testGet_NullTimeUnit() throws Exception {
797 FutureTask task = new FutureTask(new NoOpCallable());
798 long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
799
800 for (long timeout : timeouts) {
801 try {
802 task.get(timeout, null);
803 shouldThrow();
804 } catch (NullPointerException success) {}
805 }
806
807 task.run();
808
809 for (long timeout : timeouts) {
810 try {
811 task.get(timeout, null);
812 shouldThrow();
813 } catch (NullPointerException success) {}
814 }
815 }
816
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100817 /**
818 * timed get with most negative timeout works correctly (i.e. no
819 * underflow bug)
820 */
821 public void testGet_NegativeInfinityTimeout() throws Exception {
822 final ExecutorService pool = Executors.newFixedThreadPool(10);
823 final Runnable nop = new Runnable() { public void run() {}};
824 final FutureTask<Void> task = new FutureTask<>(nop, null);
825 final List<Future<?>> futures = new ArrayList<>();
826 Runnable r = new Runnable() { public void run() {
827 for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
828 try {
829 task.get(timeout, NANOSECONDS);
830 shouldThrow();
831 } catch (TimeoutException success) {
832 } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
833 for (int i = 0; i < 10; i++)
834 futures.add(pool.submit(r));
835 try {
836 joinPool(pool);
837 for (Future<?> future : futures)
838 checkCompletedNormally(future, null);
839 } finally {
840 task.run(); // last resort to help terminate
841 }
842 }
843
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100844}