ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.32
Committed: Sun Dec 16 18:52:27 2012 UTC (11 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.31: +59 -2 lines
Log Message:
cancel(true) should take possible SecurityException on interrupt() into account

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