diff --git a/core/src/main/java/org/testcontainers/Testcontainers.java b/core/src/main/java/org/testcontainers/Testcontainers.java index 4d7f5af4753..0f83725c55b 100644 --- a/core/src/main/java/org/testcontainers/Testcontainers.java +++ b/core/src/main/java/org/testcontainers/Testcontainers.java @@ -1,6 +1,10 @@ package org.testcontainers; +import java.util.Map; +import java.util.Map.Entry; + import lombok.experimental.UtilityClass; + import org.testcontainers.containers.PortForwardingContainer; @UtilityClass @@ -11,4 +15,10 @@ public void exposeHostPorts(int... ports) { PortForwardingContainer.INSTANCE.exposeHostPort(port); } } + + public void exposeHostPorts(Map ports) { + for(Entry entry : ports.entrySet()) { + PortForwardingContainer.INSTANCE.exposeHostPort(entry.getKey(), entry.getValue()); + } + } } diff --git a/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java b/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java index 576ac33d148..852a986b58f 100644 --- a/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java +++ b/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java @@ -8,10 +8,12 @@ import org.testcontainers.utility.TestcontainersConfiguration; import java.time.Duration; +import java.util.AbstractMap; import java.util.Collections; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public enum PortForwardingContainer { @@ -19,7 +21,7 @@ public enum PortForwardingContainer { private GenericContainer container; - private final Set exposedPorts = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Set> exposedPorts = Collections.newSetFromMap(new ConcurrentHashMap<>()); @Getter(value = AccessLevel.PRIVATE, lazy = true) private final Connection sshConnection = createSSHSession(); @@ -56,8 +58,13 @@ private Connection createSSHSession() { @SneakyThrows public void exposeHostPort(int port) { - if (exposedPorts.add(port)) { - getSshConnection().requestRemotePortForwarding("", port, "localhost", port); + exposeHostPort(port, port); + } + + @SneakyThrows + public void exposeHostPort(int hostPort, int containerPort) { + if (exposedPorts.add(new AbstractMap.SimpleEntry<>(hostPort, containerPort))) { + getSshConnection().requestRemotePortForwarding("", containerPort, "localhost", hostPort); } } diff --git a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java index 30bb6573533..8c98b0730b0 100644 --- a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java +++ b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java @@ -1,5 +1,6 @@ package org.testcontainers.containers; +import com.google.common.collect.ImmutableMap; import com.sun.net.httpserver.HttpServer; import lombok.SneakyThrows; import org.junit.AfterClass; @@ -30,6 +31,9 @@ public static void setUpClass() throws Exception { server.start(); Testcontainers.exposeHostPorts(server.getAddress().getPort()); + + Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 80)); + Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 81)); } @AfterClass @@ -39,22 +43,28 @@ public static void tearDownClass() throws Exception { @Test public void testExposedHost() throws Exception { - assertResponse(new GenericContainer().withCommand("top")); + assertResponse(new GenericContainer().withCommand("top"), server.getAddress().getPort()); } @Test public void testExposedHostWithNetwork() throws Exception { try (Network network = Network.newNetwork()) { - assertResponse(new GenericContainer().withNetwork(network).withCommand("top")); + assertResponse(new GenericContainer().withNetwork(network).withCommand("top"), server.getAddress().getPort()); } } + + @Test + public void testExposedHostPortOnFixedInternalPorts() throws Exception { + assertResponse(new GenericContainer().withCommand("top"), 80); + assertResponse(new GenericContainer().withCommand("top"), 81); + } @SneakyThrows - protected void assertResponse(GenericContainer container) { + protected void assertResponse(GenericContainer container, int port) { try { container.start(); - String response = container.execInContainer("wget", "-O", "-", "http://host.testcontainers.internal:" + server.getAddress().getPort()).getStdout(); + String response = container.execInContainer("wget", "-O", "-", "http://host.testcontainers.internal:" + port).getStdout(); assertEquals("received response", "Hello World!", response); } finally {