// Path: provider/src/main/java/com/cloudera/director/aws/ec2/EC2Retryer.java
// @VisibleForTesting
// static Duration getTimeout(DateTime timeout) {
//   DateTime now = DateTime.now();
// 
//   if (timeout.isBefore(now)) {
//     return Duration.ZERO;
//   }
// 
//   return new Interval(now, timeout).toDuration();
// }
// 
// Path: provider/src/main/java/com/cloudera/director/aws/ec2/EC2Retryer.java
// public static <T> T retryUntil(Callable<T> func)
//     throws InterruptedException, RetryException, ExecutionException {
//   return retryUntil(func, DEFAULT_TIMEOUT);
// }
// 
// Path: provider/src/main/java/com/cloudera/director/aws/ec2/common/EC2Exceptions.java
// public static final String INVALID_INSTANCE_ID_NOT_FOUND = "InvalidInstanceID.NotFound";


import org.junit.Test;
import static com.cloudera.director.aws.ec2.EC2Retryer.getTimeout;
import static com.cloudera.director.aws.ec2.EC2Retryer.retryUntil;
import static com.cloudera.director.aws.ec2.common.EC2Exceptions.INVALID_INSTANCE_ID_NOT_FOUND;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.cloudera.director.aws.shaded.com.amazonaws.AmazonServiceException;
import com.cloudera.director.aws.shaded.org.joda.time.DateTime;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
    Callable<Integer> task = mock(Callable.class);
    when(task.call()).thenThrow(exception);

    Thread t = new Thread(currentThread::interrupt);
    t.start();

    try {
      retryUntil(task);
      fail("expected exception didn't thrown");
    } catch (InterruptedException e) {
      verify(task, atLeastOnce()).call();
    }
  }

  @Test
  public void testOtherExceptionWillNotTriggerRetry() throws Exception {
    Callable<Integer> task = mock(Callable.class);
    when(task.call()).thenThrow(new RuntimeException());

    try {
      retryUntil(task);
      fail("expected exception didn't thrown");
    } catch (ExecutionException e) {
      assertThat(RuntimeException.class.isInstance(e.getCause())).isTrue();
      verify(task, times(1)).call();
    }
  }

  @Test
  public void testGetDuration() {
// Path: provider/src/main/java/com/cloudera/director/aws/ec2/EC2Retryer.java
// @VisibleForTesting
// static Duration getTimeout(DateTime timeout) {
//   DateTime now = DateTime.now();
// 
//   if (timeout.isBefore(now)) {
//     return Duration.ZERO;
//   }
// 
//   return new Interval(now, timeout).toDuration();
// }
// 
// Path: provider/src/main/java/com/cloudera/director/aws/ec2/EC2Retryer.java
// public static <T> T retryUntil(Callable<T> func)
//     throws InterruptedException, RetryException, ExecutionException {
//   return retryUntil(func, DEFAULT_TIMEOUT);
// }
// 
// Path: provider/src/main/java/com/cloudera/director/aws/ec2/common/EC2Exceptions.java
// public static final String INVALID_INSTANCE_ID_NOT_FOUND = "InvalidInstanceID.NotFound";


// Path: tests/src/test/java/com/cloudera/director/aws/ec2/EC2RetryerTest.java
import org.junit.Test;
import static com.cloudera.director.aws.ec2.EC2Retryer.getTimeout;
import static com.cloudera.director.aws.ec2.EC2Retryer.retryUntil;
import static com.cloudera.director.aws.ec2.common.EC2Exceptions.INVALID_INSTANCE_ID_NOT_FOUND;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.cloudera.director.aws.shaded.com.amazonaws.AmazonServiceException;
import com.cloudera.director.aws.shaded.org.joda.time.DateTime;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

    Callable<Integer> task = mock(Callable.class);
    when(task.call()).thenThrow(exception);

    Thread t = new Thread(currentThread::interrupt);
    t.start();

    try {
      retryUntil(task);
      fail("expected exception didn't thrown");
    } catch (InterruptedException e) {
      verify(task, atLeastOnce()).call();
    }
  }

  @Test
  public void testOtherExceptionWillNotTriggerRetry() throws Exception {
    Callable<Integer> task = mock(Callable.class);
    when(task.call()).thenThrow(new RuntimeException());

    try {
      retryUntil(task);
      fail("expected exception didn't thrown");
    } catch (ExecutionException e) {
      assertThat(RuntimeException.class.isInstance(e.getCause())).isTrue();
      verify(task, times(1)).call();
    }
  }

  @Test
  public void testGetDuration() {
    getTimeout(DateTime.now().plus(10L));