From c377cc3b99024fd01c4f47a365040313eca9cfff Mon Sep 17 00:00:00 2001 From: Dariusz Czajkiewicz Date: Thu, 20 Feb 2025 16:03:47 +0100 Subject: [PATCH] test containers --- mrchecker-playwright-framework/pom.xml | 15 +- .../infrastructure/Configuration.java | 11 ++ .../resources/MyMockServer.java | 35 +++++ .../resources/MyMockServerClient.java | 129 ++++++++++++++++++ .../resources/MyTestResources.java | 18 +++ .../resources/RawmindWebContainer.java | 2 +- .../mock/sample-mock-response-1.json | 10 ++ 7 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServer.java create mode 100644 mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServerClient.java create mode 100644 mrchecker-playwright-framework/src/test/resources/mock/sample-mock-response-1.json diff --git a/mrchecker-playwright-framework/pom.xml b/mrchecker-playwright-framework/pom.xml index 07a3c94d..e9c9f85e 100644 --- a/mrchecker-playwright-framework/pom.xml +++ b/mrchecker-playwright-framework/pom.xml @@ -115,9 +115,6 @@ quarkus-arc 3.18.3 - - - com.google.auto.service auto-service @@ -144,6 +141,18 @@ 1.20.4 test + + org.testcontainers + mockserver + 1.20.4 + test + + + org.mock-server + mockserver-client-java + 5.15.0 + + org.eclipse.microprofile.config diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/Configuration.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/Configuration.java index 7b758b4b..1f484e1e 100644 --- a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/Configuration.java +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/Configuration.java @@ -1,5 +1,6 @@ package com.capgemini.infrastructure; +import com.capgemini.infrastructure.resources.MyMockServer; import org.apache.commons.lang3.StringUtils; import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; @@ -9,9 +10,11 @@ public class Configuration { private static final Config CONFIG = ConfigProvider.getConfig(); public static final String MY_WEB_APP = "my-web-app"; + public static final String MY_MOCK_NAME = "my-mock"; public static final boolean DEBUG = CONFIG.getOptionalValue("testcontainers.mode.debug", Boolean.class).orElse(false); private String myWebAppUrl = ""; + private MyMockServer myMockServer = null; private Configuration() { } @@ -30,4 +33,12 @@ public void setMyWebAppUrl(String myWebAppUrl) { public String getMyWebAppUrl() { return myWebAppUrl; } + + public void setMyMockServer(MyMockServer myMockServer) { + this.myMockServer = myMockServer; + } + + public MyMockServer getMyMockServer() { + return myMockServer; + } } diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServer.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServer.java new file mode 100644 index 00000000..cc8d7aa7 --- /dev/null +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServer.java @@ -0,0 +1,35 @@ +package com.capgemini.infrastructure.resources; + +import com.capgemini.infrastructure.Configuration; +import org.testcontainers.containers.MockServerContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; + +public class MyMockServer extends MockServerContainer { + private static final String NETWORK_ALIAS = "mock-server"; + + public MyMockServer(Network network) { + super(DockerImageName.parse("mockserver/mockserver")); + withReuse(Configuration.DEBUG); + withNetwork(network) + .withNetworkAliases(NETWORK_ALIAS) + .withExposedPorts(1080) + .withStartupTimeout(Duration.ofMinutes(2)); + withCreateContainerCmdModifier(cmd -> cmd.withName(Configuration.MY_MOCK_NAME)); + setPortBindings(Arrays.asList("1080:1080")); + } + + @Override + public MyMockServer withReuse(boolean reusable) { + if (reusable) { + var aliases = new ArrayList(); + aliases.add(NETWORK_ALIAS); + this.setNetworkAliases(aliases); + } + return (MyMockServer) super.withReuse(reusable); + } +} diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServerClient.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServerClient.java new file mode 100644 index 00000000..dc685a49 --- /dev/null +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyMockServerClient.java @@ -0,0 +1,129 @@ +package com.capgemini.infrastructure.resources; + +import com.capgemini.infrastructure.Configuration; +import org.mockserver.client.MockServerClient; +import org.mockserver.matchers.TimeToLive; +import org.mockserver.matchers.Times; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; +import static org.mockserver.model.StringBody.subString; + +public class MyMockServerClient { + private final Logger logger = LoggerFactory.getLogger(MyMockServerClient.class); + private final MyMockServer mockServer = Configuration.getInstance().getMyMockServer(); + private static MyMockServerClient instance = null; + private MockServerClient mockServerClient = null; + + private MyMockServerClient() { + } + + public static MyMockServerClient getInstance() { + if (instance == null) { + instance = new MyMockServerClient(); + } + return instance; + } + + public void startMockClient() { + try { + mockServerClient = new MockServerClient(mockServer.getHost(), mockServer.getServerPort()); + + // Add rule by file + // http://localhost:1080/my-api/sample-1 + /* + { +"source": "MySystem", +"transportMode": "AIR", +"totalPackages": 1000, +"commercialValue": { +"cost": 200, +"currency": "USD" +}, +"isCancelled": false +} + */ + addRule("/my-api/sample-1", "sample-mock-response-1.json"); + + // Add conditional rule + addRuleConditionTxt("/cst/integration/api/createRequestV3", "20220415-43872", Map.of( + "AI24000595", "20220415-66666", + "BY24001263", "20220415-66666" + )); + + // Add text response + addRuleTxt("/cst/integration/api/closeRequest", "CST request closed"); + addRuleTxt("/cst/integration/api/proceedNextStep", "CST request proceeded to the next step"); + + logger.info("Mock URL: {}:{}", mockServer.getHost(), mockServer.getServerPort()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + //customResponseBody: key -> condition string, value -> response body to return + private void addRuleConditionTxt(String uriPath, String defaultResponse, Map customResponseBody) { + for (var condition : customResponseBody.entrySet()) { + addConditionExpectation(uriPath, condition.getKey(), condition.getValue()); + logger.info("Mock rule added for path: http://{}:{}{} and condition: {} -> {}", mockServer.getHost(), mockServer.getServerPort(), uriPath, condition.getKey(), condition.getValue()); + } + + mockServerClient.when( + request().withPath(uriPath), + Times.unlimited(), + TimeToLive.unlimited(), + -100 + ) + .respond(response() + .withBody(defaultResponse) + .withHeader("Content-Type", "application/json;charset=UTF-8") + ); + logger.info("Mock rule added for path: http://{}:{}{} default response {}", mockServer.getHost(), mockServer.getServerPort(), uriPath, defaultResponse); + } + + private void addConditionExpectation(String uriPath, String condtion, String responseBody) { + mockServerClient + .when( + request() + .withPath(uriPath) + .withBody(subString(condtion)) + ) + .respond(response() + .withBody(responseBody) + .withHeader("Content-Type", "application/json;charset=UTF-8") + ); + } + + private void addRuleTxt(String uriPath, String responseBody) { + logger.info("Mock rule added for path: http://{}:{}{}", mockServer.getHost(), mockServer.getServerPort(), uriPath); + mockServerClient + .when(request().withPath(uriPath)) + .respond(response() + .withBody(responseBody) + .withHeader("Content-Type", "application/json;charset=UTF-8")); + } + + private void addRule(String uriPath, String filePath) { + logger.info("Mock rule added for path: http://{}:{}{}", mockServer.getHost(), mockServer.getServerPort(), uriPath); + mockServerClient + .when(request().withPath(uriPath)) + .respond(response() + .withBody(getMyResponse(filePath)) + .withHeader("Content-Type", "application/json;charset=UTF-8")); + } + + private String getMyResponse(String fileToMock) { + try (var inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mock/" + fileToMock)) { + assert inputStream != null; + return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyTestResources.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyTestResources.java index 9677202d..47b0cd00 100644 --- a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyTestResources.java +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/MyTestResources.java @@ -13,16 +13,34 @@ public class MyTestResources implements QuarkusTestResourceLifecycleManager { private final Network network = TestNetwork.getInstance().getNetwork(); private RawmindWebContainer rawmindWebContainer = null; + private MyMockServer myMockServer = null; @Override public Map start() { var conf = new HashMap(); + startMockServer(); + startMockClient(); startWebServer(); conf.put("webAppUrl", rawmindWebContainer.getUrl()); return conf; } + private void startMockServer() { + if(myMockServer == null || !isContainerRunning(Configuration.MY_MOCK_NAME)) { + myMockServer = new MyMockServer(network); + myMockServer.start(); + if (!myMockServer.getContainerName().contains(Configuration.MY_MOCK_NAME)) { + myMockServer.withCreateContainerCmdModifier(cmd -> cmd.withName(Configuration.MY_MOCK_NAME)); + } + } + Configuration.getInstance().setMyMockServer(myMockServer); + } + + private void startMockClient() { + MyMockServerClient.getInstance().startMockClient(); + } + private void startWebServer() { if (rawmindWebContainer == null || !isContainerRunning(Configuration.MY_WEB_APP)) { rawmindWebContainer = new RawmindWebContainer(network); diff --git a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/RawmindWebContainer.java b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/RawmindWebContainer.java index 94a951d7..2d7e1a32 100644 --- a/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/RawmindWebContainer.java +++ b/mrchecker-playwright-framework/src/test/java/com/capgemini/infrastructure/resources/RawmindWebContainer.java @@ -19,7 +19,7 @@ public class RawmindWebContainer extends GenericContainer { public RawmindWebContainer(Network network) { super(DockerImageName.parse("rawmind/web-test")); - withReuse(true); + withReuse(Configuration.DEBUG); withNetwork(network) .withNetworkAliases(NETWORK_ALIAS) .withExposedPorts(APP_PORT) diff --git a/mrchecker-playwright-framework/src/test/resources/mock/sample-mock-response-1.json b/mrchecker-playwright-framework/src/test/resources/mock/sample-mock-response-1.json new file mode 100644 index 00000000..488cf9c6 --- /dev/null +++ b/mrchecker-playwright-framework/src/test/resources/mock/sample-mock-response-1.json @@ -0,0 +1,10 @@ +{ + "source": "MySystem", + "transportMode": "AIR", + "totalPackages": 1000, + "commercialValue": { + "cost": 200, + "currency": "USD" + }, + "isCancelled": false +} \ No newline at end of file