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.truth.Truth.assertThat;
21import static com.google.common.util.concurrent.Futures.allAsList;
22import static com.google.common.util.concurrent.Futures.get;
23import static com.google.common.util.concurrent.Futures.getUnchecked;
24import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
25import static com.google.common.util.concurrent.Futures.immediateFuture;
26import static com.google.common.util.concurrent.Futures.successfulAsList;
27import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
28import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
29import static java.util.concurrent.Executors.newSingleThreadExecutor;
30import static java.util.concurrent.TimeUnit.MILLISECONDS;
31import static java.util.concurrent.TimeUnit.SECONDS;
32import static org.easymock.EasyMock.expect;
33
34import com.google.common.base.Function;
35import com.google.common.base.Functions;
36import com.google.common.base.Joiner;
37import com.google.common.collect.ImmutableList;
38import com.google.common.collect.ImmutableSet;
39import com.google.common.collect.Iterables;
40import com.google.common.collect.Lists;
41import com.google.common.collect.Sets;
42import com.google.common.testing.ClassSanityTester;
43import com.google.common.testing.TestLogHandler;
44import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
45
46import junit.framework.AssertionFailedError;
47import junit.framework.TestCase;
48
49import org.easymock.EasyMock;
50import org.easymock.IMocksControl;
51
52import java.io.IOException;
53import java.util.Arrays;
54import java.util.List;
55import java.util.Set;
56import java.util.concurrent.Callable;
57import java.util.concurrent.CancellationException;
58import java.util.concurrent.CountDownLatch;
59import java.util.concurrent.ExecutionException;
60import java.util.concurrent.Executor;
61import java.util.concurrent.ExecutorService;
62import java.util.concurrent.Executors;
63import java.util.concurrent.Future;
64import java.util.concurrent.RejectedExecutionException;
65import java.util.concurrent.TimeUnit;
66import java.util.concurrent.TimeoutException;
67import java.util.logging.Handler;
68import java.util.logging.LogRecord;
69import java.util.logging.Logger;
70
71import 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 */
80public 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