package com.nurkiewicz.asyncretry; import com.nurkiewicz.asyncretry.function.RetryCallable; import com.nurkiewicz.asyncretry.function.RetryRunnable; import org.testng.annotations.Test; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; public class SyncRetryExecutorTest extends AbstractBaseTestCase { RetryExecutor executor = SyncRetryExecutor.INSTANCE; @Test void shouldReturnCompletedFutureWhenDoWithRetryCalled() throws ExecutionException, InterruptedException { //given String mainThread = Thread.currentThread().getName(); AtomicReference<String> poolThread = new AtomicReference<>(); //when CompletableFuture<Void> result = executor.doWithRetry(ctx -> poolThread.set(Thread.currentThread().getName())); //then assertThat(poolThread.get()).isEqualTo(mainThread); } @Test void shouldWrapExceptionInFutureRatherThanThrowingIt() throws InterruptedException { //given RetryRunnable block = context -> { throw new IllegalArgumentException(DON_T_PANIC); }; CompletableFuture<Void> future = executor.doWithRetry(block); try { //when future.get(); failBecauseExceptionWasNotThrown(ExecutionException.class); } catch (ExecutionException e) { //then assertThat(e).hasCauseInstanceOf(IllegalArgumentException.class); assertThat(e.getCause()).hasMessage(DON_T_PANIC); } } @Test void shouldReturnCompletedFutureWhenGetWithRetryCalled() throws ExecutionException, InterruptedException { //given String mainThread = Thread.currentThread().getName(); //when CompletableFuture<String> result = executor.getWithRetry(() -> Thread.currentThread().getName()); //then assertThat(result.get()).isEqualTo(mainThread); } @Test void shouldWrapExceptionInFutureRatherThanThrowingItInGetWithRetry() throws InterruptedException { //given Callable<Void> block = () -> { throw new IllegalArgumentException(DON_T_PANIC); }; CompletableFuture<Void> future = executor.getWithRetry(block); try { //when future.get(); failBecauseExceptionWasNotThrown(ExecutionException.class); } catch (ExecutionException e) { //then assertThat(e).hasCauseInstanceOf(IllegalArgumentException.class); assertThat(e.getCause()).hasMessage(DON_T_PANIC); } } @Test void shouldReturnCompletedFutureWhenGetWithRetryCalledContext() throws ExecutionException, InterruptedException { //given String mainThread = Thread.currentThread().getName(); //when CompletableFuture<String> result = executor.getWithRetry(ctx -> Thread.currentThread().getName()); //then assertThat(result.get()).isEqualTo(mainThread); } @Test void shouldWrapExceptionInFutureRatherThanThrowingItInGetWithRetryContext() throws InterruptedException { //given RetryCallable<Void> block = ctx -> { throw new IllegalArgumentException(DON_T_PANIC); }; CompletableFuture<Void> future = executor.getWithRetry(block); try { //when future.get(); failBecauseExceptionWasNotThrown(ExecutionException.class); } catch (ExecutionException e) { //then assertThat(e).hasCauseInstanceOf(IllegalArgumentException.class); assertThat(e.getCause()).hasMessage(DON_T_PANIC); } } @Test void shouldReturnCompletedFutureWhenGetWithRetryOnFutureCalled() throws ExecutionException, InterruptedException { //given String mainThread = Thread.currentThread().getName(); //when CompletableFuture<String> result = executor.getFutureWithRetry(ctx -> CompletableFuture.completedFuture(Thread.currentThread().getName())); //then assertThat(result.get()).isEqualTo(mainThread); } @Test void shouldWrapExceptionInFutureRatherThanThrowingItInGetWithRetryOnFuture() throws InterruptedException { //given RetryCallable<CompletableFuture<String>> block = ctx -> { final CompletableFuture<String> failedFuture = new CompletableFuture<>(); failedFuture.completeExceptionally(new IllegalArgumentException(DON_T_PANIC)); return failedFuture; }; CompletableFuture<String> future = executor.getFutureWithRetry(block); try { //when future.get(); failBecauseExceptionWasNotThrown(ExecutionException.class); } catch (ExecutionException e) { //then assertThat(e).hasCauseInstanceOf(IllegalArgumentException.class); assertThat(e.getCause()).hasMessage(DON_T_PANIC); } } }