junit - 有序启动和等待容器

标签 junit apache-kafka apache-kafka-connect testcontainers

在我的测试中,我有两个容器使用 @Testcontainers 和 Junit5,一个 Kafka 和一个 KafkaConnect

@Container
private final KafkaContainer kafka = new KafkaContainer()
        .withNetwork(network)
        .withNetworkAliases("kafka");

@Container
private final GenericContainer KafkaConnect = 
        new GenericContainer("confluentinc/cp-kafka-connect:latest")
        .withEnv("CONNECT_BOOTSTRAP_SERVERS", "kafka:9092")
        .withEnv("CONNECT_REST_PORT", 8083)
        .withNetwork(network)
        ...

当我执行测试时,我发现一个错误,因为 kafkaConnect 中的 Kafka Connect 服务未正确启动(映射端口 8083 未监听)。这是因为 kafkaConnectkafka 之前启动,并且在 kafkaConnect 执行期间到达 kafka:9092 url 时没有由于 kafka 尚未运行,因此获得了响应。 然后,我试图推迟 kafkaConnect 启动以等待 kafka 以确保 kafka:9092 可用性。

我尝试了不同的方法来做到这一点,但我没有解决问题。 我尝试添加一些配置。

启动超时。据我所知,此配置不会推迟启动操作。它只是增加了检查容器是否启动的周期。

.withStartupTimeout(Duration.of(240, SECONDS)) 

我还为 waitingFor 尝试了一些配置,例如基于超时的配置,正如预期的那样,它会产生与 withStartupTimeout 相同的结果

.waitingFor(Wait.defaultWaitStrategy().withStartupTimeout(...))

或基于端口,这不能解决我的问题,因为它不指向 kafka 容器,而是指向 kafkaConnect

.waitingFor(Wait.forHttp("http://kafka:9092"))

我也尝试添加一些启动尝试,但它没有解决问题,因为 kafkaConnect 有时会重新启动,但总是在 kafka 之前。

作为解决方案,我删除了 kafkaConnect 声明的 @Container 以便手动管理其生命周期,因此我添加了明确的开始测试用例,见下文

@Test
test() {
    kafkaConnect.start();
    ...
}

这确保 kafkaConnectkafka 之后启动。但是,我没有找到在容器定义期间通过策略、策略或类似的方式定义顺序的解决方案,以便添加容器之间的依赖关系并避免命令式和手动的生命周期管理。

这可能吗?

最佳答案

import org.junit.rules.RuleChain;

// @Container <-- Remove annotation.
private final KafkaContainer kafka = new KafkaContainer()...;

// @Container <-- Remove annotation.
private final GenericContainer kafkaConnect = 
        new GenericContainer("confluentinc/cp-kafka-connect:latest")
        .withEnv("CONNECT_BOOTSTRAP_SERVERS", "kafka:9092")
        ...;

// Start the containers in the correct order.  Prevents
// "Mapped port can only be obtained after the container is started"
// error.
@Rule
public final RuleChain chain = 
    RuleChain
    // Started first.
    .outerRule(kafka)
    // Started later.
    .around(kafkaConnect);

关于junit - 有序启动和等待容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55515090/

相关文章:

postgresql - Kafka Connect Debezium postgres

java - 将日志从 kafka 连接器推送到端口

docker - 为什么当我创建它的节点被杀死时,Kafka 分布式连接器就会死亡?

apache-spark - 为什么我们需要 kafka 将数据提供给 apache spark

java - JUnit 测试在 H2 的 RUNSCRIPT 完成之前开始

java - org.springframework.web.bind.MethodArgumentNotValidException

java - 为什么元数据添加到这个 Kafka 连接器的输出中?

apache-kafka - 未应用 Kafka 连接转换

android - RxJava2 与 JUnit : no exceptions thrown in tests

java - 如何使用Java中的新API替换sun.util.calendar.ZoneInfo