Skip to content

Commit d991952

Browse files
authored
Merge pull request #117 from aguibert/hollow-env-sanitize-fix
Fix for env var sanitization in hollow mode
2 parents 08d347b + 9082d62 commit d991952

13 files changed

Lines changed: 192 additions & 21 deletions

File tree

core/src/main/java/org/microshed/testing/ApplicationEnvironment.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ public static ApplicationEnvironment load() {
9292
return selectedEnv.orElseThrow(() -> new IllegalStateException("No available " + ApplicationEnvironment.class.getSimpleName() + " was discovered."));
9393
}
9494

95+
/**
96+
* @param clazz The {@link ApplicationEnvironment} class to check is active
97+
* @return True if the provided {@link ApplicationEnvironment} is currently active, false otherwise
98+
*/
99+
public static boolean isSelected(Class<? extends ApplicationEnvironment> clazz) {
100+
return load().getClass().equals(clazz);
101+
}
102+
95103
/**
96104
* @return true if the ApplicationEnvironment is currently available
97105
* false otherwise

modules/testcontainers/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@ description = "Extensions for using MicroShed Testing with Testcontainers for ma
44
dependencies {
55
compile project(':microshed-testing-core')
66
compile 'org.testcontainers:junit-jupiter:1.12.4'
7+
testCompile 'org.slf4j:slf4j-log4j12:1.7.29'
8+
testCompile 'org.testcontainers:mockserver:1.12.3'
79
testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
810
}
911

12+
test {
13+
// These system properties will trigger hollow mode to be triggered during unit tests
14+
systemProperty "microshed_hostname", "localhost"
15+
systemProperty "microshed_http_port", "9080"
16+
}
17+
1018
apply from: publishScript
1119

1220
publishToMavenLocal.dependsOn ':microshed-testing-core:publishToMavenLocal'

modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ private ApplicationContainer(Optional<Path> dockerfilePath) {
194194
*/
195195
public ApplicationContainer(Path dockerfilePath) {
196196
this(Optional.of(dockerfilePath));
197-
LOGGER.info("Using Dockerfile at:" + dockerfilePath);
197+
LOGGER.info("Using Dockerfile at: " + dockerfilePath);
198198
}
199199

200200
public ApplicationContainer(Future<String> dockerImageName) {
@@ -298,6 +298,15 @@ public Integer getFirstMappedPort() {
298298
return super.getFirstMappedPort();
299299
}
300300

301+
@Override
302+
public Integer getMappedPort(int originalPort) {
303+
if (isHollow) {
304+
return originalPort;
305+
} else {
306+
return super.getMappedPort(originalPort);
307+
}
308+
}
309+
301310
/**
302311
* @param appContextRoot the application context root. The protocol, hostname, and port do not need to be
303312
* included in the <code>appContextRoot</code> parameter. For example, an application

modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfiguration.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ public void applyConfiguration(Class<?> testClass) {
7979
Method addFixedPort = GenericContainer.class.getDeclaredMethod("addFixedExposedPort", int.class, int.class);
8080
addFixedPort.setAccessible(true);
8181
Map<Integer, String> fixedExposedPorts = new HashMap<>();
82-
for (GenericContainer<?> c : allContainers())
82+
for (GenericContainer<?> c : allContainers()) {
8383
for (Integer p : c.getExposedPorts()) {
84-
LOG.info("exposing port: " + p + " for container " + c.getDockerImageName());
8584
if (fixedExposedPorts.containsKey(p)) {
8685
throw new ExtensionConfigurationException("Cannot expose port " + p + " for " + c.getDockerImageName() +
8786
" because another container (" + fixedExposedPorts.get(p) +
8887
") is already using it.");
89-
} else {
90-
fixedExposedPorts.put(p, c.getDockerImageName());
9188
}
89+
LOG.info("Exposing fixed port " + p + " for container " + c.getDockerImageName());
90+
fixedExposedPorts.put(p, c.getDockerImageName());
9291
addFixedPort.invoke(c, p, p);
9392
}
93+
}
9494
} catch (Exception e) {
9595
e.printStackTrace();
9696
}
@@ -111,26 +111,26 @@ public void applyConfiguration(Class<?> testClass) {
111111

112112
/**
113113
* Attempt to translate any environment variables such as:
114-
* FOO_HOSTNAME=foo
114+
* FOO_HOSTNAME=http://foo:8080
115115
* to accomodate for the fixed exposed port such as:
116-
* FOO_HOSTNAME=localhost
116+
* FOO_HOSTNAME=http://localhost:8080
117117
*/
118118
private void sanitizeEnvVar(ApplicationContainer mpApp, Set<String> networkAliases) {
119119
mpApp.getEnvMap().forEach((k, v) -> {
120120
URL url = null;
121121
try {
122122
url = new URL(v);
123-
} catch (MalformedURLException ignore) {
124-
}
125-
for (String network : networkAliases) {
126-
String newValue = null;
127-
if (network.equals(v)) {
128-
newValue = "localhost";
129-
} else if (url != null && url.getHost().equals(network)) {
130-
newValue = v.replaceFirst(url.getHost(), "localhost");
123+
} catch (MalformedURLException e1) {
124+
try {
125+
url = new URL("http://" + v);
126+
} catch (MalformedURLException e2) {
127+
return;
131128
}
132-
if (newValue != null) {
133-
LOG.info("translating env var " + k + "=" + v + "-->localhost");
129+
}
130+
for (String networkAlias : networkAliases) {
131+
if (url.getHost().equals(networkAlias)) {
132+
String newValue = v.replaceFirst(networkAlias, "localhost");
133+
LOG.info("Translating env var key=" + k + " from " + v + " to " + newValue);
134134
mpApp.withEnv(k, newValue);
135135
}
136136
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2019 IBM Corporation and others
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* You may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.microshed.testing.testcontainers.config;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
23+
24+
import java.nio.file.Paths;
25+
import java.util.Map;
26+
27+
import org.junit.jupiter.api.Test;
28+
import org.microshed.testing.ApplicationEnvironment;
29+
import org.microshed.testing.jupiter.MicroShedTest;
30+
import org.microshed.testing.testcontainers.ApplicationContainer;
31+
import org.testcontainers.containers.MockServerContainer;
32+
import org.testcontainers.junit.jupiter.Container;
33+
34+
@MicroShedTest
35+
public class HollowTestcontainersConfigurationTest {
36+
37+
// This cointainer never actually gets started, since we are running in hollow mode
38+
@Container
39+
public static ApplicationContainer app = new ApplicationContainer(Paths.get("src", "test", "resources", "Dockerfile"))
40+
.withEnv("SVC_HOST", "mockserver")
41+
.withEnv("SVC_PORT", "1080")
42+
.withEnv("SVC_URL1", "mockserver")
43+
.withEnv("SVC_URL2", "mockserver:1080")
44+
.withEnv("SVC_URL3", "http://mockserver:1080")
45+
.withEnv("SVC_URL4", "http://mockserver:1080/hello/world")
46+
.withEnv("SVC_URL5", "http://mockserver:1080/hello/mockserver")
47+
.withEnv("SVC_URL6", oldValue -> "http://mockserver:1080")
48+
.withMpRestClient("com.foo.ExampleClass", "http://mockserver:1080");
49+
50+
@Container
51+
public static MockServerContainer mockServer = new MockServerContainer()
52+
.withNetworkAliases("mockserver")
53+
.withEnv("STAYS_UNCHANGED", "mockserver");
54+
55+
@Test
56+
public void testCorrectEnvironment() {
57+
assertEquals(HollowTestcontainersConfiguration.class, ApplicationEnvironment.load().getClass());
58+
assertTrue(ApplicationEnvironment.isSelected(HollowTestcontainersConfiguration.class),
59+
"Expected HollowTestcontainersConfiguration to be selected but it was not");
60+
assertTrue(HollowTestcontainersConfiguration.available(),
61+
"Expected HollowTestcontainersConfiguration to be available but it was not");
62+
}
63+
64+
@Test
65+
public void testFixedExposedPort() {
66+
assertEquals(9080, app.getMappedPort(9080));
67+
assertEquals(1080, mockServer.getMappedPort(1080));
68+
}
69+
70+
@Test
71+
public void testEnvVarTranslation() {
72+
Map<String, String> envMap = app.getEnvMap();
73+
assertEquals("localhost", envMap.get("SVC_HOST"));
74+
assertEquals("localhost", envMap.get("SVC_URL1"));
75+
assertEquals("localhost:1080", envMap.get("SVC_URL2"));
76+
assertEquals("http://localhost:1080", envMap.get("SVC_URL3"));
77+
assertEquals("http://localhost:1080/hello/world", envMap.get("SVC_URL4"));
78+
assertEquals("http://localhost:1080/hello/mockserver", envMap.get("SVC_URL5"));
79+
assertEquals("http://localhost:1080", envMap.get("SVC_URL6"));
80+
assertEquals("http://localhost:1080", envMap.get("com_foo_ExampleClass_mp_rest_url"));
81+
}
82+
83+
@Test
84+
public void testEnvVarUnchanged() {
85+
assertEquals("1080", app.getEnvMap().get("SVC_PORT"));
86+
assertEquals("mockserver", mockServer.getEnvMap().get("STAYS_UNCHANGED"));
87+
}
88+
89+
@Test
90+
public void testApplicationURL() {
91+
assertEquals("http://localhost:9080/", ApplicationEnvironment.load().getApplicationURL());
92+
}
93+
94+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2019 IBM Corporation and others
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* You may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.microshed.testing.testcontainers.config;
20+
21+
import java.util.Map;
22+
23+
import org.microshed.testing.testcontainers.spi.ServerAdapter;
24+
25+
public class TestServerAdapter implements ServerAdapter {
26+
27+
@Override
28+
public int getDefaultHttpPort() {
29+
return 9080;
30+
}
31+
32+
@Override
33+
public int getDefaultHttpsPort() {
34+
return 9443;
35+
}
36+
37+
@Override
38+
public void setConfigProperties(Map<String, String> properties) {
39+
// no-op
40+
}
41+
42+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM openliberty/open-liberty:full-java8-openj9-ubi
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.microshed.testing.testcontainers.config.TestServerAdapter
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
log4j.rootLogger=INFO, stdout
2+
3+
log4j.appender=org.apache.log4j.ConsoleAppender
4+
log4j.appender.layout=org.apache.log4j.PatternLayout
5+
6+
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
7+
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8+
log4j.appender.stdout.layout.ConversionPattern=%r %p %c %x - %m%n

sample-apps/jaxrs-mpjwt/src/test/resources/log4j.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender
77
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
88
log4j.appender.stdout.layout.ConversionPattern=%r %p %c %x - %m%n
99

10-
log4j.logger.org.eclipse.microprofile.system.test=DEBUG
10+
log4j.logger.org.microshed.testing=DEBUG

0 commit comments

Comments
 (0)