ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.39
Committed: Fri Aug 22 03:30:56 2014 UTC (9 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.38: +30 -2 lines
Log Message:
Fix underflow when timeout = Long.MIN_VALUE

File Contents

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