Testcontainers
container.getHost()
在 Maven 生命周期步骤和 GitLab CI-Pipeline 中的行为不同。
container.getHost()
替换为 localhost
container.getHost()
替换为实际的 HostIP
二手:
版本:
尽管 RestClient 与 RestTemplate 相比被认为是最先进的(spring.io:2024 年 4 月)... ...两者给出不同的错误反馈(如下)。
假设 Junit-Testcontainers 设置中有 3 个 java 微服务:
Container1 <- Container2 <- Validator
Container2
需要Container1
,并且验证器在Junit-Test容器环境中提升两者,观察其通信。
验证器不是一个实时系统,只是一个集成测试系统。
因此:
Container1
已开始Container1's
端口写入 Container2's
env。Container2
开始了。Container2
尝试联系 Container1's
执行器端点。 // Create a common network for all containers
@ClassRule
public static Network network = Network.newNetwork();
@ClassRule
public static GenericContainer<?> C1 =
new GenericContainer<>(C1DockerImage)
.withExposedPorts(C1Port)
.withNetwork(network)
.withNetworkAliases("C1")
@ClassRule
public static GenericContainer<?> C2 =
new GenericContainer<>(C2DockerImage)
.withExposedPorts(C2Port)
.withNetwork(network)
.withNetworkAliases("C2")
static {
// Start C1
C1.start();
C1BaseURL = "http://" + C1.getHost() + ":" + C1.getMappedPort(C1Port);
// Start C2
C2.withEnv("C1_URL", C1BaseURL);
C2.start();
logger.info("C1-Url given to C2 via ENV-Variable: " + C1BaseURL);
}
因此:
http://localhost:51059
51059
是主机系统的端口,映射到 C1's exposed port
。到目前为止 -> 很好:)
区分三 (3) 个环境:
这里启动了一个Testcontainers环境,里面有C1。 请注意,C2 正在运行
IntelliJ Maven Test livecycle
因此,C2 不在显式 Docker 容器中。
C1 的暴露端口由 testcontainers 和它提供给 C2 的代理端口包装。 C2 连接,一切正常。
It works like a charm
- 正如预期的那样。
接下来,
Validator
运行它的IntelliJ Maven Test livecycle
。
因此,C2 现在位于显式 Docker 容器内。
提供给 C2 的 URL 仍然是指向
http://localhost:TestcontainersProxyPortToC1
的指针。
假设:
假设成立:
null
在 GitLab CI 管道中使用相同的存储库、相同的 Java 代码、可重现......
http://HostIP:TestcontainersProxyPortToC1
相同的代码在 GitLab CI-Pipeline 中成功,因为
localhost
被替换为实际机器 HostIP
。
我的假设是..
..必须以同样的方式行事。 两个 C2 容器应通过 ..
之一成功连接或失败http://localhost:TestcontainersProxyPortToC1
http://HostIP:TestcontainersProxyPortToC1
还有另一个 Testcontainers 命令,它总是解析主机 IP 地址吗?
任何帮助表示赞赏:)
C1.getHost()
上的分歧行为仍然存在(2024 年 4 月)。
没有任何线索,
C1.getHost()
如何确定何时必须交付哪个答案。
本地主机的 IP 在本地始终是 Testcontainers HostIP。
但在 GitLab Ci-Pipeline 中,IP 与 HostIP 不同。 因此,与运行程序相比,C1 的 IP 对于 GitLab 来说始终是不同的主机 IP。
因此,必须对先前给出的代码进行以下更改:
C1BaseURL =
"http://" + getHostIp(C1) + ":" + C1.getMappedPort(C1Port);
自定义函数看起来像这样:
private static String getHostIp(GenericContainer<?> C1) {
if (C1.getHost().equals("localhost")) {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
return C1.getHost();
}