@Override public List<ContainerName> ps() throws IOException, InterruptedException { return retryer.runWithRetries(super::ps); } }
@Override public List<ContainerName> ps() throws IOException, InterruptedException { return retryer.runWithRetries(super::ps); } }
@Override public List<ContainerName> ps() throws IOException, InterruptedException { return retryer.runWithRetries(super::ps); } }
@Override public void up() throws IOException, InterruptedException { retryer.<Void>runWithRetries(() -> { super.up(); return null; }); }
@Override public void up() throws IOException, InterruptedException { retryer.<Void>runWithRetries(() -> { super.up(); return null; }); }
@Override public void up() throws IOException, InterruptedException { retryer.<Void>runWithRetries(() -> { super.up(); return null; }); }
private void verifyRetryerWasNotUsed() throws IOException, InterruptedException { verify(retryer, times(0)).runWithRetries(anyOperation()); }
private void verifyRetryerWasUsed() throws IOException, InterruptedException { verify(retryer).runWithRetries(anyOperation()); }
private void retryerJustCallsOperation() throws IOException, InterruptedException { when(retryer.runWithRetries(anyOperation())).thenAnswer(invocation -> { Retryer.RetryableDockerOperation<?> operation = (Retryer.RetryableDockerOperation<?>) invocation.getArguments()[0]; return operation.call(); }); }
@Test public void not_retry_if_the_operation_was_successful_and_return_result() throws Exception { when(operation.call()).thenReturn("hi"); assertThat(retryer.runWithRetries(operation), is("hi")); verify(operation).call(); }
@Test public void retryer_should_wait_after_failure_before_trying_again() throws Exception { Retryer timeRetryer = new Retryer(1, Duration.millis(100)); Stopwatch stopwatch = Stopwatch.createStarted(); when(operation.call()).thenThrow(new DockerExecutionException()).thenAnswer(i -> { assertThat(stopwatch.elapsed(TimeUnit.MILLISECONDS), greaterThan(100L)); return "success"; }); String result = timeRetryer.runWithRetries(operation); assertThat(result, is("success")); }
@Test public void retry_the_operation_if_it_failed_once_and_return_the_result_of_the_next_successful_call() throws Exception { when(operation.call()).thenAnswer(MockitoMultiAnswer.<String>of( firstInvocation -> { throw new DockerExecutionException(); }, secondInvocation -> "hola" )); assertThat(retryer.runWithRetries(operation), is("hola")); verify(operation, times(2)).call(); }
@Test public void should_not_pause_after_last_failure() throws Exception { Retryer failFast = new Retryer(0, Duration.standardSeconds(1)); when(operation.call()).thenThrow(new DockerExecutionException()); Stopwatch stopwatch = Stopwatch.createStarted(); try { failFast.runWithRetries(operation); } catch (DockerExecutionException e) { // expected } assertThat(stopwatch.elapsed(TimeUnit.MILLISECONDS), lessThan(1000L)); }
@Test public void throw_the_last_exception_when_the_operation_fails_more_times_than_the_number_of_specified_retry_attempts() throws Exception { DockerExecutionException finalException = new DockerExecutionException(); when(operation.call()).thenAnswer(MockitoMultiAnswer.<String>of( firstInvocation -> { throw new DockerExecutionException(); }, secondInvocation -> { throw finalException; } )); try { retryer.runWithRetries(operation); fail("Should have caught exception"); } catch (DockerExecutionException actualException) { assertThat(actualException, is(finalException)); } verify(operation, times(2)).call(); } }