Skip to content

Commit 4b1b72e

Browse files
authored
Merge pull request #146 from aguibert/hollow-path
Introduce microshed_app_context_root for Manual/Hollow environments
2 parents 39b480a + 97a118f commit 4b1b72e

6 files changed

Lines changed: 131 additions & 61 deletions

File tree

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

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
package org.microshed.testing;
2020

21+
import java.net.MalformedURLException;
22+
import java.net.URL;
23+
2124
/**
2225
* Configuration representing application and dependent services already
2326
* being started prior to running the tests.
@@ -27,10 +30,10 @@ public class ManuallyStartedConfiguration implements ApplicationEnvironment {
2730
public static final String MICROSHED_HOSTNAME = "microshed_hostname";
2831
public static final String MICROSHED_HTTP_PORT = "microshed_http_port";
2932
public static final String MICROSHED_HTTPS_PORT = "microshed_https_port";
30-
// public static final String RUNTIME_URL_PROPERTY = "MICROSHED_TEST_RUNTIME_URL";
33+
public static final String MICROSHED_APP_CONTEXT_ROOT = "microshed_app_context_root";
3134
public static final String MANUAL_ENALBED = "microshed_manual_env";
3235

33-
private static String runtimeURL;
36+
private static URL runtimeURL;
3437

3538
@Override
3639
public boolean isAvailable() {
@@ -48,28 +51,58 @@ public int getPriority() {
4851
}
4952

5053
public static void setRuntimeURL(String url) {
51-
runtimeURL = url;
54+
try {
55+
runtimeURL = new URL(url);
56+
} catch (MalformedURLException e) {
57+
throw new IllegalArgumentException(e);
58+
}
59+
}
60+
61+
public static String getHostname() {
62+
if (runtimeURL != null)
63+
return runtimeURL.getHost();
64+
return resolveProperty(MICROSHED_HOSTNAME);
65+
}
66+
67+
public static int getHttpPort() {
68+
if (runtimeURL != null && runtimeURL.toString().startsWith("http://"))
69+
return runtimeURL.getPort() == -1 ? runtimeURL.getDefaultPort() : runtimeURL.getPort();
70+
String port = resolveProperty(MICROSHED_HTTP_PORT);
71+
return port.isEmpty() ? -1 : Integer.valueOf(port);
72+
}
73+
74+
public static int getHttpsPort() {
75+
if (runtimeURL != null && runtimeURL.toString().startsWith("https://"))
76+
return runtimeURL.getPort() == -1 ? runtimeURL.getDefaultPort() : runtimeURL.getPort();
77+
String port = resolveProperty(MICROSHED_HTTPS_PORT);
78+
return port.isEmpty() ? -1 : Integer.valueOf(port);
79+
}
80+
81+
public static String getBasePath() {
82+
String basePath = runtimeURL != null ? runtimeURL.getPath() : resolveProperty(MICROSHED_APP_CONTEXT_ROOT);
83+
if (!basePath.startsWith("/"))
84+
basePath = "/" + basePath;
85+
return basePath;
5286
}
5387

5488
public static String getRuntimeURL() {
5589
if (runtimeURL != null)
56-
return runtimeURL;
90+
return runtimeURL.toString();
5791

58-
String host = resolveProperty(MICROSHED_HOSTNAME);
59-
String httpPort = resolveProperty(MICROSHED_HTTP_PORT);
60-
String httpsPort = resolveProperty(MICROSHED_HTTPS_PORT);
61-
if (host.isEmpty() && (httpPort.isEmpty() || httpsPort.isEmpty())) {
92+
String host = getHostname();
93+
int httpPort = getHttpPort();
94+
int httpsPort = getHttpsPort();
95+
if (host.isEmpty() || (httpPort == -1 && httpsPort == -1)) {
6296
throw new IllegalStateException("The properties '" + MICROSHED_HOSTNAME + "' and '" + MICROSHED_HTTP_PORT + "' or '" +
6397
MICROSHED_HTTPS_PORT + "' must be set in order to use this ApplicationEnvironment");
6498
}
99+
String basePath = getBasePath();
65100

66101
// Prefer HTTPS if set
67-
if (!httpsPort.isEmpty()) {
68-
Integer.parseInt(httpsPort);
69-
return "https://" + host + ':' + httpsPort;
102+
if (httpsPort != -1) {
103+
return "https://" + host + ':' + httpsPort + basePath;
70104
} else {
71-
Integer.parseInt(httpPort);
72-
return "http://" + host + ':' + httpPort;
105+
return "http://" + host + ':' + httpPort + basePath;
73106
}
74107
}
75108

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

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.lang.annotation.Annotation;
2424
import java.lang.reflect.InvocationTargetException;
2525
import java.lang.reflect.Method;
26-
import java.net.URL;
2726
import java.nio.file.Files;
2827
import java.nio.file.Path;
2928
import java.nio.file.Paths;
@@ -45,6 +44,7 @@
4544
import org.junit.jupiter.api.extension.ExtensionConfigurationException;
4645
import org.junit.platform.commons.support.AnnotationSupport;
4746
import org.microshed.testing.ApplicationEnvironment;
47+
import org.microshed.testing.ManuallyStartedConfiguration;
4848
import org.microshed.testing.testcontainers.config.HollowTestcontainersConfiguration;
4949
import org.microshed.testing.testcontainers.config.TestcontainersConfiguration;
5050
import org.microshed.testing.testcontainers.internal.ImageFromDockerfile;
@@ -118,9 +118,8 @@ private static Future<String> resolveImage(Optional<Path> dockerfile) {
118118
}
119119

120120
private static boolean isHollow() {
121-
ApplicationEnvironment current = ApplicationEnvironment.Resolver.load();
122-
return !(current instanceof TestcontainersConfiguration) ||
123-
current instanceof HollowTestcontainersConfiguration;
121+
return ApplicationEnvironment.Resolver.isSelected(HollowTestcontainersConfiguration.class) ||
122+
ApplicationEnvironment.Resolver.isSelected(ManuallyStartedConfiguration.class);
124123
}
125124

126125
private static File findAppFile() {
@@ -222,6 +221,14 @@ private void commonInit() {
222221
addExposedPorts(serverAdapter.getDefaultHttpPort());
223222
withLogConsumer(new Slf4jLogConsumer(LOGGER));
224223
withAppContextRoot("/");
224+
if (isHollow) {
225+
setContainerIpAddress(ManuallyStartedConfiguration.getHostname());
226+
if (ManuallyStartedConfiguration.getHttpsPort() != -1)
227+
setFirstMappedPort(ManuallyStartedConfiguration.getHttpsPort());
228+
else
229+
setFirstMappedPort(ManuallyStartedConfiguration.getHttpPort());
230+
withAppContextRoot(ManuallyStartedConfiguration.getBasePath());
231+
}
225232
}
226233

227234
@Override
@@ -239,17 +246,16 @@ protected void configure() {
239246
}
240247
}
241248

242-
/**
243-
* Sets the URL where the current application is running at. This method is typically called
244-
* for plugins that make use of {@link HollowTestcontainersConfiguration}. It is not necessary
245-
* for test code to call this method if they are starting the application container in the
246-
* normal way.
247-
*
248-
* @param url The URl where the current application is running
249-
*/
250-
public void setRunningURL(URL url) {
251-
lateBind_ipAddress = url.getHost();
252-
lateBind_port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
249+
public void setContainerIpAddress(String ipAddress) {
250+
if (!isHollow)
251+
throw new IllegalStateException("Can only set contaienr IP address in hollow mode");
252+
lateBind_ipAddress = ipAddress;
253+
}
254+
255+
public void setFirstMappedPort(int port) {
256+
if (!isHollow)
257+
throw new IllegalStateException("Can only set first mapped port in hollow mode");
258+
lateBind_port = port;
253259
}
254260

255261
@Override
@@ -453,9 +459,9 @@ public String getApplicationURL() {
453459
* {@code http://<container-ip-address>:<mapped-port>}
454460
*/
455461
public String getBaseURL() {
456-
if (!this.isRunning())
462+
if (!isHollow && !isRunning())
457463
throw new IllegalStateException("Container must be running to determine hostname and port");
458-
return "http://" + this.getContainerIpAddress() + ':' + this.getFirstMappedPort();
464+
return "http://" + getContainerIpAddress() + ':' + getFirstMappedPort();
459465
}
460466

461467
/**

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,6 @@ public void applyConfiguration(Class<?> testClass) {
9494
} catch (Exception e) {
9595
e.printStackTrace();
9696
}
97-
98-
// Apply configuration to a running server
99-
URL appURL;
100-
String runtimeURL = getApplicationURL();
101-
try {
102-
appURL = new URL(runtimeURL);
103-
} catch (MalformedURLException e) {
104-
throw new ExtensionConfigurationException("The application URL '" + runtimeURL + "' was not a valid URL.", e);
105-
}
106-
allContainers().stream()
107-
.filter(c -> c instanceof ApplicationContainer)
108-
.map(c -> (ApplicationContainer) c)
109-
.forEach(c -> c.setRunningURL(appURL));
110-
}
111-
112-
@Override
113-
public String getApplicationURL() {
114-
return ManuallyStartedConfiguration.getRuntimeURL();
11597
}
11698

11799
/**

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public class TestcontainersConfiguration implements ApplicationEnvironment {
4646
private static final Logger LOG = LoggerFactory.getLogger(TestcontainersConfiguration.class);
4747

4848
// Will need to rework this if we will ever support parallel test execution
49-
private static Class<?> currentTestClass;
50-
private static Class<? extends SharedContainerConfiguration> sharedConfigClass;
51-
private static final Set<GenericContainer<?>> unsharedContainers = new HashSet<>();
52-
private static final Set<GenericContainer<?>> sharedContainers = new HashSet<>();
49+
private Class<?> currentTestClass;
50+
private Class<? extends SharedContainerConfiguration> sharedConfigClass;
51+
private final Set<GenericContainer<?>> unsharedContainers = new HashSet<>();
52+
private final Set<GenericContainer<?>> sharedContainers = new HashSet<>();
5353

5454
@Override
5555
public int getPriority() {
@@ -63,7 +63,7 @@ public boolean isAvailable() {
6363

6464
@Override
6565
public void applyConfiguration(Class<?> testClass) {
66-
TestcontainersConfiguration.currentTestClass = testClass;
66+
currentTestClass = testClass;
6767

6868
if (testClass.isAnnotationPresent(SharedContainerConfig.class)) {
6969
sharedConfigClass = testClass.getAnnotation(SharedContainerConfig.class).value();
@@ -139,12 +139,6 @@ public void start() {
139139
@Override
140140
public String getApplicationURL() {
141141
ApplicationContainer mpApp = autoDiscoverMPApp(currentTestClass, true);
142-
143-
// At this point we have found exactly one ApplicationContainer
144-
if (!mpApp.isCreated() || !mpApp.isRunning())
145-
throw new ExtensionConfigurationException("ApplicationContainer " + mpApp.getDockerImageName() + " is not running yet. " +
146-
"The contianer must be running in order to obtain its URL.");
147-
148142
return mpApp.getApplicationURL();
149143
}
150144

@@ -159,7 +153,7 @@ private boolean isJwtNeeded() {
159153
return AnnotationSupport.findAnnotatedFields(currentTestClass, JwtConfig.class).size() > 0;
160154
}
161155

162-
private ApplicationContainer autoDiscoverMPApp(Class<?> clazz, boolean errorIfNone) {
156+
ApplicationContainer autoDiscoverMPApp(Class<?> clazz, boolean errorIfNone) {
163157
// First check for any MicroProfileApplicaiton directly present on the test class
164158
List<Field> mpApps = AnnotationSupport.findAnnotatedFields(clazz, Container.class,
165159
f -> Modifier.isStatic(f.getModifiers()) &&

modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/config/HollowTestcontainersConfigurationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void testEnvVarUnchanged() {
8888

8989
@Test
9090
public void testApplicationURL() {
91-
assertEquals("http://localhost:9080", ApplicationEnvironment.Resolver.load().getApplicationURL());
91+
assertEquals("http://localhost:9080/", ApplicationEnvironment.Resolver.load().getApplicationURL());
9292
}
9393

9494
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
26+
import org.junit.jupiter.api.Test;
27+
import org.microshed.testing.ApplicationEnvironment;
28+
import org.microshed.testing.jupiter.MicroShedTest;
29+
import org.microshed.testing.testcontainers.ApplicationContainer;
30+
import org.testcontainers.junit.jupiter.Container;
31+
32+
@MicroShedTest
33+
public class HollowTestcontainersConfigurationTest2 {
34+
35+
// This cointainer never actually gets started, since we are running in hollow mode
36+
@Container
37+
public static ApplicationContainer app = new ApplicationContainer(Paths.get("src", "test", "resources", "Dockerfile"))
38+
.withExposedPorts(9443)
39+
.withAppContextRoot("/myservice");
40+
41+
@Test
42+
public void testCorrectEnvironment() {
43+
assertEquals(HollowTestcontainersConfiguration.class, ApplicationEnvironment.Resolver.load().getClass());
44+
assertTrue(ApplicationEnvironment.Resolver.isSelected(HollowTestcontainersConfiguration.class),
45+
"Expected HollowTestcontainersConfiguration to be selected but it was not");
46+
assertTrue(HollowTestcontainersConfiguration.available(),
47+
"Expected HollowTestcontainersConfiguration to be available but it was not");
48+
}
49+
50+
@Test
51+
public void testApplicationURLWithPath() {
52+
assertEquals("http://localhost:9080/myservice", ApplicationEnvironment.Resolver.load().getApplicationURL());
53+
}
54+
55+
}

0 commit comments

Comments
 (0)