Home | History | Annotate | Download | only in concurrent
      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 
     77   @Override protected void setUp() throws Exception {
     78     super.setUp();
     79 
     80     mocksControl = EasyMock.createControl();
     81   }
     82 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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    */
    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    */
    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 
    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 
    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 
    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