ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.26
Committed: Tue May 31 16:16:23 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.25: +7 -1 lines
Log Message:
use serialClone in serialization tests; update imports

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 /**
153 * setting value causes get to return it
154 */
155 public void testSet() throws Exception {
156 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
157 task.set(one);
158 assertSame(task.get(), one);
159 checkCompletedNormally(task, one);
160 }
161
162 /**
163 * setException causes get to throw ExecutionException
164 */
165 public void testSetException() throws Exception {
166 Exception nse = new NoSuchElementException();
167 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
168 task.setException(nse);
169 try {
170 Object x = task.get();
171 shouldThrow();
172 } catch (ExecutionException success) {
173 assertSame(success.getCause(), nse);
174 checkCompletedAbnormally(task, nse);
175 }
176 }
177
178 /**
179 * Cancelling before running succeeds
180 */
181 public void testCancelBeforeRun() {
182 FutureTask task = new FutureTask(new NoOpCallable());
183 assertTrue(task.cancel(false));
184 task.run();
185 checkCancelled(task);
186 }
187
188 /**
189 * Cancel(true) before run succeeds
190 */
191 public void testCancelBeforeRun2() {
192 FutureTask task = new FutureTask(new NoOpCallable());
193 assertTrue(task.cancel(true));
194 task.run();
195 checkCancelled(task);
196 }
197
198 /**
199 * cancel of a completed task fails
200 */
201 public void testCancelAfterRun() {
202 FutureTask task = new FutureTask(new NoOpCallable());
203 task.run();
204 assertFalse(task.cancel(false));
205 checkCompletedNormally(task, Boolean.TRUE);
206 }
207
208 /**
209 * cancel(true) interrupts a running task
210 */
211 public void testCancelInterrupt() throws InterruptedException {
212 final CountDownLatch threadStarted = new CountDownLatch(1);
213 final FutureTask task =
214 new FutureTask(new CheckedCallable<Object>() {
215 public Object realCall() {
216 threadStarted.countDown();
217 long t0 = System.nanoTime();
218 for (;;) {
219 if (Thread.interrupted())
220 return Boolean.TRUE;
221 if (millisElapsedSince(t0) > MEDIUM_DELAY_MS)
222 fail("interrupt not delivered");
223 Thread.yield();
224 }
225 }});
226
227 Thread t = newStartedThread(task);
228 threadStarted.await();
229 assertTrue(task.cancel(true));
230 checkCancelled(task);
231 awaitTermination(t, MEDIUM_DELAY_MS);
232 checkCancelled(task);
233 }
234
235 /**
236 * cancel(false) does not interrupt a running task
237 */
238 public void testCancelNoInterrupt() throws InterruptedException {
239 final CountDownLatch threadStarted = new CountDownLatch(1);
240 final CountDownLatch cancelled = new CountDownLatch(1);
241 final FutureTask<Boolean> task =
242 new FutureTask<Boolean>(new CheckedCallable<Boolean>() {
243 public Boolean realCall() throws InterruptedException {
244 threadStarted.countDown();
245 cancelled.await(MEDIUM_DELAY_MS, MILLISECONDS);
246 assertFalse(Thread.interrupted());
247 return Boolean.TRUE;
248 }});
249
250 Thread t = newStartedThread(task);
251 threadStarted.await();
252 assertTrue(task.cancel(false));
253 checkCancelled(task);
254 cancelled.countDown();
255 awaitTermination(t, MEDIUM_DELAY_MS);
256 checkCancelled(task);
257 }
258
259 /**
260 * run in one thread causes get in another thread to retrieve value
261 */
262 public void testGetRun() throws InterruptedException {
263 final CountDownLatch threadStarted = new CountDownLatch(1);
264
265 final FutureTask task =
266 new FutureTask(new CheckedCallable<Object>() {
267 public Object realCall() throws InterruptedException {
268 return Boolean.TRUE;
269 }});
270
271 Thread t = newStartedThread(new CheckedRunnable() {
272 public void realRun() throws Exception {
273 threadStarted.countDown();
274 assertSame(Boolean.TRUE, task.get());
275 }});
276
277 threadStarted.await();
278 checkNotDone(task);
279 assertTrue(t.isAlive());
280 task.run();
281 checkCompletedNormally(task, Boolean.TRUE);
282 awaitTermination(t, MEDIUM_DELAY_MS);
283 }
284
285 /**
286 * set in one thread causes get in another thread to retrieve value
287 */
288 public void testGetSet() throws InterruptedException {
289 final CountDownLatch threadStarted = new CountDownLatch(1);
290
291 final PublicFutureTask task =
292 new PublicFutureTask(new CheckedCallable<Object>() {
293 public Object realCall() throws InterruptedException {
294 return Boolean.TRUE;
295 }});
296
297 Thread t = newStartedThread(new CheckedRunnable() {
298 public void realRun() throws Exception {
299 threadStarted.countDown();
300 assertSame(Boolean.FALSE, task.get());
301 }});
302
303 threadStarted.await();
304 checkNotDone(task);
305 assertTrue(t.isAlive());
306 task.set(Boolean.FALSE);
307 checkCompletedNormally(task, Boolean.FALSE);
308 awaitTermination(t, MEDIUM_DELAY_MS);
309 }
310
311 /**
312 * run in one thread causes timed get in another thread to retrieve value
313 */
314 public void testTimedGetRun() throws InterruptedException {
315 final CountDownLatch threadStarted = new CountDownLatch(1);
316
317 final FutureTask task =
318 new FutureTask(new CheckedCallable<Object>() {
319 public Object realCall() throws InterruptedException {
320 return Boolean.TRUE;
321 }});
322
323 Thread t = newStartedThread(new CheckedRunnable() {
324 public void realRun() throws Exception {
325 threadStarted.countDown();
326 assertSame(Boolean.TRUE,
327 task.get(MEDIUM_DELAY_MS, MILLISECONDS));
328 }});
329
330 threadStarted.await();
331 checkNotDone(task);
332 assertTrue(t.isAlive());
333 task.run();
334 checkCompletedNormally(task, Boolean.TRUE);
335 awaitTermination(t, MEDIUM_DELAY_MS);
336 }
337
338 /**
339 * set in one thread causes timed get in another thread to retrieve value
340 */
341 public void testTimedGetSet() throws InterruptedException {
342 final CountDownLatch threadStarted = new CountDownLatch(1);
343
344 final PublicFutureTask task =
345 new PublicFutureTask(new CheckedCallable<Object>() {
346 public Object realCall() throws InterruptedException {
347 return Boolean.TRUE;
348 }});
349
350 Thread t = newStartedThread(new CheckedRunnable() {
351 public void realRun() throws Exception {
352 threadStarted.countDown();
353 assertSame(Boolean.FALSE,
354 task.get(MEDIUM_DELAY_MS, MILLISECONDS));
355 }});
356
357 threadStarted.await();
358 checkNotDone(task);
359 assertTrue(t.isAlive());
360 task.set(Boolean.FALSE);
361 checkCompletedNormally(task, Boolean.FALSE);
362 awaitTermination(t, MEDIUM_DELAY_MS);
363 }
364
365 /**
366 * Cancelling a task causes timed get in another thread to throw
367 * CancellationException
368 */
369 public void testTimedGet_Cancellation() throws InterruptedException {
370 final CountDownLatch threadStarted = new CountDownLatch(2);
371 final FutureTask task =
372 new FutureTask(new CheckedInterruptedCallable<Object>() {
373 public Object realCall() throws InterruptedException {
374 threadStarted.countDown();
375 delay(LONG_DELAY_MS);
376 return Boolean.TRUE;
377 }});
378
379 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
380 public void realRun() throws Exception {
381 threadStarted.countDown();
382 task.get(MEDIUM_DELAY_MS, MILLISECONDS);
383 }};
384 Thread t2 = new Thread(task);
385 t1.start();
386 t2.start();
387 threadStarted.await();
388 task.cancel(true);
389 awaitTermination(t1, MEDIUM_DELAY_MS);
390 awaitTermination(t2, MEDIUM_DELAY_MS);
391 checkCancelled(task);
392 }
393
394 /**
395 * Cancelling a task causes get in another thread to throw
396 * CancellationException
397 */
398 public void testGet_Cancellation() throws InterruptedException {
399 final CountDownLatch threadStarted = new CountDownLatch(2);
400 final FutureTask task =
401 new FutureTask(new CheckedInterruptedCallable<Object>() {
402 public Object realCall() throws InterruptedException {
403 threadStarted.countDown();
404 delay(LONG_DELAY_MS);
405 return Boolean.TRUE;
406 }});
407
408 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
409 public void realRun() throws Exception {
410 threadStarted.countDown();
411 task.get();
412 }};
413 Thread t2 = new Thread(task);
414 t1.start();
415 t2.start();
416 threadStarted.await();
417 task.cancel(true);
418 awaitTermination(t1, MEDIUM_DELAY_MS);
419 awaitTermination(t2, MEDIUM_DELAY_MS);
420 checkCancelled(task);
421 }
422
423
424 /**
425 * A runtime exception in task causes get to throw ExecutionException
426 */
427 public void testGet_ExecutionException() throws InterruptedException {
428 final FutureTask task = new FutureTask(new Callable() {
429 public Object call() {
430 return 5/0;
431 }});
432
433 task.run();
434 try {
435 task.get();
436 shouldThrow();
437 } catch (ExecutionException success) {
438 assertTrue(success.getCause() instanceof ArithmeticException);
439 checkCompletedAbnormally(task, success.getCause());
440 }
441 }
442
443 /**
444 * A runtime exception in task causes timed get to throw ExecutionException
445 */
446 public void testTimedGet_ExecutionException2() throws Exception {
447 final FutureTask task = new FutureTask(new Callable() {
448 public Object call() {
449 return 5/0;
450 }});
451
452 task.run();
453 try {
454 task.get(SHORT_DELAY_MS, MILLISECONDS);
455 shouldThrow();
456 } catch (ExecutionException success) {
457 assertTrue(success.getCause() instanceof ArithmeticException);
458 checkCompletedAbnormally(task, success.getCause());
459 }
460 }
461
462
463 /**
464 * Interrupting a waiting get causes it to throw InterruptedException
465 */
466 public void testGet_InterruptedException() throws InterruptedException {
467 final CountDownLatch threadStarted = new CountDownLatch(1);
468 final FutureTask task = new FutureTask(new NoOpCallable());
469 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
470 public void realRun() throws Exception {
471 threadStarted.countDown();
472 task.get();
473 }});
474
475 threadStarted.await();
476 t.interrupt();
477 awaitTermination(t, MEDIUM_DELAY_MS);
478 checkNotDone(task);
479 }
480
481 /**
482 * Interrupting a waiting timed get causes it to throw InterruptedException
483 */
484 public void testTimedGet_InterruptedException2() throws InterruptedException {
485 final CountDownLatch threadStarted = new CountDownLatch(1);
486 final FutureTask task = new FutureTask(new NoOpCallable());
487 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
488 public void realRun() throws Exception {
489 threadStarted.countDown();
490 task.get(LONG_DELAY_MS, MILLISECONDS);
491 }});
492
493 threadStarted.await();
494 t.interrupt();
495 awaitTermination(t, MEDIUM_DELAY_MS);
496 checkNotDone(task);
497 }
498
499 /**
500 * A timed out timed get throws TimeoutException
501 */
502 public void testGet_TimeoutException() throws Exception {
503 try {
504 FutureTask task = new FutureTask(new NoOpCallable());
505 task.get(1, MILLISECONDS);
506 shouldThrow();
507 } catch (TimeoutException success) {}
508 }
509
510 }