001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy 006 * of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 017package com.google.common.util.concurrent.testing; 018 019import com.google.common.annotations.Beta; 020import com.google.common.annotations.GwtIncompatible; 021import com.google.common.util.concurrent.CheckedFuture; 022import com.google.common.util.concurrent.ListenableFuture; 023import java.util.concurrent.CountDownLatch; 024import java.util.concurrent.TimeUnit; 025 026/** 027 * Test case to make sure the {@link CheckedFuture#checkedGet()} and {@link 028 * CheckedFuture#checkedGet(long, TimeUnit)} methods work correctly. 029 * 030 * @author Sven Mawson 031 * @since 10.0 032 */ 033@Beta 034@GwtIncompatible 035public abstract class AbstractCheckedFutureTest extends AbstractListenableFutureTest { 036 037 /** More specific type for the create method. */ 038 protected abstract <V> CheckedFuture<V, ?> createCheckedFuture( 039 V value, Exception except, CountDownLatch waitOn); 040 041 /** Checks that the exception is the correct type of cancellation exception. */ 042 protected abstract void checkCancelledException(Exception e); 043 044 /** Checks that the exception is the correct type of execution exception. */ 045 protected abstract void checkExecutionException(Exception e); 046 047 /** Checks that the exception is the correct type of interruption exception. */ 048 protected abstract void checkInterruptedException(Exception e); 049 050 @Override 051 protected <V> ListenableFuture<V> createListenableFuture( 052 V value, Exception except, CountDownLatch waitOn) { 053 return createCheckedFuture(value, except, waitOn); 054 } 055 056 /** 057 * Tests that the {@link CheckedFuture#checkedGet()} method throws the correct type of 058 * cancellation exception when it is cancelled. 059 */ 060 public void testCheckedGetThrowsApplicationExceptionOnCancellation() { 061 062 final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch); 063 064 assertFalse(future.isDone()); 065 assertFalse(future.isCancelled()); 066 067 new Thread( 068 new Runnable() { 069 @Override 070 public void run() { 071 future.cancel(true); 072 } 073 }) 074 .start(); 075 076 try { 077 future.checkedGet(); 078 fail("RPC Should have been cancelled."); 079 } catch (Exception e) { 080 checkCancelledException(e); 081 } 082 083 assertTrue(future.isDone()); 084 assertTrue(future.isCancelled()); 085 } 086 087 public void testCheckedGetThrowsApplicationExceptionOnInterruption() throws InterruptedException { 088 089 final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch); 090 091 final CountDownLatch startingGate = new CountDownLatch(1); 092 final CountDownLatch successLatch = new CountDownLatch(1); 093 094 assertFalse(future.isDone()); 095 assertFalse(future.isCancelled()); 096 097 Thread getThread = 098 new Thread( 099 new Runnable() { 100 @Override 101 public void run() { 102 startingGate.countDown(); 103 104 try { 105 future.checkedGet(); 106 } catch (Exception e) { 107 checkInterruptedException(e); 108 109 // This only gets hit if the original call throws an exception and 110 // the check call above passes. 111 successLatch.countDown(); 112 } 113 } 114 }); 115 getThread.start(); 116 117 assertTrue(startingGate.await(500, TimeUnit.MILLISECONDS)); 118 getThread.interrupt(); 119 120 assertTrue(successLatch.await(500, TimeUnit.MILLISECONDS)); 121 122 assertFalse(future.isDone()); 123 assertFalse(future.isCancelled()); 124 } 125 126 public void testCheckedGetThrowsApplicationExceptionOnError() { 127 final CheckedFuture<Boolean, ?> future = 128 createCheckedFuture(Boolean.TRUE, new Exception("Error"), latch); 129 130 assertFalse(future.isDone()); 131 assertFalse(future.isCancelled()); 132 133 new Thread( 134 new Runnable() { 135 @Override 136 public void run() { 137 latch.countDown(); 138 } 139 }) 140 .start(); 141 142 try { 143 future.checkedGet(); 144 fail(); 145 } catch (Exception e) { 146 checkExecutionException(e); 147 } 148 149 assertTrue(future.isDone()); 150 assertFalse(future.isCancelled()); 151 } 152}