### Question:
RetryHelper { public static <V> V runWithRetries(Callable<V> callable) throws RetryHelperException { return runWithRetries(callable, RetryParams.getDefaultInstance(), ExceptionHandler.getDefaultInstance()); } @VisibleForTesting  RetryHelper(Callable<V> callable, RetryParams params, ExceptionHandler exceptionHandler,
      Stopwatch stopwatch); @Override String toString(); static V runWithRetries(Callable<V> callable); static V runWithRetries(Callable<V> callable, RetryParams params,
      ExceptionHandler exceptionHandler);  }### Answer:
@Test public void testTriesNoMoreThanMaxTimes() { final int maxAttempts = 10; RetryParams params = new RetryParams.Builder().initialRetryDelayMillis(0) .totalRetryPeriodMillis(60000) .retryMinAttempts(0) .retryMaxAttempts(maxAttempts) .build(); final AtomicInteger timesCalled = new AtomicInteger(0); try { RetryHelper.runWithRetries(callable(new Runnable() { @Override public void run() { if (timesCalled.incrementAndGet() <= maxAttempts) { throw new RuntimeException(); } fail("Body was executed too many times: " + timesCalled.get()); } }), params, new ExceptionHandler.Builder().retryOn(RuntimeException.class).build()); fail("Should not have succeeded, expected all attempts to fail and give up."); } catch (RetriesExhaustedException expected) { assertEquals(maxAttempts, timesCalled.get()); } }
@Test public void testTriesNoMoreLongerThanTotalRetryPeriod() { final FakeTicker ticker = new FakeTicker(); Stopwatch stopwatch = Stopwatch.createUnstarted(ticker); RetryParams params = new RetryParams.Builder().initialRetryDelayMillis(0) .totalRetryPeriodMillis(999) .retryMinAttempts(5) .retryMaxAttempts(10) .build(); ExceptionHandler handler = new ExceptionHandler.Builder().retryOn(RuntimeException.class).build(); final int sleepOnAttempt = 8; final AtomicInteger timesCalled = new AtomicInteger(0); try { RetryHelper.runWithRetries(callable(new Runnable() { @Override public void run() { timesCalled.incrementAndGet(); if (timesCalled.get() == sleepOnAttempt) { ticker.advance(1000, TimeUnit.MILLISECONDS); } throw new RuntimeException(); } }), params, handler, stopwatch); fail(); } catch (RetriesExhaustedException e) { assertEquals(sleepOnAttempt, timesCalled.get()); } }