From 5e8198530839dd48652af7268a1f34d379701c63 Mon Sep 17 00:00:00 2001 From: Pranav-b-7 Date: Thu, 1 Feb 2024 16:47:18 +0530 Subject: [PATCH] test(keel): demonstrate behavior of ImportDeliveryConfigTask on http errors and network errors Test cases added to verify the upcoming changes when KeelService is configured with SpinnakerRetrofitErrorHandler. These tests verifies the behaviour of the method handleRetryableFailures() when 4xx with empty error body and 5xx http erros are thrown, and also during network errors. NOTE : These tests only verifies the scenario when the error response body is empty/null, and network errors. --- .../task/ImportDeliveryConfigTaskTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/orca-keel/src/test/java/com/netflix/spinnaker/orca/keel/task/ImportDeliveryConfigTaskTest.java b/orca-keel/src/test/java/com/netflix/spinnaker/orca/keel/task/ImportDeliveryConfigTaskTest.java index 90d3fc3f379..1e71a7764b3 100644 --- a/orca-keel/src/test/java/com/netflix/spinnaker/orca/keel/task/ImportDeliveryConfigTaskTest.java +++ b/orca-keel/src/test/java/com/netflix/spinnaker/orca/keel/task/ImportDeliveryConfigTaskTest.java @@ -46,6 +46,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.junit.jupiter.api.BeforeAll; @@ -191,6 +192,81 @@ public void verifyTaskResultReturnsSpringHttpErrorWhenTimestampIsInNanos() .isNotEqualTo(expectedHttpErrorBody.getTimestamp().getNano()); } + @Test + public void testTaskResultWhenErrorBodyIsEmpty() { + + String expectedMessage = + String.format( + "Non-retryable HTTP response %s received from downstream service: %s", + HttpStatus.BAD_REQUEST.value(), + "HTTP 400 " + wireMock.baseUrl() + "/delivery-configs/: 400 Bad Request"); + + var errorMap = new HashMap<>(); + errorMap.put("message", expectedMessage); + + TaskResult terminal = + TaskResult.builder(ExecutionStatus.TERMINAL).context(Map.of("error", errorMap)).build(); + + // Simulate any 4xx http error with empty error response body + String emptyBody = ""; + simulateFault("/delivery-configs/", emptyBody, HttpStatus.BAD_REQUEST); + + getDeliveryConfigManifest(); + + var result = importDeliveryConfigTask.execute(stage); + + verifyGetDeliveryConfigManifestInvocations(); + + assertThat(result).isEqualTo(terminal); + } + + @Test + public void testTaskResultWhenHttp5xxErrorIsThrown() { + + contextMap.put("attempt", (Integer) contextMap.get("attempt") + 1); + contextMap.put( + "errorFromLastAttempt", + "Retryable HTTP response 500 received from downstream service: HTTP 500 " + + wireMock.baseUrl() + + "/delivery-configs/: 500 Server Error"); + + TaskResult running = TaskResult.builder(ExecutionStatus.RUNNING).context(contextMap).build(); + + // Simulate any 5xx http error with empty error response body + String emptyBody = ""; + simulateFault("/delivery-configs/", emptyBody, HttpStatus.INTERNAL_SERVER_ERROR); + + getDeliveryConfigManifest(); + + var result = importDeliveryConfigTask.execute(stage); + + verifyGetDeliveryConfigManifestInvocations(); + + assertThat(result).isEqualTo(running); + } + + @Test + public void testTaskResultWhenAPIFailsWithNetworkError() { + + contextMap.put("attempt", (Integer) contextMap.get("attempt") + 1); + contextMap.put( + "errorFromLastAttempt", + String.format( + "Network error talking to downstream service, attempt 1 of %s: Connection reset: Connection reset", + contextMap.get("maxRetries"))); + + TaskResult running = TaskResult.builder(ExecutionStatus.RUNNING).context(contextMap).build(); + + // Simulate network failure + simulateFault("/delivery-configs/", Fault.CONNECTION_RESET_BY_PEER); + + getDeliveryConfigManifest(); + + var result = importDeliveryConfigTask.execute(stage); + + assertThat(result).isEqualTo(running); + } + private Map getTaskResult(HttpStatus httpStatus, ChronoUnit unit) throws JsonProcessingException {