/* * Copyright 2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package net.jodah.failsafe; import static net.jodah.failsafe.Testing.failures; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.net.ConnectException; import java.util.List; import java.util.concurrent.TimeUnit; import org.testng.annotations.Test; /** * @author Jonathan Halterman */ @Test public class ExecutionTest { ConnectException e = new ConnectException(); public void testCanRetryForResult() { // Given retry for null Execution exec = new Execution(new RetryPolicy().retryWhen(null)); // When / Then assertFalse(exec.complete(null)); assertTrue(exec.canRetryFor(null)); assertFalse(exec.canRetryFor(1)); // Then assertEquals(exec.getExecutions(), 3); assertTrue(exec.isComplete()); assertEquals(exec.getLastResult(), Integer.valueOf(1)); assertNull(exec.getLastFailure()); // Given 2 max retries exec = new Execution(new RetryPolicy().retryWhen(null).withMaxRetries(2)); // When / Then assertFalse(exec.complete(null)); assertTrue(exec.canRetryFor(null)); assertFalse(exec.canRetryFor(null)); // Then assertEquals(exec.getExecutions(), 3); assertTrue(exec.isComplete()); assertNull(exec.getLastResult()); assertNull(exec.getLastFailure()); } public void testCanRetryForResultAndThrowable() { // Given retry for null Execution exec = new Execution(new RetryPolicy().retryWhen(null)); // When / Then assertFalse(exec.complete(null)); assertTrue(exec.canRetryFor(null, null)); assertTrue(exec.canRetryFor(1, new IllegalArgumentException())); assertFalse(exec.canRetryFor(1, null)); // Then assertEquals(exec.getExecutions(), 4); assertTrue(exec.isComplete()); // Given 2 max retries exec = new Execution(new RetryPolicy().retryWhen(null).withMaxRetries(2)); // When / Then assertFalse(exec.complete(null)); assertTrue(exec.canRetryFor(null, e)); assertFalse(exec.canRetryFor(null, e)); // Then assertEquals(exec.getExecutions(), 3); assertTrue(exec.isComplete()); } public void testCanRetryOn() { // Given retry on IllegalArgumentException Execution exec = new Execution(new RetryPolicy().retryOn(IllegalArgumentException.class)); // When / Then assertTrue(exec.canRetryOn(new IllegalArgumentException())); assertFalse(exec.canRetryOn(e)); // Then assertEquals(exec.getExecutions(), 2); assertTrue(exec.isComplete()); assertNull(exec.getLastResult()); assertEquals(exec.getLastFailure(), e); // Given 2 max retries exec = new Execution(new RetryPolicy().withMaxRetries(2)); // When / Then assertTrue(exec.canRetryOn(e)); assertTrue(exec.canRetryOn(e)); assertFalse(exec.canRetryOn(e)); // Then assertEquals(exec.getExecutions(), 3); assertTrue(exec.isComplete()); assertNull(exec.getLastResult()); assertEquals(exec.getLastFailure(), e); } public void testComplete() { // Given Execution exec = new Execution(new RetryPolicy()); // When exec.complete(); // Then assertEquals(exec.getExecutions(), 1); assertTrue(exec.isComplete()); assertNull(exec.getLastResult()); assertNull(exec.getLastFailure()); } public void testCompleteForResult() { // Given Execution exec = new Execution(new RetryPolicy().retryWhen(null)); // When / Then assertFalse(exec.complete(null)); assertTrue(exec.complete(true)); // Then assertEquals(exec.getExecutions(), 2); assertTrue(exec.isComplete()); assertEquals(exec.getLastResult(), Boolean.TRUE); assertNull(exec.getLastFailure()); } public void testGetAttemptCount() { Execution exec = new Execution(new RetryPolicy()); exec.recordFailure(e); exec.recordFailure(e); assertEquals(exec.getExecutions(), 2); } public void testGetElapsedMillis() throws Throwable { Execution exec = new Execution(new RetryPolicy()); assertTrue(exec.getElapsedTime().toMillis() < 100); Thread.sleep(150); assertTrue(exec.getElapsedTime().toMillis() > 100); } @SuppressWarnings("unchecked") public void testIsComplete() { List<Object> list = mock(List.class); when(list.size()).thenThrow(failures(2, new IllegalStateException())).thenReturn(5); RetryPolicy retryPolicy = new RetryPolicy().retryOn(IllegalStateException.class); Execution exec = new Execution(retryPolicy); while (!exec.isComplete()) { try { exec.complete(list.size()); } catch (IllegalStateException e) { exec.recordFailure(e); } } assertEquals(exec.getLastResult(), Integer.valueOf(5)); assertEquals(exec.getExecutions(), 3); } public void shouldAdjustWaitTimeForBackoff() { Execution exec = new Execution(new RetryPolicy().withBackoff(1, 10, TimeUnit.NANOSECONDS)); assertEquals(exec.getWaitTime().toNanos(), 1); exec.recordFailure(e); assertEquals(exec.getWaitTime().toNanos(), 2); exec.recordFailure(e); assertEquals(exec.getWaitTime().toNanos(), 4); exec.recordFailure(e); assertEquals(exec.getWaitTime().toNanos(), 8); exec.recordFailure(e); assertEquals(exec.getWaitTime().toNanos(), 10); exec.recordFailure(e); assertEquals(exec.getWaitTime().toNanos(), 10); } public void shouldAdjustWaitTimeForMaxDuration() throws Throwable { Execution exec = new Execution( new RetryPolicy().withDelay(49, TimeUnit.MILLISECONDS).withMaxDuration(50, TimeUnit.MILLISECONDS)); Thread.sleep(10); assertTrue(exec.canRetryOn(e)); assertTrue(exec.getWaitTime().toNanos() < TimeUnit.MILLISECONDS.toNanos(50) && exec.getWaitTime().toNanos() > 0); } public void shouldSupportMaxDuration() throws Exception { Execution exec = new Execution(new RetryPolicy().withMaxDuration(100, TimeUnit.MILLISECONDS)); assertTrue(exec.canRetryOn(e)); assertTrue(exec.canRetryOn(e)); Thread.sleep(105); assertFalse(exec.canRetryOn(e)); assertTrue(exec.isComplete()); } public void shouldSupportMaxRetries() throws Exception { Execution exec = new Execution(new RetryPolicy().withMaxRetries(3)); assertTrue(exec.canRetryOn(e)); assertTrue(exec.canRetryOn(e)); assertTrue(exec.canRetryOn(e)); assertFalse(exec.canRetryOn(e)); assertTrue(exec.isComplete()); } public void shouldGetWaitMillis() throws Throwable { Execution exec = new Execution(new RetryPolicy().withDelay(100, TimeUnit.MILLISECONDS) .withMaxDuration(101, TimeUnit.MILLISECONDS) .retryWhen(null)); assertEquals(exec.getWaitTime().toMillis(), 100); exec.canRetryFor(null); assertTrue(exec.getWaitTime().toMillis() <= 100); Thread.sleep(150); assertFalse(exec.canRetryFor(null)); assertEquals(exec.getWaitTime().toMillis(), 0); } @Test(expectedExceptions = IllegalStateException.class) public void shouldThrowOnMultipleCompletes() { Execution exec = new Execution(new RetryPolicy()); exec.complete(); exec.complete(); } @Test(expectedExceptions = IllegalStateException.class) public void shouldThrowOnCanRetryWhenAlreadyComplete() { Execution exec = new Execution(new RetryPolicy()); exec.complete(); exec.canRetryOn(e); } }