【问题标题】:Testcontainers with Spring actuator带弹簧执行器的测试容器
【发布时间】:2021-03-16 11:23:45
【问题描述】:

我想在网络上运行一个带有测试容器的容器。我的容器包含一个 spring 应用程序,它有一个执行器端点来表达它的状态,它是 on:

/actuator/health

我的容器如下所示:

private final static Network network = Network.newNetwork();

private static final GenericContainer<?> myContainer = new GenericContainer<>("mycontainer:latest")
            .withExposedPorts(8443)
            .withNetwork(network)
            .withNetworkAliases("myContainer")
            .withClasspathResourceMapping("certs", "/app/certs", BindMode.READ_ONLY)
            .withClasspathResourceMapping("config", "/app/config", BindMode.READ_ONLY)
            .withLogConsumer(new Slf4jLogConsumer(log))
            .waitingFor(Wait.forHttp("/actuator/health").usingTls());

但是当我启动这个容器时,我得到了以下错误:

Caused by: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for URL to be accessible (https://localhost:33092/actuator/health should return HTTP [200])
    at org.testcontainers.containers.wait.strategy.HttpWaitStrategy.waitUntilReady(HttpWaitStrategy.java:214)
    at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:35)
    at org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:890)
    at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:441)
    ... 68 more

但是如果我在容器内的应用程序启动但我正在等待评估之后卷曲这个 url(在这个例子中:https://localhost:33092/actuator/health),我会得到这样的东西:

HTTP Status Code: 200
{
    "status": "UP"
}

我错过了什么?有任何想法吗?是bug吗?

【问题讨论】:

  • .withExposedPorts(8443) 应该是 33092 吗?
  • 没有 TLS 是否可以工作?没有自定义网络?
  • @FabienMIFSUD 不,传递给 .withExposedPorts() 的参数是容器内部的端口。在主机上,Testcontainers 将其映射到随机端口,在这种情况下,据我所知,它恰好是 33092。如果您感兴趣 - testcontainers.org/features/networking/…
  • @VitalyChura 不,遗憾的是,如果没有 TLS,它就无法工作。需要自定义网络,因为它依赖于其他容器。暴露的端口将映射到 localhost:33092。端口号是一个随机未使用的端口,所以不能暴露它。我仍然不明白我怎么能从外面调用它并且工作得很好但是这个等待策略它没有。

标签: java spring-boot docker testcontainers


【解决方案1】:

好的,所以你必须分解问题。

我刚刚构建了一个带有依赖项的示例 Spring Boot 应用程序并将其打包到一个图像中:

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'

没有别的,我从https://start.spring.io/下载的

以下测试类有效(我以你的代码为例):

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;

@Slf4j
public class TestcontainersWithSpringActuator {

    private static final GenericContainer<?> myContainer = new GenericContainer<>("docker.io/vcvitaly/test_sb:latest")
            .withExposedPorts(8080)
            .withNetworkAliases("myContainer")
            .withLogConsumer(new Slf4jLogConsumer(log))
            .waitingFor(Wait.forHttp("/actuator/health"));

    @Test
    void name() {
        myContainer.start();
        System.out.println();
    }
}

我也可以在 System.out.println 上打断,当它暂停时 curl 也可以工作

~  curl http://localhost:32776/actuator/health
{"status":"UP"}⏎

我现在并没有直接猜测你的情况发生了什么,但是你必须逐层分解你的问题(摆脱 tls、网络等)或者从头开始构建它最简单的图片,并一一添加功能。

【讨论】:

    猜你喜欢
    • 2018-02-14
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多