Home | History | Annotate | Download | only in concurrent
      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 }
    194