Skip to content

Commit

Permalink
Don't interfere with testcontainers' ability to determine running con…
Browse files Browse the repository at this point in the history
…tainers

This is only applicable for containers running on a shared network.
Essentially we now ensure that for containers whose status can only
be determined by making a network call, that testcontainers can make
that network call.
In testcontainers 1.15.x, the library would actually not fail
if the connection could not be made, but would essentially give
up after a while.
With this change, startup of the tests is actually faster since testcontainers
actually determines the running status much faster.
In 1.16 the behavior seems to have changed and the testcontainers seems to try
to launch new containers and never gives up.
  • Loading branch information
geoand committed Aug 25, 2021
1 parent ba31e14 commit cf0d402
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ public static String configureSharedNetwork(GenericContainer<?> container, Strin
String hostName = hostNamePrefix + "-" + Base58.randomString(5);
container.setNetworkAliases(Collections.singletonList(hostName));

// we need to clear the exposed ports as they don't make sense when the application is going to
// to be communicating with the DB over the same network
container.setExposedPorts(Collections.emptyList());
return hostName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ DevServicesDatasourceProviderBuildItem setupDB2(
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode) {
Db2Container container = new QuarkusDb2Container(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent())
.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
QuarkusDb2Container container = new QuarkusDb2Container(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent());
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for IBM Db2 started.");

return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),
return new RunningDevServicesDatasource(container.getEffectiveJdbcUrl(), container.getUsername(),
container.getPassword(),
new Closeable() {
@Override
Expand Down Expand Up @@ -86,8 +86,11 @@ protected void configure() {
}
}

@Override
public String getJdbcUrl() {
// this is meant to be called by Quarkus code and is not strictly needed
// in the DB2 case as testcontainers does not try to establish
// a connection to determine if the container is ready, but we do it anyway to be consistent across
// DB containers
public String getEffectiveJdbcUrl() {
if (useSharedNetwork) {
// in this case we expose the URL using the network alias we created in 'configure'
// and the container port since the application communicating with this container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ DevServicesDatasourceProviderBuildItem setupMariaDB(
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode) {
MariaDBContainer container = new QuarkusMariaDBContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent())
.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
QuarkusMariaDBContainer container = new QuarkusMariaDBContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent());
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for MariaDB started.");

return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),
return new RunningDevServicesDatasource(container.getEffectiveJdbcUrl(), container.getUsername(),
container.getPassword(),
new Closeable() {
@Override
Expand Down Expand Up @@ -84,8 +84,9 @@ protected void configure() {
}
}

@Override
public String getJdbcUrl() {
// this is meant to be called by Quarkus code and is needed in order to not disrupt testcontainers
// from being able to determine the status of the container (which it does by trying to acquire a connection)
public String getEffectiveJdbcUrl() {
if (useSharedNetwork) {
String additionalUrlParams = constructUrlParameters("?", "&");
return "jdbc:mariadb://" + hostName + ":" + PORT + "/" + getDatabaseName() + additionalUrlParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.OptionalInt;

import org.jboss.logging.Logger;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.utility.DockerImageName;

Expand Down Expand Up @@ -36,15 +35,15 @@ DevServicesDatasourceProviderBuildItem setupMSSQL(
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode) {
JdbcDatabaseContainer container = new QuarkusMSSQLServerContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent())
.withPassword(password.orElse("Quarkuspassword1"));
QuarkusMSSQLServerContainer container = new QuarkusMSSQLServerContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent());
container.withPassword(password.orElse("Quarkuspassword1"));
additionalProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for Microsoft SQL Server started.");

return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),
return new RunningDevServicesDatasource(container.getEffectiveJdbcUrl(), container.getUsername(),
container.getPassword(),
new Closeable() {
@Override
Expand Down Expand Up @@ -86,8 +85,9 @@ protected void configure() {
}
}

@Override
public String getJdbcUrl() {
// this is meant to be called by Quarkus code and is needed in order to not disrupt testcontainers
// from being able to determine the status of the container (which it does by trying to acquire a connection)
public String getEffectiveJdbcUrl() {
if (useSharedNetwork) {
// in this case we expose the URL using the network alias we created in 'configure'
// and the container port since the application communicating with this container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ DevServicesDatasourceProviderBuildItem setupMysql(
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode) {
MySQLContainer container = new QuarkusMySQLContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent())
.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
QuarkusMySQLContainer container = new QuarkusMySQLContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent());
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for MySQL started.");

return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),
return new RunningDevServicesDatasource(container.getEffectiveJdbcUrl(), container.getUsername(),
container.getPassword(),
new Closeable() {
@Override
Expand Down Expand Up @@ -83,8 +83,9 @@ protected void configure() {
}
}

@Override
public String getJdbcUrl() {
// this is meant to be called by Quarkus code and is needed in order to not disrupt testcontainers
// from being able to determine the status of the container (which it does by trying to acquire a connection)
public String getEffectiveJdbcUrl() {
if (useSharedNetwork) {
// in this case we expose the URL using the network alias we created in 'configure'
// and the container port since the application communicating with this container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ DevServicesDatasourceProviderBuildItem setupPostgres(
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode) {
PostgreSQLContainer container = new QuarkusPostgreSQLContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent())
.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
QuarkusPostgreSQLContainer container = new QuarkusPostgreSQLContainer(imageName, fixedExposedPort,
devServicesSharedNetworkBuildItem.isPresent());
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);

container.start();

LOG.info("Dev Services for PostgreSQL started.");

return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),
return new RunningDevServicesDatasource(container.getEffectiveJdbcUrl(), container.getUsername(),
container.getPassword(),
new Closeable() {
@Override
Expand Down Expand Up @@ -84,8 +84,11 @@ protected void configure() {
}
}

@Override
public String getJdbcUrl() {
// this is meant to be called by Quarkus code and is not strictly needed
// in the PostgreSQL case as testcontainers does not try to establish
// a connection to determine if the container is ready, but we do it anyway to be consistent across
// DB containers
public String getEffectiveJdbcUrl() {
if (useSharedNetwork) {
// in this case we expose the URL using the network alias we created in 'configure'
// and the container port since the application communicating with this container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ protected void configure() {
setNetwork(Network.SHARED);
hostName = "redis-" + Base58.randomString(5);
setNetworkAliases(Collections.singletonList(hostName));
addExposedPort(REDIS_EXPOSED_PORT);
return;
}

Expand Down

0 comments on commit cf0d402

Please sign in to comment.