diff --git a/core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java b/core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java index 29f5a64b6df..6096e745e36 100644 --- a/core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java +++ b/core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java @@ -39,11 +39,7 @@ public class HttpWaitStrategy extends AbstractWaitStrategy { private String username; private String password; private Predicate responsePredicate; - private Predicate statusCodePredicate = responseCode -> { - // If we did not provide any status code, we assume by default HttpURLConnection.HTTP_OK - if (statusCodes.isEmpty() && HttpURLConnection.HTTP_OK == responseCode) return true; - return statusCodes.contains(responseCode); - }; + private Predicate statusCodePredicate = null; private Optional livenessPort = Optional.empty(); /** @@ -63,7 +59,7 @@ public HttpWaitStrategy forStatusCode(int statusCode) { * @return this */ public HttpWaitStrategy forStatusCodeMatching(Predicate statusCodePredicate) { - this.statusCodePredicate = this.statusCodePredicate.or(statusCodePredicate); + this.statusCodePredicate = statusCodePredicate; return this; } @@ -159,7 +155,22 @@ protected void waitUntilReady() { log.trace("Get response code {}", connection.getResponseCode()); - if (!statusCodePredicate.test(connection.getResponseCode())) { + // Choose the statusCodePredicate strategy depending on what we defined. + Predicate predicate; + if (statusCodes.isEmpty() && statusCodePredicate == null) { + // We have no status code and no predicate so we expect a 200 OK response code + predicate = responseCode -> HttpURLConnection.HTTP_OK == responseCode; + } else if (!statusCodes.isEmpty() && statusCodePredicate == null) { + // We use the default status predicate checker when we only have status codes + predicate = responseCode -> statusCodes.contains(responseCode); + } else if (statusCodes.isEmpty()) { + // We only have a predicate + predicate = statusCodePredicate; + } else { + // We have both predicate and status code + predicate = statusCodePredicate.or(responseCode -> statusCodes.contains(responseCode)); + } + if (!predicate.test(connection.getResponseCode())) { throw new RuntimeException(String.format("HTTP response code was: %s", connection.getResponseCode())); } diff --git a/core/src/test/java/org/testcontainers/junit/wait/strategy/HttpWaitStrategyTest.java b/core/src/test/java/org/testcontainers/junit/wait/strategy/HttpWaitStrategyTest.java index 65a693f514f..5820333245a 100644 --- a/core/src/test/java/org/testcontainers/junit/wait/strategy/HttpWaitStrategyTest.java +++ b/core/src/test/java/org/testcontainers/junit/wait/strategy/HttpWaitStrategyTest.java @@ -84,6 +84,21 @@ public void testWaitUntilReadyWithTimeoutAndWithManyStatusCodesAndLambda() { )); } + /** + * Expects that the WaitStrategy throws a {@link RetryCountExceededException} after not receiving any of the + * error code defined with {@link HttpWaitStrategy#forStatusCode(int)} + * and {@link HttpWaitStrategy#forStatusCodeMatching(Predicate)}. Note that a 200 status code should not + * be considered as a successful return as not explicitly set. + * Test case for: https://github.com/testcontainers/testcontainers-java/issues/880 + */ + @Test + public void testWaitUntilReadyWithTimeoutAndWithLambdaShouldNotMatchOk() { + waitUntilReadyAndTimeout(startContainerWithCommand(createShellCommand("200 OK", GOOD_RESPONSE_BODY), + createHttpWaitStrategy(ready) + .forStatusCodeMatching(it -> it >= 300) + )); + } + /** * Expects that the WaitStrategy throws a {@link RetryCountExceededException} after not receiving an HTTP 200 * response from the container within the timeout period.