### Question:
RetryStrategies { public static BiIntFunction<Throwable, Completable> retryWithExponentialBackoff( final int maxRetries, final Predicate<Throwable> causeFilter, final Duration initialDelay, final Executor timerExecutor) { checkMaxRetries(maxRetries); requireNonNull(timerExecutor); requireNonNull(causeFilter); final long initialDelayNanos = initialDelay.toNanos(); return (retryCount, cause) -> { if (retryCount > maxRetries || !causeFilter.test(cause)) { return failed(cause); } return timerExecutor.timer(initialDelayNanos << (retryCount - 1), NANOSECONDS); }; } private  RetryStrategies(); static BiIntFunction<Throwable, Completable> retryWithConstantBackoff(final int maxRetries,
                                                                                 final Predicate<Throwable> causeFilter,
                                                                                 final Duration delay,
                                                                                 final Executor timerExecutor); static BiIntFunction<Throwable, Completable> retryWithConstantBackoffAndJitter(
            final int maxRetries,
            final Predicate<Throwable> causeFilter,
            final Duration delay,
            final Executor timerExecutor); static BiIntFunction<Throwable, Completable> retryWithExponentialBackoff(
            final int maxRetries,
            final Predicate<Throwable> causeFilter,
            final Duration initialDelay,
            final Executor timerExecutor); static BiIntFunction<Throwable, Completable> retryWithExponentialBackoffAndJitter(
            final int maxRetries,
            final Predicate<Throwable> causeFilter,
            final Duration initialDelay,
            final Executor timerExecutor);  }### Answer:
@Test public void testBackoffMaxRetries() throws Exception { Duration backoff = ofSeconds(1); testMaxRetries(retryWithExponentialBackoff(1, cause -> true, backoff, timerExecutor), backoff); }
@Test public void testExpBackoff() throws Exception { Duration initialDelay = ofSeconds(1); RetryStrategy strategy = new RetryStrategy(retryWithExponentialBackoff(2, cause -> true, initialDelay, timerExecutor)); LegacyMockedCompletableListenerRule signalListener = strategy.invokeAndListen(DELIBERATE_EXCEPTION); verify(timerExecutor).timer(initialDelay.toNanos(), NANOSECONDS); timers.take().verifyListenCalled().onComplete(); signalListener.verifyCompletion(); verifyNoMoreInteractions(timerExecutor); signalListener = strategy.invokeAndListen(DELIBERATE_EXCEPTION); verify(timerExecutor).timer(initialDelay.toNanos() << 1, NANOSECONDS); timers.take().verifyListenCalled().onComplete(); signalListener.verifyCompletion(); verifyNoMoreInteractions(timerExecutor); }
@Test public void testExpBackoffMaxRetries() throws Exception { Duration backoff = ofSeconds(1); testMaxRetries(retryWithExponentialBackoff(1, cause -> true, backoff, timerExecutor), backoff); }
@Test public void testExpBackoffCauseFilter() { testCauseFilter(retryWithExponentialBackoff(1, cause -> cause instanceof IllegalStateException, ofSeconds(1), timerExecutor)); }