ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.38
Committed: Wed Jun 19 05:54:45 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.37: +3 -4 lines
Log Message:
improve testCancelInterrupt_taskFails

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