Skip to content

Commit f0901c6

Browse files
authored
Merge pull request #147 from aguibert/hollow-waitStrategy
Still honor WaitStrategy in Hollow modes
2 parents 4b1b72e + 0183cb1 commit f0901c6

5 files changed

Lines changed: 118 additions & 10 deletions

File tree

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

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,20 @@
4747
import org.microshed.testing.ManuallyStartedConfiguration;
4848
import org.microshed.testing.testcontainers.config.HollowTestcontainersConfiguration;
4949
import org.microshed.testing.testcontainers.config.TestcontainersConfiguration;
50+
import org.microshed.testing.testcontainers.internal.HollowContainerInspection;
5051
import org.microshed.testing.testcontainers.internal.ImageFromDockerfile;
5152
import org.microshed.testing.testcontainers.spi.ServerAdapter;
5253
import org.slf4j.Logger;
5354
import org.slf4j.LoggerFactory;
5455
import org.testcontainers.DockerClientFactory;
5556
import org.testcontainers.containers.GenericContainer;
5657
import org.testcontainers.containers.output.Slf4jLogConsumer;
58+
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
5759
import org.testcontainers.containers.wait.strategy.Wait;
5860
import org.testcontainers.containers.wait.strategy.WaitStrategy;
5961
import org.testcontainers.utility.Base58;
6062

63+
import com.github.dockerjava.api.command.InspectContainerResponse;
6164
import com.github.dockerjava.api.command.InspectImageResponse;
6265
import com.github.dockerjava.api.model.ExposedPort;
6366

@@ -223,10 +226,12 @@ private void commonInit() {
223226
withAppContextRoot("/");
224227
if (isHollow) {
225228
setContainerIpAddress(ManuallyStartedConfiguration.getHostname());
226-
if (ManuallyStartedConfiguration.getHttpsPort() != -1)
227-
setFirstMappedPort(ManuallyStartedConfiguration.getHttpsPort());
228-
else
229-
setFirstMappedPort(ManuallyStartedConfiguration.getHttpPort());
229+
List<Integer> ports = new ArrayList<>(2);
230+
ports.add(ManuallyStartedConfiguration.getHttpsPort());
231+
ports.add(ManuallyStartedConfiguration.getHttpPort());
232+
ports.removeIf(p -> p == -1);
233+
setExposedPorts(ports);
234+
setFirstMappedPort(ports.get(0));
230235
withAppContextRoot(ManuallyStartedConfiguration.getBasePath());
231236
}
232237
}
@@ -267,6 +272,8 @@ protected void doStart() {
267272
Map<String, String> env = getEnvMap();
268273
if (env.size() > 0)
269274
getServerAdapter().setConfigProperties(env);
275+
configure();
276+
waitUntilContainerStarted();
270277
lateBind_started = true;
271278
return;
272279
}
@@ -317,6 +324,15 @@ public Integer getMappedPort(int originalPort) {
317324
}
318325
}
319326

327+
@Override
328+
public List<Integer> getExposedPorts() {
329+
if (isHollow) {
330+
return Collections.singletonList(lateBind_port);
331+
} else {
332+
return super.getExposedPorts();
333+
}
334+
}
335+
320336
/**
321337
* @param appContextRoot the application context root. The protocol, hostname, and port do not need to be
322338
* included in the <code>appContextRoot</code> parameter. For example, an application
@@ -357,8 +373,13 @@ public ApplicationContainer withReadinessPath(String readinessUrl) {
357373
public ApplicationContainer withReadinessPath(String readinessUrl, int timeoutSeconds) {
358374
Objects.requireNonNull(readinessUrl);
359375
readinessUrl = buildPath(readinessUrl);
360-
waitingFor(Wait.forHttp(readinessUrl)
361-
.withStartupTimeout(Duration.ofSeconds(timeoutSeconds)));
376+
HttpWaitStrategy strat = Wait.forHttp(readinessUrl);
377+
strat.withStartupTimeout(Duration.ofSeconds(timeoutSeconds));
378+
getExposedPorts()
379+
.stream()
380+
.findFirst()
381+
.ifPresent(p -> strat.forPort(p));
382+
waitingFor(strat);
362383
return this;
363384
}
364385

@@ -464,6 +485,22 @@ public String getBaseURL() {
464485
return "http://" + getContainerIpAddress() + ':' + getFirstMappedPort();
465486
}
466487

488+
@Override
489+
public InspectContainerResponse getContainerInfo() {
490+
if (isHollow)
491+
return new HollowContainerInspection(this);
492+
else
493+
return super.getContainerInfo();
494+
}
495+
496+
@Override
497+
public String getDockerImageName() {
498+
if (isHollow)
499+
return "HollowApplicationContainer";
500+
else
501+
return super.getDockerImageName();
502+
}
503+
467504
/**
468505
* @return The {@link ServerAdapter} that is currently applied for this instance
469506
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void applyConfiguration(Class<?> testClass) {
8181
Map<Integer, String> fixedExposedPorts = new HashMap<>();
8282
for (GenericContainer<?> c : allContainers()) {
8383
for (Integer p : c.getExposedPorts()) {
84-
if (fixedExposedPorts.containsKey(p)) {
84+
if (fixedExposedPorts.containsKey(p) && !(c instanceof ApplicationContainer)) {
8585
throw new ExtensionConfigurationException("Cannot expose port " + p + " for " + c.getDockerImageName() +
8686
" because another container (" + fixedExposedPorts.get(p) +
8787
") is already using it.");
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2020 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.internal;
20+
21+
import org.microshed.testing.testcontainers.ApplicationContainer;
22+
23+
import com.github.dockerjava.api.command.InspectContainerResponse;
24+
25+
public class HollowContainerInspection extends InspectContainerResponse {
26+
27+
private final ApplicationContainer app;
28+
29+
public HollowContainerInspection(ApplicationContainer app) {
30+
this.app = app;
31+
}
32+
33+
@Override
34+
public String getName() {
35+
return app.getDockerImageName();
36+
}
37+
38+
}

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@
2222
import static org.junit.jupiter.api.Assertions.assertTrue;
2323

2424
import java.nio.file.Paths;
25+
import java.time.Duration;
2526
import java.util.Map;
2627

2728
import org.junit.jupiter.api.Test;
2829
import org.microshed.testing.ApplicationEnvironment;
2930
import org.microshed.testing.jupiter.MicroShedTest;
3031
import org.microshed.testing.testcontainers.ApplicationContainer;
3132
import org.testcontainers.containers.MockServerContainer;
33+
import org.testcontainers.containers.wait.strategy.WaitStrategy;
34+
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
3235
import org.testcontainers.junit.jupiter.Container;
3336

3437
@MicroShedTest
3538
public class HollowTestcontainersConfigurationTest {
3639

40+
private static boolean waitedForStartup = false;
41+
3742
// This cointainer never actually gets started, since we are running in hollow mode
3843
@Container
3944
public static ApplicationContainer app = new ApplicationContainer(Paths.get("src", "test", "resources", "Dockerfile"))
@@ -45,7 +50,18 @@ public class HollowTestcontainersConfigurationTest {
4550
.withEnv("SVC_URL4", "http://mockserver:1080/hello/world")
4651
.withEnv("SVC_URL5", "http://mockserver:1080/hello/mockserver")
4752
.withEnv("SVC_URL6", oldValue -> "http://mockserver:1080")
48-
.withMpRestClient("com.foo.ExampleClass", "http://mockserver:1080");
53+
.withMpRestClient("com.foo.ExampleClass", "http://mockserver:1080")
54+
.waitingFor(new WaitStrategy() {
55+
@Override
56+
public WaitStrategy withStartupTimeout(Duration startupTimeout) {
57+
return this;
58+
}
59+
60+
@Override
61+
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget) {
62+
waitedForStartup = true;
63+
}
64+
});
4965

5066
@Container
5167
public static MockServerContainer mockServer = new MockServerContainer()
@@ -91,4 +107,9 @@ public void testApplicationURL() {
91107
assertEquals("http://localhost:9080/", ApplicationEnvironment.Resolver.load().getApplicationURL());
92108
}
93109

110+
@Test
111+
public void testWaitFor() {
112+
assertTrue(waitedForStartup, "The ApplicationContainer did not wait for startup in hollow mode");
113+
}
114+
94115
}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
import static org.junit.jupiter.api.Assertions.assertTrue;
2323

2424
import java.nio.file.Paths;
25+
import java.time.Duration;
2526

2627
import org.junit.jupiter.api.Test;
2728
import org.microshed.testing.ApplicationEnvironment;
2829
import org.microshed.testing.jupiter.MicroShedTest;
2930
import org.microshed.testing.testcontainers.ApplicationContainer;
31+
import org.testcontainers.containers.wait.strategy.WaitStrategy;
32+
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
3033
import org.testcontainers.junit.jupiter.Container;
3134

3235
@MicroShedTest
@@ -35,8 +38,17 @@ public class HollowTestcontainersConfigurationTest2 {
3538
// This cointainer never actually gets started, since we are running in hollow mode
3639
@Container
3740
public static ApplicationContainer app = new ApplicationContainer(Paths.get("src", "test", "resources", "Dockerfile"))
38-
.withExposedPorts(9443)
39-
.withAppContextRoot("/myservice");
41+
.withAppContextRoot("/myservice")
42+
.waitingFor(new WaitStrategy() {
43+
@Override
44+
public WaitStrategy withStartupTimeout(Duration startupTimeout) {
45+
return this;
46+
}
47+
48+
@Override
49+
public void waitUntilReady(WaitStrategyTarget waitStrategyTarget) {
50+
}
51+
});
4052

4153
@Test
4254
public void testCorrectEnvironment() {

0 commit comments

Comments
 (0)