等待容器在测试容器中使用 GenericContainer 启动自定义 PostgreSQL 映像

Posted

技术标签:

【中文标题】等待容器在测试容器中使用 GenericContainer 启动自定义 PostgreSQL 映像【英文标题】:Wait till container starts in testcontainers with GenericContainer for custom PostgreSQL image 【发布时间】:2021-08-28 06:04:03 【问题描述】:

我正在开发基于 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(..) 它也可以,这不是更好的解决方案。

什么是等待的正确解决方案或知道容器已准备就绪的正确策略?

【问题讨论】:

【参考方案1】:

我认为答案在他们的documentation,尤其是这部分:

日志输出等待策略

在某些情况下,容器的日志输出是一种确定容器是否准备就绪的简单方法。例如,我们可以在容器的日志中等待 `Ready' 消息,如下所示:

public GenericContainer containerWithLogWait = new GenericContainer(DockerImageName.parse("redis:5.0.3"))
    .withExposedPorts(6379)
    .waitingFor(
        Wait.forLogMessage(".*Ready to accept connections.*\\n", 1)
    );

注意:您需要将消息更改为:

".*database system is ready to accept connections.*"

【讨论】:

以上是关于等待容器在测试容器中使用 GenericContainer 启动自定义 PostgreSQL 映像的主要内容,如果未能解决你的问题,请参考以下文章

有序启动和等待容器

如何在集成测试中等待某些操作

Testcontainers:使用 GitLab CI “等待容器端口打开超时”

Azure 存储容器命令运行时间极长

Docker Compose 在启动 Y 之前等待容器 X

在 Jenkins Docker 代理中使用测试容器:容器无法启动,NoRouteToHostException