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.truth.Truth.assertThat;
     21 import static com.google.common.util.concurrent.Futures.allAsList;
     22 import static com.google.common.util.concurrent.Futures.get;
     23 import static com.google.common.util.concurrent.Futures.getUnchecked;
     24 import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
     25 import static com.google.common.util.concurrent.Futures.immediateFuture;
     26 import static com.google.common.util.concurrent.Futures.successfulAsList;
     27 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
     28 import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
     29 import static java.util.concurrent.Executors.newSingleThreadExecutor;
     30 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     31 import static java.util.concurrent.TimeUnit.SECONDS;
     32 import static org.easymock.EasyMock.expect;
     33 
     34 import com.google.common.base.Function;
     35 import com.google.common.base.Functions;
     36 import com.google.common.base.Joiner;
     37 import com.google.common.collect.ImmutableList;
     38 import com.google.common.collect.ImmutableSet;
     39 import com.google.common.collect.Iterables;
     40 import com.google.common.collect.Lists;
     41 import com.google.common.collect.Sets;
     42 import com.google.common.testing.ClassSanityTester;
     43 import com.google.common.testing.TestLogHandler;
     44 import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
     45 
     46 import junit.framework.AssertionFailedError;
     47 import junit.framework.TestCase;
     48 
     49 import org.easymock.EasyMock;
     50 import org.easymock.IMocksControl;
     51 
     52 import java.io.IOException;
     53 import java.util.Arrays;
     54 import java.util.List;
     55 import java.util.Set;
     56 import java.util.concurrent.Callable;
     57 import java.util.concurrent.CancellationException;
     58 import java.util.concurrent.CountDownLatch;
     59 import java.util.concurrent.ExecutionException;
     60 import java.util.concurrent.Executor;
     61 import java.util.concurrent.ExecutorService;
     62 import java.util.concurrent.Executors;
     63 import java.util.concurrent.Future;
     64 import java.util.concurrent.RejectedExecutionException;
     65 import java.util.concurrent.TimeUnit;
     66 import java.util.concurrent.TimeoutException;
     67 import java.util.logging.Handler;
     68 import java.util.logging.LogRecord;
     69 import java.util.logging.Logger;
     70 
     71 import javax.annotation.Nullable;
     72 
     73 /**
     74  * Unit tests for {@link Futures}.
     75  *
     76  * TODO: Add tests for other Futures methods
     77  *
     78  * @author Nishant Thakkar
     79  */
     80 public class FuturesTest extends TestCase {
     81   private static final Logger combinedFutureLogger = Logger.getLogger(
     82       "com.google.common.util.concurrent.Futures$CombinedFuture");
     83   private final TestLogHandler combinedFutureLogHandler = new TestLogHandler();
     84 
     85   private static final String DATA1 = "data";
     86   private static final String DATA2 = "more data";
     87   private static final String DATA3 = "most data";
     88 
     89   private IMocksControl mocksControl;
     90 
     91   @Override protected void setUp() throws Exception {
     92     super.setUp();
     93     combinedFutureLogger.addHandler(combinedFutureLogHandler);
     94     mocksControl = EasyMock.createControl();
     95   }
     96 
     97   @Override protected void tearDown() throws Exception {
     98     /*
     99      * Clear interrupt for future tests.
    100      *
    101      * (Ideally we would perform interrupts only in threads that we create, but
    102      * it's hard to imagine that anything will break in practice.)
    103      */
    104     Thread.interrupted();
    105     combinedFutureLogger.removeHandler(combinedFutureLogHandler);
    106     super.tearDown();
    107   }
    108 
    109   public void testImmediateFuture() throws Exception {
    110     ListenableFuture<String> future = Futures.immediateFuture(DATA1);
    111 
    112     // Verify that the proper object is returned without waiting
    113     assertSame(DATA1, future.get(0L, TimeUnit.MILLISECONDS));
    114   }
    115 
    116   public void testMultipleImmediateFutures() throws Exception {
    117     ListenableFuture<String> future1 = Futures.immediateFuture(DATA1);
    118     ListenableFuture<String> future2 = Futures.immediateFuture(DATA2);
    119 
    120     // Verify that the proper objects are returned without waiting
    121     assertSame(DATA1, future1.get(0L, TimeUnit.MILLISECONDS));
    122     assertSame(DATA2, future2.get(0L, TimeUnit.MILLISECONDS));
    123   }
    124 
    125   public void testImmediateFailedFuture() throws Exception {
    126     Exception exception = new Exception();
    127     ListenableFuture<String> future =
    128         Futures.immediateFailedFuture(exception);
    129 
    130     try {
    131       future.get(0L, TimeUnit.MILLISECONDS);
    132       fail("This call was supposed to throw an ExecutionException");
    133     } catch (ExecutionException expected) {
    134       // This is good and expected
    135       assertSame(exception, expected.getCause());
    136     }
    137   }
    138 
    139   public void testImmediateFailedFuture_cancellationException() throws Exception {
    140     CancellationException exception = new CancellationException();
    141     ListenableFuture<String> future =
    142         Futures.immediateFailedFuture(exception);
    143 
    144     try {
    145       future.get(0L, TimeUnit.MILLISECONDS);
    146       fail("This call was supposed to throw an ExecutionException");
    147     } catch (ExecutionException expected) {
    148       // This is good and expected
    149       assertSame(exception, expected.getCause());
    150       assertFalse(future.isCancelled());
    151     }
    152   }
    153 
    154   public void testImmediateCancelledFuture() throws Exception {
    155     ListenableFuture<String> future =
    156         Futures.immediateCancelledFuture();
    157     assertTrue(future.isCancelled());
    158   }
    159 
    160   private static class MyException extends Exception {}
    161 
    162   public void testImmediateCheckedFuture() throws Exception {
    163     CheckedFuture<String, MyException> future = Futures.immediateCheckedFuture(
    164         DATA1);
    165 
    166     // Verify that the proper object is returned without waiting
    167     assertSame(DATA1, future.get(0L, TimeUnit.MILLISECONDS));
    168     assertSame(DATA1, future.checkedGet(0L, TimeUnit.MILLISECONDS));
    169   }
    170 
    171   public void testMultipleImmediateCheckedFutures() throws Exception {
    172     CheckedFuture<String, MyException> future1 = Futures.immediateCheckedFuture(
    173         DATA1);
    174     CheckedFuture<String, MyException> future2 = Futures.immediateCheckedFuture(
    175         DATA2);
    176 
    177     // Verify that the proper objects are returned without waiting
    178     assertSame(DATA1, future1.get(0L, TimeUnit.MILLISECONDS));
    179     assertSame(DATA1, future1.checkedGet(0L, TimeUnit.MILLISECONDS));
    180     assertSame(DATA2, future2.get(0L, TimeUnit.MILLISECONDS));
    181     assertSame(DATA2, future2.checkedGet(0L, TimeUnit.MILLISECONDS));
    182   }
    183 
    184   public void testImmediateFailedCheckedFuture() throws Exception {
    185     MyException exception = new MyException();
    186     CheckedFuture<String, MyException> future =
    187         Futures.immediateFailedCheckedFuture(exception);
    188 
    189     try {
    190       future.get(0L, TimeUnit.MILLISECONDS);
    191       fail("This call was supposed to throw an ExecutionException");
    192     } catch (ExecutionException expected) {
    193       // This is good and expected
    194       assertSame(exception, expected.getCause());
    195     }
    196 
    197     try {
    198       future.checkedGet(0L, TimeUnit.MILLISECONDS);
    199       fail("This call was supposed to throw an MyException");
    200     } catch (MyException expected) {
    201       // This is good and expected
    202       assertSame(exception, expected);
    203     }
    204   }
    205 
    206   // Class hierarchy for generics sanity checks
    207   private static class Foo {}
    208   private static class FooChild extends Foo {}
    209   private static class Bar {}
    210   private static class BarChild extends Bar {}
    211 
    212   public void testTransform_genericsNull() throws Exception {
    213     ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
    214     ListenableFuture<?> transformedFuture =
    215         Futures.transform(nullFuture, Functions.constant(null));
    216     assertNull(transformedFuture.get());
    217   }
    218 
    219   public void testTransform_genericsHierarchy() throws Exception {
    220     ListenableFuture<FooChild> future = Futures.immediateFuture(null);
    221     final BarChild barChild = new BarChild();
    222     Function<Foo, BarChild> function = new Function<Foo, BarChild>() {
    223       @Override public BarChild apply(Foo unused) {
    224         return barChild;
    225       }
    226     };
    227     Bar bar = Futures.transform(future, function).get();
    228     assertSame(barChild, bar);
    229   }
    230 
    231   public void testTransform_cancelPropagatesToInput() throws Exception {
    232     SettableFuture<Foo> input = SettableFuture.create();
    233     AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
    234       @Override public ListenableFuture<Bar> apply(Foo unused) {
    235         throw new AssertionFailedError("Unexpeted call to apply.");
    236       }
    237     };
    238     assertTrue(Futures.transform(input, function).cancel(false));
    239     assertTrue(input.isCancelled());
    240     assertFalse(input.wasInterrupted());
    241   }
    242 
    243   public void testTransform_interruptPropagatesToInput() throws Exception {
    244     SettableFuture<Foo> input = SettableFuture.create();
    245     AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
    246       @Override public ListenableFuture<Bar> apply(Foo unused) {
    247         throw new AssertionFailedError("Unexpeted call to apply.");
    248       }
    249     };
    250     assertTrue(Futures.transform(input, function).cancel(true));
    251     assertTrue(input.isCancelled());
    252     assertTrue(input.wasInterrupted());
    253   }
    254 
    255   public void testTransform_cancelPropagatesToAsyncOutput() throws Exception {
    256     ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
    257     final SettableFuture<Bar> secondary = SettableFuture.create();
    258     AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
    259       @Override public ListenableFuture<Bar> apply(Foo unused) {
    260         return secondary;
    261       }
    262     };
    263     assertTrue(Futures.transform(immediate, function).cancel(false));
    264     assertTrue(secondary.isCancelled());
    265     assertFalse(secondary.wasInterrupted());
    266   }
    267 
    268   public void testTransform_interruptPropagatesToAsyncOutput()
    269       throws Exception {
    270     ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
    271     final SettableFuture<Bar> secondary = SettableFuture.create();
    272     AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
    273       @Override public ListenableFuture<Bar> apply(Foo unused) {
    274         return secondary;
    275       }
    276     };
    277     assertTrue(Futures.transform(immediate, function).cancel(true));
    278     assertTrue(secondary.isCancelled());
    279     assertTrue(secondary.wasInterrupted());
    280   }
    281 
    282   public void testTransform_rejectionPropagatesToOutput()
    283       throws Exception {
    284     SettableFuture<Foo> input = SettableFuture.create();
    285     ExecutorService executor = newDirectExecutorService();
    286     ListenableFuture<String> transformed =
    287         Futures.transform(input, Functions.toStringFunction(), executor);
    288     executor.shutdown();
    289     input.set(new Foo());
    290     try {
    291       transformed.get(5, TimeUnit.SECONDS);
    292       fail();
    293     } catch (ExecutionException expected) {
    294       assertTrue(expected.getCause() instanceof RejectedExecutionException);
    295     }
    296   }
    297 
    298   /**
    299    * Tests that the function is invoked only once, even if it throws an
    300    * exception.
    301    */
    302   public void testTransformValueRemainsMemoized() throws Exception {
    303     class Holder {
    304       int value = 2;
    305     }
    306     final Holder holder = new Holder();
    307 
    308     // This function adds the holder's value to the input value.
    309     Function<Integer, Integer> adder = new Function<Integer, Integer>() {
    310       @Override public Integer apply(Integer from) {
    311         return from + holder.value;
    312       }
    313     };
    314 
    315     // Since holder.value is 2, applying 4 should yield 6.
    316     assertEquals(6, adder.apply(4).intValue());
    317 
    318     ListenableFuture<Integer> immediateFuture = Futures.immediateFuture(4);
    319     Future<Integer> transformedFuture = Futures.transform(immediateFuture, adder);
    320 
    321     // The composed future also yields 6.
    322     assertEquals(6, transformedFuture.get().intValue());
    323 
    324     // Repeated calls yield the same value even though the function's behavior
    325     // changes
    326     holder.value = 3;
    327     assertEquals(6, transformedFuture.get().intValue());
    328     assertEquals(7, adder.apply(4).intValue());
    329 
    330     // Once more, with feeling.
    331     holder.value = 4;
    332     assertEquals(6, transformedFuture.get().intValue());
    333     assertEquals(8, adder.apply(4).intValue());
    334 
    335     // Memoized get also retains the value.
    336     assertEquals(6, transformedFuture.get(1000, TimeUnit.SECONDS).intValue());
    337 
    338     // Unsurprisingly, recomposing the future will return an updated value.
    339     assertEquals(8, Futures.transform(immediateFuture, adder).get().intValue());
    340 
    341     // Repeating, with the timeout version
    342     assertEquals(8, Futures.transform(immediateFuture, adder).get(
    343         1000, TimeUnit.SECONDS).intValue());
    344   }
    345 
    346   static class MyError extends Error {}
    347   static class MyRuntimeException extends RuntimeException {}
    348 
    349   /**
    350    * Test that the function is invoked only once, even if it throws an
    351    * exception. Also, test that that function's result is wrapped in an
    352    * ExecutionException.
    353    */
    354   public void testTransformExceptionRemainsMemoized() throws Throwable {
    355     // We need to test with two input futures since ExecutionList.execute
    356     // doesn't catch Errors and we cannot depend on the order that our
    357     // transformations run. (So it is possible that the Error being thrown
    358     // could prevent our second transformations from running).
    359     SettableFuture<Integer> exceptionInput = SettableFuture.create();
    360     ListenableFuture<Integer> exceptionComposedFuture =
    361         Futures.transform(exceptionInput, newOneTimeExceptionThrower());
    362     exceptionInput.set(0);
    363     runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class);
    364 
    365     SettableFuture<Integer> errorInput = SettableFuture.create();
    366     ListenableFuture<Integer> errorComposedFuture =
    367         Futures.transform(errorInput, newOneTimeErrorThrower());
    368     errorInput.set(0);
    369 
    370     runGetIdempotencyTest(errorComposedFuture, MyError.class);
    371 
    372     /*
    373      * Try again when the input's value is already filled in, since the flow is
    374      * slightly different in that case.
    375      */
    376     exceptionComposedFuture =
    377         Futures.transform(exceptionInput, newOneTimeExceptionThrower());
    378     runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class);
    379 
    380     runGetIdempotencyTest(Futures.transform(errorInput, newOneTimeErrorThrower()), MyError.class);
    381     runGetIdempotencyTest(errorComposedFuture, MyError.class);
    382   }
    383 
    384   private static void runGetIdempotencyTest(Future<Integer> transformedFuture,
    385       Class<? extends Throwable> expectedExceptionClass) throws Throwable {
    386     for (int i = 0; i < 5; i++) {
    387       try {
    388         transformedFuture.get();
    389         fail();
    390       } catch (ExecutionException expected) {
    391         if (!expectedExceptionClass.isInstance(expected.getCause())) {
    392           throw expected.getCause();
    393         }
    394       }
    395     }
    396   }
    397 
    398   private static Function<Integer, Integer> newOneTimeExceptionThrower() {
    399     return new Function<Integer, Integer>() {
    400       int calls = 0;
    401 
    402       @Override public Integer apply(Integer from) {
    403         if (++calls > 1) {
    404           fail();
    405         }
    406         throw new MyRuntimeException();
    407       }
    408     };
    409   }
    410 
    411   private static Function<Integer, Integer> newOneTimeErrorThrower() {
    412     return new Function<Integer, Integer>() {
    413       int calls = 0;
    414 
    415       @Override public Integer apply(Integer from) {
    416         if (++calls > 1) {
    417           fail();
    418         }
    419         throw new MyError();
    420       }
    421     };
    422   }
    423 
    424   // TODO(cpovirk): top-level class?
    425   static class ExecutorSpy implements Executor {
    426     Executor delegate;
    427     boolean wasExecuted;
    428 
    429     public ExecutorSpy(Executor delegate) {
    430       this.delegate = delegate;
    431     }
    432 
    433     @Override public void execute(Runnable command) {
    434       delegate.execute(command);
    435       wasExecuted = true;
    436     }
    437   }
    438 
    439   public void testTransform_Executor() throws Exception {
    440     Object value = new Object();
    441     ExecutorSpy spy = new ExecutorSpy(directExecutor());
    442 
    443     assertFalse(spy.wasExecuted);
    444 
    445     ListenableFuture<Object> future = Futures.transform(
    446         Futures.immediateFuture(value),
    447         Functions.identity(), spy);
    448 
    449     assertSame(value, future.get());
    450     assertTrue(spy.wasExecuted);
    451   }
    452 
    453   public void testLazyTransform() throws Exception {
    454     FunctionSpy<Object, String> spy =
    455         new FunctionSpy<Object, String>(Functions.constant("bar"));
    456     Future<String> input = Futures.immediateFuture("foo");
    457     Future<String> transformed = Futures.lazyTransform(input, spy);
    458     assertEquals(0, spy.getApplyCount());
    459     assertEquals("bar", transformed.get());
    460     assertEquals(1, spy.getApplyCount());
    461     assertEquals("bar", transformed.get());
    462     assertEquals(2, spy.getApplyCount());
    463   }
    464 
    465   public void testLazyTransform_exception() throws Exception {
    466     final RuntimeException exception = new RuntimeException("deliberate");
    467     Function<Integer, String> function = new Function<Integer, String>() {
    468       @Override public String apply(Integer input) {
    469         throw exception;
    470       }
    471     };
    472     Future<String> transformed = Futures.lazyTransform(Futures.immediateFuture(1), function);
    473     try {
    474       transformed.get();
    475       fail();
    476     } catch (ExecutionException expected) {
    477       assertSame(exception, expected.getCause());
    478     }
    479     try {
    480       transformed.get(1, TimeUnit.SECONDS);
    481       fail();
    482     } catch (ExecutionException expected) {
    483       assertSame(exception, expected.getCause());
    484     }
    485   }
    486 
    487   private static class FunctionSpy<I, O> implements Function<I, O> {
    488     private int applyCount;
    489     private final Function<I, O> delegate;
    490 
    491     public FunctionSpy(Function<I, O> delegate) {
    492       this.delegate = delegate;
    493     }
    494 
    495     @Override
    496     public O apply(I input) {
    497       applyCount++;
    498       return delegate.apply(input);
    499     }
    500 
    501     public int getApplyCount() {
    502       return applyCount;
    503     }
    504   }
    505 
    506   @SuppressWarnings("unchecked")
    507   public void testWithFallback_inputDoesNotRaiseException() throws Exception {
    508     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    509     ListenableFuture<Integer> originalFuture = Futures.immediateFuture(7);
    510 
    511     mocksControl.replay();
    512     ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(originalFuture, fallback);
    513     assertEquals(7, faultToleranteFuture.get().intValue());
    514     mocksControl.verify();
    515   }
    516 
    517   @SuppressWarnings("unchecked")
    518   public void testWithFallback_inputRaisesException() throws Exception {
    519     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    520     RuntimeException raisedException = new RuntimeException();
    521     expect(fallback.create(raisedException)).andReturn(Futures.immediateFuture(20));
    522     ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
    523 
    524     mocksControl.replay();
    525     ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
    526     assertEquals(20, faultToleranteFuture.get().intValue());
    527     mocksControl.verify();
    528   }
    529 
    530   public void testWithFallback_fallbackGeneratesRuntimeException() throws Exception {
    531     RuntimeException expectedException = new RuntimeException();
    532     runExpectedExceptionFallbackTest(expectedException, false);
    533   }
    534 
    535   public void testWithFallback_fallbackGeneratesCheckedException() throws Exception {
    536     Exception expectedException = new Exception() {};
    537     runExpectedExceptionFallbackTest(expectedException, false);
    538   }
    539 
    540   @SuppressWarnings("unchecked")
    541   public void testWithFallback_fallbackGeneratesError() throws Exception {
    542     final Error error = new Error("deliberate");
    543     FutureFallback<Integer> fallback = new FutureFallback<Integer>() {
    544       @Override public ListenableFuture<Integer> create(Throwable t) throws Exception {
    545         throw error;
    546       }
    547     };
    548     ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(new RuntimeException());
    549     try {
    550       Futures.withFallback(failingFuture, fallback).get();
    551       fail("An Exception should have been thrown!");
    552     } catch (ExecutionException expected) {
    553       assertSame(error, expected.getCause());
    554     }
    555   }
    556 
    557   public void testWithFallback_fallbackReturnsRuntimeException() throws Exception {
    558     RuntimeException expectedException = new RuntimeException();
    559     runExpectedExceptionFallbackTest(expectedException, true);
    560   }
    561 
    562   public void testWithFallback_fallbackReturnsCheckedException() throws Exception {
    563     Exception expectedException = new Exception() {};
    564     runExpectedExceptionFallbackTest(expectedException, true);
    565   }
    566 
    567   @SuppressWarnings("unchecked")
    568   private void runExpectedExceptionFallbackTest(
    569       Throwable expectedException, boolean wrapInFuture) throws Exception {
    570     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    571     RuntimeException raisedException = new RuntimeException();
    572     if (!wrapInFuture) {
    573       // Exception is thrown in the body of the "fallback" method.
    574       expect(fallback.create(raisedException)).andThrow(expectedException);
    575     } else {
    576       // Exception is wrapped in a future and returned.
    577       expect(fallback.create(raisedException)).andReturn(
    578           Futures.<Integer>immediateFailedFuture(expectedException));
    579     }
    580 
    581     ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
    582 
    583     mocksControl.replay();
    584     ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
    585     try {
    586       faultToleranteFuture.get();
    587       fail("An Exception should have been thrown!");
    588     } catch (ExecutionException ee) {
    589       assertSame(expectedException, ee.getCause());
    590     }
    591     mocksControl.verify();
    592   }
    593 
    594   public void testWithFallback_fallbackNotReady() throws Exception {
    595     ListenableFuture<Integer> primary = immediateFailedFuture(new Exception());
    596     final SettableFuture<Integer> secondary = SettableFuture.create();
    597     FutureFallback<Integer> fallback = new FutureFallback<Integer>() {
    598       @Override
    599       public ListenableFuture<Integer> create(Throwable t) {
    600         return secondary;
    601       }
    602     };
    603     ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
    604     secondary.set(1);
    605     assertEquals(1, (int) derived.get());
    606   }
    607 
    608   @SuppressWarnings("unchecked")
    609   public void testWithFallback_resultInterruptedBeforeFallback() throws Exception {
    610     SettableFuture<Integer> primary = SettableFuture.create();
    611     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    612 
    613     mocksControl.replay();
    614     ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
    615     derived.cancel(true);
    616     assertTrue(primary.isCancelled());
    617     assertTrue(primary.wasInterrupted());
    618     mocksControl.verify();
    619   }
    620 
    621   @SuppressWarnings("unchecked")
    622   public void testWithFallback_resultCancelledBeforeFallback() throws Exception {
    623     SettableFuture<Integer> primary = SettableFuture.create();
    624     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    625 
    626     mocksControl.replay();
    627     ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
    628     derived.cancel(false);
    629     assertTrue(primary.isCancelled());
    630     assertFalse(primary.wasInterrupted());
    631     mocksControl.verify();
    632   }
    633 
    634   @SuppressWarnings("unchecked")
    635   public void testWithFallback_resultCancelledAfterFallback() throws Exception {
    636     SettableFuture<Integer> secondary = SettableFuture.create();
    637     FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
    638     RuntimeException raisedException = new RuntimeException();
    639     expect(fallback.create(raisedException)).andReturn(secondary);
    640     ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
    641 
    642     mocksControl.replay();
    643     ListenableFuture<Integer> derived = Futures.withFallback(failingFuture, fallback);
    644     derived.cancel(false);
    645     assertTrue(secondary.isCancelled());
    646     assertFalse(secondary.wasInterrupted());
    647     mocksControl.verify();
    648   }
    649 
    650   public void testTransform_genericsWildcard_AsyncFunction() throws Exception {
    651     ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
    652     ListenableFuture<?> chainedFuture =
    653         Futures.transform(nullFuture, constantAsyncFunction(nullFuture));
    654     assertNull(chainedFuture.get());
    655   }
    656 
    657   private static <I, O> AsyncFunction<I, O> constantAsyncFunction(
    658       final ListenableFuture<O> output) {
    659     return new AsyncFunction<I, O>() {
    660       @Override
    661       public ListenableFuture<O> apply(I input) {
    662         return output;
    663       }
    664     };
    665   }
    666 
    667   public void testTransform_genericsHierarchy_AsyncFunction() throws Exception {
    668     ListenableFuture<FooChild> future = Futures.immediateFuture(null);
    669     final BarChild barChild = new BarChild();
    670     AsyncFunction<Foo, BarChild> function =
    671         new AsyncFunction<Foo, BarChild>() {
    672           @Override public AbstractFuture<BarChild> apply(Foo unused) {
    673             AbstractFuture<BarChild> future = new AbstractFuture<BarChild>() {};
    674             future.set(barChild);
    675             return future;
    676           }
    677         };
    678     Bar bar = Futures.transform(future, function).get();
    679     assertSame(barChild, bar);
    680   }
    681 
    682   public void testTransform_asyncFunction_timeout()
    683       throws InterruptedException, ExecutionException {
    684     AsyncFunction<String, Integer> function = constantAsyncFunction(Futures.immediateFuture(1));
    685     ListenableFuture<Integer> future = Futures.transform(
    686         SettableFuture.<String>create(), function);
    687     try {
    688       future.get(1, TimeUnit.MILLISECONDS);
    689       fail();
    690     } catch (TimeoutException expected) {}
    691   }
    692 
    693   public void testTransform_asyncFunction_error() throws InterruptedException {
    694     final Error error = new Error("deliberate");
    695     AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
    696       @Override public ListenableFuture<Integer> apply(String input) {
    697         throw error;
    698       }
    699     };
    700     SettableFuture<String> inputFuture = SettableFuture.create();
    701     ListenableFuture<Integer> outputFuture = Futures.transform(inputFuture, function);
    702     inputFuture.set("value");
    703     try {
    704       outputFuture.get();
    705       fail("should have thrown error");
    706     } catch (ExecutionException e) {
    707       assertSame(error, e.getCause());
    708     }
    709   }
    710 
    711   public void testTransform_asyncFunction_cancelledWhileApplyingFunction()
    712       throws InterruptedException, ExecutionException {
    713     final CountDownLatch inFunction = new CountDownLatch(1);
    714     final CountDownLatch functionDone = new CountDownLatch(1);
    715     final SettableFuture<Integer> resultFuture = SettableFuture.create();
    716     AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
    717       @Override public ListenableFuture<Integer> apply(String input) throws Exception {
    718         inFunction.countDown();
    719         functionDone.await();
    720         return resultFuture;
    721       }
    722     };
    723     SettableFuture<String> inputFuture = SettableFuture.create();
    724     ListenableFuture<Integer> future = Futures.transform(
    725         inputFuture, function, Executors.newSingleThreadExecutor());
    726     inputFuture.set("value");
    727     inFunction.await();
    728     future.cancel(false);
    729     functionDone.countDown();
    730     try {
    731       future.get();
    732       fail();
    733     } catch (CancellationException expected) {}
    734     try {
    735       resultFuture.get();
    736       fail();
    737     } catch (CancellationException expected) {}
    738   }
    739 
    740   public void testDereference_genericsWildcard() throws Exception {
    741     ListenableFuture<?> inner = Futures.immediateFuture(null);
    742     ListenableFuture<ListenableFuture<?>> outer =
    743         Futures.<ListenableFuture<?>>immediateFuture(inner);
    744     ListenableFuture<?> dereferenced = Futures.dereference(outer);
    745     assertNull(dereferenced.get());
    746   }
    747 
    748   public void testDereference_genericsHierarchy() throws Exception {
    749     FooChild fooChild = new FooChild();
    750     ListenableFuture<FooChild> inner = Futures.immediateFuture(fooChild);
    751     ListenableFuture<ListenableFuture<FooChild>> outer = Futures.immediateFuture(inner);
    752     ListenableFuture<Foo> dereferenced = Futures.<Foo>dereference(outer);
    753     assertSame(fooChild, dereferenced.get());
    754   }
    755 
    756   public void testDereference_resultCancelsOuter() throws Exception {
    757     ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
    758     ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
    759     dereferenced.cancel(true);
    760     assertTrue(outer.isCancelled());
    761   }
    762 
    763   public void testDereference_resultCancelsInner() throws Exception {
    764     ListenableFuture<Foo> inner = SettableFuture.create();
    765     ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
    766     ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
    767     dereferenced.cancel(true);
    768     assertTrue(inner.isCancelled());
    769   }
    770 
    771   public void testDereference_outerCancelsResult() throws Exception {
    772     ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
    773     ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
    774     outer.cancel(true);
    775     assertTrue(dereferenced.isCancelled());
    776   }
    777 
    778   public void testDereference_innerCancelsResult() throws Exception {
    779     ListenableFuture<Foo> inner = SettableFuture.create();
    780     ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
    781     ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
    782     inner.cancel(true);
    783     assertTrue(dereferenced.isCancelled());
    784   }
    785 
    786   /**
    787    * Runnable which can be called a single time, and only after
    788    * {@link #expectCall} is called.
    789    */
    790   // TODO(cpovirk): top-level class?
    791   static class SingleCallListener implements Runnable {
    792     private boolean expectCall = false;
    793     private final CountDownLatch calledCountDown =
    794         new CountDownLatch(1);
    795 
    796     @Override public void run() {
    797       assertTrue("Listener called before it was expected", expectCall);
    798       assertFalse("Listener called more than once", wasCalled());
    799       calledCountDown.countDown();
    800     }
    801 
    802     public void expectCall() {
    803       assertFalse("expectCall is already true", expectCall);
    804       expectCall = true;
    805     }
    806 
    807     public boolean wasCalled() {
    808       return calledCountDown.getCount() == 0;
    809     }
    810 
    811     public void waitForCall() throws InterruptedException {
    812       assertTrue("expectCall is false", expectCall);
    813       calledCountDown.await();
    814     }
    815   }
    816 
    817   public void testAllAsList() throws Exception {
    818     // Create input and output
    819     SettableFuture<String> future1 = SettableFuture.create();
    820     SettableFuture<String> future2 = SettableFuture.create();
    821     SettableFuture<String> future3 = SettableFuture.create();
    822     @SuppressWarnings("unchecked") // array is never modified
    823     ListenableFuture<List<String>> compound =
    824         Futures.allAsList(future1, future2, future3);
    825 
    826     // Attach a listener
    827     SingleCallListener listener = new SingleCallListener();
    828     compound.addListener(listener, directExecutor());
    829 
    830     // Satisfy each input and check the output
    831     assertFalse(compound.isDone());
    832     future1.set(DATA1);
    833     assertFalse(compound.isDone());
    834     future2.set(DATA2);
    835     assertFalse(compound.isDone());
    836     listener.expectCall();
    837     future3.set(DATA3);
    838     assertTrue(compound.isDone());
    839     assertTrue(listener.wasCalled());
    840 
    841     List<String> results = compound.get();
    842     assertThat(results).has().exactly(DATA1, DATA2, DATA3).inOrder();
    843   }
    844 
    845   public void testAllAsList_emptyList() throws Exception {
    846     SingleCallListener listener = new SingleCallListener();
    847     listener.expectCall();
    848     List<ListenableFuture<String>> futures = ImmutableList.of();
    849     ListenableFuture<List<String>> compound = Futures.allAsList(futures);
    850     compound.addListener(listener, directExecutor());
    851     assertTrue(compound.isDone());
    852     assertTrue(compound.get().isEmpty());
    853     assertTrue(listener.wasCalled());
    854   }
    855 
    856   public void testAllAsList_emptyArray() throws Exception {
    857     SingleCallListener listener = new SingleCallListener();
    858     listener.expectCall();
    859     @SuppressWarnings("unchecked") // array is never modified
    860     ListenableFuture<List<String>> compound = Futures.allAsList();
    861     compound.addListener(listener, directExecutor());
    862     assertTrue(compound.isDone());
    863     assertTrue(compound.get().isEmpty());
    864     assertTrue(listener.wasCalled());
    865   }
    866 
    867   public void testAllAsList_failure() throws Exception {
    868     SingleCallListener listener = new SingleCallListener();
    869     SettableFuture<String> future1 = SettableFuture.create();
    870     SettableFuture<String> future2 = SettableFuture.create();
    871     @SuppressWarnings("unchecked") // array is never modified
    872     ListenableFuture<List<String>> compound =
    873         Futures.allAsList(future1, future2);
    874     compound.addListener(listener, directExecutor());
    875 
    876     listener.expectCall();
    877     Throwable exception = new Throwable("failed1");
    878     future1.setException(exception);
    879     assertTrue(compound.isDone());
    880     assertTrue(listener.wasCalled());
    881     future2.set("result2");
    882 
    883     try {
    884       compound.get();
    885       fail("Expected exception not thrown");
    886     } catch (ExecutionException e) {
    887       assertSame(exception, e.getCause());
    888     }
    889   }
    890 
    891   public void testAllAsList_singleFailure() throws Exception {
    892     Throwable exception = new Throwable("failed");
    893     ListenableFuture<String> future = Futures.immediateFailedFuture(exception);
    894     ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future));
    895 
    896     try {
    897       compound.get();
    898       fail("Expected exception not thrown");
    899     } catch (ExecutionException e) {
    900       assertSame(exception, e.getCause());
    901     }
    902   }
    903 
    904   public void testAllAsList_immediateFailure() throws Exception {
    905     Throwable exception = new Throwable("failed");
    906     ListenableFuture<String> future1 = Futures.immediateFailedFuture(exception);
    907     ListenableFuture<String> future2 = Futures.immediateFuture("results");
    908     ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2));
    909 
    910     try {
    911       compound.get();
    912       fail("Expected exception not thrown");
    913     } catch (ExecutionException e) {
    914       assertSame(exception, e.getCause());
    915     }
    916   }
    917 
    918   public void testAllAsList_error() throws Exception {
    919     Error error = new Error("deliberate");
    920     SettableFuture<String> future1 = SettableFuture.create();
    921     ListenableFuture<String> future2 = Futures.immediateFuture("results");
    922     ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2));
    923 
    924     future1.setException(error);
    925     try {
    926       compound.get();
    927       fail("Expected error not set in compound future.");
    928     } catch (ExecutionException ee) {
    929       assertSame(error, ee.getCause());
    930     }
    931   }
    932 
    933   public void testAllAsList_cancelled() throws Exception {
    934     SingleCallListener listener = new SingleCallListener();
    935     SettableFuture<String> future1 = SettableFuture.create();
    936     SettableFuture<String> future2 = SettableFuture.create();
    937     @SuppressWarnings("unchecked") // array is never modified
    938     ListenableFuture<List<String>> compound =
    939         Futures.allAsList(future1, future2);
    940     compound.addListener(listener, directExecutor());
    941 
    942     listener.expectCall();
    943     future1.cancel(true);
    944     assertTrue(compound.isDone());
    945     assertTrue(listener.wasCalled());
    946     future2.setException(new Throwable("failed2"));
    947 
    948     try {
    949       compound.get();
    950       fail("Expected exception not thrown");
    951     } catch (CancellationException e) {
    952       // Expected
    953     }
    954   }
    955 
    956   public void testAllAsList_resultCancelled() throws Exception {
    957     SettableFuture<String> future1 = SettableFuture.create();
    958     SettableFuture<String> future2 = SettableFuture.create();
    959     @SuppressWarnings("unchecked") // array is never modified
    960     ListenableFuture<List<String>> compound =
    961         Futures.allAsList(future1, future2);
    962 
    963     future2.set(DATA2);
    964     assertFalse(compound.isDone());
    965     assertTrue(compound.cancel(false));
    966     assertTrue(compound.isCancelled());
    967     assertTrue(future1.isCancelled());
    968     assertFalse(future1.wasInterrupted());
    969   }
    970 
    971   public void testAllAsList_resultInterrupted() throws Exception {
    972     SettableFuture<String> future1 = SettableFuture.create();
    973     SettableFuture<String> future2 = SettableFuture.create();
    974     @SuppressWarnings("unchecked") // array is never modified
    975     ListenableFuture<List<String>> compound =
    976         Futures.allAsList(future1, future2);
    977 
    978     future2.set(DATA2);
    979     assertFalse(compound.isDone());
    980     assertTrue(compound.cancel(true));
    981     assertTrue(compound.isCancelled());
    982     assertTrue(future1.isCancelled());
    983     assertTrue(future1.wasInterrupted());
    984   }
    985 
    986   /**
    987    * Test the case where the futures are fulfilled prior to
    988    * constructing the ListFuture.  There was a bug where the
    989    * loop that connects a Listener to each of the futures would die
    990    * on the last loop-check as done() on ListFuture nulled out the
    991    * variable being looped over (the list of futures).
    992    */
    993   public void testAllAsList_doneFutures() throws Exception {
    994     // Create input and output
    995     SettableFuture<String> future1 = SettableFuture.create();
    996     SettableFuture<String> future2 = SettableFuture.create();
    997     SettableFuture<String> future3 = SettableFuture.create();
    998 
    999     // Satisfy each input prior to creating compound and check the output
   1000     future1.set(DATA1);
   1001     future2.set(DATA2);
   1002     future3.set(DATA3);
   1003 
   1004     @SuppressWarnings("unchecked") // array is never modified
   1005     ListenableFuture<List<String>> compound =
   1006         Futures.allAsList(future1, future2, future3);
   1007 
   1008     // Attach a listener
   1009     SingleCallListener listener = new SingleCallListener();
   1010     listener.expectCall();
   1011     compound.addListener(listener, directExecutor());
   1012 
   1013     assertTrue(compound.isDone());
   1014     assertTrue(listener.wasCalled());
   1015 
   1016     List<String> results = compound.get();
   1017     assertThat(results).has().exactly(DATA1, DATA2, DATA3).inOrder();
   1018   }
   1019 
   1020   /**
   1021    * A single non-error failure is not logged because it is reported via the output future.
   1022    */
   1023   @SuppressWarnings("unchecked")
   1024   public void testAllAsList_logging_exception() throws Exception {
   1025     try {
   1026       Futures.allAsList(immediateFailedFuture(new MyException())).get();
   1027       fail();
   1028     } catch (ExecutionException e) {
   1029       assertTrue(e.getCause() instanceof MyException);
   1030       assertEquals("Nothing should be logged", 0,
   1031           combinedFutureLogHandler.getStoredLogRecords().size());
   1032     }
   1033   }
   1034 
   1035   /**
   1036    * Ensure that errors are always logged.
   1037    */
   1038   @SuppressWarnings("unchecked")
   1039   public void testAllAsList_logging_error() throws Exception {
   1040     try {
   1041       Futures.allAsList(immediateFailedFuture(new MyError())).get();
   1042       fail();
   1043     } catch (ExecutionException e) {
   1044       assertTrue(e.getCause() instanceof MyError);
   1045       List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords();
   1046       assertEquals(1, logged.size());  // errors are always logged
   1047       assertTrue(logged.get(0).getThrown() instanceof MyError);
   1048     }
   1049   }
   1050 
   1051   /**
   1052    * All as list will log extra exceptions that occur after failure.
   1053    */
   1054   @SuppressWarnings("unchecked")
   1055   public void testAllAsList_logging_multipleExceptions() throws Exception {
   1056     try {
   1057       Futures.allAsList(immediateFailedFuture(new MyException()),
   1058           immediateFailedFuture(new MyException())).get();
   1059       fail();
   1060     } catch (ExecutionException e) {
   1061       assertTrue(e.getCause() instanceof MyException);
   1062       List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords();
   1063       assertEquals(1, logged.size());  // the second failure is logged
   1064       assertTrue(logged.get(0).getThrown() instanceof MyException);
   1065     }
   1066   }
   1067 
   1068   private static String createCombinedResult(Integer i, Boolean b) {
   1069     return "-" + i + "-" + b;
   1070   }
   1071 
   1072   /*
   1073    * TODO(cpovirk): maybe pass around TestFuture instances instead of
   1074    * ListenableFuture instances
   1075    */
   1076   /**
   1077    * A future in {@link TestFutureBatch} that also has a name for debugging
   1078    * purposes and a {@code finisher}, a task that will complete the future in
   1079    * some fashion when it is called, allowing for testing both before and after
   1080    * the completion of the future.
   1081    */
   1082   private static final class TestFuture {
   1083     final ListenableFuture<String> future;
   1084     final String name;
   1085     final Runnable finisher;
   1086 
   1087     TestFuture(
   1088         ListenableFuture<String> future, String name, Runnable finisher) {
   1089       this.future = future;
   1090       this.name = name;
   1091       this.finisher = finisher;
   1092     }
   1093   }
   1094 
   1095   /**
   1096    * A collection of several futures, covering cancellation, success, and
   1097    * failure (both {@link ExecutionException} and {@link RuntimeException}),
   1098    * both immediate and delayed. We use each possible pair of these futures in
   1099    * {@link FuturesTest#runExtensiveMergerTest}.
   1100    *
   1101    * <p>Each test requires a new {@link TestFutureBatch} because we need new
   1102    * delayed futures each time, as the old delayed futures were completed as
   1103    * part of the old test.
   1104    */
   1105   private static final class TestFutureBatch {
   1106     final ListenableFuture<String> doneSuccess = immediateFuture("a");
   1107     final ListenableFuture<String> doneFailed =
   1108         immediateFailedFuture(new Exception());
   1109     final SettableFuture<String> doneCancelled = SettableFuture.create();
   1110     {
   1111       doneCancelled.cancel(true);
   1112     }
   1113 
   1114     final ListenableFuture<String> doneRuntimeException =
   1115         new ForwardingListenableFuture<String>() {
   1116           final ListenableFuture<String> delegate =
   1117               immediateFuture("Should never be seen");
   1118 
   1119           @Override
   1120           protected ListenableFuture<String> delegate() {
   1121             return delegate;
   1122           }
   1123 
   1124           @Override
   1125           public String get() {
   1126             throw new RuntimeException();
   1127           }
   1128 
   1129           @Override
   1130           public String get(long timeout, TimeUnit unit) {
   1131             throw new RuntimeException();
   1132           }
   1133     };
   1134 
   1135     final SettableFuture<String> delayedSuccess = SettableFuture.create();
   1136     final SettableFuture<String> delayedFailed = SettableFuture.create();
   1137     final SettableFuture<String> delayedCancelled = SettableFuture.create();
   1138 
   1139     final SettableFuture<String> delegateForDelayedRuntimeException =
   1140         SettableFuture.create();
   1141     final ListenableFuture<String> delayedRuntimeException =
   1142         new ForwardingListenableFuture<String>() {
   1143           @Override
   1144           protected ListenableFuture<String> delegate() {
   1145             return delegateForDelayedRuntimeException;
   1146           }
   1147 
   1148           @Override
   1149           public String get() throws ExecutionException, InterruptedException {
   1150             delegateForDelayedRuntimeException.get();
   1151             throw new RuntimeException();
   1152           }
   1153 
   1154           @Override
   1155           public String get(long timeout, TimeUnit unit) throws
   1156               ExecutionException, InterruptedException, TimeoutException {
   1157             delegateForDelayedRuntimeException.get(timeout, unit);
   1158             throw new RuntimeException();
   1159           }
   1160     };
   1161 
   1162     final Runnable doNothing = new Runnable() {
   1163       @Override
   1164       public void run() {
   1165       }
   1166     };
   1167     final Runnable finishSuccess = new Runnable() {
   1168       @Override
   1169       public void run() {
   1170         delayedSuccess.set("b");
   1171       }
   1172     };
   1173     final Runnable finishFailure = new Runnable() {
   1174       @Override
   1175       public void run() {
   1176         delayedFailed.setException(new Exception());
   1177       }
   1178     };
   1179     final Runnable finishCancelled = new Runnable() {
   1180       @Override
   1181       public void run() {
   1182         delayedCancelled.cancel(true);
   1183       }
   1184     };
   1185     final Runnable finishRuntimeException = new Runnable() {
   1186       @Override
   1187       public void run() {
   1188         delegateForDelayedRuntimeException.set("Should never be seen");
   1189       }
   1190     };
   1191 
   1192     /**
   1193      * All the futures, together with human-readable names for use by
   1194      * {@link #smartToString}.
   1195      */
   1196     final ImmutableList<TestFuture> allFutures =
   1197         ImmutableList.of(new TestFuture(doneSuccess, "doneSuccess", doNothing),
   1198             new TestFuture(doneFailed, "doneFailed", doNothing),
   1199             new TestFuture(doneCancelled, "doneCancelled", doNothing),
   1200             new TestFuture(
   1201                 doneRuntimeException, "doneRuntimeException", doNothing),
   1202             new TestFuture(delayedSuccess, "delayedSuccess", finishSuccess),
   1203             new TestFuture(delayedFailed, "delayedFailed", finishFailure),
   1204             new TestFuture(
   1205                 delayedCancelled, "delayedCancelled", finishCancelled),
   1206             new TestFuture(delayedRuntimeException, "delayedRuntimeException",
   1207                 finishRuntimeException));
   1208 
   1209     final Function<ListenableFuture<String>, String> nameGetter =
   1210       new Function<ListenableFuture<String>, String>() {
   1211         @Override
   1212         public String apply(ListenableFuture<String> input) {
   1213           for (TestFuture future : allFutures) {
   1214             if (future.future == input) {
   1215               return future.name;
   1216             }
   1217           }
   1218           throw new IllegalArgumentException(input.toString());
   1219         }
   1220       };
   1221 
   1222     static boolean intersect(Set<?> a, Set<?> b) {
   1223       return !Sets.intersection(a, b).isEmpty();
   1224     }
   1225 
   1226     /**
   1227      * Like {@code inputs.toString()}, but with the nonsense {@code toString}
   1228      * representations replaced with the name of each future from
   1229      * {@link #allFutures}.
   1230      */
   1231     String smartToString(ImmutableSet<ListenableFuture<String>> inputs) {
   1232       Iterable<String> inputNames = Iterables.transform(inputs, nameGetter);
   1233       return Joiner.on(", ").join(inputNames);
   1234     }
   1235 
   1236     void smartAssertTrue(ImmutableSet<ListenableFuture<String>> inputs,
   1237         Exception cause, boolean expression) {
   1238       if (!expression) {
   1239         failWithCause(cause, smartToString(inputs));
   1240       }
   1241     }
   1242 
   1243     boolean hasDelayed(ListenableFuture<String> a, ListenableFuture<String> b) {
   1244       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1245       return intersect(inputs, ImmutableSet.of(
   1246           delayedSuccess, delayedFailed, delayedCancelled,
   1247           delayedRuntimeException));
   1248     }
   1249 
   1250     void assertHasDelayed(
   1251         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
   1252       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1253       smartAssertTrue(inputs, e, hasDelayed(a, b));
   1254     }
   1255 
   1256     void assertHasFailure(
   1257         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
   1258       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1259       smartAssertTrue(inputs, e, intersect(inputs, ImmutableSet.of(doneFailed,
   1260           doneRuntimeException, delayedFailed, delayedRuntimeException)));
   1261     }
   1262 
   1263     void assertHasCancel(
   1264         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
   1265       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1266       smartAssertTrue(inputs, e,
   1267           intersect(inputs, ImmutableSet.of(doneCancelled, delayedCancelled)));
   1268     }
   1269 
   1270     void assertHasImmediateFailure(
   1271         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
   1272       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1273       smartAssertTrue(inputs, e, intersect(
   1274           inputs, ImmutableSet.of(doneFailed, doneRuntimeException)));
   1275     }
   1276 
   1277     void assertHasImmediateCancel(
   1278         ListenableFuture<String> a, ListenableFuture<String> b, Exception e) {
   1279       ImmutableSet<ListenableFuture<String>> inputs = ImmutableSet.of(a, b);
   1280       smartAssertTrue(inputs, e,
   1281           intersect(inputs, ImmutableSet.of(doneCancelled)));
   1282     }
   1283   }
   1284 
   1285   /**
   1286    * {@link Futures#allAsList(Iterable)} or
   1287    * {@link Futures#successfulAsList(Iterable)}, hidden behind a common
   1288    * interface for testing.
   1289    */
   1290   private interface Merger {
   1291     ListenableFuture<List<String>> merged(
   1292         ListenableFuture<String> a, ListenableFuture<String> b);
   1293 
   1294     Merger allMerger = new Merger() {
   1295       @Override
   1296       public ListenableFuture<List<String>> merged(
   1297           ListenableFuture<String> a, ListenableFuture<String> b) {
   1298         return allAsList(ImmutableSet.of(a, b));
   1299       }
   1300     };
   1301     Merger successMerger = new Merger() {
   1302       @Override
   1303       public ListenableFuture<List<String>> merged(
   1304           ListenableFuture<String> a, ListenableFuture<String> b) {
   1305         return successfulAsList(ImmutableSet.of(a, b));
   1306       }
   1307     };
   1308   }
   1309 
   1310   /**
   1311    * Very rough equivalent of a timed get, produced by calling the no-arg get
   1312    * method in another thread and waiting a short time for it.
   1313    *
   1314    * <p>We need this to test the behavior of no-arg get methods without hanging
   1315    * the main test thread forever in the case of failure.
   1316    */
   1317   private static <V> V pseudoTimedGet(
   1318       final Future<V> input, long timeout, TimeUnit unit)
   1319       throws InterruptedException, ExecutionException, TimeoutException {
   1320     ExecutorService executor = newSingleThreadExecutor();
   1321     Future<V> waiter = executor.submit(new Callable<V>() {
   1322       @Override
   1323       public V call() throws Exception {
   1324         return input.get();
   1325       }
   1326     });
   1327 
   1328     try {
   1329       return waiter.get(timeout, unit);
   1330     } catch (ExecutionException e) {
   1331       propagateIfInstanceOf(e.getCause(), ExecutionException.class);
   1332       propagateIfInstanceOf(e.getCause(), CancellationException.class);
   1333       AssertionFailedError error =
   1334           new AssertionFailedError("Unexpected exception");
   1335       error.initCause(e);
   1336       throw error;
   1337     } finally {
   1338       executor.shutdownNow();
   1339       assertTrue(executor.awaitTermination(10, SECONDS));
   1340     }
   1341   }
   1342 
   1343   /**
   1344    * For each possible pair of futures from {@link TestFutureBatch}, for each
   1345    * possible completion order of those futures, test that various get calls
   1346    * (timed before future completion, untimed before future completion, and
   1347    * untimed after future completion) return or throw the proper values.
   1348    */
   1349   private static void runExtensiveMergerTest(Merger merger)
   1350       throws InterruptedException {
   1351     int inputCount = new TestFutureBatch().allFutures.size();
   1352 
   1353     for (int i = 0; i < inputCount; i++) {
   1354       for (int j = 0; j < inputCount; j++) {
   1355         for (boolean iBeforeJ : new boolean[] { true, false }) {
   1356           TestFutureBatch inputs = new TestFutureBatch();
   1357           ListenableFuture<String> iFuture = inputs.allFutures.get(i).future;
   1358           ListenableFuture<String> jFuture = inputs.allFutures.get(j).future;
   1359           ListenableFuture<List<String>> future =
   1360               merger.merged(iFuture, jFuture);
   1361 
   1362           // Test timed get before we've completed any delayed futures.
   1363           try {
   1364             List<String> result = future.get(0, MILLISECONDS);
   1365             assertTrue("Got " + result,
   1366                 Arrays.asList("a", null).containsAll(result));
   1367           } catch (CancellationException e) {
   1368             assertTrue(merger == Merger.allMerger);
   1369             inputs.assertHasImmediateCancel(iFuture, jFuture, e);
   1370           } catch (ExecutionException e) {
   1371             assertTrue(merger == Merger.allMerger);
   1372             inputs.assertHasImmediateFailure(iFuture, jFuture, e);
   1373           } catch (TimeoutException e) {
   1374             inputs.assertHasDelayed(iFuture, jFuture, e);
   1375           }
   1376 
   1377           // Same tests with pseudoTimedGet.
   1378           try {
   1379             List<String> result = conditionalPseudoTimedGet(
   1380                 inputs, iFuture, jFuture, future, 20, MILLISECONDS);
   1381             assertTrue("Got " + result,
   1382                 Arrays.asList("a", null).containsAll(result));
   1383           } catch (CancellationException e) {
   1384             assertTrue(merger == Merger.allMerger);
   1385             inputs.assertHasImmediateCancel(iFuture, jFuture, e);
   1386           } catch (ExecutionException e) {
   1387             assertTrue(merger == Merger.allMerger);
   1388             inputs.assertHasImmediateFailure(iFuture, jFuture, e);
   1389           } catch (TimeoutException e) {
   1390             inputs.assertHasDelayed(iFuture, jFuture, e);
   1391           }
   1392 
   1393           // Finish the two futures in the currently specified order:
   1394           inputs.allFutures.get(iBeforeJ ? i : j).finisher.run();
   1395           inputs.allFutures.get(iBeforeJ ? j : i).finisher.run();
   1396 
   1397           // Test untimed get now that we've completed any delayed futures.
   1398           try {
   1399             List<String> result = future.get();
   1400             assertTrue("Got " + result,
   1401                 Arrays.asList("a", "b", null).containsAll(result));
   1402           } catch (CancellationException e) {
   1403             assertTrue(merger == Merger.allMerger);
   1404             inputs.assertHasCancel(iFuture, jFuture, e);
   1405           } catch (ExecutionException e) {
   1406             assertTrue(merger == Merger.allMerger);
   1407             inputs.assertHasFailure(iFuture, jFuture, e);
   1408           }
   1409         }
   1410       }
   1411     }
   1412   }
   1413 
   1414   /**
   1415    * Call the non-timed {@link Future#get()} in a way that allows us to abort if
   1416    * it's expected to hang forever. More precisely, if it's expected to return,
   1417    * we simply call it[*], but if it's expected to hang (because one of the
   1418    * input futures that we know makes it up isn't done yet), then we call it in
   1419    * a separate thread (using pseudoTimedGet). The result is that we wait as
   1420    * long as necessary when the method is expected to return (at the cost of
   1421    * hanging forever if there is a bug in the class under test) but that we time
   1422    * out fairly promptly when the method is expected to hang (possibly too
   1423    * quickly, but too-quick failures should be very unlikely, given that we used
   1424    * to bail after 20ms during the expected-successful tests, and there we saw a
   1425    * failure rate of ~1/5000, meaning that the other thread's get() call nearly
   1426    * always completes within 20ms if it's going to complete at all).
   1427    *
   1428    * [*] To avoid hangs, I've disabled the in-thread calls. This makes the test
   1429    * take (very roughly) 2.5s longer. (2.5s is also the maximum length of time
   1430    * we will wait for a timed get that is expected to succeed; the fact that the
   1431    * numbers match is only a coincidence.) See the comment below for how to
   1432    * restore the fast but hang-y version.
   1433    */
   1434   private static List<String> conditionalPseudoTimedGet(
   1435       TestFutureBatch inputs,
   1436       ListenableFuture<String> iFuture,
   1437       ListenableFuture<String> jFuture,
   1438       ListenableFuture<List<String>> future,
   1439       int timeout,
   1440       TimeUnit unit)
   1441       throws InterruptedException, ExecutionException, TimeoutException {
   1442     /*
   1443      * For faster tests (that may hang indefinitely if the class under test has
   1444      * a bug!), switch the second branch to call untimed future.get() instead of
   1445      * pseudoTimedGet.
   1446      */
   1447     return (inputs.hasDelayed(iFuture, jFuture))
   1448         ? pseudoTimedGet(future, timeout, unit)
   1449         : pseudoTimedGet(future, 2500, MILLISECONDS);
   1450   }
   1451 
   1452   public void testAllAsList_extensive() throws InterruptedException {
   1453     runExtensiveMergerTest(Merger.allMerger);
   1454   }
   1455 
   1456   public void testSuccessfulAsList_extensive() throws InterruptedException {
   1457     runExtensiveMergerTest(Merger.successMerger);
   1458   }
   1459 
   1460   public void testSuccessfulAsList() throws Exception {
   1461     // Create input and output
   1462     SettableFuture<String> future1 = SettableFuture.create();
   1463     SettableFuture<String> future2 = SettableFuture.create();
   1464     SettableFuture<String> future3 = SettableFuture.create();
   1465     @SuppressWarnings("unchecked") // array is never modified
   1466     ListenableFuture<List<String>> compound =
   1467         Futures.successfulAsList(future1, future2, future3);
   1468 
   1469     // Attach a listener
   1470     SingleCallListener listener = new SingleCallListener();
   1471     compound.addListener(listener, directExecutor());
   1472 
   1473     // Satisfy each input and check the output
   1474     assertFalse(compound.isDone());
   1475     future1.set(DATA1);
   1476     assertFalse(compound.isDone());
   1477     future2.set(DATA2);
   1478     assertFalse(compound.isDone());
   1479     listener.expectCall();
   1480     future3.set(DATA3);
   1481     assertTrue(compound.isDone());
   1482     assertTrue(listener.wasCalled());
   1483 
   1484     List<String> results = compound.get();
   1485     assertThat(results).has().exactly(DATA1, DATA2, DATA3).inOrder();
   1486   }
   1487 
   1488   public void testSuccessfulAsList_emptyList() throws Exception {
   1489     SingleCallListener listener = new SingleCallListener();
   1490     listener.expectCall();
   1491     List<ListenableFuture<String>> futures = ImmutableList.of();
   1492     ListenableFuture<List<String>> compound = Futures.successfulAsList(futures);
   1493     compound.addListener(listener, directExecutor());
   1494     assertTrue(compound.isDone());
   1495     assertTrue(compound.get().isEmpty());
   1496     assertTrue(listener.wasCalled());
   1497   }
   1498 
   1499   public void testSuccessfulAsList_emptyArray() throws Exception {
   1500     SingleCallListener listener = new SingleCallListener();
   1501     listener.expectCall();
   1502     @SuppressWarnings("unchecked") // array is never modified
   1503     ListenableFuture<List<String>> compound = Futures.successfulAsList();
   1504     compound.addListener(listener, directExecutor());
   1505     assertTrue(compound.isDone());
   1506     assertTrue(compound.get().isEmpty());
   1507     assertTrue(listener.wasCalled());
   1508   }
   1509 
   1510   public void testSuccessfulAsList_partialFailure() throws Exception {
   1511     SingleCallListener listener = new SingleCallListener();
   1512     SettableFuture<String> future1 = SettableFuture.create();
   1513     SettableFuture<String> future2 = SettableFuture.create();
   1514     @SuppressWarnings("unchecked") // array is never modified
   1515     ListenableFuture<List<String>> compound =
   1516         Futures.successfulAsList(future1, future2);
   1517     compound.addListener(listener, directExecutor());
   1518 
   1519     assertFalse(compound.isDone());
   1520     future1.setException(new Throwable("failed1"));
   1521     assertFalse(compound.isDone());
   1522     listener.expectCall();
   1523     future2.set(DATA2);
   1524     assertTrue(compound.isDone());
   1525     assertTrue(listener.wasCalled());
   1526 
   1527     List<String> results = compound.get();
   1528     assertThat(results).has().exactly(null, DATA2).inOrder();
   1529   }
   1530 
   1531   public void testSuccessfulAsList_totalFailure() throws Exception {
   1532     SingleCallListener listener = new SingleCallListener();
   1533     SettableFuture<String> future1 = SettableFuture.create();
   1534     SettableFuture<String> future2 = SettableFuture.create();
   1535     @SuppressWarnings("unchecked") // array is never modified
   1536     ListenableFuture<List<String>> compound =
   1537         Futures.successfulAsList(future1, future2);
   1538     compound.addListener(listener, directExecutor());
   1539 
   1540     assertFalse(compound.isDone());
   1541     future1.setException(new Throwable("failed1"));
   1542     assertFalse(compound.isDone());
   1543     listener.expectCall();
   1544     future2.setException(new Throwable("failed2"));
   1545     assertTrue(compound.isDone());
   1546     assertTrue(listener.wasCalled());
   1547 
   1548     List<String> results = compound.get();
   1549     assertThat(results).has().exactly(null, null).inOrder();
   1550   }
   1551 
   1552   public void testSuccessfulAsList_cancelled() throws Exception {
   1553     SingleCallListener listener = new SingleCallListener();
   1554     SettableFuture<String> future1 = SettableFuture.create();
   1555     SettableFuture<String> future2 = SettableFuture.create();
   1556     @SuppressWarnings("unchecked") // array is never modified
   1557     ListenableFuture<List<String>> compound =
   1558         Futures.successfulAsList(future1, future2);
   1559     compound.addListener(listener, directExecutor());
   1560 
   1561     assertFalse(compound.isDone());
   1562     future1.cancel(true);
   1563     assertFalse(compound.isDone());
   1564     listener.expectCall();
   1565     future2.set(DATA2);
   1566     assertTrue(compound.isDone());
   1567     assertTrue(listener.wasCalled());
   1568 
   1569     List<String> results = compound.get();
   1570     assertThat(results).has().exactly(null, DATA2).inOrder();
   1571   }
   1572 
   1573   public void testSuccessfulAsList_resultCancelled() throws Exception {
   1574     SettableFuture<String> future1 = SettableFuture.create();
   1575     SettableFuture<String> future2 = SettableFuture.create();
   1576     @SuppressWarnings("unchecked") // array is never modified
   1577     ListenableFuture<List<String>> compound =
   1578         Futures.successfulAsList(future1, future2);
   1579 
   1580     future2.set(DATA2);
   1581     assertFalse(compound.isDone());
   1582     assertTrue(compound.cancel(false));
   1583     assertTrue(compound.isCancelled());
   1584     assertTrue(future1.isCancelled());
   1585     assertFalse(future1.wasInterrupted());
   1586   }
   1587 
   1588   public void testSuccessfulAsList_resultCancelledRacingInputDone()
   1589       throws Exception {
   1590     /*
   1591      * The IllegalStateException that we're testing for is caught by
   1592      * ExecutionList and logged rather than allowed to propagate. We need to
   1593      * turn that back into a failure.
   1594      */
   1595     Handler throwingHandler = new Handler() {
   1596       @Override public void publish(@Nullable LogRecord record) {
   1597         AssertionFailedError error = new AssertionFailedError();
   1598         error.initCause(record.getThrown());
   1599         throw error;
   1600       }
   1601 
   1602       @Override public void flush() {}
   1603 
   1604       @Override public void close() {}
   1605     };
   1606 
   1607     ExecutionList.log.addHandler(throwingHandler);
   1608     try {
   1609       doTestSuccessfulAsList_resultCancelledRacingInputDone();
   1610     } finally {
   1611       ExecutionList.log.removeHandler(throwingHandler);
   1612     }
   1613   }
   1614 
   1615   private static void doTestSuccessfulAsList_resultCancelledRacingInputDone()
   1616       throws Exception {
   1617     // Simple (combined.cancel -> input.cancel -> setOneValue):
   1618     Futures.successfulAsList(ImmutableList.of(SettableFuture.create()))
   1619         .cancel(true);
   1620 
   1621     /*
   1622      * Complex (combined.cancel -> input.cancel -> other.set -> setOneValue),
   1623      * to show that this isn't just about problems with the input future we just
   1624      * cancelled:
   1625      */
   1626     final SettableFuture<String> future1 = SettableFuture.create();
   1627     final SettableFuture<String> future2 = SettableFuture.create();
   1628     @SuppressWarnings("unchecked") // array is never modified
   1629     ListenableFuture<List<String>> compound =
   1630         Futures.successfulAsList(future1, future2);
   1631 
   1632     future1.addListener(new Runnable() {
   1633       @Override public void run() {
   1634         assertTrue(future1.isCancelled());
   1635         /*
   1636          * This test relies on behavior that's unspecified but currently
   1637          * guaranteed by the implementation: Cancellation of inputs is
   1638          * performed in the order they were provided to the constructor. Verify
   1639          * that as a sanity check:
   1640          */
   1641         assertFalse(future2.isCancelled());
   1642         // Now attempt to trigger the exception:
   1643         future2.set(DATA2);
   1644       }
   1645     }, directExecutor());
   1646     assertTrue(compound.cancel(false));
   1647     assertTrue(compound.isCancelled());
   1648     assertTrue(future1.isCancelled());
   1649     assertFalse(future2.isCancelled());
   1650 
   1651     try {
   1652       compound.get();
   1653       fail("Expected exception not thrown");
   1654     } catch (CancellationException e) {
   1655       // Expected
   1656     }
   1657   }
   1658 
   1659   public void testSuccessfulAsList_resultInterrupted() throws Exception {
   1660     SettableFuture<String> future1 = SettableFuture.create();
   1661     SettableFuture<String> future2 = SettableFuture.create();
   1662     @SuppressWarnings("unchecked") // array is never modified
   1663     ListenableFuture<List<String>> compound =
   1664         Futures.successfulAsList(future1, future2);
   1665 
   1666     future2.set(DATA2);
   1667     assertFalse(compound.isDone());
   1668     assertTrue(compound.cancel(true));
   1669     assertTrue(compound.isCancelled());
   1670     assertTrue(future1.isCancelled());
   1671     assertTrue(future1.wasInterrupted());
   1672   }
   1673 
   1674   public void testSuccessfulAsList_mixed() throws Exception {
   1675     SingleCallListener listener = new SingleCallListener();
   1676     SettableFuture<String> future1 = SettableFuture.create();
   1677     SettableFuture<String> future2 = SettableFuture.create();
   1678     SettableFuture<String> future3 = SettableFuture.create();
   1679     @SuppressWarnings("unchecked") // array is never modified
   1680     ListenableFuture<List<String>> compound =
   1681         Futures.successfulAsList(future1, future2, future3);
   1682     compound.addListener(listener, directExecutor());
   1683 
   1684     // First is cancelled, second fails, third succeeds
   1685     assertFalse(compound.isDone());
   1686     future1.cancel(true);
   1687     assertFalse(compound.isDone());
   1688     future2.setException(new Throwable("failed2"));
   1689     assertFalse(compound.isDone());
   1690     listener.expectCall();
   1691     future3.set(DATA3);
   1692     assertTrue(compound.isDone());
   1693     assertTrue(listener.wasCalled());
   1694 
   1695     List<String> results = compound.get();
   1696     assertThat(results).has().exactly(null, null, DATA3).inOrder();
   1697   }
   1698 
   1699   /** Non-Error exceptions are never logged. */
   1700   @SuppressWarnings("unchecked")
   1701   public void testSuccessfulAsList_logging_exception() throws Exception {
   1702     assertEquals(Lists.newArrayList((Object) null),
   1703         Futures.successfulAsList(
   1704             immediateFailedFuture(new MyException())).get());
   1705     assertEquals("Nothing should be logged", 0,
   1706         combinedFutureLogHandler.getStoredLogRecords().size());
   1707 
   1708     // Not even if there are a bunch of failures.
   1709     assertEquals(Lists.newArrayList(null, null, null),
   1710         Futures.successfulAsList(
   1711             immediateFailedFuture(new MyException()),
   1712             immediateFailedFuture(new MyException()),
   1713             immediateFailedFuture(new MyException())).get());
   1714     assertEquals("Nothing should be logged", 0,
   1715         combinedFutureLogHandler.getStoredLogRecords().size());
   1716   }
   1717 
   1718   /**
   1719    * Ensure that errors are always logged.
   1720    */
   1721   @SuppressWarnings("unchecked")
   1722   public void testSuccessfulAsList_logging_error() throws Exception {
   1723     assertEquals(Lists.newArrayList((Object) null),
   1724         Futures.successfulAsList(
   1725             immediateFailedFuture(new MyError())).get());
   1726     List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords();
   1727     assertEquals(1, logged.size());  // errors are always logged
   1728     assertTrue(logged.get(0).getThrown() instanceof MyError);
   1729   }
   1730 
   1731   public void testNonCancellationPropagating_successful() throws Exception {
   1732     SettableFuture<Foo> input = SettableFuture.create();
   1733     ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input);
   1734     Foo foo = new Foo();
   1735 
   1736     assertFalse(wrapper.isDone());
   1737     input.set(foo);
   1738     assertTrue(wrapper.isDone());
   1739     assertSame(foo, wrapper.get());
   1740   }
   1741 
   1742   public void testNonCancellationPropagating_failure() throws Exception {
   1743     SettableFuture<Foo> input = SettableFuture.create();
   1744     ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input);
   1745     Throwable failure = new Throwable("thrown");
   1746 
   1747     assertFalse(wrapper.isDone());
   1748     input.setException(failure);
   1749     assertTrue(wrapper.isDone());
   1750     try {
   1751       wrapper.get();
   1752       fail("Expected ExecutionException");
   1753     } catch (ExecutionException e) {
   1754       assertSame(failure, e.getCause());
   1755     }
   1756   }
   1757 
   1758   public void testNonCancellationPropagating_delegateCancelled() throws Exception {
   1759     SettableFuture<Foo> input = SettableFuture.create();
   1760     ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input);
   1761 
   1762     assertFalse(wrapper.isDone());
   1763     assertTrue(input.cancel(false));
   1764     assertTrue(wrapper.isCancelled());
   1765   }
   1766 
   1767   public void testNonCancellationPropagating_doesNotPropagate() throws Exception {
   1768     SettableFuture<Foo> input = SettableFuture.create();
   1769     ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input);
   1770 
   1771     assertTrue(wrapper.cancel(true));
   1772     assertTrue(wrapper.isCancelled());
   1773     assertTrue(wrapper.isDone());
   1774     assertFalse(input.isCancelled());
   1775     assertFalse(input.isDone());
   1776   }
   1777 
   1778   private static class TestException extends Exception {
   1779     TestException(@Nullable Throwable cause) {
   1780       super(cause);
   1781     }
   1782   }
   1783 
   1784   private static final Function<Exception, TestException> mapper =
   1785       new Function<Exception, TestException>() {
   1786     @Override public TestException apply(Exception from) {
   1787       if (from instanceof ExecutionException) {
   1788         return new TestException(from.getCause());
   1789       } else {
   1790         assertTrue("got " + from.getClass(),
   1791             from instanceof InterruptedException
   1792                 || from instanceof CancellationException);
   1793         return new TestException(from);
   1794       }
   1795     }
   1796   };
   1797 
   1798   public void testMakeChecked_mapsExecutionExceptions() throws Exception {
   1799     SettableFuture<String> future = SettableFuture.create();
   1800 
   1801     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1802         future, mapper);
   1803 
   1804     future.setException(new IOException("checked"));
   1805 
   1806     assertTrue(checked.isDone());
   1807     assertFalse(checked.isCancelled());
   1808 
   1809     try {
   1810       checked.get();
   1811       fail();
   1812     } catch (ExecutionException e) {
   1813       assertTrue(e.getCause() instanceof IOException);
   1814     }
   1815 
   1816     try {
   1817       checked.get(5, TimeUnit.SECONDS);
   1818       fail();
   1819     } catch (ExecutionException e) {
   1820       assertTrue(e.getCause() instanceof IOException);
   1821     }
   1822 
   1823     try {
   1824       checked.checkedGet();
   1825       fail();
   1826     } catch (TestException e) {
   1827       assertTrue(e.getCause() instanceof IOException);
   1828     }
   1829 
   1830     try {
   1831       checked.checkedGet(5, TimeUnit.SECONDS);
   1832       fail();
   1833     } catch (TestException e) {
   1834       assertTrue(e.getCause() instanceof IOException);
   1835     }
   1836   }
   1837 
   1838   public void testMakeChecked_mapsInterruption() throws Exception {
   1839     SettableFuture<String> future = SettableFuture.create();
   1840 
   1841     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1842         future, mapper);
   1843 
   1844     Thread.currentThread().interrupt();
   1845 
   1846     try {
   1847       checked.get();
   1848       fail();
   1849     } catch (InterruptedException e) {
   1850       // Expected.
   1851     }
   1852 
   1853     Thread.currentThread().interrupt();
   1854 
   1855     try {
   1856       checked.get(5, TimeUnit.SECONDS);
   1857       fail();
   1858     } catch (InterruptedException e) {
   1859       // Expected.
   1860     }
   1861 
   1862     Thread.currentThread().interrupt();
   1863 
   1864     try {
   1865       checked.checkedGet();
   1866       fail();
   1867     } catch (TestException e) {
   1868       assertTrue(e.getCause() instanceof InterruptedException);
   1869     }
   1870 
   1871     Thread.currentThread().interrupt();
   1872 
   1873     try {
   1874       checked.checkedGet(5, TimeUnit.SECONDS);
   1875       fail();
   1876     } catch (TestException e) {
   1877       assertTrue(e.getCause() instanceof InterruptedException);
   1878     }
   1879   }
   1880 
   1881   public void testMakeChecked_mapsCancellation() throws Exception {
   1882     SettableFuture<String> future = SettableFuture.create();
   1883 
   1884     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1885         future, mapper);
   1886 
   1887     assertTrue(future.cancel(true)); // argument is ignored
   1888 
   1889     try {
   1890       checked.get();
   1891       fail();
   1892     } catch (CancellationException expected) {}
   1893 
   1894     try {
   1895       checked.get(5, TimeUnit.SECONDS);
   1896       fail();
   1897     } catch (CancellationException expected) {}
   1898 
   1899     try {
   1900       checked.checkedGet();
   1901       fail();
   1902     } catch (TestException expected) {
   1903       assertTrue(expected.getCause() instanceof CancellationException);
   1904     }
   1905 
   1906     try {
   1907       checked.checkedGet(5, TimeUnit.SECONDS);
   1908       fail();
   1909     } catch (TestException expected) {
   1910       assertTrue(expected.getCause() instanceof CancellationException);
   1911     }
   1912   }
   1913 
   1914   public void testMakeChecked_propagatesFailedMappers() throws Exception {
   1915     SettableFuture<String> future = SettableFuture.create();
   1916 
   1917     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1918         future, new Function<Exception, TestException>() {
   1919           @Override public TestException apply(Exception from) {
   1920             throw new NullPointerException();
   1921           }
   1922     });
   1923 
   1924     future.setException(new Exception("failed"));
   1925 
   1926     try {
   1927       checked.checkedGet();
   1928       fail();
   1929     } catch (NullPointerException expected) {}
   1930 
   1931     try {
   1932       checked.checkedGet(5, TimeUnit.SECONDS);
   1933       fail();
   1934     } catch (NullPointerException expected) {}
   1935   }
   1936 
   1937   public void testMakeChecked_listenersRunOnceCompleted() throws Exception {
   1938     SettableFuture<String> future = SettableFuture.create();
   1939 
   1940     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1941         future, new Function<Exception, TestException>() {
   1942           @Override public TestException apply(Exception from) {
   1943             throw new NullPointerException();
   1944           }
   1945     });
   1946 
   1947     ListenableFutureTester tester = new ListenableFutureTester(checked);
   1948     tester.setUp();
   1949     future.set(DATA1);
   1950     tester.testCompletedFuture(DATA1);
   1951     tester.tearDown();
   1952   }
   1953 
   1954   public void testMakeChecked_listenersRunOnCancel() throws Exception {
   1955     SettableFuture<String> future = SettableFuture.create();
   1956 
   1957     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1958         future, new Function<Exception, TestException>() {
   1959           @Override public TestException apply(Exception from) {
   1960             throw new NullPointerException();
   1961           }
   1962     });
   1963 
   1964     ListenableFutureTester tester = new ListenableFutureTester(checked);
   1965     tester.setUp();
   1966     future.cancel(true); // argument is ignored
   1967     tester.testCancelledFuture();
   1968     tester.tearDown();
   1969   }
   1970 
   1971   public void testMakeChecked_listenersRunOnFailure() throws Exception {
   1972     SettableFuture<String> future = SettableFuture.create();
   1973 
   1974     CheckedFuture<String, TestException> checked = Futures.makeChecked(
   1975         future, new Function<Exception, TestException>() {
   1976           @Override public TestException apply(Exception from) {
   1977             throw new NullPointerException();
   1978           }
   1979     });
   1980 
   1981     ListenableFutureTester tester = new ListenableFutureTester(checked);
   1982     tester.setUp();
   1983     future.setException(new Exception("failed"));
   1984     tester.testFailedFuture("failed");
   1985     tester.tearDown();
   1986   }
   1987 
   1988   private interface MapperFunction extends Function<Throwable, Exception> {}
   1989 
   1990   private static final class OtherThrowable extends Throwable {}
   1991 
   1992   private static final Exception CHECKED_EXCEPTION = new Exception("mymessage");
   1993   private static final Future<String> FAILED_FUTURE_CHECKED_EXCEPTION =
   1994       immediateFailedFuture(CHECKED_EXCEPTION);
   1995   private static final RuntimeException UNCHECKED_EXCEPTION =
   1996       new RuntimeException("mymessage");
   1997   private static final Future<String> FAILED_FUTURE_UNCHECKED_EXCEPTION =
   1998       immediateFailedFuture(UNCHECKED_EXCEPTION);
   1999   private static final RuntimeException RUNTIME_EXCEPTION =
   2000       new RuntimeException();
   2001   private static final OtherThrowable OTHER_THROWABLE = new OtherThrowable();
   2002   private static final Future<String> FAILED_FUTURE_OTHER_THROWABLE =
   2003       immediateFailedFuture(OTHER_THROWABLE);
   2004   private static final Error ERROR = new Error("mymessage");
   2005   private static final Future<String> FAILED_FUTURE_ERROR =
   2006       immediateFailedFuture(ERROR);
   2007   private static final Future<String> RUNTIME_EXCEPTION_FUTURE =
   2008       new SimpleForwardingFuture<String>(FAILED_FUTURE_CHECKED_EXCEPTION) {
   2009         @Override public String get() {
   2010           throw RUNTIME_EXCEPTION;
   2011         }
   2012 
   2013         @Override public String get(long timeout, TimeUnit unit) {
   2014           throw RUNTIME_EXCEPTION;
   2015         }
   2016       };
   2017 
   2018   // Boring untimed-get tests:
   2019 
   2020   public void testGetUntimed_success()
   2021       throws TwoArgConstructorException {
   2022     assertEquals("foo",
   2023         get(immediateFuture("foo"), TwoArgConstructorException.class));
   2024   }
   2025 
   2026   public void testGetUntimed_interrupted() {
   2027     SettableFuture<String> future = SettableFuture.create();
   2028     Thread.currentThread().interrupt();
   2029     try {
   2030       get(future, TwoArgConstructorException.class);
   2031       fail();
   2032     } catch (TwoArgConstructorException expected) {
   2033       assertTrue(expected.getCause() instanceof InterruptedException);
   2034       assertTrue(Thread.currentThread().isInterrupted());
   2035     } finally {
   2036       Thread.interrupted();
   2037     }
   2038   }
   2039 
   2040   public void testGetUntimed_cancelled()
   2041       throws TwoArgConstructorException {
   2042     SettableFuture<String> future = SettableFuture.create();
   2043     future.cancel(true);
   2044     try {
   2045       get(future, TwoArgConstructorException.class);
   2046       fail();
   2047     } catch (CancellationException expected) {
   2048     }
   2049   }
   2050 
   2051   public void testGetUntimed_ExecutionExceptionChecked() {
   2052     try {
   2053       get(FAILED_FUTURE_CHECKED_EXCEPTION, TwoArgConstructorException.class);
   2054       fail();
   2055     } catch (TwoArgConstructorException expected) {
   2056       assertEquals(CHECKED_EXCEPTION, expected.getCause());
   2057     }
   2058   }
   2059 
   2060   public void testGetUntimed_ExecutionExceptionUnchecked()
   2061       throws TwoArgConstructorException {
   2062     try {
   2063       get(FAILED_FUTURE_UNCHECKED_EXCEPTION, TwoArgConstructorException.class);
   2064       fail();
   2065     } catch (UncheckedExecutionException expected) {
   2066       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
   2067     }
   2068   }
   2069 
   2070   public void testGetUntimed_ExecutionExceptionError()
   2071       throws TwoArgConstructorException {
   2072     try {
   2073       get(FAILED_FUTURE_ERROR, TwoArgConstructorException.class);
   2074       fail();
   2075     } catch (ExecutionError expected) {
   2076       assertEquals(ERROR, expected.getCause());
   2077     }
   2078   }
   2079 
   2080   public void testGetUntimed_ExecutionExceptionOtherThrowable() {
   2081     try {
   2082       get(FAILED_FUTURE_OTHER_THROWABLE, TwoArgConstructorException.class);
   2083       fail();
   2084     } catch (TwoArgConstructorException expected) {
   2085       assertEquals(OTHER_THROWABLE, expected.getCause());
   2086     }
   2087   }
   2088 
   2089   public void testGetUntimed_RuntimeException()
   2090       throws TwoArgConstructorException {
   2091     try {
   2092       get(RUNTIME_EXCEPTION_FUTURE, TwoArgConstructorException.class);
   2093       fail();
   2094     } catch (RuntimeException expected) {
   2095       assertEquals(RUNTIME_EXCEPTION, expected);
   2096     }
   2097   }
   2098 
   2099   public void testGetUntimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
   2100     try {
   2101       get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithBadConstructor.class);
   2102       fail();
   2103     } catch (IllegalArgumentException expected) {
   2104       assertSame(CHECKED_EXCEPTION, expected.getCause());
   2105     }
   2106   }
   2107 
   2108   public void testGetUntimed_withGoodAndBadExceptionConstructor() throws Exception {
   2109     try {
   2110       get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithGoodAndBadConstructor.class);
   2111       fail();
   2112     } catch (ExceptionWithGoodAndBadConstructor expected) {
   2113       assertSame(CHECKED_EXCEPTION, expected.getCause());
   2114     }
   2115   }
   2116 
   2117   // Boring timed-get tests:
   2118 
   2119   public void testGetTimed_success()
   2120       throws TwoArgConstructorException {
   2121     assertEquals("foo", get(
   2122         immediateFuture("foo"), 0, SECONDS, TwoArgConstructorException.class));
   2123   }
   2124 
   2125   public void testGetTimed_interrupted() {
   2126     SettableFuture<String> future = SettableFuture.create();
   2127     Thread.currentThread().interrupt();
   2128     try {
   2129       get(future, 0, SECONDS, TwoArgConstructorException.class);
   2130       fail();
   2131     } catch (TwoArgConstructorException expected) {
   2132       assertTrue(expected.getCause() instanceof InterruptedException);
   2133       assertTrue(Thread.currentThread().isInterrupted());
   2134     } finally {
   2135       Thread.interrupted();
   2136     }
   2137   }
   2138 
   2139   public void testGetTimed_cancelled()
   2140       throws TwoArgConstructorException {
   2141     SettableFuture<String> future = SettableFuture.create();
   2142     future.cancel(true);
   2143     try {
   2144       get(future, 0, SECONDS, TwoArgConstructorException.class);
   2145       fail();
   2146     } catch (CancellationException expected) {
   2147     }
   2148   }
   2149 
   2150   public void testGetTimed_ExecutionExceptionChecked() {
   2151     try {
   2152       get(FAILED_FUTURE_CHECKED_EXCEPTION, 0, SECONDS,
   2153           TwoArgConstructorException.class);
   2154       fail();
   2155     } catch (TwoArgConstructorException expected) {
   2156       assertEquals(CHECKED_EXCEPTION, expected.getCause());
   2157     }
   2158   }
   2159 
   2160   public void testGetTimed_ExecutionExceptionUnchecked()
   2161       throws TwoArgConstructorException {
   2162     try {
   2163       get(FAILED_FUTURE_UNCHECKED_EXCEPTION, 0, SECONDS,
   2164           TwoArgConstructorException.class);
   2165       fail();
   2166     } catch (UncheckedExecutionException expected) {
   2167       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
   2168     }
   2169   }
   2170 
   2171   public void testGetTimed_ExecutionExceptionError()
   2172       throws TwoArgConstructorException {
   2173     try {
   2174       get(FAILED_FUTURE_ERROR, 0, SECONDS, TwoArgConstructorException.class);
   2175       fail();
   2176     } catch (ExecutionError expected) {
   2177       assertEquals(ERROR, expected.getCause());
   2178     }
   2179   }
   2180 
   2181   public void testGetTimed_ExecutionExceptionOtherThrowable() {
   2182     try {
   2183       get(FAILED_FUTURE_OTHER_THROWABLE, 0, SECONDS,
   2184           TwoArgConstructorException.class);
   2185       fail();
   2186     } catch (TwoArgConstructorException expected) {
   2187       assertEquals(OTHER_THROWABLE, expected.getCause());
   2188     }
   2189   }
   2190 
   2191   public void testGetTimed_RuntimeException()
   2192       throws TwoArgConstructorException {
   2193     try {
   2194       get(RUNTIME_EXCEPTION_FUTURE, 0, SECONDS,
   2195           TwoArgConstructorException.class);
   2196       fail();
   2197     } catch (RuntimeException expected) {
   2198       assertEquals(RUNTIME_EXCEPTION, expected);
   2199     }
   2200   }
   2201 
   2202   public void testGetTimed_TimeoutException() {
   2203     SettableFuture<String> future = SettableFuture.create();
   2204     try {
   2205       get(future, 0, SECONDS, TwoArgConstructorException.class);
   2206       fail();
   2207     } catch (TwoArgConstructorException expected) {
   2208       assertTrue(expected.getCause() instanceof TimeoutException);
   2209     }
   2210   }
   2211 
   2212   public void testGetTimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
   2213     try {
   2214       get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS, ExceptionWithBadConstructor.class);
   2215       fail();
   2216     } catch (IllegalArgumentException expected) {
   2217       assertSame(CHECKED_EXCEPTION, expected.getCause());
   2218     }
   2219   }
   2220 
   2221   public void testGetTimed_withGoodAndBadExceptionConstructor() throws Exception {
   2222     try {
   2223       get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS,
   2224           ExceptionWithGoodAndBadConstructor.class);
   2225       fail();
   2226     } catch (ExceptionWithGoodAndBadConstructor expected) {
   2227       assertSame(CHECKED_EXCEPTION, expected.getCause());
   2228     }
   2229   }
   2230 
   2231   // Boring getUnchecked tests:
   2232 
   2233   public void testGetUnchecked_success() {
   2234     assertEquals("foo", getUnchecked(immediateFuture("foo")));
   2235   }
   2236 
   2237   public void testGetUnchecked_interrupted() {
   2238     Thread.currentThread().interrupt();
   2239     try {
   2240       assertEquals("foo", getUnchecked(immediateFuture("foo")));
   2241       assertTrue(Thread.currentThread().isInterrupted());
   2242     } finally {
   2243       Thread.interrupted();
   2244     }
   2245   }
   2246 
   2247   public void testGetUnchecked_cancelled() {
   2248     SettableFuture<String> future = SettableFuture.create();
   2249     future.cancel(true);
   2250     try {
   2251       getUnchecked(future);
   2252       fail();
   2253     } catch (CancellationException expected) {
   2254     }
   2255   }
   2256 
   2257   public void testGetUnchecked_ExecutionExceptionChecked() {
   2258     try {
   2259       getUnchecked(FAILED_FUTURE_CHECKED_EXCEPTION);
   2260       fail();
   2261     } catch (UncheckedExecutionException expected) {
   2262       assertEquals(CHECKED_EXCEPTION, expected.getCause());
   2263     }
   2264   }
   2265 
   2266   public void testGetUnchecked_ExecutionExceptionUnchecked() {
   2267     try {
   2268       getUnchecked(FAILED_FUTURE_UNCHECKED_EXCEPTION);
   2269       fail();
   2270     } catch (UncheckedExecutionException expected) {
   2271       assertEquals(UNCHECKED_EXCEPTION, expected.getCause());
   2272     }
   2273   }
   2274 
   2275   public void testGetUnchecked_ExecutionExceptionError() {
   2276     try {
   2277       getUnchecked(FAILED_FUTURE_ERROR);
   2278       fail();
   2279     } catch (ExecutionError expected) {
   2280       assertEquals(ERROR, expected.getCause());
   2281     }
   2282   }
   2283 
   2284   public void testGetUnchecked_ExecutionExceptionOtherThrowable() {
   2285     try {
   2286       getUnchecked(FAILED_FUTURE_OTHER_THROWABLE);
   2287       fail();
   2288     } catch (UncheckedExecutionException expected) {
   2289       assertEquals(OTHER_THROWABLE, expected.getCause());
   2290     }
   2291   }
   2292 
   2293   public void testGetUnchecked_RuntimeException() {
   2294     try {
   2295       getUnchecked(RUNTIME_EXCEPTION_FUTURE);
   2296       fail();
   2297     } catch (RuntimeException expected) {
   2298       assertEquals(RUNTIME_EXCEPTION, expected);
   2299     }
   2300   }
   2301 
   2302   // Edge case tests of the exception-construction code through untimed get():
   2303 
   2304   public void testGetUntimed_exceptionClassIsRuntimeException() {
   2305     try {
   2306       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2307           TwoArgConstructorRuntimeException.class);
   2308       fail();
   2309     } catch (IllegalArgumentException expected) {
   2310     }
   2311   }
   2312 
   2313   public void testGetUntimed_exceptionClassSomePublicConstructors() {
   2314     try {
   2315       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2316           ExceptionWithSomePrivateConstructors.class);
   2317       fail();
   2318     } catch (ExceptionWithSomePrivateConstructors expected) {
   2319     }
   2320   }
   2321 
   2322   public void testGetUntimed_exceptionClassNoPublicConstructor()
   2323       throws ExceptionWithPrivateConstructor {
   2324     try {
   2325       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2326           ExceptionWithPrivateConstructor.class);
   2327       fail();
   2328     } catch (IllegalArgumentException expected) {
   2329     }
   2330   }
   2331 
   2332   public void testGetUntimed_exceptionClassPublicConstructorWrongType()
   2333       throws ExceptionWithWrongTypesConstructor {
   2334     try {
   2335       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2336           ExceptionWithWrongTypesConstructor.class);
   2337       fail();
   2338     } catch (IllegalArgumentException expected) {
   2339     }
   2340   }
   2341 
   2342   public void testGetUntimed_exceptionClassPrefersStringConstructor() {
   2343     try {
   2344       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2345           ExceptionWithManyConstructors.class);
   2346       fail();
   2347     } catch (ExceptionWithManyConstructors expected) {
   2348       assertTrue(expected.usedExpectedConstructor);
   2349     }
   2350   }
   2351 
   2352   public void testGetUntimed_exceptionClassUsedInitCause() {
   2353     try {
   2354       get(FAILED_FUTURE_CHECKED_EXCEPTION,
   2355           ExceptionWithoutThrowableConstructor.class);
   2356       fail();
   2357     } catch (ExceptionWithoutThrowableConstructor expected) {
   2358       assertThat(expected.getMessage()).contains("mymessage");
   2359       assertEquals(CHECKED_EXCEPTION, expected.getCause());
   2360     }
   2361   }
   2362 
   2363   public void testCompletionOrder() throws Exception {
   2364     SettableFuture<Long> future1 = SettableFuture.create();
   2365     SettableFuture<Long> future2 = SettableFuture.create();
   2366     SettableFuture<Long> future3 = SettableFuture.create();
   2367     SettableFuture<Long> future4 = SettableFuture.create();
   2368     SettableFuture<Long> future5 = SettableFuture.create();
   2369 
   2370     ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder(
   2371         ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5));
   2372     future2.set(1L);
   2373     future5.set(2L);
   2374     future1.set(3L);
   2375     future3.set(4L);
   2376     future4.set(5L);
   2377 
   2378     long expected = 1L;
   2379     for (ListenableFuture<Long> future : futures) {
   2380       assertEquals((Long) expected, future.get());
   2381       expected++;
   2382     }
   2383   }
   2384 
   2385   public void testCompletionOrderExceptionThrown() throws Exception {
   2386     SettableFuture<Long> future1 = SettableFuture.create();
   2387     SettableFuture<Long> future2 = SettableFuture.create();
   2388     SettableFuture<Long> future3 = SettableFuture.create();
   2389     SettableFuture<Long> future4 = SettableFuture.create();
   2390     SettableFuture<Long> future5 = SettableFuture.create();
   2391 
   2392     ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder(
   2393         ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5));
   2394     future2.set(1L);
   2395     future5.setException(new IllegalStateException("2L"));
   2396     future1.set(3L);
   2397     future3.set(4L);
   2398     future4.set(5L);
   2399 
   2400     long expected = 1L;
   2401     for (ListenableFuture<Long> future : futures) {
   2402       if (expected != 2) {
   2403         assertEquals((Long) expected, future.get());
   2404       } else {
   2405         try {
   2406           future.get();
   2407           fail();
   2408         } catch (ExecutionException e) {
   2409           // Expected
   2410           assertEquals("2L", e.getCause().getMessage());
   2411         }
   2412       }
   2413       expected++;
   2414     }
   2415   }
   2416 
   2417   public void testCompletionOrderFutureCancelled() throws Exception {
   2418     SettableFuture<Long> future1 = SettableFuture.create();
   2419     SettableFuture<Long> future2 = SettableFuture.create();
   2420     SettableFuture<Long> future3 = SettableFuture.create();
   2421     SettableFuture<Long> future4 = SettableFuture.create();
   2422     SettableFuture<Long> future5 = SettableFuture.create();
   2423 
   2424     ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder(
   2425         ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5));
   2426     future2.set(1L);
   2427     future5.set(2L);
   2428     future1.set(3L);
   2429     future3.cancel(true);
   2430     future4.set(5L);
   2431 
   2432     long expected = 1L;
   2433     for (ListenableFuture<Long> future : futures) {
   2434       if (expected != 4) {
   2435         assertEquals((Long) expected, future.get());
   2436       } else {
   2437         try {
   2438           future.get();
   2439           fail();
   2440         } catch (CancellationException e) {
   2441           // Expected
   2442         }
   2443       }
   2444       expected++;
   2445     }
   2446   }
   2447 
   2448   public void testCancellingADelegateDoesNotPropagate() throws Exception {
   2449     SettableFuture<Long> future1 = SettableFuture.create();
   2450     SettableFuture<Long> future2 = SettableFuture.create();
   2451 
   2452     ImmutableList<ListenableFuture<Long>> delegates = Futures.inCompletionOrder(
   2453         ImmutableList.<ListenableFuture<Long>>of(future1, future2));
   2454 
   2455     future1.set(1L);
   2456     // Cannot cancel a complete delegate
   2457     assertFalse(delegates.get(0).cancel(true));
   2458     // Cancel the delegate before the input future is done
   2459     assertTrue(delegates.get(1).cancel(true));
   2460     // Setting the future still works since cancellation didn't propagate
   2461     assertTrue(future2.set(2L));
   2462     // Second check to ensure the input future was not cancelled
   2463     assertEquals((Long) 2L, future2.get());
   2464   }
   2465 
   2466   // Mostly an example of how it would look like to use a list of mixed types
   2467   public void testCompletionOrderMixedBagOTypes() throws Exception {
   2468     SettableFuture<Long> future1 = SettableFuture.create();
   2469     SettableFuture<String> future2 = SettableFuture.create();
   2470     SettableFuture<Integer> future3 = SettableFuture.create();
   2471 
   2472     ImmutableList<? extends ListenableFuture<?>> inputs =
   2473         ImmutableList.<ListenableFuture<?>>of(future1, future2, future3);
   2474     ImmutableList<ListenableFuture<Object>> futures = Futures.inCompletionOrder(inputs);
   2475     future2.set("1L");
   2476     future1.set(2L);
   2477     future3.set(3);
   2478 
   2479     ImmutableList<?> expected = ImmutableList.of("1L", 2L, 3);
   2480     for (int i = 0; i < expected.size(); i++) {
   2481       assertEquals(expected.get(i), futures.get(i).get());
   2482     }
   2483   }
   2484 
   2485   public static final class TwoArgConstructorException extends Exception {
   2486     public TwoArgConstructorException(String message, Throwable cause) {
   2487       super(message, cause);
   2488     }
   2489   }
   2490 
   2491   public static final class TwoArgConstructorRuntimeException
   2492       extends RuntimeException {
   2493     public TwoArgConstructorRuntimeException(String message, Throwable cause) {
   2494       super(message, cause);
   2495     }
   2496   }
   2497 
   2498   public static final class ExceptionWithPrivateConstructor extends Exception {
   2499     private ExceptionWithPrivateConstructor(String message, Throwable cause) {
   2500       super(message, cause);
   2501     }
   2502   }
   2503 
   2504   @SuppressWarnings("unused") // we're testing that they're not used
   2505   public static final class ExceptionWithSomePrivateConstructors
   2506       extends Exception {
   2507     private ExceptionWithSomePrivateConstructors(String a) {
   2508     }
   2509 
   2510     private ExceptionWithSomePrivateConstructors(String a, String b) {
   2511     }
   2512 
   2513     public ExceptionWithSomePrivateConstructors(
   2514         String a, String b, String c) {
   2515     }
   2516 
   2517     private ExceptionWithSomePrivateConstructors(
   2518         String a, String b, String c, String d) {
   2519     }
   2520 
   2521     private ExceptionWithSomePrivateConstructors(
   2522         String a, String b, String c, String d, String e) {
   2523     }
   2524   }
   2525 
   2526   public static final class ExceptionWithManyConstructors extends Exception {
   2527     boolean usedExpectedConstructor;
   2528 
   2529     public ExceptionWithManyConstructors() {
   2530     }
   2531 
   2532     public ExceptionWithManyConstructors(Integer i) {
   2533     }
   2534 
   2535     public ExceptionWithManyConstructors(Throwable a) {
   2536     }
   2537 
   2538     public ExceptionWithManyConstructors(Throwable a, Throwable b) {
   2539     }
   2540 
   2541     public ExceptionWithManyConstructors(String s, Throwable b) {
   2542       usedExpectedConstructor = true;
   2543     }
   2544 
   2545     public ExceptionWithManyConstructors(
   2546         Throwable a, Throwable b, Throwable c) {
   2547     }
   2548 
   2549     public ExceptionWithManyConstructors(
   2550         Throwable a, Throwable b, Throwable c, Throwable d) {
   2551     }
   2552 
   2553     public ExceptionWithManyConstructors(
   2554         Throwable a, Throwable b, Throwable c, Throwable d, Throwable e) {
   2555     }
   2556 
   2557     public ExceptionWithManyConstructors(Throwable a, Throwable b, Throwable c,
   2558         Throwable d, Throwable e, String s, Integer i) {
   2559     }
   2560   }
   2561 
   2562   public static final class ExceptionWithoutThrowableConstructor
   2563       extends Exception {
   2564     public ExceptionWithoutThrowableConstructor(String s) {
   2565       super(s);
   2566     }
   2567   }
   2568 
   2569   public static final class ExceptionWithWrongTypesConstructor
   2570       extends Exception {
   2571     public ExceptionWithWrongTypesConstructor(Integer i, String s) {
   2572       super(s);
   2573     }
   2574   }
   2575 
   2576   private static final class ExceptionWithGoodAndBadConstructor extends Exception {
   2577     public ExceptionWithGoodAndBadConstructor(String message, Throwable cause) {
   2578       throw new RuntimeException("bad constructor");
   2579     }
   2580     public ExceptionWithGoodAndBadConstructor(Throwable cause) {
   2581       super(cause);
   2582     }
   2583   }
   2584 
   2585   private static final class ExceptionWithBadConstructor extends Exception {
   2586     public ExceptionWithBadConstructor(String message, Throwable cause) {
   2587       throw new RuntimeException("bad constructor");
   2588     }
   2589   }
   2590 
   2591   public void testFutures_nullChecks() throws Exception {
   2592     new ClassSanityTester()
   2593         .forAllPublicStaticMethods(Futures.class)
   2594         .thatReturn(Future.class)
   2595         .testNulls();
   2596   }
   2597 
   2598   private static void failWithCause(Throwable cause, String message) {
   2599     AssertionFailedError failure = new AssertionFailedError(message);
   2600     failure.initCause(cause);
   2601     throw failure;
   2602   }
   2603 }
   2604