Я разрабатываю системные/интеграционные тесты на основе решения Testcontainers. Мне необходимо использовать образ нашей собственной базы данных PostgreSQL с уже примененной схемой базы данных.
По этой причине я использую Testcontainers GenericContainer.
private static final GenericContainer postgresDb = new GenericContainer(POSTGRES_IMAGE).withExposedPorts(5432);
Я разрабатываю тесты с помощью Spring Boot, поэтому я создал абстрактный класс, который будет содержать эту конфигурацию для всех тестов.
@ActiveProfiles("test")
@SpringBootTest
public abstract class AbstractTests {
private static final DockerImageName POSTGRES_IMAGE = DockerImageName.parse("docker-name:latest");
private static final GenericContainer postgresDb;
static {
postgresDb = new GenericContainer(POSTGRES_IMAGE)
.withExposedPorts(5432);
postgresDb.withStartupTimeout(Duration.ofSeconds(30))
.start();
}
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) throws InterruptedException {
final String s = "jdbc:postgresql://"+ postgresDb.getHost() +":"+ postgresDb.getMappedPort(5432) + "/test";
registry.add("spring.datasource.url", () ->s);
}
}
Однако проблема в том, что когда тесты выполняются, контейнер все еще запускается. Это withStartupTimeout(Duration.ofSeconds(30)) по какой-то причине не работает.
Когда я останавливаюсь в методе отладки в свойствах и даю пару секунд для запуска контейнера, все тесты выполняются нормально.
Когда тесты терпят неудачу, я вижу следующий журнал:
org.postgresql.util.PSQLException: FATAL: the database system is starting up
Если я поставлю Thread.sleep(..), это тоже сработает, это не предпочтительное решение.
Каково правильное решение, чтобы подождать или правильная стратегия, чтобы знать, что контейнер готов?