public void testCompletionOrderMixedBagOTypes() throws Exception { SettableFuture<Long> future1 = SettableFuture.create(); SettableFuture<String> future2 = SettableFuture.create(); SettableFuture<Integer> future3 = SettableFuture.create(); ImmutableList<? extends ListenableFuture<?>> inputs = ImmutableList.<ListenableFuture<?>>of(future1, future2, future3); ImmutableList<ListenableFuture<Object>> futures = inCompletionOrder(inputs); future2.set("1L"); future1.set(2L); future3.set(3); ImmutableList<?> expected = ImmutableList.of("1L", 2L, 3); for (int i = 0; i < expected.size(); i++) { assertEquals(expected.get(i), getDone(futures.get(i))); } }
public void testCompletionOrder() throws Exception { SettableFuture<Long> future1 = SettableFuture.create(); SettableFuture<Long> future2 = SettableFuture.create(); SettableFuture<Long> future3 = SettableFuture.create(); SettableFuture<Long> future4 = SettableFuture.create(); SettableFuture<Long> future5 = SettableFuture.create(); ImmutableList<ListenableFuture<Long>> futures = inCompletionOrder( ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5)); future2.set(1L); future5.set(2L); future1.set(3L); future3.set(4L); future4.set(5L); long expectedResult = 1L; for (ListenableFuture<Long> future : futures) { assertEquals((Long) expectedResult, getDone(future)); expectedResult++; } }
public void testCatchingAsync_inputDoesNotRaiseException() throws Exception { AsyncFunction<Throwable, Integer> fallback = unexpectedAsyncFunction(); ListenableFuture<Integer> originalFuture = immediateFuture(7); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(7, getDone(faultTolerantFuture).intValue()); }
public void testCatching_inputDoesNotRaiseException() throws Exception { Function<Throwable, Integer> fallback = unexpectedFunction(); ListenableFuture<Integer> originalFuture = immediateFuture(7); ListenableFuture<Integer> faultTolerantFuture = catching(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(7, getDone(faultTolerantFuture).intValue()); }
public void testCatchingAsync_fallbackNotReady() throws Exception { ListenableFuture<Integer> primary = immediateFailedFuture(new Exception()); final SettableFuture<Integer> secondary = SettableFuture.create(); AsyncFunction<Throwable, Integer> fallback = new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) { return secondary; } }; ListenableFuture<Integer> derived = catchingAsync(primary, Throwable.class, fallback, directExecutor()); secondary.set(1); assertEquals(1, (int) getDone(derived)); }
public void testWhenAllComplete_runnableResult() throws Exception { final SettableFuture<Integer> futureInteger = SettableFuture.create(); final SettableFuture<Boolean> futureBoolean = SettableFuture.create(); final String[] result = new String[1]; Runnable combiner = new Runnable() { @Override public void run() { assertTrue(futureInteger.isDone()); assertTrue(futureBoolean.isDone()); result[0] = createCombinedResult( Futures.getUnchecked(futureInteger), Futures.getUnchecked(futureBoolean)); } }; ListenableFuture<?> futureResult = whenAllComplete(futureInteger, futureBoolean).run(combiner, directExecutor()); Integer integerPartial = 1; futureInteger.set(integerPartial); Boolean booleanPartial = true; futureBoolean.set(booleanPartial); futureResult.get(); assertEquals(createCombinedResult(integerPartial, booleanPartial), result[0]); }
public void testCatchingAsync_Throwable() throws Exception { AsyncFunction<Throwable, Integer> fallback = asyncFunctionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new IOException()); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
public void testWhenAllComplete_asyncResult() throws Exception { final SettableFuture<Integer> futureInteger = SettableFuture.create(); final SettableFuture<Boolean> futureBoolean = SettableFuture.create(); AsyncCallable<String> combiner = new AsyncCallable<String>() { @Override public ListenableFuture<String> call() throws Exception { return immediateFuture( createCombinedResult(getDone(futureInteger), getDone(futureBoolean))); } }; ListenableFuture<String> futureResult = whenAllComplete(futureInteger, futureBoolean).callAsync(combiner, directExecutor()); Integer integerPartial = 1; futureInteger.set(integerPartial); Boolean booleanPartial = true; futureBoolean.set(booleanPartial); assertEquals(createCombinedResult(integerPartial, booleanPartial), getDone(futureResult)); }
public void testCatching_Throwable() throws Exception { Function<Throwable, Integer> fallback = functionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new IOException()); ListenableFuture<Integer> faultTolerantFuture = catching(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
/** A single non-error failure is not logged because it is reported via the output future. */ @SuppressWarnings("unchecked") public void testAllAsList_logging_exception() throws Exception { try { getDone(allAsList(immediateFailedFuture(new MyException()))); fail(); } catch (ExecutionException expected) { assertThat(expected.getCause()).isInstanceOf(MyException.class); assertEquals( "Nothing should be logged", 0, aggregateFutureLogHandler.getStoredLogRecords().size()); } }
/** Ensure that errors are always logged. */ @SuppressWarnings("unchecked") public void testSuccessfulAsList_logging_error() throws Exception { assertEquals( newArrayList((Object) null), getDone(successfulAsList(immediateFailedFuture(new MyError())))); List<LogRecord> logged = aggregateFutureLogHandler.getStoredLogRecords(); assertThat(logged).hasSize(1); // errors are always logged assertThat(logged.get(0).getThrown()).isInstanceOf(MyError.class); }
@GwtIncompatible // non-Throwable exceptionType public void testCatching_customTypeMatch() throws Exception { Function<IOException, Integer> fallback = functionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new FileNotFoundException()); ListenableFuture<Integer> faultTolerantFuture = catching(originalFuture, IOException.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
@GwtIncompatible // non-Throwable exceptionType public void testCatchingAsync_customTypeMatch() throws Exception { AsyncFunction<IOException, Integer> fallback = asyncFunctionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new FileNotFoundException()); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, IOException.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
/** The same exception happening on multiple futures should not be logged. */ @SuppressWarnings("unchecked") public void testAllAsList_logging_same_exception() throws Exception { try { MyException sameInstance = new MyException(); getDone(allAsList(immediateFailedFuture(sameInstance), immediateFailedFuture(sameInstance))); fail(); } catch (ExecutionException expected) { assertThat(expected.getCause()).isInstanceOf(MyException.class); assertEquals( "Nothing should be logged", 0, aggregateFutureLogHandler.getStoredLogRecords().size()); } }
public void testCatching_inputRaisesException() throws Exception { final RuntimeException raisedException = new RuntimeException(); FunctionSpy<Throwable, Integer> fallback = spy( new Function<Throwable, Integer>() { @Override public Integer apply(Throwable t) { assertThat(t).isSameAs(raisedException); return 20; } }); ListenableFuture<Integer> failingFuture = immediateFailedFuture(raisedException); ListenableFuture<Integer> faultTolerantFuture = catching(failingFuture, Throwable.class, fallback, directExecutor()); assertEquals(20, getDone(faultTolerantFuture).intValue()); fallback.verifyCallCount(1); }
public void testCatchingAsync_inputRaisesException() throws Exception { final RuntimeException raisedException = new RuntimeException(); AsyncFunctionSpy<Throwable, Integer> fallback = spy( new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) throws Exception { assertThat(t).isSameAs(raisedException); return immediateFuture(20); } }); ListenableFuture<Integer> failingFuture = immediateFailedFuture(raisedException); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(failingFuture, Throwable.class, fallback, directExecutor()); assertEquals(20, getDone(faultTolerantFuture).intValue()); fallback.verifyCallCount(1); }
public void testCancellingADelegatePropagates() throws Exception { SettableFuture<Long> future1 = SettableFuture.create(); SettableFuture<Long> future2 = SettableFuture.create(); SettableFuture<Long> future3 = SettableFuture.create(); ImmutableList<ListenableFuture<Long>> delegates = inCompletionOrder(ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3)); future1.set(1L); // Cannot cancel a complete delegate assertFalse(delegates.get(0).cancel(true)); // Cancel the delegate before the input future is done assertTrue(delegates.get(1).cancel(true)); // Setting the future still works since cancellation didn't propagate assertTrue(future2.set(2L)); // Second check to ensure the input future was not cancelled assertEquals((Long) 2L, getDone(future2)); // All futures are now complete; outstanding inputs are cancelled assertTrue(future3.isCancelled()); assertTrue(future3.wasInterrupted()); }
@GwtIncompatible // lazyTransform public void testLazyTransform() throws Exception { FunctionSpy<Object, String> spy = new FunctionSpy<>(constant("bar")); Future<String> input = immediateFuture("foo"); Future<String> transformed = lazyTransform(input, spy); spy.verifyCallCount(0); assertEquals("bar", getDone(transformed)); spy.verifyCallCount(1); assertEquals("bar", getDone(transformed)); spy.verifyCallCount(2); }
/** * Different exceptions happening on multiple futures with the same cause should not be logged. */ @SuppressWarnings("unchecked") public void testAllAsList_logging_same_cause() throws Exception { try { MyException exception1 = new MyException(); MyException exception2 = new MyException(); MyException exception3 = new MyException(); MyException sameInstance = new MyException(); exception1.initCause(sameInstance); exception2.initCause(sameInstance); exception3.initCause(exception2); getDone(allAsList(immediateFailedFuture(exception1), immediateFailedFuture(exception3))); fail(); } catch (ExecutionException expected) { assertThat(expected.getCause()).isInstanceOf(MyException.class); assertEquals( "Nothing should be logged", 0, aggregateFutureLogHandler.getStoredLogRecords().size()); } }
/** Non-Error exceptions are never logged. */ @SuppressWarnings("unchecked") public void testSuccessfulAsList_logging_exception() throws Exception { assertEquals( newArrayList((Object) null), getDone(successfulAsList(immediateFailedFuture(new MyException())))); assertWithMessage("Nothing should be logged") .that(aggregateFutureLogHandler.getStoredLogRecords()) .isEmpty(); // Not even if there are a bunch of failures. assertEquals( newArrayList(null, null, null), getDone( successfulAsList( immediateFailedFuture(new MyException()), immediateFailedFuture(new MyException()), immediateFailedFuture(new MyException())))); assertWithMessage("Nothing should be logged") .that(aggregateFutureLogHandler.getStoredLogRecords()) .isEmpty(); }