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