From 31a061029590ddad2072a0f04aca692ce21f8ed3 Mon Sep 17 00:00:00 2001 From: Andrew Guibert Date: Fri, 6 Dec 2019 14:01:12 -0600 Subject: [PATCH 1/3] Do not translate MP Rest Client vars if running in non-Testcontainer mode --- .../testing/testcontainers/ApplicationContainer.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java b/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java index cc8c2a1b..19fe81a9 100644 --- a/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java +++ b/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java @@ -427,10 +427,14 @@ private String readMpRestClientConfigKey(Class restClientClass) { * @return the current instance */ public ApplicationContainer withMpRestClient(String restClientClass, String hostUrl) { - // Sanitize environment variable name using Environment Variables Mapping Rules defined in MP Config: + // If we will be running in Docker, sanitize environment variable name using Environment Variables Mapping Rules defined in MP Config: // https://github.com/eclipse/microprofile-config/blob/master/spec/src/main/asciidoc/configsources.asciidoc#environment-variables-mapping-rules - String envName = restClientClass.replaceAll("[^a-zA-Z0-9_]", "_") + "_mp_rest_url"; - return withEnv(envName, hostUrl); + if (ApplicationEnvironment.isSelected(TestcontainersConfiguration.class)) { + restClientClass = restClientClass.replaceAll("[^a-zA-Z0-9_]", "_") + "_mp_rest_url"; + } else { + restClientClass += "/mp-rest/url"; + } + return withEnv(restClientClass, hostUrl); } /** From b05825aa9cfe3742f9dd1ff64ac4875449f488d0 Mon Sep 17 00:00:00 2001 From: Andrew Guibert Date: Fri, 6 Dec 2019 14:06:38 -0600 Subject: [PATCH 2/3] Disable configure.sh until docker daemon caching is fixed --- .../containers/liberty/LibertyAdapter.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/liberty/src/main/java/org/testcontainers/containers/liberty/LibertyAdapter.java b/modules/liberty/src/main/java/org/testcontainers/containers/liberty/LibertyAdapter.java index 7adb5bda..aa51257b 100644 --- a/modules/liberty/src/main/java/org/testcontainers/containers/liberty/LibertyAdapter.java +++ b/modules/liberty/src/main/java/org/testcontainers/containers/liberty/LibertyAdapter.java @@ -67,7 +67,7 @@ public void setConfigProperties(Map properties) { if (WLP_USR_DIR == null) WLP_USR_DIR = System.getProperty("wlp.user.dir"); if (WLP_USR_DIR == null) - throw new IllegalStateException("The 'w.p.user.dir', 'WLP_USR_DIR', or '" + CONFIG_FILE_PROP + throw new IllegalStateException("The 'wlp.user.dir', 'WLP_USR_DIR', or '" + CONFIG_FILE_PROP + "' property must be set in order to dynamically set config properties"); Path usrDir = Paths.get(WLP_USR_DIR); configFile = usrDir.resolve("servers/defaultServer/configDropins/defaults/system-test-vars.xml"); @@ -111,10 +111,12 @@ public ImageFromDockerfile getDefaultImage(File appFile) { if (configDirExists) { builder.copy("/config", "/config"); } - // Best practice is to run configure.sh after the app is added, but we will - // run it before adding the app because due to how often the app changes while - // running tests this will yeild the most overall time saved - builder.run("configure.sh"); +// // Best practice is to run configure.sh after the app is added, but we will +// // run it before adding the app because due to how often the app changes while +// // running tests this will yeild the most overall time saved + // TODO: Cache does not work correctly when running the previous docker line + // which causes configure.sh to be run every time. See https://github.com/MicroShed/microshed-testing/issues/122 +// builder.run("configure.sh"); builder.add("/config/dropins/" + appName, "/config/dropins/" + appName); builder.build(); }) From 4c439a74558c4b546f23e2dd4c8ec5415a80e830 Mon Sep 17 00:00:00 2001 From: Andrew Guibert Date: Fri, 6 Dec 2019 15:29:03 -0600 Subject: [PATCH 3/3] Add integration tests for Testcontainers mode --- modules/testcontainers/build.gradle | 33 ++++++++ .../ApplicationContainerIT.java | 71 ++++++++++++++++++ .../config/TestcontainersConfigurationIT.java | 75 +++++++++++++++++++ .../src/integrationTest/resources/Dockerfile | 1 + .../resources/log4j.properties | 8 ++ .../ApplicationContainerTest.java | 8 +- ...HollowTestcontainersConfigurationTest.java | 16 ++-- 7 files changed, 200 insertions(+), 12 deletions(-) create mode 100644 modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/ApplicationContainerIT.java create mode 100644 modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/config/TestcontainersConfigurationIT.java create mode 100644 modules/testcontainers/src/integrationTest/resources/Dockerfile create mode 100644 modules/testcontainers/src/integrationTest/resources/log4j.properties diff --git a/modules/testcontainers/build.gradle b/modules/testcontainers/build.gradle index c54552d9..8ccf92d8 100644 --- a/modules/testcontainers/build.gradle +++ b/modules/testcontainers/build.gradle @@ -1,6 +1,19 @@ ext.title = "MicroShed Testing Framework :: Testcontainers extension" description = "Extensions for using MicroShed Testing with Testcontainers for managing application and resource lifecycle" +configurations { + intTestImplementation.extendsFrom testImplementation + intTestCompile.extendsFrom testCompile + intTestRuntimeOnly.extendsFrom testRuntimeOnly +} + +sourceSets { + integrationTest { + compileClasspath += sourceSets.main.output + configurations.testCompile + runtimeClasspath += output + compileClasspath + configurations.intTestImplementation + } +} + dependencies { compile project(':microshed-testing-core') compile 'org.testcontainers:junit-jupiter:1.12.4' @@ -19,3 +32,23 @@ test { apply from: publishScript publishToMavenLocal.dependsOn ':microshed-testing-core:publishToMavenLocal' + +task integrationTest(type: Test) { + description = 'Runs integration tests.' + group = 'verification' + defaultCharacterEncoding = "UTF-8" + useJUnitPlatform() + testLogging { + displayGranularity 1 + showStandardStreams = true + showStackTraces = true + exceptionFormat = 'full' + events 'PASSED', 'FAILED', 'SKIPPED' + } + + testClassesDirs = sourceSets.integrationTest.output.classesDirs + classpath = sourceSets.integrationTest.runtimeClasspath + shouldRunAfter test +} + +check.dependsOn integrationTest \ No newline at end of file diff --git a/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/ApplicationContainerIT.java b/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/ApplicationContainerIT.java new file mode 100644 index 00000000..c37c0aab --- /dev/null +++ b/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/ApplicationContainerIT.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 IBM Corporation and others + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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 org.microshed.testing.testcontainers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.file.Paths; +import java.util.Map; + +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import org.junit.jupiter.api.Test; + +public class ApplicationContainerIT { + + // Base uri configured with: com_example_StringRestClient_mp_rest_url + @RegisterRestClient + public static class SampleRestClient1 { + } + + // Base uri configured with: rc_config_key_mp_rest_url + @RegisterRestClient(configKey = "rc-config-key") + public static class SampleRestClient2 { + } + + // Base uri configured with: CLIENT_CONFIG_KEY_mp_rest_url + @RegisterRestClient(configKey = "CLIENT_CONFIG_KEY") + public static class SampleRestClient3 { + } + + @Test + public void testMpRestClient() { + final String clientUrl = "http://example.com"; + + @SuppressWarnings("resource") + ApplicationContainer app = new ApplicationContainer(Paths.get("src", "integrationTest", "resources", "Dockerfile")) + .withMpRestClient("com.example.StringRestClient", clientUrl) + .withMpRestClient(SampleRestClient1.class, clientUrl) + .withMpRestClient(SampleRestClient2.class, clientUrl) + .withMpRestClient(SampleRestClient3.class, clientUrl); + + Map appEnv = app.getEnvMap(); + assertEquals(clientUrl, appEnv.get("com_example_StringRestClient_mp_rest_url")); + assertEquals(clientUrl, appEnv.get("org_microshed_testing_testcontainers_ApplicationContainerIT_SampleRestClient1_mp_rest_url")); + assertEquals(clientUrl, appEnv.get("rc_config_key_mp_rest_url")); + assertEquals(clientUrl, appEnv.get("CLIENT_CONFIG_KEY_mp_rest_url")); + } + + @Test + public void testCorrectServerAdapter() { + @SuppressWarnings("resource") + ApplicationContainer app = new ApplicationContainer(Paths.get("src", "integrationTest", "resources", "Dockerfile")); + assertEquals("org.microshed.testing.testcontainers.ApplicationContainer.DefaultServerAdapter", app.getServerAdapter().getClass().getCanonicalName()); + } + +} diff --git a/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/config/TestcontainersConfigurationIT.java b/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/config/TestcontainersConfigurationIT.java new file mode 100644 index 00000000..1cee84d5 --- /dev/null +++ b/modules/testcontainers/src/integrationTest/java/org/microshed/testing/testcontainers/config/TestcontainersConfigurationIT.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 IBM Corporation and others + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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 org.microshed.testing.testcontainers.config; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Paths; + +import org.junit.jupiter.api.Test; +import org.microshed.testing.ApplicationEnvironment; +import org.microshed.testing.jupiter.MicroShedTest; +import org.microshed.testing.testcontainers.ApplicationContainer; +import org.testcontainers.containers.MockServerContainer; +import org.testcontainers.junit.jupiter.Container; + +@MicroShedTest +public class TestcontainersConfigurationIT { + + @Container + public static ApplicationContainer app = new ApplicationContainer(Paths.get("src", "integrationTest", "resources", "Dockerfile")) + .withEnv("SVC_HOST", "mockserver") + .withEnv("SVC_PORT", "1080") + .withEnv("SVC_URL1", "mockserver") + .withEnv("SVC_URL2", "mockserver:1080") + .withEnv("SVC_URL3", "http://mockserver:1080") + .withEnv("SVC_URL4", "http://mockserver:1080/hello/world") + .withEnv("SVC_URL5", "http://mockserver:1080/hello/mockserver") + .withEnv("SVC_URL6", oldValue -> "http://mockserver:1080") + .withMpRestClient("com.foo.ExampleClass", "http://mockserver:1080"); + + @Container + public static MockServerContainer mockServer = new MockServerContainer() + .withNetworkAliases("mockserver") + .withEnv("STAYS_UNCHANGED", "mockserver"); + + @Test + public void testCorrectEnvironment() { + assertEquals(TestcontainersConfiguration.class, ApplicationEnvironment.load().getClass()); + assertTrue(ApplicationEnvironment.isSelected(TestcontainersConfiguration.class), + "Expected TestcontainersConfiguration to be selected but it was not"); + } + + @Test + public void testExposedPort() { + assertTrue(app.getMappedPort(9080) != 9080, "Port 9080 should have been mapped to a random port but was not"); + assertTrue(mockServer.getMappedPort(1080) != 1080, "Port 9080 should have been mapped to a random port but was not"); + } + + @Test + public void testApplicationURL() { + String appUrl = ApplicationEnvironment.load().getApplicationURL(); + assertNotNull(appUrl); + assertEquals(appUrl, app.getApplicationURL()); + assertTrue(appUrl.startsWith("http://"), "Application URL did not start with 'http://' " + appUrl); + } + +} \ No newline at end of file diff --git a/modules/testcontainers/src/integrationTest/resources/Dockerfile b/modules/testcontainers/src/integrationTest/resources/Dockerfile new file mode 100644 index 00000000..94b7b645 --- /dev/null +++ b/modules/testcontainers/src/integrationTest/resources/Dockerfile @@ -0,0 +1 @@ +FROM openliberty/open-liberty:full-java8-openj9-ubi diff --git a/modules/testcontainers/src/integrationTest/resources/log4j.properties b/modules/testcontainers/src/integrationTest/resources/log4j.properties new file mode 100644 index 00000000..a2743154 --- /dev/null +++ b/modules/testcontainers/src/integrationTest/resources/log4j.properties @@ -0,0 +1,8 @@ +log4j.rootLogger=INFO, stdout + +log4j.appender=org.apache.log4j.ConsoleAppender +log4j.appender.layout=org.apache.log4j.PatternLayout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%r %p %c %x - %m%n diff --git a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java index a49d91e1..e556c893 100644 --- a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java +++ b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java @@ -55,10 +55,10 @@ public void testMpRestClient() { .withMpRestClient(SampleRestClient3.class, clientUrl); Map appEnv = app.getEnvMap(); - assertEquals(clientUrl, appEnv.get("com_example_StringRestClient_mp_rest_url")); - assertEquals(clientUrl, appEnv.get("org_microshed_testing_testcontainers_ApplicationContainerTest_SampleRestClient1_mp_rest_url")); - assertEquals(clientUrl, appEnv.get("rc_config_key_mp_rest_url")); - assertEquals(clientUrl, appEnv.get("CLIENT_CONFIG_KEY_mp_rest_url")); + assertEquals(clientUrl, appEnv.get("com.example.StringRestClient/mp-rest/url"), appEnv.toString()); + assertEquals(clientUrl, appEnv.get("org.microshed.testing.testcontainers.ApplicationContainerTest.SampleRestClient1/mp-rest/url"), appEnv.toString()); + assertEquals(clientUrl, appEnv.get("rc-config-key/mp-rest/url"), appEnv.toString()); + assertEquals(clientUrl, appEnv.get("CLIENT_CONFIG_KEY/mp-rest/url"), appEnv.toString()); } @Test diff --git a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfigurationTest.java b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfigurationTest.java index fa4db345..14ea6e5e 100644 --- a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfigurationTest.java +++ b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfigurationTest.java @@ -70,14 +70,14 @@ public void testFixedExposedPort() { @Test public void testEnvVarTranslation() { Map envMap = app.getEnvMap(); - assertEquals("localhost", envMap.get("SVC_HOST")); - assertEquals("localhost", envMap.get("SVC_URL1")); - assertEquals("localhost:1080", envMap.get("SVC_URL2")); - assertEquals("http://localhost:1080", envMap.get("SVC_URL3")); - assertEquals("http://localhost:1080/hello/world", envMap.get("SVC_URL4")); - assertEquals("http://localhost:1080/hello/mockserver", envMap.get("SVC_URL5")); - assertEquals("http://localhost:1080", envMap.get("SVC_URL6")); - assertEquals("http://localhost:1080", envMap.get("com_foo_ExampleClass_mp_rest_url")); + assertEquals("localhost", envMap.get("SVC_HOST"), envMap.toString()); + assertEquals("localhost", envMap.get("SVC_URL1"), envMap.toString()); + assertEquals("localhost:1080", envMap.get("SVC_URL2"), envMap.toString()); + assertEquals("http://localhost:1080", envMap.get("SVC_URL3"), envMap.toString()); + assertEquals("http://localhost:1080/hello/world", envMap.get("SVC_URL4"), envMap.toString()); + assertEquals("http://localhost:1080/hello/mockserver", envMap.get("SVC_URL5"), envMap.toString()); + assertEquals("http://localhost:1080", envMap.get("SVC_URL6"), envMap.toString()); + assertEquals("http://localhost:1080", envMap.get("com.foo.ExampleClass/mp-rest/url"), envMap.toString()); } @Test