AbstractCheckedFutureTest.java revision 1d580d0f6ee4f21eb309ba7b509d2c6d671c4044
1/*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.  You may obtain a copy
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.google.common.util.concurrent.testing;
18
19import com.google.common.annotations.Beta;
20import com.google.common.util.concurrent.CheckedFuture;
21import com.google.common.util.concurrent.ListenableFuture;
22
23import java.util.concurrent.CountDownLatch;
24import java.util.concurrent.TimeUnit;
25
26/**
27 * Test case to make sure the {@link CheckedFuture#checkedGet()} and
28 * {@link CheckedFuture#checkedGet(long, TimeUnit)} methods work correctly.
29 *
30 * @author Sven Mawson
31 * @since 10.0
32 */
33@Beta
34public abstract class AbstractCheckedFutureTest
35    extends AbstractListenableFutureTest {
36
37  /**
38   * More specific type for the create method.
39   */
40  protected abstract <V> CheckedFuture<V, ?> createCheckedFuture(V value,
41      Exception except, CountDownLatch waitOn);
42
43  /**
44   * Checks that the exception is the correct type of cancellation exception.
45   */
46  protected abstract void checkCancelledException(Exception e);
47
48  /**
49   * Checks that the exception is the correct type of execution exception.
50   */
51  protected abstract void checkExecutionException(Exception e);
52
53  /**
54   * Checks that the exception is the correct type of interruption exception.
55   */
56  protected abstract void checkInterruptedException(Exception e);
57
58  @Override
59  protected <V> ListenableFuture<V> createListenableFuture(V value,
60      Exception except, CountDownLatch waitOn) {
61    return createCheckedFuture(value, except, waitOn);
62  }
63
64  /**
65   * Tests that the {@link CheckedFuture#checkedGet()} method throws the correct
66   * type of cancellation exception when it is cancelled.
67   */
68  public void testCheckedGetThrowsApplicationExceptionOnCancellation() {
69
70    final CheckedFuture<Boolean, ?> future =
71        createCheckedFuture(Boolean.TRUE, null, latch);
72
73    assertFalse(future.isDone());
74    assertFalse(future.isCancelled());
75
76    new Thread(new Runnable() {
77      @Override
78      public void run() {
79        future.cancel(true);
80      }
81    }).start();
82
83    try {
84      future.checkedGet();
85      fail("RPC Should have been cancelled.");
86    } catch (Exception e) {
87      checkCancelledException(e);
88    }
89
90    assertTrue(future.isDone());
91    assertTrue(future.isCancelled());
92  }
93
94  public void testCheckedGetThrowsApplicationExceptionOnInterruption()
95      throws InterruptedException {
96
97    final CheckedFuture<Boolean, ?> future =
98        createCheckedFuture(Boolean.TRUE, null, latch);
99
100    final CountDownLatch startingGate = new CountDownLatch(1);
101    final CountDownLatch successLatch = new CountDownLatch(1);
102
103    assertFalse(future.isDone());
104    assertFalse(future.isCancelled());
105
106    Thread getThread = new Thread(new Runnable() {
107      @Override
108      public void run() {
109        startingGate.countDown();
110
111        try {
112          future.checkedGet();
113        } catch (Exception e) {
114          checkInterruptedException(e);
115
116          // This only gets hit if the original call throws an exception and
117          // the check call above passes.
118          successLatch.countDown();
119        }
120      }
121    });
122    getThread.start();
123
124    assertTrue(startingGate.await(500, TimeUnit.MILLISECONDS));
125    getThread.interrupt();
126
127    assertTrue(successLatch.await(500, TimeUnit.MILLISECONDS));
128
129    assertFalse(future.isDone());
130    assertFalse(future.isCancelled());
131  }
132
133  public void testCheckedGetThrowsApplicationExceptionOnError() {
134    final CheckedFuture<Boolean, ?> future =
135        createCheckedFuture(Boolean.TRUE, new Exception("Error"), latch);
136
137    assertFalse(future.isDone());
138    assertFalse(future.isCancelled());
139
140    new Thread(new Runnable() {
141      @Override
142      public void run() {
143        latch.countDown();
144      }
145    }).start();
146
147    try {
148      future.checkedGet();
149      fail();
150    } catch (Exception e) {
151      checkExecutionException(e);
152    }
153
154    assertTrue(future.isDone());
155    assertFalse(future.isCancelled());
156  }
157}
158