ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.22
Committed: Sun Nov 28 20:20:00 2010 UTC (13 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.21: +169 -91 lines
Log Message:
optimize; add more assertions

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