Home | History | Annotate | Download | only in testing
      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    */
     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