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.22 by jsr166, Sun Nov 28 20:20:00 2010 UTC

# 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 FutureTask task =
234 <            new FutureTask(new CheckedCallable<Object>() {
235 <                public Object realCall() throws InterruptedException {
236 <                    Thread.sleep(MEDIUM_DELAY_MS);
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 = new Thread(task);
245 <        t.start();
176 <        Thread.sleep(SHORT_DELAY_MS);
244 >        Thread t = newStartedThread(task);
245 >        threadStarted.await();
246          assertTrue(task.cancel(false));
247 <        t.join();
248 <        assertTrue(task.isDone());
249 <        assertTrue(task.isCancelled());
247 >        checkCancelled(task);
248 >        cancelled.countDown();
249 >        awaitTermination(t, MEDIUM_DELAY_MS);
250 >        checkCancelled(task);
251      }
252  
253      /**
254       * set in one thread causes get in another thread to retrieve value
255       */
256      public void testGet1() throws InterruptedException {
257 <        final FutureTask ft =
257 >        final FutureTask task =
258              new FutureTask(new CheckedCallable<Object>() {
259                  public Object realCall() throws InterruptedException {
260                      return Boolean.TRUE;
261                  }});
262 <        Thread t = new Thread(new CheckedRunnable() {
262 >        checkNotDone(task);
263 >
264 >        Thread t = newStartedThread(new CheckedRunnable() {
265              public void realRun() throws Exception {
266 <                assertSame(Boolean.TRUE, ft.get());
266 >                assertSame(Boolean.TRUE, task.get());
267              }});
268  
269 <        assertFalse(ft.isDone());
270 <        assertFalse(ft.isCancelled());
271 <        t.start();
200 <        Thread.sleep(SHORT_DELAY_MS);
201 <        ft.run();
202 <        t.join();
203 <        assertTrue(ft.isDone());
204 <        assertFalse(ft.isCancelled());
269 >        task.run();
270 >        checkCompletedNormally(task, Boolean.TRUE);
271 >        awaitTermination(t, MEDIUM_DELAY_MS);
272      }
273  
274      /**
275       * set in one thread causes timed get in another thread to retrieve value
276       */
277      public void testTimedGet1() throws InterruptedException {
278 <        final FutureTask ft =
278 >        final FutureTask task =
279              new FutureTask(new CheckedCallable<Object>() {
280                  public Object realCall() throws InterruptedException {
281                      return Boolean.TRUE;
282                  }});
283 <        Thread t = new Thread(new CheckedRunnable() {
283 >        checkNotDone(task);
284 >
285 >        Thread t = newStartedThread(new CheckedRunnable() {
286              public void realRun() throws Exception {
287 <                assertSame(Boolean.TRUE, ft.get(SMALL_DELAY_MS, MILLISECONDS));
287 >                assertSame(Boolean.TRUE, task.get(SMALL_DELAY_MS, MILLISECONDS));
288              }});
289  
290 <        assertFalse(ft.isDone());
291 <        assertFalse(ft.isCancelled());
292 <        t.start();
224 <        Thread.sleep(SHORT_DELAY_MS);
225 <        ft.run();
226 <        t.join();
227 <        assertTrue(ft.isDone());
228 <        assertFalse(ft.isCancelled());
290 >        task.run();
291 >        checkCompletedNormally(task, Boolean.TRUE);
292 >        awaitTermination(t, MEDIUM_DELAY_MS);
293      }
294  
295      /**
# Line 233 | Line 297 | public class FutureTaskTest extends JSR1
297       * CancellationException
298       */
299      public void testTimedGet_Cancellation() throws InterruptedException {
300 <        final FutureTask ft =
300 >        final CountDownLatch threadStarted = new CountDownLatch(2);
301 >        final FutureTask task =
302              new FutureTask(new CheckedInterruptedCallable<Object>() {
303                  public Object realCall() throws InterruptedException {
304 <                    Thread.sleep(SMALL_DELAY_MS);
304 >                    threadStarted.countDown();
305 >                    Thread.sleep(LONG_DELAY_MS);
306                      return Boolean.TRUE;
307                  }});
308  
309          Thread t1 = new ThreadShouldThrow(CancellationException.class) {
310              public void realRun() throws Exception {
311 <                ft.get(MEDIUM_DELAY_MS, MILLISECONDS);
311 >                threadStarted.countDown();
312 >                task.get(MEDIUM_DELAY_MS, MILLISECONDS);
313              }};
314 <        Thread t2 = new Thread(ft);
314 >        Thread t2 = new Thread(task);
315          t1.start();
316          t2.start();
317 <        Thread.sleep(SHORT_DELAY_MS);
318 <        ft.cancel(true);
319 <        t1.join();
320 <        t2.join();
317 >        threadStarted.await();
318 >        task.cancel(true);
319 >        awaitTermination(t1, MEDIUM_DELAY_MS);
320 >        awaitTermination(t2, MEDIUM_DELAY_MS);
321 >        checkCancelled(task);
322      }
323  
324      /**
# Line 258 | Line 326 | public class FutureTaskTest extends JSR1
326       * CancellationException
327       */
328      public void testGet_Cancellation() throws InterruptedException {
329 <        final FutureTask ft =
329 >        final CountDownLatch threadStarted = new CountDownLatch(2);
330 >        final FutureTask task =
331              new FutureTask(new CheckedInterruptedCallable<Object>() {
332                  public Object realCall() throws InterruptedException {
333 <                    Thread.sleep(SMALL_DELAY_MS);
333 >                    threadStarted.countDown();
334 >                    Thread.sleep(LONG_DELAY_MS);
335                      return Boolean.TRUE;
336                  }});
337 +
338          Thread t1 = new ThreadShouldThrow(CancellationException.class) {
339              public void realRun() throws Exception {
340 <                ft.get();
340 >                threadStarted.countDown();
341 >                task.get();
342              }};
343 <
272 <        Thread t2 = new Thread(ft);
343 >        Thread t2 = new Thread(task);
344          t1.start();
345          t2.start();
346 <        Thread.sleep(SHORT_DELAY_MS);
347 <        ft.cancel(true);
348 <        t1.join();
349 <        t2.join();
346 >        threadStarted.await();
347 >        task.cancel(true);
348 >        awaitTermination(t1, MEDIUM_DELAY_MS);
349 >        awaitTermination(t2, MEDIUM_DELAY_MS);
350 >        checkCancelled(task);
351      }
352  
353  
# Line 283 | Line 355 | public class FutureTaskTest extends JSR1
355       * A runtime exception in task causes get to throw ExecutionException
356       */
357      public void testGet_ExecutionException() throws InterruptedException {
358 <        final FutureTask ft = new FutureTask(new Callable() {
358 >        final FutureTask task = new FutureTask(new Callable() {
359              public Object call() {
360                  return 5/0;
361              }});
362  
363 <        ft.run();
363 >        task.run();
364          try {
365 <            ft.get();
365 >            task.get();
366              shouldThrow();
367          } catch (ExecutionException success) {
368              assertTrue(success.getCause() instanceof ArithmeticException);
369 +            checkCompletedAbnormally(task, success.getCause());
370          }
371      }
372  
# Line 301 | Line 374 | public class FutureTaskTest extends JSR1
374       * A runtime exception in task causes timed get to throw ExecutionException
375       */
376      public void testTimedGet_ExecutionException2() throws Exception {
377 <        final FutureTask ft = new FutureTask(new Callable() {
377 >        final FutureTask task = new FutureTask(new Callable() {
378              public Object call() {
379                  return 5/0;
380              }});
381  
382 <        ft.run();
382 >        task.run();
383          try {
384 <            ft.get(SHORT_DELAY_MS, MILLISECONDS);
384 >            task.get(SHORT_DELAY_MS, MILLISECONDS);
385              shouldThrow();
386          } catch (ExecutionException success) {
387              assertTrue(success.getCause() instanceof ArithmeticException);
388 +            checkCompletedAbnormally(task, success.getCause());
389          }
390      }
391  
# Line 320 | Line 394 | public class FutureTaskTest extends JSR1
394       * Interrupting a waiting get causes it to throw InterruptedException
395       */
396      public void testGet_InterruptedException() throws InterruptedException {
397 <        final FutureTask ft = new FutureTask(new NoOpCallable());
398 <        Thread t = new Thread(new CheckedInterruptedRunnable() {
397 >        final CountDownLatch threadStarted = new CountDownLatch(1);
398 >        final FutureTask task = new FutureTask(new NoOpCallable());
399 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
400              public void realRun() throws Exception {
401 <                ft.get();
401 >                threadStarted.countDown();
402 >                task.get();
403              }});
404  
405 <        t.start();
330 <        Thread.sleep(SHORT_DELAY_MS);
405 >        threadStarted.await();
406          t.interrupt();
407 <        t.join();
407 >        awaitTermination(t, MEDIUM_DELAY_MS);
408 >        checkNotDone(task);
409      }
410  
411      /**
412       * Interrupting a waiting timed get causes it to throw InterruptedException
413       */
414      public void testTimedGet_InterruptedException2() throws InterruptedException {
415 <        final FutureTask ft = new FutureTask(new NoOpCallable());
416 <        Thread t = new Thread(new CheckedInterruptedRunnable() {
415 >        final CountDownLatch threadStarted = new CountDownLatch(1);
416 >        final FutureTask task = new FutureTask(new NoOpCallable());
417 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
418              public void realRun() throws Exception {
419 <                ft.get(LONG_DELAY_MS,MILLISECONDS);
419 >                threadStarted.countDown();
420 >                task.get(LONG_DELAY_MS, MILLISECONDS);
421              }});
422  
423 <        t.start();
346 <        Thread.sleep(SHORT_DELAY_MS);
423 >        threadStarted.await();
424          t.interrupt();
425 <        t.join();
425 >        awaitTermination(t, MEDIUM_DELAY_MS);
426 >        checkNotDone(task);
427      }
428  
429      /**
# Line 353 | Line 431 | public class FutureTaskTest extends JSR1
431       */
432      public void testGet_TimeoutException() throws Exception {
433          try {
434 <            FutureTask ft = new FutureTask(new NoOpCallable());
435 <            ft.get(1,MILLISECONDS);
434 >            FutureTask task = new FutureTask(new NoOpCallable());
435 >            task.get(1, MILLISECONDS);
436              shouldThrow();
437          } catch (TimeoutException success) {}
438      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines