Package com.nurkiewicz.asyncretry

Source Code of com.nurkiewicz.asyncretry.AsyncRetryJobTest

package com.nurkiewicz.asyncretry;

import com.nurkiewicz.asyncretry.policy.AbortRetryException;
import org.assertj.core.api.Assertions;
import org.mockito.InOrder;
import org.testng.annotations.Test;

import java.io.IOException;
import java.net.SocketException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static com.nurkiewicz.asyncretry.backoff.FixedIntervalBackoff.DEFAULT_PERIOD_MILLIS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.times;

/**
* @author Tomasz Nurkiewicz
* @since 7/21/13, 7:07 PM
*/
public class AsyncRetryJobTest extends AbstractBaseTestCase {

  @Test
  public void shouldUnwrapUserFutureAndReturnIt() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock);
    given(serviceMock.safeAsync()).willReturn(CompletableFuture.completedFuture("42"));

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    assertThat(future.get()).isEqualTo("42");
  }

  @Test
  public void shouldSucceedAfterFewAsynchronousRetries() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock);
    given(serviceMock.safeAsync()).willReturn(
        failedAsync(new SocketException("First")),
        failedAsync(new IOException("Second")),
        CompletableFuture.completedFuture("42")
    );

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    assertThat(future.get()).isEqualTo("42");
  }

  @Test
  public void shouldScheduleTwoTimesWhenRetries() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock);
    given(serviceMock.safeAsync()).willReturn(
        failedAsync(new SocketException("First")),
        failedAsync(new IOException("Second")),
        CompletableFuture.completedFuture("42")
    );

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    future.get();

    final InOrder order = inOrder(schedulerMock);
    order.verify(schedulerMock).schedule(notNullRunnable(), eq(0L), millis());
    order.verify(schedulerMock, times(2)).schedule(notNullRunnable(), eq(DEFAULT_PERIOD_MILLIS), millis());
  }

  private CompletableFuture<String> failedAsync(Throwable throwable) {
    final CompletableFuture<String> future = new CompletableFuture<>();
    future.completeExceptionally(throwable);
    return future;
  }

  @Test
  public void shouldRethrowOriginalExceptionFromUserFutureCompletion() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock).
        abortOn(SocketException.class);
    given(serviceMock.safeAsync()).willReturn(
        failedAsync(new SocketException(DON_T_PANIC))
    );

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    assertThat(future.isCompletedExceptionally()).isTrue();

    try {
      future.get();
      failBecauseExceptionWasNotThrown(ExecutionException.class);
    } catch (ExecutionException e) {
      final Throwable cause = e.getCause();
      assertThat(cause).isInstanceOf(SocketException.class);
      assertThat(cause).hasMessage(DON_T_PANIC);
    }
  }

  @Test
  public void shouldAbortWhenTargetFutureWantsToAbort() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock);
    given(serviceMock.safeAsync()).willReturn(
        failedAsync(new AbortRetryException())
    );

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    assertThat(future.isCompletedExceptionally()).isTrue();

    try {
      future.get();
      failBecauseExceptionWasNotThrown(ExecutionException.class);
    } catch (ExecutionException e) {
      final Throwable cause = e.getCause();
      assertThat(cause).isInstanceOf(AbortRetryException.class);
    }
  }

  @Test
  public void shouldRethrowExceptionThatWasThrownFromUserTaskBeforeReturningFuture() throws Exception {
    //given
    final RetryExecutor executor = new AsyncRetryExecutor(schedulerMock).
        abortOn(IllegalArgumentException.class);
    given(serviceMock.safeAsync()).willThrow(new IllegalArgumentException(DON_T_PANIC));

    //when
    final CompletableFuture<String> future = executor.getFutureWithRetry(ctx -> serviceMock.safeAsync());

    //then
    assertThat(future.isCompletedExceptionally()).isTrue();

    try {
      future.get();
      Assertions.failBecauseExceptionWasNotThrown(ExecutionException.class);
    } catch (ExecutionException e) {
      assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
      assertThat(e.getCause()).hasMessage(DON_T_PANIC);
    }
  }

}
TOP

Related Classes of com.nurkiewicz.asyncretry.AsyncRetryJobTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.