77import org .junit .AfterClass ;
88import org .junit .BeforeClass ;
99import org .junit .Test ;
10+ import org .junit .runner .Description ;
11+ import org .junit .runners .model .Statement ;
12+ import org .testcontainers .DockerClientFactory ;
1013import org .testcontainers .TestImages ;
1114import org .testcontainers .Testcontainers ;
1215
16+ import java .io .IOException ;
1317import java .io .OutputStream ;
1418import java .net .InetSocketAddress ;
19+ import java .util .UUID ;
1520
1621import static org .assertj .core .api .Assertions .assertThat ;
1722
1823public 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