diff --git a/src/main/java/org/wiremock/integrations/testcontainers/WireMockContainer.java b/src/main/java/org/wiremock/integrations/testcontainers/WireMockContainer.java index 5c96d65..9217ad7 100644 --- a/src/main/java/org/wiremock/integrations/testcontainers/WireMockContainer.java +++ b/src/main/java/org/wiremock/integrations/testcontainers/WireMockContainer.java @@ -15,14 +15,20 @@ */ package org.wiremock.integrations.testcontainers; +import com.github.dockerjava.api.DockerClient; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy; +import org.testcontainers.containers.startupcheck.StartupCheckStrategy; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.images.builder.Transferable; +import org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.testcontainers.shaded.com.google.common.io.Resources; import org.testcontainers.utility.ComparableVersion; import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; import java.io.File; import java.io.IOException; @@ -57,8 +63,9 @@ public class WireMockContainer extends GenericContainer { private static final String FILES_DIR = "/home/wiremock/__files/"; private static final String EXTENSIONS_DIR = "/var/wiremock/extensions/"; + private static final String MAPPINGS_ENDPOINT = "/__admin/mappings"; private static final WaitStrategy DEFAULT_WAITER = Wait - .forHttp("/__admin/mappings") + .forHttp(MAPPINGS_ENDPOINT) .withMethod("GET") .forStatusCode(200); private static final int PORT = 8080; @@ -92,6 +99,7 @@ public WireMockContainer(DockerImageName dockerImage) { wireMockArgs = new StringBuilder(); setWaitStrategy(DEFAULT_WAITER); + setStartupCheckStrategy(new WireMockStartupStrategy()); } /** @@ -284,4 +292,34 @@ public Extension(String id) { this.id = id; } } + + private final class WireMockStartupStrategy extends IsRunningStartupCheckStrategy { + + @Override + public StartupStatus checkStartupState(DockerClient dockerClient, String containerId) { + StartupStatus dockerInspectStatus = super.checkStartupState(dockerClient, containerId); + if (dockerInspectStatus != StartupStatus.SUCCESSFUL) { + return dockerInspectStatus; + } + + // Poll WireMock mappings + final String url = WireMockContainer.this.getUrl(MAPPINGS_ENDPOINT); + final SimpleHttpResponse response; + try { + response = new SimpleHttpClient().get(url); + } catch (IOException ex) { + // WireMock is still starting up, right? + // TODO: Add better processing of the status once HealthCheck endpoints are introduced in WireMock + return StartupStatus.NOT_YET_KNOWN; + } + + final int wiremockStatusCode = response.getStatusCode(); + if (wiremockStatusCode != 200) { + // TODO: same as above + return StartupStatus.NOT_YET_KNOWN; + } + + return StartupStatus.SUCCESSFUL; + } + } } diff --git a/src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/TestHttpClient.java b/src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpClient.java similarity index 70% rename from src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/TestHttpClient.java rename to src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpClient.java index 47b641b..bb6d6de 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/TestHttpClient.java +++ b/src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpClient.java @@ -1,4 +1,4 @@ -package org.wiremock.integrations.testcontainers.testsupport.http; +package org.wiremock.integrations.testcontainers.util; import java.io.IOException; import java.io.InputStream; @@ -9,9 +9,14 @@ import java.net.URL; import java.nio.charset.StandardCharsets; -public final class TestHttpClient { +/** + * @deprecated this class is used only for the Java 8 which has no embedded client. + * It is not a part of public API and will be removed at any moment. + */ +@Deprecated +public final class SimpleHttpClient { - public HttpResponse send(HttpURLConnection connection) throws IOException { + public SimpleHttpResponse send(HttpURLConnection connection) throws IOException { InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); @@ -22,13 +27,11 @@ public HttpResponse send(HttpURLConnection connection) throws IOException { response.append(line); } reader.close(); - - - - return new HttpResponse(response.toString(), connection.getResponseCode()); + + return new SimpleHttpResponse(response.toString(), connection.getResponseCode()); } - public HttpResponse get(String uri) throws IOException { + public SimpleHttpResponse get(String uri) throws IOException { URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); @@ -37,7 +40,7 @@ public HttpResponse get(String uri) throws IOException { } - public HttpResponse post(String uri, String body) throws IOException { + public SimpleHttpResponse post(String uri, String body) throws IOException { URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); diff --git a/src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpResponse.java b/src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpResponse.java new file mode 100644 index 0000000..1cf937c --- /dev/null +++ b/src/main/java/org/wiremock/integrations/testcontainers/util/SimpleHttpResponse.java @@ -0,0 +1,25 @@ +package org.wiremock.integrations.testcontainers.util; + +/* + * @deprecated this class is used only for the Java 8 which has no embedded client. + * It is not a part of public API and will be removed at any moment. + */ +@Deprecated +public class SimpleHttpResponse { + + String body; + int statusCode; + + public SimpleHttpResponse(String body, int statusCode) { + this.body = body; + this.statusCode = statusCode; + } + + public String getBody() { + return body; + } + + public int getStatusCode() { + return statusCode; + } +} diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionTest.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionTest.java index 440269c..5b659da 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionTest.java +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionTest.java @@ -21,8 +21,8 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; -import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; import java.nio.file.Paths; import java.time.Duration; @@ -55,7 +55,7 @@ void testJSONBodyTransformer() throws Exception { String body = "{\"name\":\"John Doe\"}"; // when - HttpResponse response = new TestHttpClient().post(url, body); + SimpleHttpResponse response = new SimpleHttpClient().post(url, body); // then assertThat(response.getBody()) diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsCombinationTest.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsCombinationTest.java index 353b019..1404fdc 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsCombinationTest.java +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsCombinationTest.java @@ -21,8 +21,8 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; -import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; import java.nio.file.Paths; import java.util.Collections; @@ -56,7 +56,7 @@ void testJSONBodyTransformer() throws Exception { String body = "{\"name\":\"John Doe\"}"; // when - HttpResponse response = new TestHttpClient().post(url, body); + SimpleHttpResponse response = new SimpleHttpClient().post(url, body); // then assertThat(response.getBody()) diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest.java index 0428f6b..0a6f4bf 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest.java +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest.java @@ -22,8 +22,8 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; -import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpServer; import java.nio.file.Paths; @@ -75,7 +75,7 @@ void callbackUsingJsonStub() throws Exception { String applicationCallbackUrl = String.format("http://%s:%d%s", GenericContainer.INTERNAL_HOST_HOSTNAME, applicationServer.getPort(), APPLICATION_PATH); // when - HttpResponse response = new TestHttpClient().post( + SimpleHttpResponse response = new SimpleHttpClient().post( wiremockUrl, "{\"callbackMethod\": \"PUT\", \"callbackUrl\": \"" + applicationCallbackUrl + "\"}" ); diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerJunit4Test.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerJunit4Test.java index 8397d8b..9621e68 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerJunit4Test.java +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerJunit4Test.java @@ -17,8 +17,8 @@ import org.junit.Rule; import org.junit.Test; -import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; -import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; import static org.assertj.core.api.Assertions.assertThat; @@ -36,7 +36,7 @@ public void helloWorld() throws Exception { String url = wiremockServer.getUrl("/hello"); // when - HttpResponse response = new TestHttpClient().get(url); + SimpleHttpResponse response = new SimpleHttpClient().get(url); // then assertThat(response.getBody()) @@ -50,7 +50,7 @@ public void helloWorldWithoutLeadingSlashInPath() throws Exception { String url = wiremockServer.getUrl("hello"); // when - HttpResponse response = new TestHttpClient().get(url); + SimpleHttpResponse response = new SimpleHttpClient().get(url); // then assertThat(response.getBody()) @@ -64,7 +64,7 @@ public void helloWorldFromFile() throws Exception { String url = wiremockServer.getUrl("/hello-from-file"); // when - HttpResponse response = new TestHttpClient().get(url); + SimpleHttpResponse response = new SimpleHttpClient().get(url); // then assertThat(response.getBody()) diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerTest.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerTest.java index 2ede03d..9e14ea0 100644 --- a/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerTest.java +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockContainerTest.java @@ -20,8 +20,8 @@ import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; -import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; +import org.wiremock.integrations.testcontainers.util.SimpleHttpResponse; +import org.wiremock.integrations.testcontainers.util.SimpleHttpClient; import static org.assertj.core.api.Assertions.assertThat; @@ -46,7 +46,7 @@ void helloWorld(String path) throws Exception { String url = wiremockServer.getUrl(path); // when - HttpResponse response = new TestHttpClient().get(url); + SimpleHttpResponse response = new SimpleHttpClient().get(url); // then assertThat(response.getBody()) @@ -60,7 +60,7 @@ void helloWorldFromFile() throws Exception { String url = wiremockServer.getUrl("/hello-from-file"); // when - HttpResponse response = new TestHttpClient().get(url); + SimpleHttpResponse response = new SimpleHttpClient().get(url); // then assertThat(response.getBody()) diff --git a/src/test/java/org/wiremock/integrations/testcontainers/WireMockNoMappingFailureTest.java b/src/test/java/org/wiremock/integrations/testcontainers/WireMockNoMappingFailureTest.java new file mode 100644 index 0000000..1284be7 --- /dev/null +++ b/src/test/java/org/wiremock/integrations/testcontainers/WireMockNoMappingFailureTest.java @@ -0,0 +1,20 @@ +package org.wiremock.integrations.testcontainers; + +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import static org.assertj.core.api.Assertions.assertThat; + +@Testcontainers +public class WireMockNoMappingFailureTest { + + // We deliberately pass + @Container + WireMockContainer wiremockServer = new WireMockContainer(WireMockContainer.WIREMOCK_2_LATEST); + + @Test + void shouldFailOnStartup() { + // No op + } +} diff --git a/src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/HttpResponse.java b/src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/HttpResponse.java deleted file mode 100644 index 7f4ea0f..0000000 --- a/src/test/java/org/wiremock/integrations/testcontainers/testsupport/http/HttpResponse.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.wiremock.integrations.testcontainers.testsupport.http; - -public class HttpResponse { - - String body; - int statusCode; - public HttpResponse(String body, int statusCode) { - this.body = body; - this.statusCode = statusCode; - } - - public String getBody() { - return body; - } - - public int getStatusCode() { - return statusCode; - } -}