blob: 5c2ce32cbe94d68fd12a111810da82e204b13a8b [file] [log] [blame]
/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.common.util.concurrent.testing;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Test case to make sure the {@link CheckedFuture#checkedGet()} and {@link
* CheckedFuture#checkedGet(long, TimeUnit)} methods work correctly.
*
* @author Sven Mawson
* @since 10.0
*/
@Beta
@GwtIncompatible
public abstract class AbstractCheckedFutureTest extends AbstractListenableFutureTest {
/** More specific type for the create method. */
protected abstract <V> CheckedFuture<V, ?> createCheckedFuture(
V value, Exception except, CountDownLatch waitOn);
/** Checks that the exception is the correct type of cancellation exception. */
protected abstract void checkCancelledException(Exception e);
/** Checks that the exception is the correct type of execution exception. */
protected abstract void checkExecutionException(Exception e);
/** Checks that the exception is the correct type of interruption exception. */
protected abstract void checkInterruptedException(Exception e);
@Override
protected <V> ListenableFuture<V> createListenableFuture(
V value, Exception except, CountDownLatch waitOn) {
return createCheckedFuture(value, except, waitOn);
}
/**
* Tests that the {@link CheckedFuture#checkedGet()} method throws the correct type of
* cancellation exception when it is cancelled.
*/
public void testCheckedGetThrowsApplicationExceptionOnCancellation() {
final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch);
assertFalse(future.isDone());
assertFalse(future.isCancelled());
new Thread(
new Runnable() {
@Override
public void run() {
future.cancel(true);
}
})
.start();
try {
future.checkedGet();
fail("RPC Should have been cancelled.");
} catch (Exception e) {
checkCancelledException(e);
}
assertTrue(future.isDone());
assertTrue(future.isCancelled());
}
public void testCheckedGetThrowsApplicationExceptionOnInterruption() throws InterruptedException {
final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch);
final CountDownLatch startingGate = new CountDownLatch(1);
final CountDownLatch successLatch = new CountDownLatch(1);
assertFalse(future.isDone());
assertFalse(future.isCancelled());
Thread getThread =
new Thread(
new Runnable() {
@Override
public void run() {
startingGate.countDown();
try {
future.checkedGet();
} catch (Exception e) {
checkInterruptedException(e);
// This only gets hit if the original call throws an exception and
// the check call above passes.
successLatch.countDown();
}
}
});
getThread.start();
assertTrue(startingGate.await(500, TimeUnit.MILLISECONDS));
getThread.interrupt();
assertTrue(successLatch.await(500, TimeUnit.MILLISECONDS));
assertFalse(future.isDone());
assertFalse(future.isCancelled());
}
public void testCheckedGetThrowsApplicationExceptionOnError() {
final CheckedFuture<Boolean, ?> future =
createCheckedFuture(Boolean.TRUE, new Exception("Error"), latch);
assertFalse(future.isDone());
assertFalse(future.isCancelled());
new Thread(
new Runnable() {
@Override
public void run() {
latch.countDown();
}
})
.start();
try {
future.checkedGet();
fail();
} catch (Exception e) {
checkExecutionException(e);
}
assertTrue(future.isDone());
assertFalse(future.isCancelled());
}
}