ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
(Generate patch)

Comparing jsr166/src/test/tck/FutureTaskTest.java (file contents):
Revision 1.4 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.18 by jsr166, Tue Dec 1 09:56:28 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines