11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * use this file except in compliance with the License.  You may obtain a copy
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * License for the specific language governing permissions and limitations under
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent.testing;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.util.concurrent.CheckedFuture;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.util.concurrent.ListenableFuture;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CountDownLatch;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Test case to make sure the {@link CheckedFuture#checkedGet()} and
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link CheckedFuture#checkedGet(long, TimeUnit)} methods work correctly.
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Sven Mawson
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class AbstractCheckedFutureTest
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    extends AbstractListenableFutureTest {
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * More specific type for the create method.
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected abstract <V> CheckedFuture<V, ?> createCheckedFuture(V value,
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Exception except, CountDownLatch waitOn);
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Checks that the exception is the correct type of cancellation exception.
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected abstract void checkCancelledException(Exception e);
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Checks that the exception is the correct type of execution exception.
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected abstract void checkExecutionException(Exception e);
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Checks that the exception is the correct type of interruption exception.
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected abstract void checkInterruptedException(Exception e);
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected <V> ListenableFuture<V> createListenableFuture(V value,
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Exception except, CountDownLatch waitOn) {
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return createCheckedFuture(value, except, waitOn);
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Tests that the {@link CheckedFuture#checkedGet()} method throws the correct
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * type of cancellation exception when it is cancelled.
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedGetThrowsApplicationExceptionOnCancellation() {
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final CheckedFuture<Boolean, ?> future =
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        createCheckedFuture(Boolean.TRUE, null, latch);
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isDone());
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isCancelled());
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    new Thread(new Runnable() {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public void run() {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        future.cancel(true);
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }).start();
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      future.checkedGet();
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("RPC Should have been cancelled.");
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkCancelledException(e);
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(future.isDone());
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(future.isCancelled());
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedGetThrowsApplicationExceptionOnInterruption()
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws InterruptedException {
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final CheckedFuture<Boolean, ?> future =
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        createCheckedFuture(Boolean.TRUE, null, latch);
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final CountDownLatch startingGate = new CountDownLatch(1);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final CountDownLatch successLatch = new CountDownLatch(1);
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isDone());
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isCancelled());
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Thread getThread = new Thread(new Runnable() {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public void run() {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        startingGate.countDown();
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          future.checkedGet();
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (Exception e) {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          checkInterruptedException(e);
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          // This only gets hit if the original call throws an exception and
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          // the check call above passes.
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          successLatch.countDown();
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    });
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    getThread.start();
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(startingGate.await(500, TimeUnit.MILLISECONDS));
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    getThread.interrupt();
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(successLatch.await(500, TimeUnit.MILLISECONDS));
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isDone());
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isCancelled());
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedGetThrowsApplicationExceptionOnError() {
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final CheckedFuture<Boolean, ?> future =
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        createCheckedFuture(Boolean.TRUE, new Exception("Error"), latch);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isDone());
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isCancelled());
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    new Thread(new Runnable() {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public void run() {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        latch.countDown();
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }).start();
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      future.checkedGet();
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Exception e) {
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkExecutionException(e);
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(future.isDone());
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(future.isCancelled());
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
158