[cvs] / jsr166 / src / test / tck / FutureTaskTest.java Repository:
ViewVC logotype

Annotation of /jsr166/src/test/tck/FutureTaskTest.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.53 - (view) (download)

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.29 Thread.currentThread().interrupt();
758 :     try {
759 :     task.get(2*LONG_DELAY_MS, MILLISECONDS);
760 :     shouldThrow();
761 :     } catch (InterruptedException success) {}
762 :     assertFalse(Thread.interrupted());
763 :    
764 :     pleaseInterrupt.countDown();
765 :     try {
766 :     task.get(2*LONG_DELAY_MS, MILLISECONDS);
767 :     shouldThrow();
768 :     } catch (InterruptedException success) {}
769 :     assertFalse(Thread.interrupted());
770 : jsr166 1.15 }});
771 :    
772 : jsr166 1.29 await(pleaseInterrupt);
773 : jsr166 1.15 t.interrupt();
774 : jsr166 1.28 awaitTermination(t);
775 : jsr166 1.22 checkNotDone(task);
776 : dl 1.1 }
777 : jsr166 1.12
778 : dl 1.5 /**
779 : dl 1.6 * A timed out timed get throws TimeoutException
780 : dl 1.5 */
781 : jsr166 1.15 public void testGet_TimeoutException() throws Exception {
782 : jsr166 1.29 FutureTask task = new FutureTask(new NoOpCallable());
783 :     long startTime = System.nanoTime();
784 : jsr166 1.16 try {
785 : jsr166 1.29 task.get(timeoutMillis(), MILLISECONDS);
786 : jsr166 1.17 shouldThrow();
787 : jsr166 1.29 } catch (TimeoutException success) {
788 :     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
789 :     }
790 :     }
791 :    
792 :     /**
793 :     * timed get with null TimeUnit throws NullPointerException
794 :     */
795 :     public void testGet_NullTimeUnit() throws Exception {
796 :     FutureTask task = new FutureTask(new NoOpCallable());
797 :     long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
798 :    
799 :     for (long timeout : timeouts) {
800 :     try {
801 :     task.get(timeout, null);
802 :     shouldThrow();
803 :     } catch (NullPointerException success) {}
804 :     }
805 :    
806 :     task.run();
807 :    
808 :     for (long timeout : timeouts) {
809 :     try {
810 :     task.get(timeout, null);
811 :     shouldThrow();
812 :     } catch (NullPointerException success) {}
813 :     }
814 : dl 1.1 }
815 : jsr166 1.12
816 : jsr166 1.39 /**
817 :     * timed get with most negative timeout works correctly (i.e. no
818 :     * underflow bug)
819 :     */
820 :     public void testGet_NegativeInfinityTimeout() throws Exception {
821 :     final ExecutorService pool = Executors.newFixedThreadPool(10);
822 :     final Runnable nop = new Runnable() { public void run() {}};
823 :     final FutureTask<Void> task = new FutureTask<>(nop, null);
824 :     final List<Future<?>> futures = new ArrayList<>();
825 :     Runnable r = new Runnable() { public void run() {
826 :     for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
827 :     try {
828 :     task.get(timeout, NANOSECONDS);
829 :     shouldThrow();
830 :     } catch (TimeoutException success) {
831 :     } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
832 :     for (int i = 0; i < 10; i++)
833 :     futures.add(pool.submit(r));
834 :     try {
835 :     joinPool(pool);
836 :     for (Future<?> future : futures)
837 :     checkCompletedNormally(future, null);
838 :     } finally {
839 :     task.run(); // last resort to help terminate
840 :     }
841 :     }
842 :    
843 : jsr166 1.47 /**
844 :     * toString indicates current completion state
845 :     */
846 :     public void testToString_incomplete() {
847 : jsr166 1.51 FutureTask<String> f = new FutureTask<>(() -> "");
848 : jsr166 1.47 assertTrue(f.toString().matches(".*\\[.*Not completed.*\\]"));
849 :     if (testImplementationDetails)
850 :     assertTrue(f.toString().startsWith(
851 :     identityString(f) + "[Not completed, task ="));
852 :     }
853 :    
854 :     public void testToString_normal() {
855 : jsr166 1.51 FutureTask<String> f = new FutureTask<>(() -> "");
856 : jsr166 1.47 f.run();
857 :     assertTrue(f.toString().matches(".*\\[.*Completed normally.*\\]"));
858 :     if (testImplementationDetails)
859 :     assertEquals(identityString(f) + "[Completed normally]",
860 :     f.toString());
861 :     }
862 :    
863 :     public void testToString_exception() {
864 : jsr166 1.51 FutureTask<String> f = new FutureTask<>(
865 : jsr166 1.47 () -> { throw new ArithmeticException(); });
866 :     f.run();
867 :     assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]"));
868 :     if (testImplementationDetails)
869 :     assertTrue(f.toString().startsWith(
870 :     identityString(f) + "[Completed exceptionally: "));
871 :     }
872 :    
873 :     public void testToString_cancelled() {
874 :     for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
875 : jsr166 1.51 FutureTask<String> f = new FutureTask<>(() -> "");
876 : jsr166 1.47 assertTrue(f.cancel(mayInterruptIfRunning));
877 :     assertTrue(f.toString().matches(".*\\[.*Cancelled.*\\]"));
878 :     if (testImplementationDetails)
879 :     assertEquals(identityString(f) + "[Cancelled]",
880 :     f.toString());
881 :     }
882 :     }
883 :    
884 : dl 1.1 }

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8