Skip to content

Commit 6a9355f

Browse files
committed
make exposing host ports work when used together with a reusable container
1 parent d3d1085 commit 6a9355f

File tree

2 files changed

+121
-2
lines changed

2 files changed

+121
-2
lines changed

core/src/main/java/org/testcontainers/containers/GenericContainer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,9 @@ private void tryStart() {
446446
copyToTransferableContainerPathMap.forEach(this::copyFileToContainer);
447447
}
448448

449-
connectToPortForwardingNetwork(createCommand.getNetworkMode());
449+
if (!reused) {
450+
connectToPortForwardingNetwork(createCommand.getNetworkMode());
451+
}
450452

451453
if (!reused) {
452454
containerIsCreated(containerId);

core/src/test/java/org/testcontainers/containers/ExposedHostTest.java

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@
77
import org.junit.AfterClass;
88
import org.junit.BeforeClass;
99
import org.junit.Test;
10+
import org.junit.runner.Description;
11+
import org.junit.runners.model.Statement;
12+
import org.testcontainers.DockerClientFactory;
1013
import org.testcontainers.TestImages;
1114
import org.testcontainers.Testcontainers;
1215

16+
import java.io.IOException;
1317
import java.io.OutputStream;
1418
import java.net.InetSocketAddress;
19+
import java.util.UUID;
1520

1621
import static org.assertj.core.api.Assertions.assertThat;
1722

1823
public class ExposedHostTest {
1924

2025
private static HttpServer server;
26+
private static Network network;
2127

2228
@BeforeClass
2329
public static void setUpClass() throws Exception {
@@ -33,13 +39,14 @@ public static void setUpClass() throws Exception {
3339
}
3440
}
3541
);
36-
3742
server.start();
43+
network = createReusableNetwork(UUID.randomUUID());
3844
}
3945

4046
@AfterClass
4147
public static void tearDownClass() {
4248
server.stop(0);
49+
DockerClientFactory.instance().client().removeNetworkCmd(network.getId()).exec();
4350
}
4451

4552
@After
@@ -82,6 +89,65 @@ public void testExposedHostPortOnFixedInternalPorts() {
8289
assertResponse(new GenericContainer<>(tinyContainerDef()), 81);
8390
}
8491

92+
@Test
93+
public void testExposedHostWithReusableContainerAndFixedNetworkName() throws IOException, InterruptedException {
94+
Testcontainers.exposeHostPorts(server.getAddress().getPort());
95+
96+
try (
97+
GenericContainer<?> container = new GenericContainer<>(tinyContainerDef())
98+
.withReuse(true)
99+
.withNetwork(network)
100+
) {
101+
container.start();
102+
103+
assertHttpResponseFromHost(container, server.getAddress().getPort());
104+
105+
PortForwardingContainer.INSTANCE.reset();
106+
Testcontainers.exposeHostPorts(server.getAddress().getPort());
107+
108+
try (
109+
GenericContainer<?> reusedContainer = new GenericContainer<>(tinyContainerDef())
110+
.withReuse(true)
111+
.withNetwork(network)
112+
) {
113+
reusedContainer.start();
114+
115+
assertThat(reusedContainer.getContainerId()).isEqualTo(container.getContainerId());
116+
assertHttpResponseFromHost(reusedContainer, server.getAddress().getPort());
117+
}
118+
}
119+
}
120+
121+
@Test
122+
public void testExposedHostOnFixedInternalPortsWithReusableContainerAndFixedNetworkName()
123+
throws IOException, InterruptedException {
124+
Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 1234));
125+
126+
try (
127+
GenericContainer<?> container = new GenericContainer<>(tinyContainerDef())
128+
.withReuse(true)
129+
.withNetwork(network)
130+
) {
131+
container.start();
132+
133+
assertHttpResponseFromHost(container, 1234);
134+
135+
PortForwardingContainer.INSTANCE.reset();
136+
Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 1234));
137+
138+
try (
139+
GenericContainer<?> reusedContainer = new GenericContainer<>(tinyContainerDef())
140+
.withReuse(true)
141+
.withNetwork(network)
142+
) {
143+
reusedContainer.start();
144+
145+
assertThat(reusedContainer.getContainerId()).isEqualTo(container.getContainerId());
146+
assertHttpResponseFromHost(reusedContainer, 1234);
147+
}
148+
}
149+
}
150+
85151
@SneakyThrows
86152
protected void assertResponse(GenericContainer<?> container, int port) {
87153
try {
@@ -108,4 +174,55 @@ private static class TinyContainerDef extends ContainerDef {
108174
setCommand("top");
109175
}
110176
}
177+
178+
private void assertHttpResponseFromHost(GenericContainer<?> container, int port)
179+
throws IOException, InterruptedException {
180+
String httpResponseFromHost = container
181+
.execInContainer("wget", "-O", "-", "http://host.testcontainers.internal:" + port)
182+
.getStdout();
183+
assertThat(httpResponseFromHost).isEqualTo("Hello World!");
184+
}
185+
186+
private static Network createReusableNetwork(UUID name) {
187+
String id = DockerClientFactory
188+
.instance()
189+
.client()
190+
.listNetworksCmd()
191+
.exec()
192+
.stream()
193+
.filter(network ->
194+
network.getName().equals(name.toString()) &&
195+
network.getLabels().equals(DockerClientFactory.DEFAULT_LABELS)
196+
)
197+
.map(com.github.dockerjava.api.model.Network::getId)
198+
.findFirst()
199+
.orElseGet(() ->
200+
DockerClientFactory
201+
.instance()
202+
.client()
203+
.createNetworkCmd()
204+
.withName(name.toString())
205+
.withCheckDuplicate(true)
206+
.withLabels(DockerClientFactory.DEFAULT_LABELS)
207+
.exec()
208+
.getId()
209+
);
210+
211+
return new Network() {
212+
@Override
213+
public Statement apply(Statement base, Description description) {
214+
return base;
215+
}
216+
217+
@Override
218+
public String getId() {
219+
return id;
220+
}
221+
222+
@Override
223+
public void close() {
224+
// never close
225+
}
226+
};
227+
}
111228
}

0 commit comments

Comments
 (0)