View Javadoc
1   /*
2    * Copyright (C) 2012 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 junit.framework.TestCase;
20  
21  import java.util.concurrent.CancellationException;
22  import java.util.concurrent.ExecutionException;
23  import java.util.concurrent.TimeUnit;
24  import java.util.concurrent.TimeoutException;
25  
26  /**
27   * Tests that {@code AsyncSettableFuture} is a valid {@link ListenableFuture}
28   * that behaves itself as expected.
29   */
30  
31  public class AsyncSettableFutureTest extends TestCase {
32  
33    private static class Foo {}
34    private static class FooChild extends Foo {}
35  
36    /** Tests the initial state of the future. */
37    public void testCreate() throws Exception {
38      AsyncSettableFuture<Integer> future = AsyncSettableFuture.create();
39      assertFalse(future.isSet());
40      assertFalse(future.isDone());
41      assertFalse(future.isCancelled());
42    }
43  
44    public void testSetValue() throws Exception {
45      AsyncSettableFuture<Integer> future = AsyncSettableFuture.create();
46      assertTrue(future.setValue(42));
47      assertTrue(future.isSet());
48      // Later attempts to set the future should return false.
49      assertFalse(future.setValue(23));
50      assertFalse(future.setException(new Exception("bar")));
51      assertFalse(future.setFuture(SettableFuture.<Integer>create()));
52      // Check that the future has been set properly.
53      assertTrue(future.isDone());
54      assertFalse(future.isCancelled());
55      assertEquals(42, (int) future.get());
56    }
57  
58    public void testSetException() throws Exception {
59      AsyncSettableFuture<Object> future = AsyncSettableFuture.create();
60      Exception e = new Exception("foobarbaz");
61      assertTrue(future.setException(e));
62      assertTrue(future.isSet());
63      // Later attempts to set the future should return false.
64      assertFalse(future.setValue(23));
65      assertFalse(future.setException(new Exception("quux")));
66      assertFalse(future.setFuture(SettableFuture.create()));
67      // Check that the future has been set properly.
68      assertTrue(future.isDone());
69      assertFalse(future.isCancelled());
70      try {
71        future.get();
72        fail("Expected ExecutionException");
73      } catch (ExecutionException ee) {
74        assertSame(e, ee.getCause());
75      }
76    }
77  
78    public void testSetFuture() throws Exception {
79      AsyncSettableFuture<String> future = AsyncSettableFuture.create();
80      SettableFuture<String> nested = SettableFuture.create();
81      assertTrue(future.setFuture(nested));
82      assertTrue(future.isSet());
83      // Later attempts to set the future should return false.
84      assertFalse(future.setValue("x"));
85      assertFalse(future.setException(new Exception("bar")));
86      assertFalse(future.setFuture(SettableFuture.<String>create()));
87      // Check that the future has been set properly.
88      assertFalse(future.isDone());
89      assertFalse(future.isCancelled());
90      try {
91        future.get(0, TimeUnit.MILLISECONDS);
92        fail("Expected TimeoutException");
93      } catch (TimeoutException expected) { /* expected */ }
94      nested.set("foo");
95      assertTrue(future.isDone());
96      assertFalse(future.isCancelled());
97      assertEquals("foo", future.get());
98    }
99  
100   public void testSetFuture_genericsHierarchy() throws Exception {
101     AsyncSettableFuture<Foo> future = AsyncSettableFuture.create();
102     SettableFuture<FooChild> nested = SettableFuture.create();
103     assertTrue(future.setFuture(nested));
104     assertTrue(future.isSet());
105     // Later attempts to set the future should return false.
106     assertFalse(future.setValue(new Foo()));
107     assertFalse(future.setException(new Exception("bar")));
108     assertFalse(future.setFuture(SettableFuture.<Foo>create()));
109     // Check that the future has been set properly.
110     assertFalse(future.isDone());
111     assertFalse(future.isCancelled());
112     try {
113       future.get(0, TimeUnit.MILLISECONDS);
114       fail("Expected TimeoutException");
115     } catch (TimeoutException expected) { /* expected */ }
116     FooChild value = new FooChild();
117     nested.set(value);
118     assertTrue(future.isDone());
119     assertFalse(future.isCancelled());
120     assertSame(value, future.get());
121   }
122 
123   public void testCancel_innerCancelsAsync() throws Exception {
124     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
125     SettableFuture<Object> inner = SettableFuture.create();
126     async.setFuture(inner);
127     inner.cancel(true);
128     assertTrue(async.isCancelled());
129     try {
130       async.get();
131       fail("Expected CancellationException");
132     } catch (CancellationException expected) { /* expected */ }
133   }
134 
135   public void testCancel_resultCancelsInner_interrupted() throws Exception {
136     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
137     MyFuture<Object> inner = new MyFuture<Object>();
138     async.setFuture(inner);
139     async.cancel(true);
140     assertTrue(inner.isCancelled());
141     assertTrue(inner.myWasInterrupted());
142     try {
143       inner.get();
144       fail("Expected CancellationException");
145     } catch (CancellationException expected) { /* expected */ }
146   }
147 
148   public void testCancel_resultCancelsInner() throws Exception {
149     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
150     MyFuture<Object> inner = new MyFuture<Object>();
151     async.setFuture(inner);
152     async.cancel(false);
153     assertTrue(inner.isCancelled());
154     assertFalse(inner.myWasInterrupted());
155     try {
156       inner.get();
157       fail("Expected CancellationException");
158     } catch (CancellationException expected) { /* expected */ }
159   }
160 
161   public void testCancel_beforeSet() throws Exception {
162     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
163     async.cancel(true);
164     assertFalse(async.setValue(42));
165   }
166 
167   public void testCancel_multipleBeforeSetFuture_noInterruptFirst() throws Exception {
168     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
169     async.cancel(false);
170     async.cancel(true);
171     MyFuture<Object> inner = new MyFuture<Object>();
172     assertFalse(async.setFuture(inner));
173     assertTrue(inner.isCancelled());
174     assertFalse(inner.myWasInterrupted());
175   }
176 
177   public void testCancel_multipleBeforeSetFuture_interruptFirst() throws Exception {
178     AsyncSettableFuture<Object> async = AsyncSettableFuture.create();
179     async.cancel(true);
180     async.cancel(false);
181     MyFuture<Object> inner = new MyFuture<Object>();
182     assertFalse(async.setFuture(inner));
183     assertTrue(inner.isCancelled());
184     assertTrue(inner.myWasInterrupted());
185   }
186 
187   private static class MyFuture<V> extends AbstractFuture<V> {
188     boolean myWasInterrupted() {
189       // we need a new method since wasInterrupted is final, so we can't increase its visibility.
190       return wasInterrupted();
191     }
192   }
193 }