1

我正在使用 testcontainers ( 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)

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

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

所以这里提出了例外:

  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);

谁能让我知道我在这里做错了什么?

提前谢谢了。

西摩

4

1 回答 1

0

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

networks:
  of-network:
    ipv4_address: ...

甚至:

container_name: ...

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

所以最后我会说,由于 docker-compose 模块不完全支持官方语法,它还不够成熟。

于 2021-02-17T16:02:59.123 回答