测试容器:无法初始化 DockerComposeContainer

问题描述

我正在使用测试容器 (https://www.testcontainers.org) 来执行集成测试。测试用例需要一个 Oracle 数据库和一个 Eclipse Microprofile 兼容平台,在我的例子中是 Wildfly 20。我有以下 docker-compose.yaml 文件:

version: '3.7'
...
services:
  oracle:
    image: oracleinanutshell/oracle-xe-11g:latest
    ....
    ports:
      - 49161:1521
      - 5500:5500
    environment:
      ...
    volumes:
      ...
  customers:
    image: customers:1.0-SNAPSHOT
    ...
    depends_on:
      - oracle
    ports:
      - 8080:8080
      - 9990:9990
    environment:
      ...

当使用 docker-compose 命令或使用 docker-compose-maven-plugin 运行时,这个 docker-compose 文件没问题并且按预期工作。

为了使用相同的 docker-compose.yaml 文件进行集成测试,我使用了以下代码:

public class CustomersIT
{
  @ClassRule
  public static DockerComposeContainer composer = DockerCompose.newContainer()
    .withLogConsumer(DockerCompose.DATABASE,new Slf4jLogConsumer(log))
    .withLogConsumer(DockerCompose.SERVICE,new Slf4jLogConsumer(log));
  private static URI baseUri;
  private static URI finalUri;
  private static String id;
  private static Map<String,String> props = new HashMap<>();

  @BeforeAll
  public static void beforeAll()
  {
    baseUri = UriBuilder.fromPath("customers")
      .scheme("http")
      .host(composer.getServiceHost(DockerCompose.SERVICE,DockerCompose.SERVICE_PORT))
      .port(composer.getServicePort(DockerCompose.SERVICE,DockerCompose.SERVICE_PORT))
      .build();
    finalUri = UriBuilder.fromUri(baseUri).path("test").path("customers").build();
  }
....
}

上面的代码使用了 DockerCompose 类,它是 DockerComposeContainer 的包装器,如下所示:

public class DockerCompose
{
  public static final String DATABASE = "oracle";
  public static final String SERVICE = "customers";
  public static final int DATABASE_PORT = 1521;
  public static final int SERVICE_PORT = 8080;
  private final DockerComposeContainer dcc =
    new DockerComposeContainer(new File("../platform/src/main/resources/docker-compose.yaml"))
    .withExposedService(DATABASE,DATABASE_PORT,Wait.forLogMessage(".*WFLYSRV0051.*",1))
    .withExposedService(SERVICE,SERVICE_PORT);

  private DockerCompose()
  {
    super();
  }

  public static DockerComposeContainer newContainer()
  {
    return new DockerCompose().dcc;
  }
}

尝试运行集成测试会引发以下异常:

[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running ...tests.CustomersIT
2021-02-16 19:16:06 DEBUG TestcontainersConfiguration:178 - Testcontainers configuration overrides will be loaded from file:/home/seymour/.testcontainers.properties
[ERROR] Tests run: 1,Failures: 0,Errors: 1,Skipped: 0,Time elapsed: 0.149 s <<< FAILURE!  - in ....tests.CustomersIT
[ERROR] ....tests.CustomersIT  Time elapsed: 0.148 s  <<< ERROR!
java.lang.ExceptionInInitializerError
        at ...tests.CustomersIT.<clinit>(CustomersIT.java:26)

即使在 DEBUG 模式下也没有任何附加信息。上面引用的第 26 行如下:

  public static DockerComposeContainer composer = DockerCompose.newContainer()
    .withLogConsumer(DockerCompose.DATABASE,new Slf4jLogConsumer(log));

所以这里抛出异常:

  private final DockerComposeContainer dcc =
    new DockerComposeContainer(new File("../platform/src/main/resources/docker-compose.yaml"))
    .withExposedService(DATABASE,SERVICE_PORT);

谁能告诉我我在这里做错了什么?

非常感谢。

西摩

解决方法

似乎 testcontainers 中的 docker-compose 模块不支持以下内容:

networks:
  of-network:
    ipv4_address: ...

甚至:

container_name: ...

从 yaml 文件中删除这些语句将解决问题。但是,当然,如果这些语句存在,那是因为它们是必需的,删除它们可能不是一种选择。

所以我总结一下,由于docker-compose模块不完全支持官方语法,所以还不够成熟。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...