• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.common.util.concurrent;
18 
19 import com.google.common.util.concurrent.testing.MockFutureListener;
20 
21 import junit.framework.TestCase;
22 
23 import java.util.concurrent.TimeUnit;
24 import 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  */
33 public 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
setUp()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 
testFutureGetBeforeCallback()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 
testFutureGetThrowsWrappedException()60   public void testFutureGetThrowsWrappedException() throws Exception {
61     inputFuture.setException(EXCEPTION);
62     listener.assertException(EXCEPTION);
63   }
64 
testFutureGetThrowsWrappedError()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 
testAddListenerAfterCallback()79   public void testAddListenerAfterCallback() throws Throwable {
80     inputFuture.set(VALID_INPUT_DATA);
81 
82     listener.assertSuccess(getSuccessfulResult());
83   }
84 
testFutureBeforeCallback()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    */
buildChainingFuture( ListenableFuture<Integer> inputFuture)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    */
getSuccessfulResult()103   protected abstract T getSuccessfulResult();
104 }
105