Search in sources :

Example 1 with FailsafeExecutor

use of dev.failsafe.FailsafeExecutor in project failsafe by jhalterman.

the class OkHttpTesting method test.

private <T> void test(FailsafeExecutor<Response> failsafe, Call when, Then<Response> then, int expectedStatus, T expectedResult, Class<? extends Throwable>[] expectedExceptions) {
    AtomicReference<CompletableFuture<Response>> futureRef = new AtomicReference<>();
    AtomicReference<ExecutionCompletedEvent<Response>> completedEventRef = new AtomicReference<>();
    Waiter completionListenerWaiter = new Waiter();
    EventListener<ExecutionCompletedEvent<Response>> setCompletedEventFn = e -> {
        completedEventRef.set(e);
        completionListenerWaiter.resume();
    };
    List<Class<? extends Throwable>> expected = new LinkedList<>();
    Class<? extends Throwable>[] expectedExInner = expectedExceptions == null ? new Class[] {} : expectedExceptions;
    Collections.addAll(expected, expectedExInner);
    failsafe.onComplete(setCompletedEventFn);
    Runnable postTestFn = () -> {
        ignoreExceptions(() -> completionListenerWaiter.await(5000));
        ExecutionCompletedEvent<Response> completedEvent = completedEventRef.get();
        if (expectedExceptions == null) {
            assertEquals(completedEvent.getResult().code(), expectedStatus);
            assertNull(completedEvent.getException());
        } else {
            assertNull(completedEvent.getResult());
            assertMatches(completedEvent.getException(), expectedExceptions);
        }
        if (then != null)
            then.accept(futureRef.get(), completedEvent);
    };
    Consumer<Response> assertResult = response -> {
        String result = unwrapExceptions(() -> response.body().string());
        assertEquals(result, expectedResult);
        assertEquals(response.code(), expectedStatus);
    };
    // Run sync test and assert result
    System.out.println("\nRunning sync test");
    FailsafeCall failsafeCall = FailsafeCall.with(failsafe).compose(when);
    if (expectedExceptions == null) {
        assertResult.accept(unwrapExceptions(failsafeCall::execute));
    } else {
        assertThrows(failsafeCall::execute, expectedExceptions);
    }
    postTestFn.run();
    if (expectedExInner.length > 0)
        expected.add(0, ExecutionException.class);
    // Run async test and assert result
    System.out.println("\nRunning async test");
    failsafeCall = failsafeCall.clone();
    CompletableFuture<Response> future = failsafeCall.executeAsync();
    futureRef.set(future);
    if (expectedExInner.length == 0) {
        assertResult.accept(unwrapExceptions(future::get));
    } else {
        assertThrowsSup(future::get, expected);
    }
    postTestFn.run();
}
Also used : FailsafeCall(dev.failsafe.okhttp.FailsafeCall) ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) Request(okhttp3.Request) FailsafeExecutor(dev.failsafe.FailsafeExecutor) Assert.assertNull(org.testng.Assert.assertNull) Assert.assertEquals(org.testng.Assert.assertEquals) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) EventListener(dev.failsafe.event.EventListener) ExecutionException(java.util.concurrent.ExecutionException) Consumer(java.util.function.Consumer) Waiter(net.jodah.concurrentunit.Waiter) List(java.util.List) OkHttpClient(okhttp3.OkHttpClient) Response(okhttp3.Response) Call(okhttp3.Call) LinkedList(java.util.LinkedList) Collections(java.util.Collections) Testing(dev.failsafe.testing.Testing) AtomicReference(java.util.concurrent.atomic.AtomicReference) LinkedList(java.util.LinkedList) ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) Response(okhttp3.Response) CompletableFuture(java.util.concurrent.CompletableFuture) FailsafeCall(dev.failsafe.okhttp.FailsafeCall) Waiter(net.jodah.concurrentunit.Waiter) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with FailsafeExecutor

use of dev.failsafe.FailsafeExecutor in project failsafe by jhalterman.

the class Testing method testGetInternal.

/**
 * This method helps ensure behavior is identical between sync and async executions.
 * <p>
 * Does a .get, .getAsync, .getAsyncExecution, and .getStageAsync against the failsafe, performing pre-test setup and
 * post-test assertion checks. {@code expectedResult} and {@code expectedExceptions} are verified against the returned
 * result or thrown exceptions _and_ the ExecutionCompletedEvent's result and failure.
 *
 * @param given The pre-execution setup to perform. Useful for resetting stats and mocks.
 * @param failsafe The FailsafeExecutor to execute with
 * @param when the Supplier to provide to the FailsafeExecutor
 * @param then post-test Assertions that are provided with Future (if any) and ExecutionCompletedEvent
 * @param expectedResult The expected result to assert against the actual result
 * @param expectedExceptions The expected exceptions to assert against the actual exceptions
 * @param runAsyncExecutions Indicates whether to run the AsyncExecution tests, including .getAsyncExecution. These
 * may be skipped for tests that involve timeouts, which don't work reliably against AsyncExecutions, since those may
 * return immediately.
 */
private static <T> void testGetInternal(boolean runAsyncExecutions, CheckedRunnable given, FailsafeExecutor<T> failsafe, ContextualSupplier<T, T> when, Then<T> then, T expectedResult, Class<? extends Throwable>[] expectedExceptions) {
    AtomicReference<CompletableFuture<T>> futureRef = new AtomicReference<>();
    AtomicReference<ExecutionCompletedEvent<T>> completedEventRef = new AtomicReference<>();
    Waiter completionListenerWaiter = new Waiter();
    EventListener<ExecutionCompletedEvent<T>> setCompletedEventFn = e -> {
        completedEventRef.set(e);
        completionListenerWaiter.resume();
    };
    List<Class<? extends Throwable>> expected = new LinkedList<>();
    Class<? extends Throwable>[] expectedExInner = expectedExceptions == null ? new Class[] {} : expectedExceptions;
    Collections.addAll(expected, expectedExInner);
    // Assert results by treating COMPLETE_SIGNAL as a null expected result
    Consumer<T> resultAssertion = result -> {
        if (result == COMPLETE_SIGNAL)
            assertNull(expectedResult);
        else
            assertEquals(result, expectedResult);
    };
    Runnable postTestFn = () -> {
        ignoreExceptions(() -> completionListenerWaiter.await(5000));
        ExecutionCompletedEvent<T> completedEvent = completedEventRef.get();
        if (expectedExInner.length > 0) {
            assertNull(completedEvent.getResult());
            assertMatches(completedEvent.getException(), Arrays.asList(expectedExInner));
        } else {
            resultAssertion.accept(completedEvent.getResult());
            assertNull(completedEvent.getException());
        }
        if (then != null)
            then.accept(futureRef.get(), completedEvent);
    };
    // Run sync test
    System.out.println("\nRunning sync test");
    if (given != null)
        uncheck(given).run();
    if (expectedExInner.length == 0) {
        resultAssertion.accept(unwrapExceptions(() -> failsafe.onComplete(setCompletedEventFn).get(when)));
    } else {
        assertThrows(() -> failsafe.onComplete(setCompletedEventFn).get(when), t -> {
            // Insert FailsafeException into expected exceptions if needed
            if (t instanceof FailsafeException && !FailsafeException.class.equals(expected.get(0)) && !RuntimeException.class.isAssignableFrom(expected.get(0)))
                return Lists.of(FailsafeException.class, expectedExInner);
            return expected;
        });
    }
    postTestFn.run();
    if (expectedExInner.length > 0)
        expected.add(0, ExecutionException.class);
    // Create async tester
    Consumer<Function<FailsafeExecutor<T>, CompletableFuture<T>>> asyncTester = test -> {
        if (given != null)
            uncheck(given).run();
        CompletableFuture<T> future = test.apply(failsafe.onComplete(setCompletedEventFn));
        futureRef.set(future);
        if (expectedExInner.length == 0)
            resultAssertion.accept(unwrapExceptions(future::get));
        else
            assertThrowsSup(future::get, expected);
        postTestFn.run();
    };
    // Run async test
    System.out.println("\nRunning async test");
    asyncTester.accept(executor -> executor.getAsync(when));
    // Run async execution test
    if (runAsyncExecutions) {
        System.out.println("\nRunning async execution test");
        AsyncRunnable<T> asyncExecutionWhen = exec -> {
            // Run supplier in a different thread
            runInThread(() -> {
                try {
                    T result = when.get(exec);
                    if (result == COMPLETE_SIGNAL)
                        exec.complete();
                    else
                        exec.recordResult(result);
                } catch (Throwable t) {
                    exec.recordException(t);
                }
            });
        };
        asyncTester.accept(executor -> executor.getAsyncExecution(asyncExecutionWhen));
    }
    // Run stage async test
    System.out.println("\nRunning get stage async test");
    ContextualSupplier<T, ? extends CompletionStage<T>> stageAsyncWhen = ctx -> {
        CompletableFuture<T> promise = new CompletableFuture<>();
        // Run supplier in a different thread
        runInThread(() -> {
            try {
                promise.complete(when.get(ctx));
            } catch (Throwable t) {
                promise.completeExceptionally(t);
            }
        });
        return promise;
    };
    asyncTester.accept(executor -> executor.getStageAsync(stageAsyncWhen));
}
Also used : Lists(dev.failsafe.internal.util.Lists) ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) Arrays(java.util.Arrays) FailsafeExecutor(dev.failsafe.FailsafeExecutor) Assert.assertNull(org.testng.Assert.assertNull) java.util.concurrent(java.util.concurrent) InternalTesting(dev.failsafe.internal.InternalTesting) Assert.assertEquals(org.testng.Assert.assertEquals) FailsafeException(dev.failsafe.FailsafeException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) EventListener(dev.failsafe.event.EventListener) Consumer(java.util.function.Consumer) Waiter(net.jodah.concurrentunit.Waiter) List(java.util.List) RetryPolicy(dev.failsafe.RetryPolicy) LinkedList(java.util.LinkedList) Collections(java.util.Collections) dev.failsafe.function(dev.failsafe.function) FailsafeException(dev.failsafe.FailsafeException) AtomicReference(java.util.concurrent.atomic.AtomicReference) LinkedList(java.util.LinkedList) ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) Function(java.util.function.Function) Waiter(net.jodah.concurrentunit.Waiter)

Example 3 with FailsafeExecutor

use of dev.failsafe.FailsafeExecutor in project failsafe by jhalterman.

the class RetrofitTesting method test.

private <T> void test(FailsafeExecutor<Response<T>> failsafe, Call<T> when, Then<Response<T>> then, int expectedStatus, T expectedResult, Class<? extends Throwable>[] expectedExceptions) {
    AtomicReference<CompletableFuture<Response<T>>> futureRef = new AtomicReference<>();
    AtomicReference<ExecutionCompletedEvent<Response<T>>> completedEventRef = new AtomicReference<>();
    Waiter completionListenerWaiter = new Waiter();
    EventListener<ExecutionCompletedEvent<Response<T>>> setCompletedEventFn = e -> {
        completedEventRef.set(e);
        completionListenerWaiter.resume();
    };
    List<Class<? extends Throwable>> expected = new LinkedList<>();
    Class<? extends Throwable>[] expectedExInner = expectedExceptions == null ? new Class[] {} : expectedExceptions;
    Collections.addAll(expected, expectedExInner);
    failsafe.onComplete(setCompletedEventFn);
    Runnable postTestFn = () -> {
        ignoreExceptions(() -> completionListenerWaiter.await(5000));
        ExecutionCompletedEvent<Response<T>> completedEvent = completedEventRef.get();
        if (expectedExceptions == null) {
            assertEquals(completedEvent.getResult().code(), expectedStatus);
            assertNull(completedEvent.getException());
        } else {
            assertNull(completedEvent.getResult());
            assertMatches(completedEvent.getException(), expectedExceptions);
        }
        if (then != null)
            then.accept(futureRef.get(), completedEvent);
    };
    Consumer<Response<T>> assertResult = response -> {
        T result = unwrapExceptions(response::body);
        assertEquals(result, expectedResult);
        assertEquals(response.code(), expectedStatus);
    };
    // Run sync test and assert result
    System.out.println("\nRunning sync test");
    FailsafeCall<T> failsafeCall = FailsafeCall.with(failsafe).compose(when);
    if (expectedExceptions == null) {
        assertResult.accept(unwrapExceptions(failsafeCall::execute));
    } else {
        assertThrows(failsafeCall::execute, expectedExceptions);
    }
    postTestFn.run();
    if (expectedExInner.length > 0)
        expected.add(0, ExecutionException.class);
    // Run async test and assert result
    System.out.println("\nRunning async test");
    failsafeCall = failsafeCall.clone();
    CompletableFuture<Response<T>> future = failsafeCall.executeAsync();
    futureRef.set(future);
    if (expectedExInner.length == 0) {
        assertResult.accept(unwrapExceptions(future::get));
    } else {
        assertThrowsSup(future::get, expected);
    }
    postTestFn.run();
}
Also used : ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) FailsafeExecutor(dev.failsafe.FailsafeExecutor) Assert.assertNull(org.testng.Assert.assertNull) Assert.assertEquals(org.testng.Assert.assertEquals) CompletableFuture(java.util.concurrent.CompletableFuture) Response(retrofit2.Response) AtomicReference(java.util.concurrent.atomic.AtomicReference) EventListener(dev.failsafe.event.EventListener) ExecutionException(java.util.concurrent.ExecutionException) Consumer(java.util.function.Consumer) FailsafeCall(dev.failsafe.retrofit.FailsafeCall) Waiter(net.jodah.concurrentunit.Waiter) List(java.util.List) LinkedList(java.util.LinkedList) Call(retrofit2.Call) Collections(java.util.Collections) Testing(dev.failsafe.testing.Testing) AtomicReference(java.util.concurrent.atomic.AtomicReference) LinkedList(java.util.LinkedList) ExecutionCompletedEvent(dev.failsafe.event.ExecutionCompletedEvent) Response(retrofit2.Response) CompletableFuture(java.util.concurrent.CompletableFuture) Waiter(net.jodah.concurrentunit.Waiter) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with FailsafeExecutor

use of dev.failsafe.FailsafeExecutor in project failsafe by jhalterman.

the class NoPolicyTest method testWithNoPolicy.

public void testWithNoPolicy() {
    AtomicInteger successCounter = new AtomicInteger();
    AtomicInteger failureCounter = new AtomicInteger();
    FailsafeExecutor<Object> failsafe = Failsafe.none().onFailure(e -> {
        System.out.println("Failure");
        failureCounter.incrementAndGet();
    }).onSuccess(e -> {
        System.out.println("Success");
        successCounter.incrementAndGet();
    });
    // Test success
    testGetSuccess(() -> {
        successCounter.set(0);
        failureCounter.set(0);
    }, failsafe, ctx -> {
        return "success";
    }, (f, e) -> {
        assertEquals(e.getAttemptCount(), 1);
        assertEquals(e.getExecutionCount(), 1);
        assertEquals(successCounter.get(), 1);
        assertEquals(failureCounter.get(), 0);
    }, "success");
    // Test failure
    testRunFailure(() -> {
        successCounter.set(0);
        failureCounter.set(0);
    }, failsafe, ctx -> {
        throw new IllegalStateException();
    }, (f, e) -> {
        assertEquals(e.getAttemptCount(), 1);
        assertEquals(e.getExecutionCount(), 1);
        assertEquals(successCounter.get(), 0);
        assertEquals(failureCounter.get(), 1);
    }, IllegalStateException.class);
}
Also used : FailsafeExecutor(dev.failsafe.FailsafeExecutor) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Assert.assertEquals(org.testng.Assert.assertEquals) Failsafe(dev.failsafe.Failsafe) Test(org.testng.annotations.Test) Testing(dev.failsafe.testing.Testing) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Aggregations

FailsafeExecutor (dev.failsafe.FailsafeExecutor)4 Assert.assertEquals (org.testng.Assert.assertEquals)4 EventListener (dev.failsafe.event.EventListener)3 ExecutionCompletedEvent (dev.failsafe.event.ExecutionCompletedEvent)3 Testing (dev.failsafe.testing.Testing)3 Collections (java.util.Collections)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 Consumer (java.util.function.Consumer)3 Waiter (net.jodah.concurrentunit.Waiter)3 Assert.assertNull (org.testng.Assert.assertNull)3 CompletableFuture (java.util.concurrent.CompletableFuture)2 ExecutionException (java.util.concurrent.ExecutionException)2 Function (java.util.function.Function)2 Failsafe (dev.failsafe.Failsafe)1 FailsafeException (dev.failsafe.FailsafeException)1 RetryPolicy (dev.failsafe.RetryPolicy)1 dev.failsafe.function (dev.failsafe.function)1 InternalTesting (dev.failsafe.internal.InternalTesting)1