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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines