Timeout issue with Testcontainers JDBC support
After upgrading Quarkus to 2.8.2
for my project, the GitHub Actions build failed. Below is the stacktrace.
java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
Caused by: java.lang.RuntimeException: Failed to start quarkus
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException:
Unable to obtain connection from database: Acquisition timeout while waiting for new connection
-----------------------------------------------------------------------------------------------
SQL State : null
Error Code : 0
Message : Acquisition timeout while waiting for new connection
Caused by: java.sql.SQLException: Acquisition timeout while waiting for new connection
Caused by: java.util.concurrent.TimeoutException
From the message, we can know that Flyway couldn't connect to the PostgreSQL database started by Testcontainers.
PostgreSQL containers were started using Testcontainers JDBC support. When using this approach, the container startup timeout cannot be configured. When running with GitHub Actions, container images need to be pulled down first, so the default timeout duration was not long enough for the container to finish startup.
"%test":
quarkus:
datasource:
jdbc:
driver: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:postgresql:12:///
To solve this issue, a Quarkus test resource for PostgreSQL is added. withStartupTimeout(Duration.ofMinutes(5))
is used to set the startup timeout to 5 minutes. @QuarkusTestResource(PostgreSQLResource.class)
needs to be added to the test class.
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import java.time.Duration;
import java.util.Map;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
public class PostgreSQLResource implements QuarkusTestResourceLifecycleManager {
private final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
DockerImageName.parse("postgres:12")
).withStartupTimeout(Duration.ofMinutes(5));
@Override
public Map<String, String> start() {
this.postgres.start();
return Map.of(
"quarkus.datasource.jdbc.url", this.postgres.getJdbcUrl(),
"quarkus.datasource.username", this.postgres.getUsername(),
"quarkus.datasource.password", this.postgres.getPassword()
);
}
@Override
public void stop() {
}
}
With this new Quarkus test resource, GitHub Actions builds can pass.