### Question:
RetryableExecutor implements Executor<T> { @Override public T execute() { logger.debug("Initializing retry"); RetryPolicy<Object> policy = new RetryPolicy<>(); if (retryableExceptions != null && retryableExceptions.size() > 0) { policy.handle(retryableExceptions); } if (nonRetryableExceptions != null && nonRetryableExceptions.size() > 0) { policy.abortOn(nonRetryableExceptions); } policy = policy.withMaxRetries(maxRetries); return Failsafe .with(policy) .onFailure(executionCompletedEvent -> { currentRetry++; logger.error("Retrying Operation {} :", currentRetry, executionCompletedEvent.getFailure()); }) .get((() -> { logger.debug("Running Operation - Attempt: {}", currentRetry); return executor.execute(); })); } RetryableExecutor(
        Executor<T> executor,
        int maxRetries);  RetryableExecutor(
        Executor<T> executor,
        int maxRetries,
        List<Class<? extends Throwable>> retryableExceptions);  RetryableExecutor(
        Executor<T> operationPerformer,
        int maxRetries,
        List<Class<? extends Throwable>> retryableExceptions,
        List<Class<? extends Throwable>> nonRetryableExceptions); @Override T execute();  }### Answer:
@Test(dataProvider = "retriesTestProvider") public void testRetries(Exception exceptionToThrow, final int exceptionCount, final int maxRetries, final int expectedAttemptCount) { setupTest(exceptionToThrow, exceptionCount, maxRetries, null, null); try { retryableExecutor.execute(); if(exceptionCount > maxRetries) { Assert.fail("Expected " + exceptionToThrow.getClass() + " exception."); } } catch(Exception ex) { Assert.assertEquals(ex, exceptionToThrow); } Assert.assertEquals(testExecutor.getAttemptCount(), expectedAttemptCount); }
@Test(dataProvider = "retriesExceptionRuleTestProvider") public void testExceptionRuleRetries(Exception exceptionToThrow, Class retryableExceptionClass, Class nonRetryableExceptionClass) { final int MAX_RETRIES = 1; int expectedAttempts = exceptionToThrow.getClass() == nonRetryableExceptionClass ? 1 : 2; setupTest(exceptionToThrow, 1, MAX_RETRIES, Collections.singletonList(retryableExceptionClass), Collections.singletonList(nonRetryableExceptionClass)); try { retryableExecutor.execute(); } catch(Exception ex) { Assert.assertEquals(ex, exceptionToThrow); } Assert.assertEquals(testExecutor.getAttemptCount(), expectedAttempts); }