• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.util.concurrent;
18 
19 import static com.google.common.base.Throwables.propagateIfInstanceOf;
20 import static com.google.common.util.concurrent.Futures.allAsList;
21 import static com.google.common.util.concurrent.Futures.get;
22 import static com.google.common.util.concurrent.Futures.getUnchecked;
23 import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
24 import static com.google.common.util.concurrent.Futures.immediateFuture;
25 import static com.google.common.util.concurrent.Futures.successfulAsList;
26 import static java.util.concurrent.Executors.newSingleThreadExecutor;
27 import static java.util.concurrent.TimeUnit.MILLISECONDS;
28 import static java.util.concurrent.TimeUnit.SECONDS;
29 import static org.junit.contrib.truth.Truth.ASSERT;
30 
31 import com.google.common.base.Function;
32 import com.google.common.base.Functions;
33 import com.google.common.base.Joiner;
34 import com.google.common.collect.ImmutableList;
35 import com.google.common.collect.ImmutableSet;
36 import com.google.common.collect.Iterables;
37 import com.google.common.collect.Sets;
38 import com.google.common.testing.NullPointerTester;
39 import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
40 
41 import junit.framework.AssertionFailedError;
42 import junit.framework.TestCase;
43 
44 import org.easymock.EasyMock;
45 import org.easymock.IMocksControl;
46 
47 import java.io.IOException;
48 import java.util.Arrays;
49 import java.util.List;
50 import java.util.Set;
51 import java.util.concurrent.Callable;
52 import java.util.concurrent.CancellationException;
53 import java.util.concurrent.CountDownLatch;
54 import java.util.concurrent.ExecutionException;
55 import java.util.concurrent.Executor;
56 import java.util.concurrent.ExecutorService;
57 import java.util.concurrent.Future;
58 import java.util.concurrent.TimeUnit;
59 import java.util.concurrent.TimeoutException;
60 
61 import javax.annotation.Nullable;
62 
63 /**
64  * Unit tests for {@link Futures}.
65  *
66  * TODO: Add tests for other Futures methods
67  *
68  * @author Nishant Thakkar
69  */
70 public class FuturesTest extends TestCase {
71   private static final String DATA1 = "data";
72   private static final String DATA2 = "more data";
73   private static final String DATA3 = "most data";
74 
75   private IMocksControl mocksControl;
76 
setUp()77   @Override protected void setUp() throws Exception {
78     super.setUp();
79 
80     mocksControl = EasyMock.createControl();
81   }
82 
tearDown()83   @Override protected void tearDown() throws Exception {
84     /*
85      * Clear interrupt for future tests.
86      *
87      * (Ideally we would perform interrupts only in threads that we create, but
88      * it's hard to imagine that anything will break in practice.)
89      */
90     Thread.interrupted();
91 
92     super.tearDown();
93   }
94 
testImmediateFuture()95   public void testImmediateFuture() throws Exception {
96     ListenableFuture<String> future = Futures.immediateFuture(DATA1);
97 
98     // Verify that the proper object is returned without waiting
99     assertSame(DATA1, future.get(0L, TimeUnit.MILLISECONDS));
100   }
101 
testMultipleImmediateFutures()102   public void testMultipleImmediateFutures() throws Exception {
103     ListenableFuture<String> future1 = Futures.immediateFuture(DATA1);
104     ListenableFuture<String> future2 = Futures.immediateFuture(DATA2);
105 
106     // Verify that the proper objects are returned without waiting
107     assertSame(DATA1, future1.get(0L, TimeUnit.MILLISECONDS));
108     assertSame(DATA2, future2.get(0L, TimeUnit.MILLISECONDS));
109   }
110 
testImmediateFailedFuture()111   public void testImmediateFailedFuture() throws Exception {
112     Exception exception = new Exception();
113     ListenableFuture<String> future =
114         Futures.immediateFailedFuture(exception);
115 
116     try {
117       future.get(0L, TimeUnit.MILLISECONDS);
118       fail("This call was supposed to throw an ExecutionException");
119     } catch (ExecutionException expected) {
120       // This is good and expected
121       assertSame(exception, expected.getCause());
122     }
123   }
124 
125   private static class MyException extends Exception {}
126 
testImmediateCheckedFuture()127   public void testImmediateCheckedFuture() throws Exception {
128     CheckedFuture<String, MyException> future = Futures.immediateCheckedFuture(
129         DATA1);
130 
131     // Verify that the proper object is returned without waiting
132     assertSame(DATA1, future.get(0L, TimeUnit.MILLISECONDS));
133     assertSame(DATA1, future.checkedGet(0L, TimeUnit.MILLISECONDS));
134   }
135 
testMultipleImmediateCheckedFutures()136   public void testMultipleImmediateCheckedFutures() throws Exception {
137     CheckedFuture<String, MyException> future1 = Futures.immediateCheckedFuture(
138         DATA1);
139     CheckedFuture<String, MyException> future2 = Futures.immediateCheckedFuture(
140         DATA2);
141 
142     // Verify that the proper objects are returned without waiting
143     assertSame(DATA1, future1.get(0L, TimeUnit.MILLISECONDS));
144     assertSame(DATA1, future1.checkedGet(0L, TimeUnit.MILLISECONDS));
145     assertSame(DATA2, future2.get(0L, TimeUnit.MILLISECONDS));
146     assertSame(DATA2, future2.checkedGet(0L, TimeUnit.MILLISECONDS));
147   }
148 
testImmediateFailedCheckedFuture()149   public void testImmediateFailedCheckedFuture() throws Exception {
150     MyException exception = new MyException();
151     CheckedFuture<String, MyException> future =
152         Futures.immediateFailedCheckedFuture(exception);
153 
154     try {
155       future.get(0L, TimeUnit.MILLISECONDS);
156       fail("This call was supposed to throw an ExecutionException");
157     } catch (ExecutionException expected) {
158       // This is good and expected
159       assertSame(exception, expected.getCause());
160     }
161 
162     try {
163       future.checkedGet(0L, TimeUnit.MILLISECONDS);
164       fail("This call was supposed to throw an MyException");
165     } catch (MyException expected) {
166       // This is good and expected
167       assertSame(exception, expected);
168     }
169   }
170 
171   // Class hierarchy for generics sanity checks
172   private static class Foo {}
173   private static class FooChild extends Foo {}
174   private static class Bar {}
175   private static class BarChild extends Bar {}
176 
testTransform_ListenableFuture_genericsNull()177   public void testTransform_ListenableFuture_genericsNull() throws Exception {
178     ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
179     ListenableFuture<?> transformedFuture =
180         Futures.transform(nullFuture, Functions.constant(null));
181     assertNull(transformedFuture.get());
182   }
183 
testTransform_ListenableFuture_genericsHierarchy()184   public void testTransform_ListenableFuture_genericsHierarchy()
185       throws Exception {
186     ListenableFuture<FooChild> future = Futures.immediateFuture(null);
187     final BarChild barChild = new BarChild();
188     Function<Foo, BarChild> function = new Function<Foo, BarChild>() {
189       @Override public BarChild apply(Foo unused) {
190         return barChild;
191       }
192     };
193     Bar bar = Futures.transform(future, function).get();
194     assertSame(barChild, bar);
195   }
196 
197   /**
198    * {@link ListenableFuture} variant of
199    * {@link #testTransformValueRemainsMemoized_Future()}.
200    */
testTransformValueRemainsMemoized_ListenableFuture()201   public void testTransformValueRemainsMemoized_ListenableFuture()
202       throws Exception {
203     class Holder {
204       int value = 2;
205     }
206     final Holder holder = new Holder();
207 
208     // This function adds the holder's value to the input value.
209     Function<Integer, Integer> adder = new Function<Integer, Integer>() {
210       @Override public Integer apply(Integer from) {
211         return from + holder.value;
212       }
213     };
214 
215     // Since holder.value is 2, applying 4 should yield 6.
216     assertEquals(6, adder.apply(4).intValue());
217 
218     ListenableFuture<Integer> immediateFuture = Futures.immediateFuture(4);
219     Future<Integer> transformedFuture = Futures.transform(immediateFuture, adder);
220 
221     // The composed future also yields 6.
222     assertEquals(6, transformedFuture.get().intValue());
223 
224     // Repeated calls yield the same value even though the function's behavior
225     // changes
226     holder.value = 3;
227     assertEquals(6, transformedFuture.get().intValue());
228     assertEquals(7, adder.apply(4).intValue());
229 
230     // Once more, with feeling.
231     holder.value = 4;
232     assertEquals(6, transformedFuture.get().intValue());
233     assertEquals(8, adder.apply(4).intValue());
234 
235     // Memoized get also retains the value.
236     assertEquals(6, transformedFuture.get(1000, TimeUnit.SECONDS).intValue());
237 
238     // Unsurprisingly, recomposing the future will return an updated value.
239     assertEquals(8, Futures.transform(immediateFuture, adder).get().intValue());
240 
241     // Repeating, with the timeout version
242     assertEquals(8, Futures.transform(immediateFuture, adder).get(
243         1000, TimeUnit.SECONDS).intValue());
244   }
245 
246   static class MyError extends Error {}
247   static class MyRuntimeException extends RuntimeException {}
248 
249   /**
250    * {@link ListenableFuture} variant of
251    * {@link #testTransformExceptionRemainsMemoized_Future()}.
252    */
testTransformExceptionRemainsMemoized_ListenableFuture()253   public void testTransformExceptionRemainsMemoized_ListenableFuture()
254       throws Throwable {
255     SettableFuture<Integer> input = SettableFuture.create();
256 
257     ListenableFuture<Integer> exceptionComposedFuture =
258         Futures.transform(input, newOneTimeExceptionThrower());
259     ListenableFuture<Integer> errorComposedFuture =
260         Futures.transform(input, newOneTimeErrorThrower());
261 
262     try {
263       input.set(0);
264       fail();
265     } catch (MyError expected) {
266       /*
267        * The ListenableFuture variant rethrows errors from execute() as well
268        * as assigning them to the output of the future.
269        */
270     }
271 
272     runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class);
273     runGetIdempotencyTest(errorComposedFuture, MyError.class);
274 
275     /*
276      * Try again when the input's value is already filled in, since the flow is
277      * slightly different in that case.
278      */
279     exceptionComposedFuture =
280         Futures.transform(input, newOneTimeExceptionThrower());
281     runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class);
282 
283     try {
284       Futures.transform(input, newOneTimeErrorThrower());
285       fail();
286     } catch (MyError expected) {
287     }
288   }
289 
runGetIdempotencyTest(Future<Integer> transformedFuture, Class<? extends Throwable> expectedExceptionClass)290   private static void runGetIdempotencyTest(Future<Integer> transformedFuture,
291       Class<? extends Throwable> expectedExceptionClass) throws Throwable {
292     for (int i = 0; i < 5; i++) {
293       try {
294         transformedFuture.get();
295         fail();
296       } catch (ExecutionException expected) {
297         if (!expectedExceptionClass.isInstance(expected.getCause())) {
298           throw expected.getCause();
299         }
300       }
301     }
302   }
303 
newOneTimeValueReturner(final O output)304   private static <I, O> Function<I, O> newOneTimeValueReturner(final O output) {
305     return new Function<I, O>() {
306       int calls = 0;
307 
308       @Override
309       public O apply(I arg0) {
310         if (++calls > 1) {
311           fail();
312         }
313         return output;
314       }
315     };
316   }
317 
newOneTimeExceptionThrower()318   private static Function<Integer, Integer> newOneTimeExceptionThrower() {
319     return new Function<Integer, Integer>() {
320       int calls = 0;
321 
322       @Override public Integer apply(Integer from) {
323         if (++calls > 1) {
324           fail();
325         }
326         throw new MyRuntimeException();
327       }
328     };
329   }
330 
331   private static Function<Integer, Integer> newOneTimeErrorThrower() {
332     return new Function<Integer, Integer>() {
333       int calls = 0;
334 
335       @Override public Integer apply(Integer from) {
336         if (++calls > 1) {
337           fail();
338         }
339         throw new MyError();
340       }
341     };
342   }
343 
344   // TODO(cpovirk): top-level class?
345   static class ExecutorSpy implements Executor {
346     Executor delegate;
347     boolean wasExecuted;
348 
349     public ExecutorSpy(Executor delegate) {
350       this.delegate = delegate;
351     }
352 
353     @Override public void execute(Runnable command) {
354       delegate.execute(command);
355       wasExecuted = true;
356     }
357   }
358 
359   public void testTransform_Executor() throws Exception {
360     Object value = new Object();
361     ExecutorSpy spy = new ExecutorSpy(MoreExecutors.sameThreadExecutor());
362 
363     assertFalse(spy.wasExecuted);
364 
365     ListenableFuture<Object> future = Futures.transform(
366         Futures.immediateFuture(value),
367         Functions.identity(), spy);
368 
369     assertSame(value, future.get());
370     assertTrue(spy.wasExecuted);
371   }
372 
373   public void testLazyTransform() throws Exception {
374     FunctionSpy<Object, String> spy =
375         new FunctionSpy<Object, String>(Functions.constant("bar"));
376     Future<String> input = Futures.immediateFuture("foo");
377     Future<String> transformed = Futures.lazyTransform(input, spy);
378     assertEquals(0, spy.getApplyCount());
379     assertEquals("bar", transformed.get());
380     assertEquals(1, spy.getApplyCount());
381     assertEquals("bar", transformed.get());
382     assertEquals(2, spy.getApplyCount());
383   }
384 
385   private static class FunctionSpy<I, O> implements Function<I, O> {
386     private int applyCount;
387     private final Function<I, O> delegate;
388 
389     public FunctionSpy(Function<I, O> delegate) {
390       this.delegate = delegate;
391     }
392 
393     @Override
394     public O apply(I input) {
395       applyCount++;
396       return delegate.apply(input);
397     }
398 
399     public int getApplyCount() {
400       return applyCount;
401     }
402   }
403 
404   public void testTransform_genericsWildcard_AsyncFunction() throws Exception {
405     ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
406     ListenableFuture<?> chainedFuture =
407         Futures.transform(nullFuture, constantAsyncFunction(nullFuture));
408     assertNull(chainedFuture.get());
409   }
410 
411   private static <I, O> AsyncFunction<I, O> constantAsyncFunction(
412       final ListenableFuture<O> output) {
413     return new AsyncFunction<I, O>() {
414       @Override
415       public ListenableFuture<O> apply(I input) {
416         return output;
417       }
418     };
419   }
420 
421   public void testTransform_genericsHierarchy_AsyncFunction() throws Exception {
422     ListenableFuture<FooChild> future = Futures.immediateFuture(null);
423     final BarChild barChild = new BarChild();
424     AsyncFunction<Foo, BarChild> function =
425         new AsyncFunction<Foo, BarChild>() {
426           @Override public AbstractFuture<BarChild> apply(Foo unused) {
427             AbstractFuture<BarChild> future = new AbstractFuture<BarChild>() {};
428             future.set(barChild);
429             return future;
430           }
431         };
432     Bar bar = Futures.transform(future, function).get();
433     assertSame(barChild, bar);
434   }
435 
436   public void testTransform_delegatesBlockingGet_AsyncFunction() throws Exception {
437     performAsyncFunctionTransformedFutureDelgationTest(0, null);
438   }
439 
440   public void testTransform_delegatesTimedGet_AsyncFunction() throws Exception {
441     performAsyncFunctionTransformedFutureDelgationTest(25, TimeUnit.SECONDS);
442   }
443 
444   private void performAsyncFunctionTransformedFutureDelgationTest(
445       long timeout, TimeUnit unit)
446       throws InterruptedException, ExecutionException, TimeoutException {
447     final Foo foo = new Foo();
448     MockRequiresGetCallFuture<Foo> fooFuture =
449         new MockRequiresGetCallFuture<Foo>(foo);
450 
451     Bar bar = new Bar();
452     final MockRequiresGetCallFuture<Bar> barFuture =
453         new MockRequiresGetCallFuture<Bar>(bar);
454     AsyncFunction<Foo, Bar> function =
455         new AsyncFunction<Foo, Bar>() {
456           @Override public ListenableFuture<Bar> apply(Foo from) {
457             assertSame(foo, from);
458             return barFuture;
459           }
460         };
461 
462     ListenableFuture<Bar> chainFuture = Futures.transform(fooFuture, function);
463     Bar theBar;
464     if (unit != null) {
465       theBar = chainFuture.get(timeout, unit);
466     } else {
467       theBar = chainFuture.get();
468     }
469     assertSame(bar, theBar);
470     assertTrue(fooFuture.getWasGetCalled());
471     assertTrue(barFuture.getWasGetCalled());
472   }
473 
474   /**
475    * A mock listenable future that requires the caller invoke
476    * either form of get() before the future will make its value
477    * available or invoke listeners.
478    */
479   private static class MockRequiresGetCallFuture<T> extends AbstractFuture<T> {
480 
481     private final T value;
482     private boolean getWasCalled;
483 
484     MockRequiresGetCallFuture(T value) {
485       this.value = value;
486     }
487 
488     @Override public T get() throws InterruptedException, ExecutionException {
489       set(value);
490       getWasCalled = true;
491       return super.get();
492     }
493 
494     @Override public T get(long timeout, TimeUnit unit)
495         throws TimeoutException, ExecutionException, InterruptedException {
496       set(value);
497       getWasCalled = true;
498       return super.get(timeout, unit);
499     }
500 
501     boolean getWasGetCalled() {
502       return getWasCalled;
503     }
504   }
505 
506   /**
507    * Runnable which can be called a single time, and only after
508    * {@link #expectCall} is called.
509    */
510   // TODO(cpovirk): top-level class?
511   static class SingleCallListener implements Runnable {
512     private boolean expectCall = false;
513     private final CountDownLatch calledCountDown =
514         new CountDownLatch(1);
515 
516     @Override public void run() {
517       assertTrue("Listener called before it was expected", expectCall);
518       assertFalse("Listener called more than once", wasCalled());
519       calledCountDown.countDown();
520     }
521 
522     public void expectCall() {
523       assertFalse("expectCall is already true", expectCall);
524       expectCall = true;
525     }
526 
527     public boolean wasCalled() {
528       return calledCountDown.getCount() == 0;
529     }
530 
531     public void waitForCall() throws InterruptedException {
532       assertTrue("expectCall is false", expectCall);
533       calledCountDown.await();
534     }
535   }
536 
537   public void testAllAsList() throws Exception {
538     // Create input and output
539     SettableFuture<String> future1 = SettableFuture.create();
540     SettableFuture<String> future2 = SettableFuture.create();
541     SettableFuture<String> future3 = SettableFuture.create();
542     @SuppressWarnings("unchecked") // array is never modified
543     ListenableFuture<List<String>> compound =
544         Futures.allAsList(future1, future2, future3);
545 
546     // Attach a listener
547     SingleCallListener listener = new SingleCallListener();
548     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
549 
550     // Satisfy each input and check the output
551     assertFalse(compound.isDone());
552     future1.set(DATA1);
553     assertFalse(compound.isDone());
554     future2.set(DATA2);
555     assertFalse(compound.isDone());
556     listener.expectCall();
557     future3.set(DATA3);
558     assertTrue(compound.isDone());
559     assertTrue(listener.wasCalled());
560 
561     List<String> results = compound.get();
562     ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
563   }
564 
565   public void testAllAsList_emptyList() throws Exception {
566     SingleCallListener listener = new SingleCallListener();
567     listener.expectCall();
568     List<ListenableFuture<String>> futures = ImmutableList.of();
569     ListenableFuture<List<String>> compound = Futures.allAsList(futures);
570     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
571     assertTrue(compound.isDone());
572     assertTrue(compound.get().isEmpty());
573     assertTrue(listener.wasCalled());
574   }
575 
576   public void testAllAsList_emptyArray() throws Exception {
577     SingleCallListener listener = new SingleCallListener();
578     listener.expectCall();
579     @SuppressWarnings("unchecked") // array is never modified
580     ListenableFuture<List<String>> compound = Futures.allAsList();
581     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
582     assertTrue(compound.isDone());
583     assertTrue(compound.get().isEmpty());
584     assertTrue(listener.wasCalled());
585   }
586 
587   public void testAllAsList_failure() throws Exception {
588     SingleCallListener listener = new SingleCallListener();
589     SettableFuture<String> future1 = SettableFuture.create();
590     SettableFuture<String> future2 = SettableFuture.create();
591     @SuppressWarnings("unchecked") // array is never modified
592     ListenableFuture<List<String>> compound =
593         Futures.allAsList(future1, future2);
594     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
595 
596     listener.expectCall();
597     Throwable exception = new Throwable("failed1");
598     future1.setException(exception);
599     assertTrue(compound.isDone());
600     assertTrue(listener.wasCalled());
601     future2.set("result2");
602 
603     try {
604       compound.get();
605       fail("Expected exception not thrown");
606     } catch (ExecutionException e) {
607       assertSame(exception, e.getCause());
608     }
609   }
610 
611   public void testAllAsList_singleFailure() throws Exception {
612     Throwable exception = new Throwable("failed");
613     ListenableFuture<String> future = Futures.immediateFailedFuture(exception);
614     ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future));
615 
616     try {
617       compound.get();
618       fail("Expected exception not thrown");
619     } catch (ExecutionException e) {
620       assertSame(exception, e.getCause());
621     }
622   }
623 
624   public void testAllAsList_immediateFailure() throws Exception {
625     Throwable exception = new Throwable("failed");
626     ListenableFuture<String> future1 = Futures.immediateFailedFuture(exception);
627     ListenableFuture<String> future2 = Futures.immediateFuture("results");
628     ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2));
629 
630     try {
631       compound.get();
632       fail("Expected exception not thrown");
633     } catch (ExecutionException e) {
634       assertSame(exception, e.getCause());
635     }
636   }
637 
638   public void testAllAsList_cancelled() throws Exception {
639     SingleCallListener listener = new SingleCallListener();
640     SettableFuture<String> future1 = SettableFuture.create();
641     SettableFuture<String> future2 = SettableFuture.create();
642     @SuppressWarnings("unchecked") // array is never modified
643     ListenableFuture<List<String>> compound =
644         Futures.allAsList(future1, future2);
645     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
646 
647     listener.expectCall();
648     future1.cancel(true);
649     assertTrue(compound.isDone());
650     assertTrue(listener.wasCalled());
651     future2.setException(new Throwable("failed2"));
652 
653     try {
654       compound.get();
655       fail("Expected exception not thrown");
656     } catch (CancellationException e) {
657       // Expected
658     }
659   }
660 
661   public void testAllAsList_buggyInputFutures() throws Exception {
662     final Foo foo1 = new Foo();
663     MockRequiresGetCallFuture<Foo> foo1Future =
664         new MockRequiresGetCallFuture<Foo>(foo1);
665     final Foo foo2 = new Foo();
666     MockRequiresGetCallFuture<Foo> foo2Future =
667         new MockRequiresGetCallFuture<Foo>(foo2);
668 
669     @SuppressWarnings("unchecked") // array is never modified
670     ListenableFuture<List<Foo>> compound =
671         Futures.allAsList(foo1Future, foo2Future);
672 
673     assertFalse(compound.isDone());
674     ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
675     assertTrue(foo1Future.getWasGetCalled());
676     assertTrue(foo2Future.getWasGetCalled());
677   }
678 
679   /**
680    * Test the case where the futures are fulfilled prior to
681    * constructing the ListFuture.  There was a bug where the
682    * loop that connects a Listener to each of the futures would die
683    * on the last loop-check as done() on ListFuture nulled out the
684    * variable being looped over (the list of futures).
685    */
686   public void testAllAsList_doneFutures() throws Exception {
687     // Create input and output
688     SettableFuture<String> future1 = SettableFuture.create();
689     SettableFuture<String> future2 = SettableFuture.create();
690     SettableFuture<String> future3 = SettableFuture.create();
691 
692     // Satisfy each input prior to creating compound and check the output
693     future1.set(DATA1);
694     future2.set(DATA2);
695     future3.set(DATA3);
696 
697     @SuppressWarnings("unchecked") // array is never modified
698     ListenableFuture<List<String>> compound =
699         Futures.allAsList(future1, future2, future3);
700 
701     // Attach a listener
702     SingleCallListener listener = new SingleCallListener();
703     listener.expectCall();
704     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
705 
706     assertTrue(compound.isDone());
707     assertTrue(listener.wasCalled());
708 
709     List<String> results = compound.get();
710     ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
711   }
712 
713   private String createCombinedResult(Integer i, Boolean b) {
714     return "-" + i + "-" + b;
715   }
716 
717   /*
718    * TODO(cpovirk): maybe pass around TestFuture instances instead of
719    * ListenableFuture instances
720    */
721   /**
722    * A future in {@link TestFutureBatch} that also has a name for debugging
723    * purposes and a {@code finisher}, a task that will complete the future in
724    * some fashion when it is called, allowing for testing both before and after
725    * the completion of the future.
726    */
727   private static final class TestFuture {
728     final ListenableFuture<String> future;
729     final String name;
730     final Runnable finisher;
731 
732     TestFuture(
733         ListenableFuture<String> future, String name, Runnable finisher) {
734       this.future = future;
735       this.name = name;
736       this.finisher = finisher;
737     }
738   }
739 
740   /**
741    * A collection of several futures, covering cancellation, success, and
742    * failure (both {@link ExecutionException} and {@link RuntimeException}),
743    * both immediate and delayed. We use each possible pair of these futures in
744    * {@link FuturesTest#runExtensiveMergerTest}.
745    *
746    * <p>Each test requires a new {@link TestFutureBatch} because we need new
747    * delayed futures each time, as the old delayed futures were completed as
748    * part of the old test.
749    */
750   private static final class TestFutureBatch {
751     final ListenableFuture<String> doneSuccess = immediateFuture("a");
752     final ListenableFuture<String> doneFailed =
753         immediateFailedFuture(new Exception());
754     final SettableFuture<String> doneCancelled = SettableFuture.create();
755     {
756       doneCancelled.cancel(true);
757     }
758 
759     final ListenableFuture<String> doneRuntimeException =
760         new ForwardingListenableFuture<String>() {
761           final ListenableFuture<String> delegate =
762               immediateFuture("Should never be seen");
763 
764           @Override
765           protected ListenableFuture<String> delegate() {
766             return delegate;
767           }
768 
769           @Override
770           public String get() {
771             throw new RuntimeException();
772           }
773 
774           @Override
775           public String get(long timeout, TimeUnit unit) {
776             throw new RuntimeException();
777           }
778     };
779 
780     final SettableFuture<String> delayedSuccess = SettableFuture.create();
781     final SettableFuture<String> delayedFailed = SettableFuture.create();
782     final SettableFuture<String> delayedCancelled = SettableFuture.create();
783 
784     final SettableFuture<String> delegateForDelayedRuntimeException =
785         SettableFuture.create();
786     final ListenableFuture<String> delayedRuntimeException =
787         new ForwardingListenableFuture<String>() {
788           @Override
789           protected ListenableFuture<String> delegate() {
790             return delegateForDelayedRuntimeException;
791           }
792 
793           @Override
794           public String get() throws ExecutionException, InterruptedException {
795             delegateForDelayedRuntimeException.get();
796             throw new RuntimeException();
797           }
798 
799           @Override
800           public String get(long timeout, TimeUnit unit) throws
801               ExecutionException, InterruptedException, TimeoutException {
802             delegateForDelayedRuntimeException.get(timeout, unit);
803             throw new RuntimeException();
804           }
805     };
806 
807     final Runnable doNothing = new Runnable() {
808       @Override
809       public void run() {
810       }
811     };
812     final Runnable finishSuccess = new Runnable() {
813       @Override
814       public void run() {
815         delayedSuccess.set("b");
816       }
817     };
818     final Runnable finishFailure = new Runnable() {
819       @Override
820       public void run() {
821         delayedFailed.setException(new Exception());
822       }
823     };
824     final Runnable finishCancelled = new Runnable() {
825       @Override
826       public void run() {
827         delayedCancelled.cancel(true);
828       }
829     };
830     final Runnable finishRuntimeException = new Runnable() {
831       @Override
832       public void run() {
833         delegateForDelayedRuntimeException.set("Should never be seen");
834       }
835     };
836 
837     /**
838      * All the futures, together with human-readable names for use by
839      * {@link #smartToString}.
840      */
841     final ImmutableList<TestFuture> allFutures =
842         ImmutableList.of(new TestFuture(doneSuccess, "doneSuccess", doNothing),
843             new TestFuture(doneFailed, "doneFailed", doNothing),
844             new TestFuture(doneCancelled, "doneCancelled", doNothing),
845             new TestFuture(
846                 doneRuntimeException, "doneRuntimeException", doNothing),
847             new TestFuture(delayedSuccess, "delayedSuccess", finishSuccess),
848             new TestFuture(delayedFailed, "delayedFailed", finishFailure),
849             new TestFuture(
850                 delayedCancelled, "delayedCancelled", finishCancelled),
851             new TestFuture(delayedRuntimeException, "delayedRuntimeException",
852                 finishRuntimeException));
853 
854     final Function<ListenableFuture<String>, String> nameGetter =
855       new Function<ListenableFuture<String>, String>() {
856         @Override
857         public String apply(ListenableFuture<String> input) {
858           for (TestFuture future : allFutures) {
859             if (future.future == input) {
860               return future.name;
861             }
862           }
863           throw new IllegalArgumentException(input.toString());
864         }
865       };
866 
867     static boolean intersect(Set<?> a, Set<?> b) {
868       return !Sets.intersection(a, b).isEmpty();
869     }
870 
871     /**
872      * Like {@code inputs.toString()}, but with the nonsense {@code toString}
873      * representations replaced with the name of each future from
874      * {@link #allFutures}.
875      */
876     String smartToString(ImmutableSet<ListenableFuture<String>> inputs) {
877       Iterable<String> inputNames = Iterables.transform(inputs, nameGetter);
878       return Joiner.on(", ").join(inputNames);
879     }
880 
881     void smartAssertTrue(ImmutableSet<ListenableFuture<String>> inputs,
882         Exception cause, boolean expression) {
883       if (!expression) {
884         failWithCause(cause, smartToString(inputs));
885       }
886     }
887 
888     boolean hasDelayed(ListenableFuture<String> a, ListenableFuture<String> b) {
889       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
890       return intersect(inputs, ImmutableSet.of(
891           delayedSuccess, delayedFailed, delayedCancelled,
892           delayedRuntimeException));
893     }
894 
895     void assertHasDelayed(
896         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
897       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
898       smartAssertTrue(inputs, e, hasDelayed(a, b));
899     }
900 
901     void assertHasFailure(
902         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
903       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
904       smartAssertTrue(inputs, e, intersect(inputs, ImmutableSet.of(doneFailed,
905           doneRuntimeException, delayedFailed, delayedRuntimeException)));
906     }
907 
908     void assertHasCancel(
909         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
910       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
911       smartAssertTrue(inputs, e,
912           intersect(inputs, ImmutableSet.of(doneCancelled, delayedCancelled)));
913     }
914 
915     void assertHasImmediateFailure(
916         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
917       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
918       smartAssertTrue(inputs, e, intersect(
919           inputs, ImmutableSet.of(doneFailed, doneRuntimeException)));
920     }
921 
922     void assertHasImmediateCancel(
923         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
924       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
925       smartAssertTrue(inputs, e,
926           intersect(inputs, ImmutableSet.of(doneCancelled)));
927     }
928   }
929 
930   /**
931    * {@link Futures#allAsList(Iterable)} or
932    * {@link Futures#successfulAsList(Iterable)}, hidden behind a common
933    * interface for testing.
934    */
935   private interface Merger {
936     ListenableFuture<List<String>> merged(
937         ListenableFuture<String> a, ListenableFuture<String> b);
938 
939     Merger allMerger = new Merger() {
940       @Override
941       public ListenableFuture<List<String>> merged(
942           ListenableFuture<String> a, ListenableFuture<String> b) {
943         return allAsList(ImmutableSet.of(a, b));
944       }
945     };
946     Merger successMerger = new Merger() {
947       @Override
948       public ListenableFuture<List<String>> merged(
949           ListenableFuture<String> a, ListenableFuture<String> b) {
950         return successfulAsList(ImmutableSet.of(a, b));
951       }
952     };
953   }
954 
955   /**
956    * Very rough equivalent of a timed get, produced by calling the no-arg get
957    * method in another thread and waiting a short time for it.
958    *
959    * <p>We need this to test the behavior of no-arg get methods without hanging
960    * the main test thread forever in the case of failure.
961    */
962   private static <V> V pseudoTimedGet(
963       final Future<V> input, long timeout, TimeUnit unit)
964       throws InterruptedException, ExecutionException, TimeoutException {
965     ExecutorService executor = newSingleThreadExecutor();
966     Future<V> waiter = executor.submit(new Callable<V>() {
967       @Override
968       public V call() throws Exception {
969         return input.get();
970       }
971     });
972 
973     try {
974       return waiter.get(timeout, unit);
975     } catch (ExecutionException e) {
976       propagateIfInstanceOf(e.getCause(), ExecutionException.class);
977       propagateIfInstanceOf(e.getCause(), CancellationException.class);
978       AssertionFailedError error =
979           new AssertionFailedError("Unexpected exception");
980       error.initCause(e);
981       throw error;
982     } finally {
983       executor.shutdownNow();
984       assertTrue(executor.awaitTermination(10, SECONDS));
985     }
986   }
987 
988   /**
989    * For each possible pair of futures from {@link TestFutureBatch}, for each
990    * possible completion order of those futures, test that various get calls
991    * (timed before future completion, untimed before future completion, and
992    * untimed after future completion) return or throw the proper values.
993    */
994   private static void runExtensiveMergerTest(Merger merger)
995       throws InterruptedException {
996     int inputCount = new TestFutureBatch().allFutures.size();
997 
998     for (int i = 0; i < inputCount; i++) {
999       for (int j = 0; j < inputCount; j++) {
1000         for (boolean iBeforeJ : new boolean[] { true, false }) {
1001           TestFutureBatch inputs = new TestFutureBatch();
1002           ListenableFuture<String> iFuture = inputs.allFutures.get(i).future;
1003           ListenableFuture<String> jFuture = inputs.allFutures.get(j).future;
1004           ListenableFuture<List<String>> future =
1005               merger.merged(iFuture, jFuture);
1006 
1007           // Test timed get before we've completed any delayed futures.
1008           try {
1009             List<String> result = future.get(0, MILLISECONDS);
1010             assertTrue("Got " + result,
1011                 Arrays.asList("a", null).containsAll(result));
1012           } catch (CancellationException e) {
1013             assertTrue(merger == Merger.allMerger);
1014             inputs.assertHasImmediateCancel(iFuture, jFuture, e);
1015           } catch (ExecutionException e) {
1016             assertTrue(merger == Merger.allMerger);
1017             inputs.assertHasImmediateFailure(iFuture, jFuture, e);
1018           } catch (TimeoutException e) {
1019             inputs.assertHasDelayed(iFuture, jFuture, e);
1020           }
1021 
1022           // Same tests with pseudoTimedGet.
1023           try {
1024             List<String> result = conditionalPseudoTimedGet(
1025                 inputs, iFuture, jFuture, future, 20, MILLISECONDS);
1026             assertTrue("Got " + result,
1027                 Arrays.asList("a", null).containsAll(result));
1028           } catch (CancellationException e) {
1029             assertTrue(merger == Merger.allMerger);
1030             inputs.assertHasImmediateCancel(iFuture, jFuture, e);
1031           } catch (ExecutionException e) {
1032             assertTrue(merger == Merger.allMerger);
1033             inputs.assertHasImmediateFailure(iFuture, jFuture, e);
1034           } catch (TimeoutException e) {
1035             inputs.assertHasDelayed(iFuture, jFuture, e);
1036           }
1037 
1038           // Finish the two futures in the currently specified order:
1039           inputs.allFutures.get(iBeforeJ ? i : j).finisher.run();
1040           inputs.allFutures.get(iBeforeJ ? j : i).finisher.run();
1041 
1042           // Test untimed get now that we've completed any delayed futures.
1043           try {
1044             List<String> result = future.get();
1045             assertTrue("Got " + result,
1046                 Arrays.asList("a", "b", null).containsAll(result));
1047           } catch (CancellationException e) {
1048             assertTrue(merger == Merger.allMerger);
1049             inputs.assertHasCancel(iFuture, jFuture, e);
1050           } catch (ExecutionException e) {
1051             assertTrue(merger == Merger.allMerger);
1052             inputs.assertHasFailure(iFuture, jFuture, e);
1053           }
1054         }
1055       }
1056     }
1057   }
1058 
1059   /**
1060    * Call the non-timed {@link Future#get()} in a way that allows us to abort if
1061    * it's expected to hang forever. More precisely, if it's expected to return,
1062    * we simply call it[*], but if it's expected to hang (because one of the
1063    * input futures that we know makes it up isn't done yet), then we call it in
1064    * a separate thread (using pseudoTimedGet). The result is that we wait as
1065    * long as necessary when the method is expected to return (at the cost of
1066    * hanging forever if there is a bug in the class under test) but that we time
1067    * out fairly promptly when the method is expected to hang (possibly too
1068    * quickly, but too-quick failures should be very unlikely, given that we used
1069    * to bail after 20ms during the expected-successful tests, and there we saw a
1070    * failure rate of ~1/5000, meaning that the other thread's get() call nearly
1071    * always completes within 20ms if it's going to complete at all).
1072    *
1073    * [*] To avoid hangs, I've disabled the in-thread calls. This makes the test
1074    * take (very roughly) 2.5s longer. (2.5s is also the maximum length of time
1075    * we will wait for a timed get that is expected to succeed; the fact that the
1076    * numbers match is only a coincidence.) See the comment below for how to
1077    * restore the fast but hang-y version.
1078    */
1079   private static List<String> conditionalPseudoTimedGet(
1080       TestFutureBatch inputs,
1081       ListenableFuture<String> iFuture,
1082       ListenableFuture<String> jFuture,
1083       ListenableFuture<List<String>> future,
1084       int timeout,
1085       TimeUnit unit)
1086       throws InterruptedException, ExecutionException, TimeoutException {
1087     /*
1088      * For faster tests (that may hang indefinitely if the class under test has
1089      * a bug!), switch the second branch to call untimed future.get() instead of
1090      * pseudoTimedGet.
1091      */
1092     return (inputs.hasDelayed(iFuture, jFuture))
1093         ? pseudoTimedGet(future, timeout, unit)
1094         : pseudoTimedGet(future, 2500, MILLISECONDS);
1095   }
1096 
1097   public void testAllAsList_extensive() throws InterruptedException {
1098     runExtensiveMergerTest(Merger.allMerger);
1099   }
1100 
1101   public void testSuccessfulAsList_extensive() throws InterruptedException {
1102     runExtensiveMergerTest(Merger.successMerger);
1103   }
1104 
1105   public void testSuccessfulAsList() throws Exception {
1106     // Create input and output
1107     SettableFuture<String> future1 = SettableFuture.create();
1108     SettableFuture<String> future2 = SettableFuture.create();
1109     SettableFuture<String> future3 = SettableFuture.create();
1110     @SuppressWarnings("unchecked") // array is never modified
1111     ListenableFuture<List<String>> compound =
1112         Futures.successfulAsList(future1, future2, future3);
1113 
1114     // Attach a listener
1115     SingleCallListener listener = new SingleCallListener();
1116     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1117 
1118     // Satisfy each input and check the output
1119     assertFalse(compound.isDone());
1120     future1.set(DATA1);
1121     assertFalse(compound.isDone());
1122     future2.set(DATA2);
1123     assertFalse(compound.isDone());
1124     listener.expectCall();
1125     future3.set(DATA3);
1126     assertTrue(compound.isDone());
1127     assertTrue(listener.wasCalled());
1128 
1129     List<String> results = compound.get();
1130     ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
1131   }
1132 
1133   public void testSuccessfulAsList_emptyList() throws Exception {
1134     SingleCallListener listener = new SingleCallListener();
1135     listener.expectCall();
1136     List<ListenableFuture<String>> futures = ImmutableList.of();
1137     ListenableFuture<List<String>> compound = Futures.successfulAsList(futures);
1138     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1139     assertTrue(compound.isDone());
1140     assertTrue(compound.get().isEmpty());
1141     assertTrue(listener.wasCalled());
1142   }
1143 
1144   public void testSuccessfulAsList_emptyArray() throws Exception {
1145     SingleCallListener listener = new SingleCallListener();
1146     listener.expectCall();
1147     @SuppressWarnings("unchecked") // array is never modified
1148     ListenableFuture<List<String>> compound = Futures.successfulAsList();
1149     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1150     assertTrue(compound.isDone());
1151     assertTrue(compound.get().isEmpty());
1152     assertTrue(listener.wasCalled());
1153   }
1154 
1155   public void testSuccessfulAsList_partialFailure() throws Exception {
1156     SingleCallListener listener = new SingleCallListener();
1157     SettableFuture<String> future1 = SettableFuture.create();
1158     SettableFuture<String> future2 = SettableFuture.create();
1159     @SuppressWarnings("unchecked") // array is never modified
1160     ListenableFuture<List<String>> compound =
1161         Futures.successfulAsList(future1, future2);
1162     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1163 
1164     assertFalse(compound.isDone());
1165     future1.setException(new Throwable("failed1"));
1166     assertFalse(compound.isDone());
1167     listener.expectCall();
1168     future2.set(DATA2);
1169     assertTrue(compound.isDone());
1170     assertTrue(listener.wasCalled());
1171 
1172     List<String> results = compound.get();
1173     ASSERT.that(results).hasContentsInOrder(null, DATA2);
1174   }
1175 
1176   public void testSuccessfulAsList_totalFailure() throws Exception {
1177     SingleCallListener listener = new SingleCallListener();
1178     SettableFuture<String> future1 = SettableFuture.create();
1179     SettableFuture<String> future2 = SettableFuture.create();
1180     @SuppressWarnings("unchecked") // array is never modified
1181     ListenableFuture<List<String>> compound =
1182         Futures.successfulAsList(future1, future2);
1183     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1184 
1185     assertFalse(compound.isDone());
1186     future1.setException(new Throwable("failed1"));
1187     assertFalse(compound.isDone());
1188     listener.expectCall();
1189     future2.setException(new Throwable("failed2"));
1190     assertTrue(compound.isDone());
1191     assertTrue(listener.wasCalled());
1192 
1193     List<String> results = compound.get();
1194     ASSERT.that(results).hasContentsInOrder(null, null);
1195   }
1196 
1197   public void testSuccessfulAsList_cancelled() throws Exception {
1198     SingleCallListener listener = new SingleCallListener();
1199     SettableFuture<String> future1 = SettableFuture.create();
1200     SettableFuture<String> future2 = SettableFuture.create();
1201     @SuppressWarnings("unchecked") // array is never modified
1202     ListenableFuture<List<String>> compound =
1203         Futures.successfulAsList(future1, future2);
1204     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1205 
1206     assertFalse(compound.isDone());
1207     future1.cancel(true);
1208     assertFalse(compound.isDone());
1209     listener.expectCall();
1210     future2.set(DATA2);
1211     assertTrue(compound.isDone());
1212     assertTrue(listener.wasCalled());
1213 
1214     List<String> results = compound.get();
1215     ASSERT.that(results).hasContentsInOrder(null, DATA2);
1216   }
1217 
1218   public void testSuccessfulAsList_mixed() throws Exception {
1219     SingleCallListener listener = new SingleCallListener();
1220     SettableFuture<String> future1 = SettableFuture.create();
1221     SettableFuture<String> future2 = SettableFuture.create();
1222     SettableFuture<String> future3 = SettableFuture.create();
1223     @SuppressWarnings("unchecked") // array is never modified
1224     ListenableFuture<List<String>> compound =
1225         Futures.successfulAsList(future1, future2, future3);
1226     compound.addListener(listener, MoreExecutors.sameThreadExecutor());
1227 
1228     // First is cancelled, second fails, third succeeds
1229     assertFalse(compound.isDone());
1230     future1.cancel(true);
1231     assertFalse(compound.isDone());
1232     future2.setException(new Throwable("failed2"));
1233     assertFalse(compound.isDone());
1234     listener.expectCall();
1235     future3.set(DATA3);
1236     assertTrue(compound.isDone());
1237     assertTrue(listener.wasCalled());
1238 
1239     List<String> results = compound.get();
1240     ASSERT.that(results).hasContentsInOrder(null, null, DATA3);
1241   }
1242 
1243   public void testSuccessfulAsList_buggyInputFutures() throws Exception {
1244     final Foo foo1 = new Foo();
1245     MockRequiresGetCallFuture<Foo> foo1Future =
1246         new MockRequiresGetCallFuture<Foo>(foo1);
1247     final Foo foo2 = new Foo();
1248     MockRequiresGetCallFuture<Foo> foo2Future =
1249         new MockRequiresGetCallFuture<Foo>(foo2);
1250 
1251     @SuppressWarnings("unchecked") // array is never modified
1252     ListenableFuture<List<Foo>> compound =
1253         Futures.successfulAsList(foo1Future, foo2Future);
1254 
1255     assertFalse(compound.isDone());
1256     ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
1257     assertTrue(foo1Future.getWasGetCalled());
1258     assertTrue(foo2Future.getWasGetCalled());
1259   }
1260 
1261   private static class TestException extends Exception {
1262     TestException(@Nullable Throwable cause) {
1263       super(cause);
1264     }
1265   }
1266 
1267   private static final Function<Exception, TestException> mapper =
1268       new Function<Exception, TestException>() {
1269     @Override public TestException apply(Exception from) {
1270       if (from instanceof ExecutionException) {
1271         return new TestException(from.getCause());
1272       } else {
1273         assertTrue("got " + from.getClass(),
1274             from instanceof InterruptedException
1275                 || from instanceof CancellationException);
1276         return new TestException(from);
1277       }
1278     }
1279   };
1280 
1281   public void testMakeChecked_mapsExecutionExceptions() throws Exception {
1282     SettableFuture<String> future = SettableFuture.create();
1283 
1284     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1285         future, mapper);
1286 
1287     future.setException(new IOException("checked"));
1288 
1289     assertTrue(checked.isDone());
1290     assertFalse(checked.isCancelled());
1291 
1292     try {
1293       checked.get();
1294       fail();
1295     } catch (ExecutionException e) {
1296       assertTrue(e.getCause() instanceof IOException);
1297     }
1298 
1299     try {
1300       checked.get(5, TimeUnit.SECONDS);
1301       fail();
1302     } catch (ExecutionException e) {
1303       assertTrue(e.getCause() instanceof IOException);
1304     }
1305 
1306     try {
1307       checked.checkedGet();
1308       fail();
1309     } catch (TestException e) {
1310       assertTrue(e.getCause() instanceof IOException);
1311     }
1312 
1313     try {
1314       checked.checkedGet(5, TimeUnit.SECONDS);
1315       fail();
1316     } catch (TestException e) {
1317       assertTrue(e.getCause() instanceof IOException);
1318     }
1319   }
1320 
1321   public void testMakeChecked_mapsInterruption() throws Exception {
1322     SettableFuture<String> future = SettableFuture.create();
1323 
1324     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1325         future, mapper);
1326 
1327     Thread.currentThread().interrupt();
1328 
1329     try {
1330       checked.get();
1331       fail();
1332     } catch (InterruptedException e) {
1333       // Expected.
1334     }
1335 
1336     Thread.currentThread().interrupt();
1337 
1338     try {
1339       checked.get(5, TimeUnit.SECONDS);
1340       fail();
1341     } catch (InterruptedException e) {
1342       // Expected.
1343     }
1344 
1345     Thread.currentThread().interrupt();
1346 
1347     try {
1348       checked.checkedGet();
1349       fail();
1350     } catch (TestException e) {
1351       assertTrue(e.getCause() instanceof InterruptedException);
1352     }
1353 
1354     Thread.currentThread().interrupt();
1355 
1356     try {
1357       checked.checkedGet(5, TimeUnit.SECONDS);
1358       fail();
1359     } catch (TestException e) {
1360       assertTrue(e.getCause() instanceof InterruptedException);
1361     }
1362   }
1363 
1364   public void testMakeChecked_mapsCancellation() throws Exception {
1365     SettableFuture<String> future = SettableFuture.create();
1366 
1367     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1368         future, mapper);
1369 
1370     assertTrue(future.cancel(true)); // argument is ignored
1371 
1372     try {
1373       checked.get();
1374       fail();
1375     } catch (CancellationException expected) {}
1376 
1377     try {
1378       checked.get(5, TimeUnit.SECONDS);
1379       fail();
1380     } catch (CancellationException expected) {}
1381 
1382     try {
1383       checked.checkedGet();
1384       fail();
1385     } catch (TestException expected) {
1386       assertTrue(expected.getCause() instanceof CancellationException);
1387     }
1388 
1389     try {
1390       checked.checkedGet(5, TimeUnit.SECONDS);
1391       fail();
1392     } catch (TestException expected) {
1393       assertTrue(expected.getCause() instanceof CancellationException);
1394     }
1395   }
1396 
1397   public void testMakeChecked_propagatesFailedMappers() throws Exception {
1398     SettableFuture<String> future = SettableFuture.create();
1399 
1400     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1401         future, new Function<Exception, TestException>() {
1402           @Override public TestException apply(Exception from) {
1403             throw new NullPointerException();
1404           }
1405     });
1406 
1407     future.setException(new Exception("failed"));
1408 
1409     try {
1410       checked.checkedGet();
1411       fail();
1412     } catch (NullPointerException expected) {}
1413 
1414     try {
1415       checked.checkedGet(5, TimeUnit.SECONDS);
1416       fail();
1417     } catch (NullPointerException expected) {}
1418   }
1419 
1420   public void testMakeChecked_listenersRunOnceCompleted() throws Exception {
1421     SettableFuture<String> future = SettableFuture.create();
1422 
1423     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1424         future, new Function<Exception, TestException>() {
1425           @Override public TestException apply(Exception from) {
1426             throw new NullPointerException();
1427           }
1428     });
1429 
1430     ListenableFutureTester tester = new ListenableFutureTester(checked);
1431     tester.setUp();
1432     future.set(DATA1);
1433     tester.testCompletedFuture(DATA1);
1434     tester.tearDown();
1435   }
1436 
1437   public void testMakeChecked_listenersRunOnCancel() throws Exception {
1438     SettableFuture<String> future = SettableFuture.create();
1439 
1440     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1441         future, new Function<Exception, TestException>() {
1442           @Override public TestException apply(Exception from) {
1443             throw new NullPointerException();
1444           }
1445     });
1446 
1447     ListenableFutureTester tester = new ListenableFutureTester(checked);
1448     tester.setUp();
1449     future.cancel(true); // argument is ignored
1450     tester.testCancelledFuture();
1451     tester.tearDown();
1452   }
1453 
1454   public void testMakeChecked_listenersRunOnFailure() throws Exception {
1455     SettableFuture<String> future = SettableFuture.create();
1456 
1457     CheckedFuture<String, TestException> checked = Futures.makeChecked(
1458         future, new Function<Exception, TestException>() {
1459           @Override public TestException apply(Exception from) {
1460             throw new NullPointerException();
1461           }
1462     });
1463 
1464     ListenableFutureTester tester = new ListenableFutureTester(checked);
1465     tester.setUp();
1466     future.setException(new Exception("failed"));
1467     tester.testFailedFuture("failed");
1468     tester.tearDown();
1469   }
1470 
1471   private interface MapperFunction extends Function<Throwable, Exception> {}
1472 
1473   private static final class OtherThrowable extends Throwable {}
1474 
1475   private static final Exception CHECKED_EXCEPTION = new Exception("mymessage");
1476   private static final Future<String> FAILED_FUTURE_CHECKED_EXCEPTION =
1477       immediateFailedFuture(CHECKED_EXCEPTION);
1478   private static final RuntimeException UNCHECKED_EXCEPTION =
1479       new RuntimeException("mymessage");
1480   private static final Future<String> FAILED_FUTURE_UNCHECKED_EXCEPTION =
1481       immediateFailedFuture(UNCHECKED_EXCEPTION);
1482   private static final RuntimeException RUNTIME_EXCEPTION =
1483       new RuntimeException();
1484   private static final OtherThrowable OTHER_THROWABLE = new OtherThrowable();
1485   private static final Future<String> FAILED_FUTURE_OTHER_THROWABLE =
1486       immediateFailedFuture(OTHER_THROWABLE);
1487   private static final Error ERROR = new Error("mymessage");
1488   private static final Future<String> FAILED_FUTURE_ERROR;
1489   /*
1490    * We can't write "= immediateFailedFuture(ERROR)" because setException
1491    * rethrows the error....
1492    */
1493   static {
1494     SettableFuture<String> f = SettableFuture.create();
1495     try {
1496       f.setException(ERROR);
1497     } catch (Error e) {
1498       assertEquals(e, ERROR);
1499     }
1500     FAILED_FUTURE_ERROR = f;
1501   }
1502   private static final Future<String> RUNTIME_EXCEPTION_FUTURE =
1503       new SimpleForwardingFuture<String>(FAILED_FUTURE_CHECKED_EXCEPTION) {
1504         @Override public String get() {
1505           throw RUNTIME_EXCEPTION;
1506         }
1507 
1508         @Override public String get(long timeout, TimeUnit unit) {
1509           throw RUNTIME_EXCEPTION;
1510         }
1511       };
1512 
1513   // Boring untimed-get tests:
1514 
1515   public void testGetUntimed_success()
1516       throws TwoArgConstructorException {
1517     assertEquals("foo",
1518         get(immediateFuture("foo"), TwoArgConstructorException.class));
1519   }
1520 
1521   public void testGetUntimed_interrupted() {
1522     Thread.currentThread().interrupt();
1523     try {
1524       get(immediateFuture("foo"), TwoArgConstructorException.class);
1525       fail();
1526     } catch (TwoArgConstructorException expected) {
1527       assertTrue(expected.getCause() instanceof InterruptedException);
1528       assertTrue(Thread.currentThread().isInterrupted());
1529     } finally {
1530       Thread.interrupted();
1531     }
1532   }
1533 
1534   public void testGetUntimed_cancelled()
1535       throws TwoArgConstructorException {
1536     SettableFuture<String> future = SettableFuture.create();
1537     future.cancel(true);
1538     try {
1539       get(future, TwoArgConstructorException.class);
1540       fail();
1541     } catch (CancellationException expected) {
1542     }
1543   }
1544 
1545   public void testGetUntimed_ExecutionExceptionChecked() {
1546     try {
1547       get(FAILED_FUTURE_CHECKED_EXCEPTION, TwoArgConstructorException.class);
1548       fail();
1549     } catch (TwoArgConstructorException expected) {
1550       assertEquals(CHECKED_EXCEPTION, expected.getCause());
1551     }
1552   }
1553 
1554   public void testGetUntimed_ExecutionExceptionUnchecked()
1555       throws TwoArgConstructorException {
1556     try {
1557       get(FAILED_FUTURE_UNCHECKED_EXCEPTION, TwoArgConstructorException.class);
1558       fail();
1559     } catch (UncheckedExecutionException expected) {
1560       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
1561     }
1562   }
1563 
1564   public void testGetUntimed_ExecutionExceptionError()
1565       throws TwoArgConstructorException {
1566     try {
1567       get(FAILED_FUTURE_ERROR, TwoArgConstructorException.class);
1568       fail();
1569     } catch (ExecutionError expected) {
1570       assertEquals(ERROR, expected.getCause());
1571     }
1572   }
1573 
1574   public void testGetUntimed_ExecutionExceptionOtherThrowable() {
1575     try {
1576       get(FAILED_FUTURE_OTHER_THROWABLE, TwoArgConstructorException.class);
1577       fail();
1578     } catch (TwoArgConstructorException expected) {
1579       assertEquals(OTHER_THROWABLE, expected.getCause());
1580     }
1581   }
1582 
1583   public void testGetUntimed_RuntimeException()
1584       throws TwoArgConstructorException {
1585     try {
1586       get(RUNTIME_EXCEPTION_FUTURE, TwoArgConstructorException.class);
1587       fail();
1588     } catch (RuntimeException expected) {
1589       assertEquals(RUNTIME_EXCEPTION, expected);
1590     }
1591   }
1592 
1593   // Boring timed-get tests:
1594 
1595   public void testGetTimed_success()
1596       throws TwoArgConstructorException {
1597     assertEquals("foo", get(
1598         immediateFuture("foo"), 0, SECONDS, TwoArgConstructorException.class));
1599   }
1600 
1601   public void testGetTimed_interrupted() {
1602     Thread.currentThread().interrupt();
1603     try {
1604       get(immediateFuture("foo"), 0, SECONDS, TwoArgConstructorException.class);
1605       fail();
1606     } catch (TwoArgConstructorException expected) {
1607       assertTrue(expected.getCause() instanceof InterruptedException);
1608       assertTrue(Thread.currentThread().isInterrupted());
1609     } finally {
1610       Thread.interrupted();
1611     }
1612   }
1613 
1614   public void testGetTimed_cancelled()
1615       throws TwoArgConstructorException {
1616     SettableFuture<String> future = SettableFuture.create();
1617     future.cancel(true);
1618     try {
1619       get(future, 0, SECONDS, TwoArgConstructorException.class);
1620       fail();
1621     } catch (CancellationException expected) {
1622     }
1623   }
1624 
1625   public void testGetTimed_ExecutionExceptionChecked() {
1626     try {
1627       get(FAILED_FUTURE_CHECKED_EXCEPTION, 0, SECONDS,
1628           TwoArgConstructorException.class);
1629       fail();
1630     } catch (TwoArgConstructorException expected) {
1631       assertEquals(CHECKED_EXCEPTION, expected.getCause());
1632     }
1633   }
1634 
1635   public void testGetTimed_ExecutionExceptionUnchecked()
1636       throws TwoArgConstructorException {
1637     try {
1638       get(FAILED_FUTURE_UNCHECKED_EXCEPTION, 0, SECONDS,
1639           TwoArgConstructorException.class);
1640       fail();
1641     } catch (UncheckedExecutionException expected) {
1642       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
1643     }
1644   }
1645 
1646   public void testGetTimed_ExecutionExceptionError()
1647       throws TwoArgConstructorException {
1648     try {
1649       get(FAILED_FUTURE_ERROR, 0, SECONDS, TwoArgConstructorException.class);
1650       fail();
1651     } catch (ExecutionError expected) {
1652       assertEquals(ERROR, expected.getCause());
1653     }
1654   }
1655 
1656   public void testGetTimed_ExecutionExceptionOtherThrowable() {
1657     try {
1658       get(FAILED_FUTURE_OTHER_THROWABLE, 0, SECONDS,
1659           TwoArgConstructorException.class);
1660       fail();
1661     } catch (TwoArgConstructorException expected) {
1662       assertEquals(OTHER_THROWABLE, expected.getCause());
1663     }
1664   }
1665 
1666   public void testGetTimed_RuntimeException()
1667       throws TwoArgConstructorException {
1668     try {
1669       get(RUNTIME_EXCEPTION_FUTURE, 0, SECONDS,
1670           TwoArgConstructorException.class);
1671       fail();
1672     } catch (RuntimeException expected) {
1673       assertEquals(RUNTIME_EXCEPTION, expected);
1674     }
1675   }
1676 
1677   public void testGetTimed_TimeoutException() {
1678     SettableFuture<String> future = SettableFuture.create();
1679     try {
1680       get(future, 0, SECONDS, TwoArgConstructorException.class);
1681       fail();
1682     } catch (TwoArgConstructorException expected) {
1683       assertTrue(expected.getCause() instanceof TimeoutException);
1684     }
1685   }
1686 
1687   // Boring getUnchecked tests:
1688 
1689   public void testGetUnchecked_success() {
1690     assertEquals("foo", getUnchecked(immediateFuture("foo")));
1691   }
1692 
1693   public void testGetUnchecked_interrupted() {
1694     Thread.currentThread().interrupt();
1695     try {
1696       assertEquals("foo", getUnchecked(immediateFuture("foo")));
1697       assertTrue(Thread.currentThread().isInterrupted());
1698     } finally {
1699       Thread.interrupted();
1700     }
1701   }
1702 
1703   public void testGetUnchecked_cancelled() {
1704     SettableFuture<String> future = SettableFuture.create();
1705     future.cancel(true);
1706     try {
1707       getUnchecked(future);
1708       fail();
1709     } catch (CancellationException expected) {
1710     }
1711   }
1712 
1713   public void testGetUnchecked_ExecutionExceptionChecked() {
1714     try {
1715       getUnchecked(FAILED_FUTURE_CHECKED_EXCEPTION);
1716       fail();
1717     } catch (UncheckedExecutionException expected) {
1718       assertEquals(CHECKED_EXCEPTION, expected.getCause());
1719     }
1720   }
1721 
1722   public void testGetUnchecked_ExecutionExceptionUnchecked() {
1723     try {
1724       getUnchecked(FAILED_FUTURE_UNCHECKED_EXCEPTION);
1725       fail();
1726     } catch (UncheckedExecutionException expected) {
1727       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
1728     }
1729   }
1730 
1731   public void testGetUnchecked_ExecutionExceptionError() {
1732     try {
1733       getUnchecked(FAILED_FUTURE_ERROR);
1734       fail();
1735     } catch (ExecutionError expected) {
1736       assertEquals(ERROR, expected.getCause());
1737     }
1738   }
1739 
1740   public void testGetUnchecked_ExecutionExceptionOtherThrowable() {
1741     try {
1742       getUnchecked(FAILED_FUTURE_OTHER_THROWABLE);
1743       fail();
1744     } catch (UncheckedExecutionException expected) {
1745       assertEquals(OTHER_THROWABLE, expected.getCause());
1746     }
1747   }
1748 
1749   public void testGetUnchecked_RuntimeException() {
1750     try {
1751       getUnchecked(RUNTIME_EXCEPTION_FUTURE);
1752       fail();
1753     } catch (RuntimeException expected) {
1754       assertEquals(RUNTIME_EXCEPTION, expected);
1755     }
1756   }
1757 
1758   // Edge case tests of the exception-construction code through untimed get():
1759 
1760   public void testGetUntimed_exceptionClassIsRuntimeException() {
1761     try {
1762       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1763           TwoArgConstructorRuntimeException.class);
1764       fail();
1765     } catch (IllegalArgumentException expected) {
1766     }
1767   }
1768 
1769   public void testGetUntimed_exceptionClassSomePublicConstructors() {
1770     try {
1771       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1772           ExceptionWithSomePrivateConstructors.class);
1773       fail();
1774     } catch (ExceptionWithSomePrivateConstructors expected) {
1775     }
1776   }
1777 
1778   public void testGetUntimed_exceptionClassNoPublicConstructor()
1779       throws ExceptionWithPrivateConstructor {
1780     try {
1781       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1782           ExceptionWithPrivateConstructor.class);
1783       fail();
1784     } catch (IllegalArgumentException expected) {
1785     }
1786   }
1787 
1788   public void testGetUntimed_exceptionClassPublicConstructorWrongType()
1789       throws ExceptionWithWrongTypesConstructor {
1790     try {
1791       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1792           ExceptionWithWrongTypesConstructor.class);
1793       fail();
1794     } catch (IllegalArgumentException expected) {
1795     }
1796   }
1797 
1798   public void testGetUntimed_exceptionClassPrefersStringConstructor() {
1799     try {
1800       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1801           ExceptionWithManyConstructors.class);
1802       fail();
1803     } catch (ExceptionWithManyConstructors expected) {
1804       assertTrue(expected.usedExpectedConstructor);
1805     }
1806   }
1807 
1808   public void testGetUntimed_exceptionClassUsedInitCause() {
1809     try {
1810       get(FAILED_FUTURE_CHECKED_EXCEPTION,
1811           ExceptionWithoutThrowableConstructor.class);
1812       fail();
1813     } catch (ExceptionWithoutThrowableConstructor expected) {
1814       ASSERT.that(expected.getMessage()).contains("mymessage");
1815       assertEquals(CHECKED_EXCEPTION, expected.getCause());
1816     }
1817   }
1818 
1819   public static final class TwoArgConstructorException extends Exception {
1820     public TwoArgConstructorException(String message, Throwable cause) {
1821       super(message, cause);
1822     }
1823   }
1824 
1825   public static final class TwoArgConstructorRuntimeException
1826       extends RuntimeException {
1827     public TwoArgConstructorRuntimeException(String message, Throwable cause) {
1828       super(message, cause);
1829     }
1830   }
1831 
1832   public static final class ExceptionWithPrivateConstructor extends Exception {
1833     private ExceptionWithPrivateConstructor(String message, Throwable cause) {
1834       super(message, cause);
1835     }
1836   }
1837 
1838   @SuppressWarnings("unused") // we're testing that they're not used
1839   public static final class ExceptionWithSomePrivateConstructors
1840       extends Exception {
1841     private ExceptionWithSomePrivateConstructors(String a) {
1842     }
1843 
1844     private ExceptionWithSomePrivateConstructors(String a, String b) {
1845     }
1846 
1847     public ExceptionWithSomePrivateConstructors(
1848         String a, String b, String c) {
1849     }
1850 
1851     private ExceptionWithSomePrivateConstructors(
1852         String a, String b, String c, String d) {
1853     }
1854 
1855     private ExceptionWithSomePrivateConstructors(
1856         String a, String b, String c, String d, String e) {
1857     }
1858   }
1859 
1860   public static final class ExceptionWithManyConstructors extends Exception {
1861     boolean usedExpectedConstructor;
1862 
1863     public ExceptionWithManyConstructors() {
1864     }
1865 
1866     public ExceptionWithManyConstructors(Integer i) {
1867     }
1868 
1869     public ExceptionWithManyConstructors(Throwable a) {
1870     }
1871 
1872     public ExceptionWithManyConstructors(Throwable a, Throwable b) {
1873     }
1874 
1875     public ExceptionWithManyConstructors(String s, Throwable b) {
1876       usedExpectedConstructor = true;
1877     }
1878 
1879     public ExceptionWithManyConstructors(
1880         Throwable a, Throwable b, Throwable c) {
1881     }
1882 
1883     public ExceptionWithManyConstructors(
1884         Throwable a, Throwable b, Throwable c, Throwable d) {
1885     }
1886 
1887     public ExceptionWithManyConstructors(
1888         Throwable a, Throwable b, Throwable c, Throwable d, Throwable e) {
1889     }
1890 
1891     public ExceptionWithManyConstructors(Throwable a, Throwable b, Throwable c,
1892         Throwable d, Throwable e, String s, Integer i) {
1893     }
1894   }
1895 
1896   public static final class ExceptionWithoutThrowableConstructor
1897       extends Exception {
1898     public ExceptionWithoutThrowableConstructor(String s) {
1899       super(s);
1900     }
1901   }
1902 
1903   public static final class ExceptionWithWrongTypesConstructor
1904       extends Exception {
1905     public ExceptionWithWrongTypesConstructor(Integer i, String s) {
1906       super(s);
1907     }
1908   }
1909 
1910   public void testNullArguments() throws Exception {
1911     NullPointerTester tester = new NullPointerTester();
1912     tester.setDefault(ListenableFuture.class, Futures.immediateFuture(DATA1));
1913     tester.setDefault(ListenableFuture[].class,
1914         new ListenableFuture[] {Futures.immediateFuture(DATA1)});
1915     tester.setDefault(Future.class, Futures.immediateFuture(DATA1));
1916     tester.setDefault(Executor.class, MoreExecutors.sameThreadExecutor());
1917     tester.setDefault(Callable.class, Callables.returning(null));
1918     tester.setDefault(AsyncFunction.class, new AsyncFunction() {
1919       @Override
1920       public ListenableFuture apply(Object input) throws Exception {
1921         return immediateFuture(DATA1);
1922       }
1923     });
1924 
1925     FutureCallback<Object> callback =
1926         new FutureCallback<Object>() {
1927           @Override
1928           public void onSuccess(Object result) {}
1929           @Override
1930           public void onFailure(Throwable t) {}
1931         };
1932     tester.setDefault(FutureCallback.class, callback);
1933 
1934     tester.testAllPublicStaticMethods(Futures.class);
1935   }
1936 
1937   private static void failWithCause(Throwable cause, String message) {
1938     AssertionFailedError failure = new AssertionFailedError(message);
1939     failure.initCause(cause);
1940     throw failure;
1941   }
1942 }
1943