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.21 by jsr166, Sat Oct 9 19:30:35 2010 UTC vs.
Revision 1.25 by dl, Fri May 6 11:22:07 2011 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.
7   */
# Line 9 | Line 9
9   import junit.framework.*;
10   import java.util.concurrent.*;
11   import static java.util.concurrent.TimeUnit.MILLISECONDS;
12 + import static java.util.concurrent.TimeUnit.SECONDS;
13   import java.util.*;
14  
15   public class FutureTaskTest extends JSR166TestCase {
# Line 20 | Line 21 | public class FutureTaskTest extends JSR1
21          return new TestSuite(FutureTaskTest.class);
22      }
23  
24 +    void checkNotDone(Future<?> f) {
25 +        assertFalse(f.isDone());
26 +        assertFalse(f.isCancelled());
27 +    }
28 +
29 +    <T> void checkCompletedNormally(Future<T> f, T expected) {
30 +        assertTrue(f.isDone());
31 +        assertFalse(f.isCancelled());
32 +
33 +        try {
34 +            assertSame(expected, f.get());
35 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
36 +        try {
37 +            assertSame(expected, f.get(5L, SECONDS));
38 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
39 +
40 +        assertFalse(f.cancel(false));
41 +        assertFalse(f.cancel(true));
42 +    }
43 +
44 +    void checkCancelled(Future<?> f) {
45 +        assertTrue(f.isDone());
46 +        assertTrue(f.isCancelled());
47 +
48 +        try {
49 +            f.get();
50 +            shouldThrow();
51 +        } catch (CancellationException success) {
52 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
53 +
54 +        try {
55 +            f.get(5L, SECONDS);
56 +            shouldThrow();
57 +        } catch (CancellationException success) {
58 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
59 +
60 +        assertFalse(f.cancel(false));
61 +        assertFalse(f.cancel(true));
62 +    }
63 +
64 +    void checkCompletedAbnormally(Future<?> f, Throwable t) {
65 +        assertTrue(f.isDone());
66 +        assertFalse(f.isCancelled());
67 +
68 +        try {
69 +            f.get();
70 +            shouldThrow();
71 +        } catch (ExecutionException success) {
72 +            assertSame(t, success.getCause());
73 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
74 +
75 +        try {
76 +            f.get(5L, SECONDS);
77 +            shouldThrow();
78 +        } catch (ExecutionException success) {
79 +            assertSame(t, success.getCause());
80 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
81 +
82 +        assertFalse(f.cancel(false));
83 +        assertFalse(f.cancel(true));
84 +    }
85 +
86      /**
87       * Subclass to expose protected methods
88       */
# Line 57 | Line 120 | public class FutureTaskTest extends JSR1
120          FutureTask task = new FutureTask(new NoOpCallable());
121          task.run();
122          assertTrue(task.isDone());
123 <        assertFalse(task.isCancelled());
123 >        checkCompletedNormally(task, Boolean.TRUE);
124      }
125  
126      /**
# Line 66 | Line 129 | public class FutureTaskTest extends JSR1
129      public void testRunAndReset() {
130          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
131          assertTrue(task.runAndReset());
132 <        assertFalse(task.isDone());
132 >        checkNotDone(task);
133      }
134  
135      /**
# Line 76 | Line 139 | public class FutureTaskTest extends JSR1
139          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
140          assertTrue(task.cancel(false));
141          assertFalse(task.runAndReset());
142 <        assertTrue(task.isDone());
80 <        assertTrue(task.isCancelled());
142 >        checkCancelled(task);
143      }
144  
145  
84
146      /**
147       * setting value causes get to return it
148       */
# Line 89 | Line 150 | public class FutureTaskTest extends JSR1
150          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
151          task.set(one);
152          assertSame(task.get(), one);
153 +        checkCompletedNormally(task, one);
154      }
155  
156      /**
# Line 103 | Line 165 | public class FutureTaskTest extends JSR1
165              shouldThrow();
166          } catch (ExecutionException success) {
167              assertSame(success.getCause(), nse);
168 +            checkCompletedAbnormally(task, nse);
169          }
170      }
171  
# Line 113 | Line 176 | public class FutureTaskTest extends JSR1
176          FutureTask task = new FutureTask(new NoOpCallable());
177          assertTrue(task.cancel(false));
178          task.run();
179 <        assertTrue(task.isDone());
117 <        assertTrue(task.isCancelled());
179 >        checkCancelled(task);
180      }
181  
182      /**
# Line 124 | Line 186 | public class FutureTaskTest extends JSR1
186          FutureTask task = new FutureTask(new NoOpCallable());
187          assertTrue(task.cancel(true));
188          task.run();
189 <        assertTrue(task.isDone());
128 <        assertTrue(task.isCancelled());
189 >        checkCancelled(task);
190      }
191  
192      /**
# Line 135 | Line 196 | public class FutureTaskTest extends JSR1
196          FutureTask task = new FutureTask(new NoOpCallable());
197          task.run();
198          assertFalse(task.cancel(false));
199 <        assertTrue(task.isDone());
139 <        assertFalse(task.isCancelled());
199 >        checkCompletedNormally(task, Boolean.TRUE);
200      }
201  
202      /**
203       * cancel(true) interrupts a running task
204       */
205      public void testCancelInterrupt() throws InterruptedException {
206 +        final CountDownLatch threadStarted = new CountDownLatch(1);
207          final FutureTask task =
208 <            new FutureTask(new CheckedInterruptedCallable<Object>() {
209 <                public Object realCall() throws InterruptedException {
210 <                    Thread.sleep(SMALL_DELAY_MS);
211 <                    return Boolean.TRUE;
208 >            new FutureTask(new CheckedCallable<Object>() {
209 >                public Object realCall() {
210 >                    threadStarted.countDown();
211 >                    long t0 = System.nanoTime();
212 >                    for (;;) {
213 >                        if (Thread.interrupted())
214 >                            return Boolean.TRUE;
215 >                        if (millisElapsedSince(t0) > MEDIUM_DELAY_MS)
216 >                            fail("interrupt not delivered");
217 >                        Thread.yield();
218 >                    }
219                  }});
220  
221 <        Thread t = new Thread(task);
222 <        t.start();
155 <        Thread.sleep(SHORT_DELAY_MS);
221 >        Thread t = newStartedThread(task);
222 >        threadStarted.await();
223          assertTrue(task.cancel(true));
224 <        t.join();
225 <        assertTrue(task.isDone());
226 <        assertTrue(task.isCancelled());
224 >        checkCancelled(task);
225 >        awaitTermination(t, MEDIUM_DELAY_MS);
226 >        checkCancelled(task);
227      }
228  
162
229      /**
230       * cancel(false) does not interrupt a running task
231       */
232      public void testCancelNoInterrupt() throws InterruptedException {
233 +        final CountDownLatch threadStarted = new CountDownLatch(1);
234 +        final CountDownLatch cancelled = new CountDownLatch(1);
235 +        final FutureTask<Boolean> task =
236 +            new FutureTask<Boolean>(new CheckedCallable<Boolean>() {
237 +                public Boolean realCall() throws InterruptedException {
238 +                    threadStarted.countDown();
239 +                    cancelled.await(MEDIUM_DELAY_MS, MILLISECONDS);
240 +                    assertFalse(Thread.interrupted());
241 +                    return Boolean.TRUE;
242 +                }});
243 +
244 +        Thread t = newStartedThread(task);
245 +        threadStarted.await();
246 +        assertTrue(task.cancel(false));
247 +        checkCancelled(task);
248 +        cancelled.countDown();
249 +        awaitTermination(t, MEDIUM_DELAY_MS);
250 +        checkCancelled(task);
251 +    }
252 +
253 +    /**
254 +     * run in one thread causes get in another thread to retrieve value
255 +     */
256 +    public void testGetRun() throws InterruptedException {
257 +        final CountDownLatch threadStarted = new CountDownLatch(1);
258 +
259          final FutureTask task =
260              new FutureTask(new CheckedCallable<Object>() {
261                  public Object realCall() throws InterruptedException {
170                    Thread.sleep(MEDIUM_DELAY_MS);
262                      return Boolean.TRUE;
263                  }});
264  
265 <        Thread t = new Thread(task);
266 <        t.start();
267 <        Thread.sleep(SHORT_DELAY_MS);
268 <        assertTrue(task.cancel(false));
269 <        t.join();
270 <        assertTrue(task.isDone());
271 <        assertTrue(task.isCancelled());
265 >        Thread t = newStartedThread(new CheckedRunnable() {
266 >            public void realRun() throws Exception {
267 >                threadStarted.countDown();
268 >                assertSame(Boolean.TRUE, task.get());
269 >            }});
270 >
271 >        threadStarted.await();
272 >        checkNotDone(task);
273 >        assertTrue(t.isAlive());
274 >        task.run();
275 >        checkCompletedNormally(task, Boolean.TRUE);
276 >        awaitTermination(t, MEDIUM_DELAY_MS);
277      }
278  
279      /**
280       * set in one thread causes get in another thread to retrieve value
281       */
282 <    public void testGet1() throws InterruptedException {
283 <        final FutureTask ft =
282 >    public void testGetSet() throws InterruptedException {
283 >        final CountDownLatch threadStarted = new CountDownLatch(1);
284 >
285 >        final PublicFutureTask task =
286 >            new PublicFutureTask(new CheckedCallable<Object>() {
287 >                public Object realCall() throws InterruptedException {
288 >                    return Boolean.TRUE;
289 >                }});
290 >
291 >        Thread t = newStartedThread(new CheckedRunnable() {
292 >            public void realRun() throws Exception {
293 >                threadStarted.countDown();
294 >                assertSame(Boolean.FALSE, task.get());
295 >            }});
296 >
297 >        threadStarted.await();
298 >        checkNotDone(task);
299 >        assertTrue(t.isAlive());
300 >        task.set(Boolean.FALSE);
301 >        checkCompletedNormally(task, Boolean.FALSE);
302 >        awaitTermination(t, MEDIUM_DELAY_MS);
303 >    }
304 >
305 >    /**
306 >     * run in one thread causes timed get in another thread to retrieve value
307 >     */
308 >    public void testTimedGetRun() throws InterruptedException {
309 >        final CountDownLatch threadStarted = new CountDownLatch(1);
310 >
311 >        final FutureTask task =
312              new FutureTask(new CheckedCallable<Object>() {
313                  public Object realCall() throws InterruptedException {
314                      return Boolean.TRUE;
315                  }});
316 <        Thread t = new Thread(new CheckedRunnable() {
316 >
317 >        Thread t = newStartedThread(new CheckedRunnable() {
318              public void realRun() throws Exception {
319 <                assertSame(Boolean.TRUE, ft.get());
319 >                threadStarted.countDown();
320 >                assertSame(Boolean.TRUE,
321 >                           task.get(MEDIUM_DELAY_MS, MILLISECONDS));
322              }});
323  
324 <        assertFalse(ft.isDone());
325 <        assertFalse(ft.isCancelled());
326 <        t.start();
327 <        Thread.sleep(SHORT_DELAY_MS);
328 <        ft.run();
329 <        t.join();
203 <        assertTrue(ft.isDone());
204 <        assertFalse(ft.isCancelled());
324 >        threadStarted.await();
325 >        checkNotDone(task);
326 >        assertTrue(t.isAlive());
327 >        task.run();
328 >        checkCompletedNormally(task, Boolean.TRUE);
329 >        awaitTermination(t, MEDIUM_DELAY_MS);
330      }
331  
332      /**
333       * set in one thread causes timed get in another thread to retrieve value
334       */
335 <    public void testTimedGet1() throws InterruptedException {
336 <        final FutureTask ft =
337 <            new FutureTask(new CheckedCallable<Object>() {
335 >    public void testTimedGetSet() throws InterruptedException {
336 >        final CountDownLatch threadStarted = new CountDownLatch(1);
337 >
338 >        final PublicFutureTask task =
339 >            new PublicFutureTask(new CheckedCallable<Object>() {
340                  public Object realCall() throws InterruptedException {
341                      return Boolean.TRUE;
342                  }});
343 <        Thread t = new Thread(new CheckedRunnable() {
343 >
344 >        Thread t = newStartedThread(new CheckedRunnable() {
345              public void realRun() throws Exception {
346 <                assertSame(Boolean.TRUE, ft.get(SMALL_DELAY_MS, MILLISECONDS));
346 >                threadStarted.countDown();
347 >                assertSame(Boolean.FALSE,
348 >                           task.get(MEDIUM_DELAY_MS, MILLISECONDS));
349              }});
350  
351 <        assertFalse(ft.isDone());
352 <        assertFalse(ft.isCancelled());
353 <        t.start();
354 <        Thread.sleep(SHORT_DELAY_MS);
355 <        ft.run();
356 <        t.join();
227 <        assertTrue(ft.isDone());
228 <        assertFalse(ft.isCancelled());
351 >        threadStarted.await();
352 >        checkNotDone(task);
353 >        assertTrue(t.isAlive());
354 >        task.set(Boolean.FALSE);
355 >        checkCompletedNormally(task, Boolean.FALSE);
356 >        awaitTermination(t, MEDIUM_DELAY_MS);
357      }
358  
359      /**
# Line 233 | Line 361 | public class FutureTaskTest extends JSR1
361       * CancellationException
362       */
363      public void testTimedGet_Cancellation() throws InterruptedException {
364 <        final FutureTask ft =
364 >        final CountDownLatch threadStarted = new CountDownLatch(2);
365 >        final FutureTask task =
366              new FutureTask(new CheckedInterruptedCallable<Object>() {
367                  public Object realCall() throws InterruptedException {
368 <                    Thread.sleep(SMALL_DELAY_MS);
368 >                    threadStarted.countDown();
369 >                    delay(LONG_DELAY_MS);
370                      return Boolean.TRUE;
371                  }});
372  
373          Thread t1 = new ThreadShouldThrow(CancellationException.class) {
374              public void realRun() throws Exception {
375 <                ft.get(MEDIUM_DELAY_MS, MILLISECONDS);
375 >                threadStarted.countDown();
376 >                task.get(MEDIUM_DELAY_MS, MILLISECONDS);
377              }};
378 <        Thread t2 = new Thread(ft);
378 >        Thread t2 = new Thread(task);
379          t1.start();
380          t2.start();
381 <        Thread.sleep(SHORT_DELAY_MS);
382 <        ft.cancel(true);
383 <        t1.join();
384 <        t2.join();
381 >        threadStarted.await();
382 >        task.cancel(true);
383 >        awaitTermination(t1, MEDIUM_DELAY_MS);
384 >        awaitTermination(t2, MEDIUM_DELAY_MS);
385 >        checkCancelled(task);
386      }
387  
388      /**
# Line 258 | Line 390 | public class FutureTaskTest extends JSR1
390       * CancellationException
391       */
392      public void testGet_Cancellation() throws InterruptedException {
393 <        final FutureTask ft =
393 >        final CountDownLatch threadStarted = new CountDownLatch(2);
394 >        final FutureTask task =
395              new FutureTask(new CheckedInterruptedCallable<Object>() {
396                  public Object realCall() throws InterruptedException {
397 <                    Thread.sleep(SMALL_DELAY_MS);
397 >                    threadStarted.countDown();
398 >                    delay(LONG_DELAY_MS);
399                      return Boolean.TRUE;
400                  }});
401 +
402          Thread t1 = new ThreadShouldThrow(CancellationException.class) {
403              public void realRun() throws Exception {
404 <                ft.get();
404 >                threadStarted.countDown();
405 >                task.get();
406              }};
407 <
272 <        Thread t2 = new Thread(ft);
407 >        Thread t2 = new Thread(task);
408          t1.start();
409          t2.start();
410 <        Thread.sleep(SHORT_DELAY_MS);
411 <        ft.cancel(true);
412 <        t1.join();
413 <        t2.join();
410 >        threadStarted.await();
411 >        task.cancel(true);
412 >        awaitTermination(t1, MEDIUM_DELAY_MS);
413 >        awaitTermination(t2, MEDIUM_DELAY_MS);
414 >        checkCancelled(task);
415      }
416  
417  
# Line 283 | Line 419 | public class FutureTaskTest extends JSR1
419       * A runtime exception in task causes get to throw ExecutionException
420       */
421      public void testGet_ExecutionException() throws InterruptedException {
422 <        final FutureTask ft = new FutureTask(new Callable() {
422 >        final FutureTask task = new FutureTask(new Callable() {
423              public Object call() {
424                  return 5/0;
425              }});
426  
427 <        ft.run();
427 >        task.run();
428          try {
429 <            ft.get();
429 >            task.get();
430              shouldThrow();
431          } catch (ExecutionException success) {
432              assertTrue(success.getCause() instanceof ArithmeticException);
433 +            checkCompletedAbnormally(task, success.getCause());
434          }
435      }
436  
# Line 301 | Line 438 | public class FutureTaskTest extends JSR1
438       * A runtime exception in task causes timed get to throw ExecutionException
439       */
440      public void testTimedGet_ExecutionException2() throws Exception {
441 <        final FutureTask ft = new FutureTask(new Callable() {
441 >        final FutureTask task = new FutureTask(new Callable() {
442              public Object call() {
443                  return 5/0;
444              }});
445  
446 <        ft.run();
446 >        task.run();
447          try {
448 <            ft.get(SHORT_DELAY_MS, MILLISECONDS);
448 >            task.get(SHORT_DELAY_MS, MILLISECONDS);
449              shouldThrow();
450          } catch (ExecutionException success) {
451              assertTrue(success.getCause() instanceof ArithmeticException);
452 +            checkCompletedAbnormally(task, success.getCause());
453          }
454      }
455  
# Line 320 | Line 458 | public class FutureTaskTest extends JSR1
458       * Interrupting a waiting get causes it to throw InterruptedException
459       */
460      public void testGet_InterruptedException() throws InterruptedException {
461 <        final FutureTask ft = new FutureTask(new NoOpCallable());
462 <        Thread t = new Thread(new CheckedInterruptedRunnable() {
461 >        final CountDownLatch threadStarted = new CountDownLatch(1);
462 >        final FutureTask task = new FutureTask(new NoOpCallable());
463 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
464              public void realRun() throws Exception {
465 <                ft.get();
465 >                threadStarted.countDown();
466 >                task.get();
467              }});
468  
469 <        t.start();
330 <        Thread.sleep(SHORT_DELAY_MS);
469 >        threadStarted.await();
470          t.interrupt();
471 <        t.join();
471 >        awaitTermination(t, MEDIUM_DELAY_MS);
472 >        checkNotDone(task);
473      }
474  
475      /**
476       * Interrupting a waiting timed get causes it to throw InterruptedException
477       */
478      public void testTimedGet_InterruptedException2() throws InterruptedException {
479 <        final FutureTask ft = new FutureTask(new NoOpCallable());
480 <        Thread t = new Thread(new CheckedInterruptedRunnable() {
479 >        final CountDownLatch threadStarted = new CountDownLatch(1);
480 >        final FutureTask task = new FutureTask(new NoOpCallable());
481 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
482              public void realRun() throws Exception {
483 <                ft.get(LONG_DELAY_MS,MILLISECONDS);
483 >                threadStarted.countDown();
484 >                task.get(LONG_DELAY_MS, MILLISECONDS);
485              }});
486  
487 <        t.start();
346 <        Thread.sleep(SHORT_DELAY_MS);
487 >        threadStarted.await();
488          t.interrupt();
489 <        t.join();
489 >        awaitTermination(t, MEDIUM_DELAY_MS);
490 >        checkNotDone(task);
491      }
492  
493      /**
# Line 353 | Line 495 | public class FutureTaskTest extends JSR1
495       */
496      public void testGet_TimeoutException() throws Exception {
497          try {
498 <            FutureTask ft = new FutureTask(new NoOpCallable());
499 <            ft.get(1,MILLISECONDS);
498 >            FutureTask task = new FutureTask(new NoOpCallable());
499 >            task.get(1, MILLISECONDS);
500              shouldThrow();
501          } catch (TimeoutException success) {}
502      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines