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 inputFuture.setException(error); 68 // Verify that get throws an ExecutionException, caused by an Error, when 69 // the callback is called. 70 listener.assertException(error); 71 } 72 testAddListenerAfterCallback()73 public void testAddListenerAfterCallback() throws Throwable { 74 inputFuture.set(VALID_INPUT_DATA); 75 76 listener.assertSuccess(getSuccessfulResult()); 77 } 78 testFutureBeforeCallback()79 public void testFutureBeforeCallback() throws Throwable { 80 inputFuture.set(VALID_INPUT_DATA); 81 82 listener.assertSuccess(getSuccessfulResult()); 83 } 84 85 /** 86 * Override to return a chaining listenableFuture that returns the result of 87 * getSuccessfulResult() when inputFuture returns VALID_INPUT_DATA, and sets 88 * the exception to EXCEPTION in all other cases. 89 */ buildChainingFuture( ListenableFuture<Integer> inputFuture)90 protected abstract ListenableFuture<T> buildChainingFuture( 91 ListenableFuture<Integer> inputFuture); 92 93 /** 94 * Override to return the result when VALID_INPUT_DATA is passed in to 95 * the chaining listenableFuture 96 */ getSuccessfulResult()97 protected abstract T getSuccessfulResult(); 98 } 99