1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.util.concurrent;
18
19 import static com.google.common.base.Throwables.propagateIfInstanceOf;
20 import static com.google.common.truth.Truth.assertThat;
21 import static com.google.common.util.concurrent.Futures.allAsList;
22 import static com.google.common.util.concurrent.Futures.get;
23 import static com.google.common.util.concurrent.Futures.getUnchecked;
24 import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
25 import static com.google.common.util.concurrent.Futures.immediateFuture;
26 import static com.google.common.util.concurrent.Futures.successfulAsList;
27 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
28 import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
29 import static java.util.concurrent.Executors.newSingleThreadExecutor;
30 import static java.util.concurrent.TimeUnit.MILLISECONDS;
31 import static java.util.concurrent.TimeUnit.SECONDS;
32 import static org.easymock.EasyMock.expect;
33
34 import com.google.common.base.Function;
35 import com.google.common.base.Functions;
36 import com.google.common.base.Joiner;
37 import com.google.common.collect.ImmutableList;
38 import com.google.common.collect.ImmutableSet;
39 import com.google.common.collect.Iterables;
40 import com.google.common.collect.Lists;
41 import com.google.common.collect.Sets;
42 import com.google.common.testing.ClassSanityTester;
43 import com.google.common.testing.TestLogHandler;
44 import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
45
46 import junit.framework.AssertionFailedError;
47 import junit.framework.TestCase;
48
49 import org.easymock.EasyMock;
50 import org.easymock.IMocksControl;
51
52 import java.io.IOException;
53 import java.util.Arrays;
54 import java.util.List;
55 import java.util.Set;
56 import java.util.concurrent.Callable;
57 import java.util.concurrent.CancellationException;
58 import java.util.concurrent.CountDownLatch;
59 import java.util.concurrent.ExecutionException;
60 import java.util.concurrent.Executor;
61 import java.util.concurrent.ExecutorService;
62 import java.util.concurrent.Executors;
63 import java.util.concurrent.Future;
64 import java.util.concurrent.RejectedExecutionException;
65 import java.util.concurrent.TimeUnit;
66 import java.util.concurrent.TimeoutException;
67 import java.util.logging.Handler;
68 import java.util.logging.LogRecord;
69 import java.util.logging.Logger;
70
71 import javax.annotation.Nullable;
72
73
74
75
76
77
78
79
80 public class FuturesTest extends TestCase {
81 private static final Logger combinedFutureLogger = Logger.getLogger(
82 "com.google.common.util.concurrent.Futures$CombinedFuture");
83 private final TestLogHandler combinedFutureLogHandler = new TestLogHandler();
84
85 private static final String DATA1 = "data";
86 private static final String DATA2 = "more data";
87 private static final String DATA3 = "most data";
88
89 private IMocksControl mocksControl;
90
91 @Override protected void setUp() throws Exception {
92 super.setUp();
93 combinedFutureLogger.addHandler(combinedFutureLogHandler);
94 mocksControl = EasyMock.createControl();
95 }
96
97 @Override protected void tearDown() throws Exception {
98
99
100
101
102
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
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
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
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
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
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
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
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
202 assertSame(exception, expected);
203 }
204 }
205
206
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
300
301
302 public void testTransformValueRemainsMemoized() throws Exception {
303 class Holder {
304 int value = 2;
305 }
306 final Holder holder = new Holder();
307
308
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
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
322 assertEquals(6, transformedFuture.get().intValue());
323
324
325
326 holder.value = 3;
327 assertEquals(6, transformedFuture.get().intValue());
328 assertEquals(7, adder.apply(4).intValue());
329
330
331 holder.value = 4;
332 assertEquals(6, transformedFuture.get().intValue());
333 assertEquals(8, adder.apply(4).intValue());
334
335
336 assertEquals(6, transformedFuture.get(1000, TimeUnit.SECONDS).intValue());
337
338
339 assertEquals(8, Futures.transform(immediateFuture, adder).get().intValue());
340
341
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
351
352
353
354 public void testTransformExceptionRemainsMemoized() throws Throwable {
355
356
357
358
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
374
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
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
574 expect(fallback.create(raisedException)).andThrow(expectedException);
575 } else {
576
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
788
789
790
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
819 SettableFuture<String> future1 = SettableFuture.create();
820 SettableFuture<String> future2 = SettableFuture.create();
821 SettableFuture<String> future3 = SettableFuture.create();
822 @SuppressWarnings("unchecked")
823 ListenableFuture<List<String>> compound =
824 Futures.allAsList(future1, future2, future3);
825
826
827 SingleCallListener listener = new SingleCallListener();
828 compound.addListener(listener, directExecutor());
829
830
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")
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")
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")
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
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")
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")
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
988
989
990
991
992
993 public void testAllAsList_doneFutures() throws Exception {
994
995 SettableFuture<String> future1 = SettableFuture.create();
996 SettableFuture<String> future2 = SettableFuture.create();
997 SettableFuture<String> future3 = SettableFuture.create();
998
999
1000 future1.set(DATA1);
1001 future2.set(DATA2);
1002 future3.set(DATA3);
1003
1004 @SuppressWarnings("unchecked")
1005 ListenableFuture<List<String>> compound =
1006 Futures.allAsList(future1, future2, future3);
1007
1008
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
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
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());
1047 assertTrue(logged.get(0).getThrown() instanceof MyError);
1048 }
1049 }
1050
1051
1052
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());
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
1074
1075
1076
1077
1078
1079
1080
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
1097
1098
1099
1100
1101
1102
1103
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
1194
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
1228
1229
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
1287
1288
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
1312
1313
1314
1315
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
1345
1346
1347
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
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
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
1394 inputs.allFutures.get(iBeforeJ ? i : j).finisher.run();
1395 inputs.allFutures.get(iBeforeJ ? j : i).finisher.run();
1396
1397
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
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
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
1444
1445
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
1462 SettableFuture<String> future1 = SettableFuture.create();
1463 SettableFuture<String> future2 = SettableFuture.create();
1464 SettableFuture<String> future3 = SettableFuture.create();
1465 @SuppressWarnings("unchecked")
1466 ListenableFuture<List<String>> compound =
1467 Futures.successfulAsList(future1, future2, future3);
1468
1469
1470 SingleCallListener listener = new SingleCallListener();
1471 compound.addListener(listener, directExecutor());
1472
1473
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")
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")
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")
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")
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")
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
1592
1593
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
1618 Futures.successfulAsList(ImmutableList.of(SettableFuture.create()))
1619 .cancel(true);
1620
1621
1622
1623
1624
1625
1626 final SettableFuture<String> future1 = SettableFuture.create();
1627 final SettableFuture<String> future2 = SettableFuture.create();
1628 @SuppressWarnings("unchecked")
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
1637
1638
1639
1640
1641 assertFalse(future2.isCancelled());
1642
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
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")
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")
1680 ListenableFuture<List<String>> compound =
1681 Futures.successfulAsList(future1, future2, future3);
1682 compound.addListener(listener, directExecutor());
1683
1684
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
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
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
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());
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
1851 }
1852
1853 Thread.currentThread().interrupt();
1854
1855 try {
1856 checked.get(5, TimeUnit.SECONDS);
1857 fail();
1858 } catch (InterruptedException e) {
1859
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));
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);
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
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
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
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
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
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
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
2457 assertFalse(delegates.get(0).cancel(true));
2458
2459 assertTrue(delegates.get(1).cancel(true));
2460
2461 assertTrue(future2.set(2L));
2462
2463 assertEquals((Long) 2L, future2.get());
2464 }
2465
2466
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")
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 }