ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.33
Committed: Thu Dec 20 04:58:53 2012 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.32: +17 -18 lines
Log Message:
improve testCancelInterrupt_ThrowsSecurityException

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.33 * cancel(true) tries to interrupt a running task, but
410     * Thread.interrupt throws (simulating a restrictive security
411     * manager)
412 jsr166 1.32 */
413     public void testCancelInterrupt_ThrowsSecurityException() {
414     final CountDownLatch pleaseCancel = new CountDownLatch(1);
415     final CountDownLatch cancelled = new CountDownLatch(1);
416     final PublicFutureTask task =
417     new PublicFutureTask(new CheckedRunnable() {
418     public void realRun() {
419     pleaseCancel.countDown();
420     await(cancelled);
421     assertFalse(Thread.interrupted());
422     }});
423    
424 jsr166 1.33 final Thread t = new Thread(task) {
425     // Simulate a restrictive security manager.
426     @Override public void interrupt() {
427     throw new SecurityException();
428     }};
429     t.setDaemon(true);
430     t.start();
431    
432 jsr166 1.32 await(pleaseCancel);
433     try {
434 jsr166 1.33 task.cancel(true);
435     shouldThrow();
436     } catch (SecurityException expected) {}
437    
438     // We failed to deliver the interrupt, but the world retains
439     // its sanity, as if we had done task.cancel(false)
440 jsr166 1.32 assertTrue(task.isCancelled());
441     assertTrue(task.isDone());
442     assertEquals(1, task.runCount());
443     assertEquals(1, task.doneCount());
444     assertEquals(0, task.setCount());
445     assertEquals(0, task.setExceptionCount());
446     cancelled.countDown();
447     awaitTermination(t);
448     assertEquals(1, task.setCount());
449     assertEquals(0, task.setExceptionCount());
450     tryToConfuseDoneTask(task);
451     checkCancelled(task);
452     }
453    
454     /**
455 jsr166 1.29 * cancel(true) interrupts a running task that subsequently throws
456     */
457     public void testCancelInterrupt_taskFails() {
458     final CountDownLatch pleaseCancel = new CountDownLatch(1);
459     final PublicFutureTask task =
460     new PublicFutureTask(new Runnable() {
461     public void run() {
462     try {
463     pleaseCancel.countDown();
464     delay(LONG_DELAY_MS);
465     } finally { throw new RuntimeException(); }
466     }});
467    
468     Thread t = newStartedThread(task);
469     await(pleaseCancel);
470     assertTrue(task.cancel(true));
471     assertTrue(task.isCancelled());
472     awaitTermination(t);
473     assertEquals(1, task.runCount());
474     assertEquals(0, task.setCount());
475     assertEquals(1, task.setExceptionCount());
476     tryToConfuseDoneTask(task);
477 jsr166 1.22 checkCancelled(task);
478 dl 1.1 }
479    
480 dl 1.5 /**
481 dl 1.6 * cancel(false) does not interrupt a running task
482 dl 1.5 */
483 jsr166 1.29 public void testCancelNoInterrupt() {
484     final CountDownLatch pleaseCancel = new CountDownLatch(1);
485 jsr166 1.22 final CountDownLatch cancelled = new CountDownLatch(1);
486 jsr166 1.29 final PublicFutureTask task =
487     new PublicFutureTask(new CheckedCallable<Boolean>() {
488     public Boolean realCall() {
489     pleaseCancel.countDown();
490     await(cancelled);
491 jsr166 1.22 assertFalse(Thread.interrupted());
492 dl 1.1 return Boolean.TRUE;
493 jsr166 1.15 }});
494    
495 jsr166 1.22 Thread t = newStartedThread(task);
496 jsr166 1.29 await(pleaseCancel);
497 jsr166 1.15 assertTrue(task.cancel(false));
498 jsr166 1.29 assertTrue(task.isCancelled());
499 jsr166 1.22 cancelled.countDown();
500 jsr166 1.29 awaitTermination(t);
501     assertEquals(1, task.runCount());
502     assertEquals(1, task.setCount());
503     assertEquals(0, task.setExceptionCount());
504     tryToConfuseDoneTask(task);
505 jsr166 1.22 checkCancelled(task);
506 dl 1.1 }
507    
508 dl 1.5 /**
509 jsr166 1.23 * run in one thread causes get in another thread to retrieve value
510 dl 1.5 */
511 jsr166 1.29 public void testGetRun() {
512     final CountDownLatch pleaseRun = new CountDownLatch(2);
513 jsr166 1.23
514     final PublicFutureTask task =
515     new PublicFutureTask(new CheckedCallable<Object>() {
516 jsr166 1.29 public Object realCall() {
517     return two;
518 jsr166 1.23 }});
519    
520 jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
521 jsr166 1.23 public void realRun() throws Exception {
522 jsr166 1.29 pleaseRun.countDown();
523     assertSame(two, task.get());
524 jsr166 1.23 }});
525    
526 jsr166 1.29 Thread t2 = newStartedThread(new CheckedRunnable() {
527 jsr166 1.15 public void realRun() throws Exception {
528 jsr166 1.29 pleaseRun.countDown();
529     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
530 jsr166 1.15 }});
531 jsr166 1.12
532 jsr166 1.29 await(pleaseRun);
533 jsr166 1.23 checkNotDone(task);
534 jsr166 1.29 assertTrue(t1.isAlive());
535     assertTrue(t2.isAlive());
536 jsr166 1.22 task.run();
537 jsr166 1.29 checkCompletedNormally(task, two);
538     assertEquals(1, task.runCount());
539     assertEquals(1, task.setCount());
540     assertEquals(0, task.setExceptionCount());
541     awaitTermination(t1);
542     awaitTermination(t2);
543     tryToConfuseDoneTask(task);
544     checkCompletedNormally(task, two);
545 dl 1.1 }
546    
547 dl 1.5 /**
548 jsr166 1.29 * set in one thread causes get in another thread to retrieve value
549 jsr166 1.23 */
550 jsr166 1.29 public void testGetSet() {
551     final CountDownLatch pleaseSet = new CountDownLatch(2);
552 jsr166 1.23
553     final PublicFutureTask task =
554     new PublicFutureTask(new CheckedCallable<Object>() {
555     public Object realCall() throws InterruptedException {
556 jsr166 1.29 return two;
557 jsr166 1.23 }});
558    
559 jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
560     public void realRun() throws Exception {
561     pleaseSet.countDown();
562     assertSame(two, task.get());
563     }});
564    
565     Thread t2 = newStartedThread(new CheckedRunnable() {
566 jsr166 1.23 public void realRun() throws Exception {
567 jsr166 1.29 pleaseSet.countDown();
568     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
569 jsr166 1.23 }});
570    
571 jsr166 1.29 await(pleaseSet);
572 jsr166 1.23 checkNotDone(task);
573 jsr166 1.29 assertTrue(t1.isAlive());
574     assertTrue(t2.isAlive());
575     task.set(two);
576     assertEquals(0, task.runCount());
577     assertEquals(1, task.setCount());
578     assertEquals(0, task.setExceptionCount());
579     tryToConfuseDoneTask(task);
580     checkCompletedNormally(task, two);
581     awaitTermination(t1);
582     awaitTermination(t2);
583 jsr166 1.23 }
584    
585     /**
586 jsr166 1.21 * Cancelling a task causes timed get in another thread to throw
587     * CancellationException
588 dl 1.5 */
589 jsr166 1.29 public void testTimedGet_Cancellation() {
590     for (final boolean mayInterruptIfRunning :
591     new boolean[] { true, false }) {
592     final CountDownLatch pleaseCancel = new CountDownLatch(3);
593     final CountDownLatch cancelled = new CountDownLatch(1);
594     final PublicFutureTask task =
595     new PublicFutureTask(new CheckedCallable<Object>() {
596     public Object realCall() throws InterruptedException {
597     pleaseCancel.countDown();
598     if (mayInterruptIfRunning) {
599     try {
600     delay(2*LONG_DELAY_MS);
601     } catch (InterruptedException success) {}
602     } else {
603     await(cancelled);
604     }
605     return two;
606     }});
607    
608     Thread t1 = new ThreadShouldThrow(CancellationException.class) {
609     public void realRun() throws Exception {
610     pleaseCancel.countDown();
611     task.get();
612     }};
613     Thread t2 = new ThreadShouldThrow(CancellationException.class) {
614     public void realRun() throws Exception {
615     pleaseCancel.countDown();
616     task.get(2*LONG_DELAY_MS, MILLISECONDS);
617     }};
618     t1.start();
619     t2.start();
620     Thread t3 = newStartedThread(task);
621     await(pleaseCancel);
622     checkIsRunning(task);
623     task.cancel(mayInterruptIfRunning);
624     checkCancelled(task);
625     awaitTermination(t1);
626     awaitTermination(t2);
627     cancelled.countDown();
628     awaitTermination(t3);
629     assertEquals(1, task.runCount());
630     assertEquals(1, task.setCount());
631     assertEquals(0, task.setExceptionCount());
632     tryToConfuseDoneTask(task);
633     checkCancelled(task);
634     }
635 dl 1.1 }
636 jsr166 1.12
637 dl 1.5 /**
638 dl 1.6 * A runtime exception in task causes get to throw ExecutionException
639 dl 1.5 */
640 jsr166 1.15 public void testGet_ExecutionException() throws InterruptedException {
641 jsr166 1.29 final ArithmeticException e = new ArithmeticException();
642     final PublicFutureTask task = new PublicFutureTask(new Callable() {
643 jsr166 1.16 public Object call() {
644 jsr166 1.29 throw e;
645 jsr166 1.15 }});
646    
647 jsr166 1.22 task.run();
648 jsr166 1.29 assertEquals(1, task.runCount());
649     assertEquals(0, task.setCount());
650     assertEquals(1, task.setExceptionCount());
651 jsr166 1.15 try {
652 jsr166 1.22 task.get();
653 jsr166 1.17 shouldThrow();
654 jsr166 1.16 } catch (ExecutionException success) {
655 jsr166 1.29 assertSame(e, success.getCause());
656     tryToConfuseDoneTask(task);
657 jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
658 dl 1.1 }
659     }
660 jsr166 1.12
661 dl 1.5 /**
662 jsr166 1.20 * A runtime exception in task causes timed get to throw ExecutionException
663 dl 1.5 */
664 jsr166 1.15 public void testTimedGet_ExecutionException2() throws Exception {
665 jsr166 1.29 final ArithmeticException e = new ArithmeticException();
666     final PublicFutureTask task = new PublicFutureTask(new Callable() {
667 jsr166 1.16 public Object call() {
668 jsr166 1.29 throw e;
669 jsr166 1.15 }});
670    
671 jsr166 1.22 task.run();
672 jsr166 1.16 try {
673 jsr166 1.29 task.get(LONG_DELAY_MS, MILLISECONDS);
674 jsr166 1.17 shouldThrow();
675 jsr166 1.16 } catch (ExecutionException success) {
676 jsr166 1.29 assertSame(e, success.getCause());
677     tryToConfuseDoneTask(task);
678 jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
679 jsr166 1.15 }
680 dl 1.1 }
681 jsr166 1.12
682 dl 1.5 /**
683 jsr166 1.29 * get is interruptible
684 dl 1.5 */
685 jsr166 1.29 public void testGet_interruptible() {
686     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
687 jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
688 jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
689 jsr166 1.15 public void realRun() throws Exception {
690 jsr166 1.29 Thread.currentThread().interrupt();
691     try {
692     task.get();
693     shouldThrow();
694     } catch (InterruptedException success) {}
695     assertFalse(Thread.interrupted());
696    
697     pleaseInterrupt.countDown();
698     try {
699     task.get();
700     shouldThrow();
701     } catch (InterruptedException success) {}
702     assertFalse(Thread.interrupted());
703 jsr166 1.15 }});
704    
705 jsr166 1.29 await(pleaseInterrupt);
706 jsr166 1.15 t.interrupt();
707 jsr166 1.28 awaitTermination(t);
708 jsr166 1.22 checkNotDone(task);
709 dl 1.1 }
710    
711 dl 1.5 /**
712 jsr166 1.29 * timed get is interruptible
713 dl 1.5 */
714 jsr166 1.29 public void testTimedGet_interruptible() {
715     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
716 jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
717 jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
718 jsr166 1.15 public void realRun() throws Exception {
719 jsr166 1.29 Thread.currentThread().interrupt();
720     try {
721     task.get(2*LONG_DELAY_MS, MILLISECONDS);
722     shouldThrow();
723     } catch (InterruptedException success) {}
724     assertFalse(Thread.interrupted());
725    
726     pleaseInterrupt.countDown();
727     try {
728     task.get(2*LONG_DELAY_MS, MILLISECONDS);
729     shouldThrow();
730     } catch (InterruptedException success) {}
731     assertFalse(Thread.interrupted());
732 jsr166 1.15 }});
733    
734 jsr166 1.29 await(pleaseInterrupt);
735 jsr166 1.15 t.interrupt();
736 jsr166 1.28 awaitTermination(t);
737 jsr166 1.22 checkNotDone(task);
738 dl 1.1 }
739 jsr166 1.12
740 dl 1.5 /**
741 dl 1.6 * A timed out timed get throws TimeoutException
742 dl 1.5 */
743 jsr166 1.15 public void testGet_TimeoutException() throws Exception {
744 jsr166 1.29 FutureTask task = new FutureTask(new NoOpCallable());
745     long startTime = System.nanoTime();
746 jsr166 1.16 try {
747 jsr166 1.29 task.get(timeoutMillis(), MILLISECONDS);
748 jsr166 1.17 shouldThrow();
749 jsr166 1.29 } catch (TimeoutException success) {
750     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
751     }
752     }
753    
754     /**
755     * timed get with null TimeUnit throws NullPointerException
756     */
757     public void testGet_NullTimeUnit() throws Exception {
758     FutureTask task = new FutureTask(new NoOpCallable());
759     long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
760    
761     for (long timeout : timeouts) {
762     try {
763     task.get(timeout, null);
764     shouldThrow();
765     } catch (NullPointerException success) {}
766     }
767    
768     task.run();
769    
770     for (long timeout : timeouts) {
771     try {
772     task.get(timeout, null);
773     shouldThrow();
774     } catch (NullPointerException success) {}
775     }
776 dl 1.1 }
777 jsr166 1.12
778 dl 1.1 }