### Question:
GenericRetryExecution implements RetryExecution { public Optional<Long> nextDelay() { if (lastAttemptIndex == 0) { lastAttemptIndex++; return Optional.of(0L); } if (genericRetry.getMaxAttempts() > -1 && lastAttemptIndex >= genericRetry.getMaxAttempts()) { return Optional.empty(); } if (lastAttemptIndex > 1) { currentInterval = (long) (currentInterval * genericRetry.getIntervalMultiplier()); if (genericRetry.getMaxInterval() > -1 && currentInterval > genericRetry.getMaxInterval()) { currentInterval = genericRetry.getMaxInterval(); } } lastAttemptIndex++; return Optional.of(currentInterval); } GenericRetryExecution(GenericRetry genericRetry); Optional<Long> nextDelay(); @Override boolean isLastExecution();  }### Answer:
@Test public void forFirstBackOffAlwaysReturnsZero() { assertThat(getDefaultRetryExecution().nextDelay().get()).isEqualTo(0); }
@Test public void delayIsMultipliedEveryNextDelayCall() { RetryExecution retryExecution = getDefaultRetryExecution(); Optional<Long> res = callNextDelayNTimes(retryExecution, 2); assertThat(res.get()).isEqualTo(DEFAULT_INITIAL_INTERVAL); res = retryExecution.nextDelay(); assertThat(res.get()).isEqualTo((long) (DEFAULT_INITIAL_INTERVAL * DEFAULT_MULTIPLIER)); res = retryExecution.nextDelay(); assertThat(res.get()).isEqualTo((long) (DEFAULT_INITIAL_INTERVAL * DEFAULT_MULTIPLIER * DEFAULT_MULTIPLIER)); }
@Test public void noNextDelayIfMaxAttemptLimitReached() { RetryExecution retryExecution = GenericRetry.defaultLimitedExponentialRetry().setMaxAttempts(3).initExecution(); Optional<Long> res = callNextDelayNTimes(retryExecution, 3); assertThat(res).isNotEmpty(); res = retryExecution.nextDelay(); assertThat(res).isEmpty(); }
@Test public void supportsNoRetry() { RetryExecution retryExecution = GenericRetry.noRetry().initExecution(); assertThat(retryExecution.nextDelay().get()).isZero(); assertThat(retryExecution.nextDelay()).isEmpty(); }