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. */ testCreate()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 testSetValue()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 testSetException()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 testSetFuture()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 testSetFuture_genericsHierarchy()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 testCancel_innerCancelsAsync()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 testCancel_resultCancelsInner_interrupted()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 testCancel_resultCancelsInner()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 testCancel_beforeSet()161 public void testCancel_beforeSet() throws Exception { 162 AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); 163 async.cancel(true); 164 assertFalse(async.setValue(42)); 165 } 166 testCancel_multipleBeforeSetFuture_noInterruptFirst()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 testCancel_multipleBeforeSetFuture_interruptFirst()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> { myWasInterrupted()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 } 194