AbstractChainedListenableFutureTest.java revision 1d580d0f6ee4f21eb309ba7b509d2c6d671c4044
1/*
2 * Copyright (C) 2008 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.util.concurrent;
18
19import com.google.common.util.concurrent.testing.MockFutureListener;
20
21import junit.framework.TestCase;
22
23import java.util.concurrent.TimeUnit;
24import java.util.concurrent.TimeoutException;
25
26/**
27 * Unit tests for any listenable future that chains other listenable futures.
28 * Unit tests need only override buildChainingFuture and getSuccessfulResult,
29 * but they can add custom tests as needed.
30 *
31 * @author Nishant Thakkar
32 */
33public abstract class AbstractChainedListenableFutureTest<T> extends TestCase {
34  protected static final int EXCEPTION_DATA = -1;
35  protected static final int VALID_INPUT_DATA = 1;
36  protected static final Exception EXCEPTION = new Exception("Test exception");
37
38  protected SettableFuture<Integer> inputFuture;
39  protected ListenableFuture<T> resultFuture;
40  protected MockFutureListener listener;
41
42  @Override
43  protected void setUp() throws Exception {
44    super.setUp();
45
46    inputFuture = SettableFuture.create();
47    resultFuture = buildChainingFuture(inputFuture);
48    listener = new MockFutureListener(resultFuture);
49
50  }
51
52  public void testFutureGetBeforeCallback() throws Exception {
53    // Verify that get throws a timeout exception before the callback is called.
54    try {
55      resultFuture.get(1L, TimeUnit.MILLISECONDS);
56      fail("The data is not yet ready, so a TimeoutException is expected");
57    } catch (TimeoutException expected) {}
58  }
59
60  public void testFutureGetThrowsWrappedException() throws Exception {
61    inputFuture.setException(EXCEPTION);
62    listener.assertException(EXCEPTION);
63  }
64
65  public void testFutureGetThrowsWrappedError() throws Exception {
66    Error error = new Error();
67    try {
68      inputFuture.setException(error);
69      fail("Expected an Error to be thrown");  // COV_NF_LINE
70    } catch (Error expected) {
71      assertSame(error, expected);
72    }
73
74    // Verify that get throws an ExecutionException, caused by an Error, when
75    // the callback is called.
76    listener.assertException(error);
77  }
78
79  public void testAddListenerAfterCallback() throws Throwable {
80    inputFuture.set(VALID_INPUT_DATA);
81
82    listener.assertSuccess(getSuccessfulResult());
83  }
84
85  public void testFutureBeforeCallback() throws Throwable {
86    inputFuture.set(VALID_INPUT_DATA);
87
88    listener.assertSuccess(getSuccessfulResult());
89  }
90
91  /**
92   * Override to return a chaining listenableFuture that returns the result of
93   * getSuccessfulResult() when inputFuture returns VALID_INPUT_DATA, and sets
94   * the exception to EXCEPTION in all other cases.
95   */
96  protected abstract ListenableFuture<T> buildChainingFuture(
97      ListenableFuture<Integer> inputFuture);
98
99  /**
100   * Override to return the result when VALID_INPUT_DATA is passed in to
101   * the chaining listenableFuture
102   */
103  protected abstract T getSuccessfulResult();
104}
105