diff --git a/CHANGELOG.md b/CHANGELOG.md index 52f2147c666..dc1a6927a0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ All notable changes to this project will be documented in this file. ### Fixed - - Fixed problem with case-sensitivity when checking internal port. ([\#524](https://github.com/testcontainers/testcontainers-java/pull/524)) +- Fixed problem with case-sensitivity when checking internal port. ([\#524](https://github.com/testcontainers/testcontainers-java/pull/524)) +- Add retry logic around checkExposedPort pre-flight check for improved robustness ([\#513](https://github.com/testcontainers/testcontainers-java/issues/513)) ### Changed - Added `getDatabaseName` method to JdbcDatabaseContainer, MySQLContainer, PostgreSQLContainer ([\#473](https://github.com/testcontainers/testcontainers-java/issues/473)) @@ -18,8 +19,7 @@ All notable changes to this project will be documented in this file. - Stopping creation of temporary directory prior to creating temporary file ([\#443](https://github.com/testcontainers/testcontainers-java/issues/443)) - Ensure that temp files are created in a temp directory ([\#423](https://github.com/testcontainers/testcontainers-java/issues/423)) - Added `WaitAllStrategy` as a mechanism for composing multiple startup `WaitStrategy` objects together -- Changed `BrowserWebDriverContainer` to use improved wait strategies, to eliminate race conditions when starting VNC recording containers. This should lead to far fewer 'error' messages logged when starting up selenium containers, and less exposure to race related bugs (fixes [\#466](https://github.com/testcontainers/testcontainers-java/issues/466)). -- Add retry logic around checkExposedPort pre-flight check for improved robustness. +- Changed `BrowserWebDriverContainer` to use improved wait strategies, to eliminate race conditions when starting VNC recording containers. This should lead to far fewer 'error' messages logged when starting up selenium containers, and less exposure to race related bugs (fixes [\#466](https://github.com/testcontainers/testcontainers-java/issues/466)). ### Changed - Make Network instances reusable (i.e. work with `@ClassRule`) ([\#469](https://github.com/testcontainers/testcontainers-java/issues/469)) diff --git a/core/src/main/java/org/testcontainers/DockerClientFactory.java b/core/src/main/java/org/testcontainers/DockerClientFactory.java index ef0edab403c..c7568fd8b40 100644 --- a/core/src/main/java/org/testcontainers/DockerClientFactory.java +++ b/core/src/main/java/org/testcontainers/DockerClientFactory.java @@ -14,6 +14,7 @@ import org.apache.commons.io.IOUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; +import org.rnorth.ducttape.unreliables.Unreliables; import org.rnorth.visibleassertions.VisibleAssertions; import org.testcontainers.dockerclient.*; import org.testcontainers.utility.ComparableVersion; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Optional; import java.util.ServiceLoader; +import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -177,16 +179,18 @@ private void checkMountableFile(DockerClient dockerClient, String id) { } private void checkExposedPort(String hostIpAddress, DockerClient dockerClient, String id) { - InspectContainerResponse inspectedContainer = dockerClient.inspectContainerCmd(id).exec(); + String response = Unreliables.retryUntilSuccess(3, TimeUnit.SECONDS, () -> { + InspectContainerResponse inspectedContainer = dockerClient.inspectContainerCmd(id).exec(); - String portSpec = inspectedContainer.getNetworkSettings().getPorts().getBindings().values().iterator().next()[0].getHostPortSpec(); + String portSpec = inspectedContainer.getNetworkSettings().getPorts().getBindings().values().iterator().next()[0].getHostPortSpec(); + + try (Socket socket = new Socket(hostIpAddress, Integer.parseInt(portSpec))) { + return IOUtils.toString(socket.getInputStream(), Charset.defaultCharset()); + } catch (IOException e) { + return e.getMessage(); + } + }); - String response; - try (Socket socket = new Socket(hostIpAddress, Integer.parseInt(portSpec))) { - response = IOUtils.toString(socket.getInputStream(), Charset.defaultCharset()); - } catch (IOException e) { - response = e.getMessage(); - } VisibleAssertions.assertEquals("A port exposed by a docker container should be accessible", "hello", response); }