ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.27
Committed: Sat Jun 18 14:16:42 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.26: +0 -3 lines
Log Message:
whitespace

File Contents

# Content
1 /*
2 * 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 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9 import junit.framework.*;
10 import java.util.concurrent.Callable;
11 import java.util.concurrent.CancellationException;
12 import java.util.concurrent.CountDownLatch;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.Future;
15 import java.util.concurrent.FutureTask;
16 import java.util.concurrent.TimeoutException;
17 import static java.util.concurrent.TimeUnit.MILLISECONDS;
18 import static java.util.concurrent.TimeUnit.SECONDS;
19 import java.util.*;
20
21 public class FutureTaskTest extends JSR166TestCase {
22
23 public static void main(String[] args) {
24 junit.textui.TestRunner.run(suite());
25 }
26 public static Test suite() {
27 return new TestSuite(FutureTaskTest.class);
28 }
29
30 void checkNotDone(Future<?> f) {
31 assertFalse(f.isDone());
32 assertFalse(f.isCancelled());
33 }
34
35 <T> void checkCompletedNormally(Future<T> f, T expected) {
36 assertTrue(f.isDone());
37 assertFalse(f.isCancelled());
38
39 try {
40 assertSame(expected, f.get());
41 } catch (Throwable fail) { threadUnexpectedException(fail); }
42 try {
43 assertSame(expected, f.get(5L, SECONDS));
44 } catch (Throwable fail) { threadUnexpectedException(fail); }
45
46 assertFalse(f.cancel(false));
47 assertFalse(f.cancel(true));
48 }
49
50 void checkCancelled(Future<?> f) {
51 assertTrue(f.isDone());
52 assertTrue(f.isCancelled());
53
54 try {
55 f.get();
56 shouldThrow();
57 } catch (CancellationException success) {
58 } catch (Throwable fail) { threadUnexpectedException(fail); }
59
60 try {
61 f.get(5L, SECONDS);
62 shouldThrow();
63 } catch (CancellationException success) {
64 } catch (Throwable fail) { threadUnexpectedException(fail); }
65
66 assertFalse(f.cancel(false));
67 assertFalse(f.cancel(true));
68 }
69
70 void checkCompletedAbnormally(Future<?> f, Throwable t) {
71 assertTrue(f.isDone());
72 assertFalse(f.isCancelled());
73
74 try {
75 f.get();
76 shouldThrow();
77 } catch (ExecutionException success) {
78 assertSame(t, success.getCause());
79 } catch (Throwable fail) { threadUnexpectedException(fail); }
80
81 try {
82 f.get(5L, SECONDS);
83 shouldThrow();
84 } catch (ExecutionException success) {
85 assertSame(t, success.getCause());
86 } catch (Throwable fail) { threadUnexpectedException(fail); }
87
88 assertFalse(f.cancel(false));
89 assertFalse(f.cancel(true));
90 }
91
92 /**
93 * Subclass to expose protected methods
94 */
95 static class PublicFutureTask extends FutureTask {
96 public PublicFutureTask(Callable r) { super(r); }
97 public boolean runAndReset() { return super.runAndReset(); }
98 public void set(Object x) { super.set(x); }
99 public void setException(Throwable t) { super.setException(t); }
100 }
101
102 /**
103 * Creating a future with a null callable throws NPE
104 */
105 public void testConstructor() {
106 try {
107 FutureTask task = new FutureTask(null);
108 shouldThrow();
109 } catch (NullPointerException success) {}
110 }
111
112 /**
113 * creating a future with null runnable fails
114 */
115 public void testConstructor2() {
116 try {
117 FutureTask task = new FutureTask(null, Boolean.TRUE);
118 shouldThrow();
119 } catch (NullPointerException success) {}
120 }
121
122 /**
123 * isDone is true when a task completes
124 */
125 public void testIsDone() {
126 FutureTask task = new FutureTask(new NoOpCallable());
127 task.run();
128 assertTrue(task.isDone());
129 checkCompletedNormally(task, Boolean.TRUE);
130 }
131
132 /**
133 * runAndReset of a non-cancelled task succeeds
134 */
135 public void testRunAndReset() {
136 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
137 assertTrue(task.runAndReset());
138 checkNotDone(task);
139 }
140
141 /**
142 * runAndReset after cancellation fails
143 */
144 public void testResetAfterCancel() {
145 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
146 assertTrue(task.cancel(false));
147 assertFalse(task.runAndReset());
148 checkCancelled(task);
149 }
150
151 /**
152 * setting value causes get to return it
153 */
154 public void testSet() throws Exception {
155 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
156 task.set(one);
157 assertSame(task.get(), one);
158 checkCompletedNormally(task, one);
159 }
160
161 /**
162 * setException causes get to throw ExecutionException
163 */
164 public void testSetException() throws Exception {
165 Exception nse = new NoSuchElementException();
166 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
167 task.setException(nse);
168 try {
169 Object x = task.get();
170 shouldThrow();
171 } catch (ExecutionException success) {
172 assertSame(success.getCause(), nse);
173 checkCompletedAbnormally(task, nse);
174 }
175 }
176
177 /**
178 * Cancelling before running succeeds
179 */
180 public void testCancelBeforeRun() {
181 FutureTask task = new FutureTask(new NoOpCallable());
182 assertTrue(task.cancel(false));
183 task.run();
184 checkCancelled(task);
185 }
186
187 /**
188 * Cancel(true) before run succeeds
189 */
190 public void testCancelBeforeRun2() {
191 FutureTask task = new FutureTask(new NoOpCallable());
192 assertTrue(task.cancel(true));
193 task.run();
194 checkCancelled(task);
195 }
196
197 /**
198 * cancel of a completed task fails
199 */
200 public void testCancelAfterRun() {
201 FutureTask task = new FutureTask(new NoOpCallable());
202 task.run();
203 assertFalse(task.cancel(false));
204 checkCompletedNormally(task, Boolean.TRUE);
205 }
206
207 /**
208 * cancel(true) interrupts a running task
209 */
210 public void testCancelInterrupt() throws InterruptedException {
211 final CountDownLatch threadStarted = new CountDownLatch(1);
212 final FutureTask task =
213 new FutureTask(new CheckedCallable<Object>() {
214 public Object realCall() {
215 threadStarted.countDown();
216 long t0 = System.nanoTime();
217 for (;;) {
218 if (Thread.interrupted())
219 return Boolean.TRUE;
220 if (millisElapsedSince(t0) > MEDIUM_DELAY_MS)
221 fail("interrupt not delivered");
222 Thread.yield();
223 }
224 }});
225
226 Thread t = newStartedThread(task);
227 threadStarted.await();
228 assertTrue(task.cancel(true));
229 checkCancelled(task);
230 awaitTermination(t, MEDIUM_DELAY_MS);
231 checkCancelled(task);
232 }
233
234 /**
235 * cancel(false) does not interrupt a running task
236 */
237 public void testCancelNoInterrupt() throws InterruptedException {
238 final CountDownLatch threadStarted = new CountDownLatch(1);
239 final CountDownLatch cancelled = new CountDownLatch(1);
240 final FutureTask<Boolean> task =
241 new FutureTask<Boolean>(new CheckedCallable<Boolean>() {
242 public Boolean realCall() throws InterruptedException {
243 threadStarted.countDown();
244 cancelled.await(MEDIUM_DELAY_MS, MILLISECONDS);
245 assertFalse(Thread.interrupted());
246 return Boolean.TRUE;
247 }});
248
249 Thread t = newStartedThread(task);
250 threadStarted.await();
251 assertTrue(task.cancel(false));
252 checkCancelled(task);
253 cancelled.countDown();
254 awaitTermination(t, MEDIUM_DELAY_MS);
255 checkCancelled(task);
256 }
257
258 /**
259 * run in one thread causes get in another thread to retrieve value
260 */
261 public void testGetRun() throws InterruptedException {
262 final CountDownLatch threadStarted = new CountDownLatch(1);
263
264 final FutureTask task =
265 new FutureTask(new CheckedCallable<Object>() {
266 public Object realCall() throws InterruptedException {
267 return Boolean.TRUE;
268 }});
269
270 Thread t = newStartedThread(new CheckedRunnable() {
271 public void realRun() throws Exception {
272 threadStarted.countDown();
273 assertSame(Boolean.TRUE, task.get());
274 }});
275
276 threadStarted.await();
277 checkNotDone(task);
278 assertTrue(t.isAlive());
279 task.run();
280 checkCompletedNormally(task, Boolean.TRUE);
281 awaitTermination(t, MEDIUM_DELAY_MS);
282 }
283
284 /**
285 * set in one thread causes get in another thread to retrieve value
286 */
287 public void testGetSet() throws InterruptedException {
288 final CountDownLatch threadStarted = new CountDownLatch(1);
289
290 final PublicFutureTask task =
291 new PublicFutureTask(new CheckedCallable<Object>() {
292 public Object realCall() throws InterruptedException {
293 return Boolean.TRUE;
294 }});
295
296 Thread t = newStartedThread(new CheckedRunnable() {
297 public void realRun() throws Exception {
298 threadStarted.countDown();
299 assertSame(Boolean.FALSE, task.get());
300 }});
301
302 threadStarted.await();
303 checkNotDone(task);
304 assertTrue(t.isAlive());
305 task.set(Boolean.FALSE);
306 checkCompletedNormally(task, Boolean.FALSE);
307 awaitTermination(t, MEDIUM_DELAY_MS);
308 }
309
310 /**
311 * run in one thread causes timed get in another thread to retrieve value
312 */
313 public void testTimedGetRun() throws InterruptedException {
314 final CountDownLatch threadStarted = new CountDownLatch(1);
315
316 final FutureTask task =
317 new FutureTask(new CheckedCallable<Object>() {
318 public Object realCall() throws InterruptedException {
319 return Boolean.TRUE;
320 }});
321
322 Thread t = newStartedThread(new CheckedRunnable() {
323 public void realRun() throws Exception {
324 threadStarted.countDown();
325 assertSame(Boolean.TRUE,
326 task.get(MEDIUM_DELAY_MS, MILLISECONDS));
327 }});
328
329 threadStarted.await();
330 checkNotDone(task);
331 assertTrue(t.isAlive());
332 task.run();
333 checkCompletedNormally(task, Boolean.TRUE);
334 awaitTermination(t, MEDIUM_DELAY_MS);
335 }
336
337 /**
338 * set in one thread causes timed get in another thread to retrieve value
339 */
340 public void testTimedGetSet() throws InterruptedException {
341 final CountDownLatch threadStarted = new CountDownLatch(1);
342
343 final PublicFutureTask task =
344 new PublicFutureTask(new CheckedCallable<Object>() {
345 public Object realCall() throws InterruptedException {
346 return Boolean.TRUE;
347 }});
348
349 Thread t = newStartedThread(new CheckedRunnable() {
350 public void realRun() throws Exception {
351 threadStarted.countDown();
352 assertSame(Boolean.FALSE,
353 task.get(MEDIUM_DELAY_MS, MILLISECONDS));
354 }});
355
356 threadStarted.await();
357 checkNotDone(task);
358 assertTrue(t.isAlive());
359 task.set(Boolean.FALSE);
360 checkCompletedNormally(task, Boolean.FALSE);
361 awaitTermination(t, MEDIUM_DELAY_MS);
362 }
363
364 /**
365 * Cancelling a task causes timed get in another thread to throw
366 * CancellationException
367 */
368 public void testTimedGet_Cancellation() throws InterruptedException {
369 final CountDownLatch threadStarted = new CountDownLatch(2);
370 final FutureTask task =
371 new FutureTask(new CheckedInterruptedCallable<Object>() {
372 public Object realCall() throws InterruptedException {
373 threadStarted.countDown();
374 delay(LONG_DELAY_MS);
375 return Boolean.TRUE;
376 }});
377
378 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
379 public void realRun() throws Exception {
380 threadStarted.countDown();
381 task.get(MEDIUM_DELAY_MS, MILLISECONDS);
382 }};
383 Thread t2 = new Thread(task);
384 t1.start();
385 t2.start();
386 threadStarted.await();
387 task.cancel(true);
388 awaitTermination(t1, MEDIUM_DELAY_MS);
389 awaitTermination(t2, MEDIUM_DELAY_MS);
390 checkCancelled(task);
391 }
392
393 /**
394 * Cancelling a task causes get in another thread to throw
395 * CancellationException
396 */
397 public void testGet_Cancellation() throws InterruptedException {
398 final CountDownLatch threadStarted = new CountDownLatch(2);
399 final FutureTask task =
400 new FutureTask(new CheckedInterruptedCallable<Object>() {
401 public Object realCall() throws InterruptedException {
402 threadStarted.countDown();
403 delay(LONG_DELAY_MS);
404 return Boolean.TRUE;
405 }});
406
407 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
408 public void realRun() throws Exception {
409 threadStarted.countDown();
410 task.get();
411 }};
412 Thread t2 = new Thread(task);
413 t1.start();
414 t2.start();
415 threadStarted.await();
416 task.cancel(true);
417 awaitTermination(t1, MEDIUM_DELAY_MS);
418 awaitTermination(t2, MEDIUM_DELAY_MS);
419 checkCancelled(task);
420 }
421
422 /**
423 * A runtime exception in task causes get to throw ExecutionException
424 */
425 public void testGet_ExecutionException() throws InterruptedException {
426 final FutureTask task = new FutureTask(new Callable() {
427 public Object call() {
428 return 5/0;
429 }});
430
431 task.run();
432 try {
433 task.get();
434 shouldThrow();
435 } catch (ExecutionException success) {
436 assertTrue(success.getCause() instanceof ArithmeticException);
437 checkCompletedAbnormally(task, success.getCause());
438 }
439 }
440
441 /**
442 * A runtime exception in task causes timed get to throw ExecutionException
443 */
444 public void testTimedGet_ExecutionException2() throws Exception {
445 final FutureTask task = new FutureTask(new Callable() {
446 public Object call() {
447 return 5/0;
448 }});
449
450 task.run();
451 try {
452 task.get(SHORT_DELAY_MS, MILLISECONDS);
453 shouldThrow();
454 } catch (ExecutionException success) {
455 assertTrue(success.getCause() instanceof ArithmeticException);
456 checkCompletedAbnormally(task, success.getCause());
457 }
458 }
459
460 /**
461 * Interrupting a waiting get causes it to throw InterruptedException
462 */
463 public void testGet_InterruptedException() throws InterruptedException {
464 final CountDownLatch threadStarted = new CountDownLatch(1);
465 final FutureTask task = new FutureTask(new NoOpCallable());
466 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
467 public void realRun() throws Exception {
468 threadStarted.countDown();
469 task.get();
470 }});
471
472 threadStarted.await();
473 t.interrupt();
474 awaitTermination(t, MEDIUM_DELAY_MS);
475 checkNotDone(task);
476 }
477
478 /**
479 * Interrupting a waiting timed get causes it to throw InterruptedException
480 */
481 public void testTimedGet_InterruptedException2() throws InterruptedException {
482 final CountDownLatch threadStarted = new CountDownLatch(1);
483 final FutureTask task = new FutureTask(new NoOpCallable());
484 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
485 public void realRun() throws Exception {
486 threadStarted.countDown();
487 task.get(LONG_DELAY_MS, MILLISECONDS);
488 }});
489
490 threadStarted.await();
491 t.interrupt();
492 awaitTermination(t, MEDIUM_DELAY_MS);
493 checkNotDone(task);
494 }
495
496 /**
497 * A timed out timed get throws TimeoutException
498 */
499 public void testGet_TimeoutException() throws Exception {
500 try {
501 FutureTask task = new FutureTask(new NoOpCallable());
502 task.get(1, MILLISECONDS);
503 shouldThrow();
504 } catch (TimeoutException success) {}
505 }
506
507 }