ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.54
Committed: Sun Aug 11 22:29:26 2019 UTC (4 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.53: +6 -2 lines
Log Message:
more assertions; more interleavings

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