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