• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.common.util.concurrent.testing;
18 
19 import com.google.common.annotations.Beta;
20 import com.google.common.util.concurrent.CheckedFuture;
21 import com.google.common.util.concurrent.ListenableFuture;
22 
23 import java.util.concurrent.CountDownLatch;
24 import 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
34 public abstract class AbstractCheckedFutureTest
35     extends AbstractListenableFutureTest {
36 
37   /**
38    * More specific type for the create method.
39    */
createCheckedFuture(V value, Exception except, CountDownLatch waitOn)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    */
checkCancelledException(Exception e)46   protected abstract void checkCancelledException(Exception e);
47 
48   /**
49    * Checks that the exception is the correct type of execution exception.
50    */
checkExecutionException(Exception e)51   protected abstract void checkExecutionException(Exception e);
52 
53   /**
54    * Checks that the exception is the correct type of interruption exception.
55    */
checkInterruptedException(Exception e)56   protected abstract void checkInterruptedException(Exception e);
57 
58   @Override
createListenableFuture(V value, Exception except, CountDownLatch waitOn)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    */
testCheckedGetThrowsApplicationExceptionOnCancellation()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 
testCheckedGetThrowsApplicationExceptionOnInterruption()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 
testCheckedGetThrowsApplicationExceptionOnError()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