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