简体   繁体   English

在 testcontainers 中使用 PostgreSQLContainer 和图像 on-the-fly

[英]Use PostgreSQLContainer with image on-the-fly in testcontainers

Goal目标

I want to use customized PostgreSQL image with locale support with test containers.我想使用定制的 PostgreSQL 映像,并带有测试容器的语言环境支持。

On postgres side在 postgres 方面

I prepared Dockerfile as described in postgres image documentation :我准备Dockerfile ,如postgres 图像文档中所述:

You can extend the Debian-based images with a simple Dockerfile to set a different locale.您可以使用简单的 Dockerfile 扩展基于 Debian 的映像以设置不同的语言环境。 The following example will set the default locale to de_DE.utf8:以下示例将默认语言环境设置为 de_DE.utf8:

FROM postgres:14.3来自 postgres:14.3

RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8运行 localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8

ENV LANG de_DE.utf8 ENV LANG de_DE.utf8

So essentially nothing changes in the way this image works, but has some more capabilities in terms of locale support.因此,该图像的工作方式基本上没有任何变化,但在语言环境支持方面具有更多功能。

On testcontainers side在测试容器方面

I wanted to use it as described in testcontainers documentation :我想按照testcontainers 文档中的描述使用它:

Simply pass a configured instance of ImageFromDockerfile as a constructor parameter to GenericContainer.只需将 ImageFromDockerfile 的配置实例作为构造函数参数传递给 GenericContainer。 Testcontainers will docker build a temporary container image, and will use it when creating the container. Testcontainers 将 docker 构建一个临时容器镜像,并在创建容器时使用它。

public GenericContainer dslContainer = new GenericContainer(
new ImageFromDockerfile()
        .withFileFromString("folder/someFile.txt", "hello")
        .withFileFromClasspath("test.txt", "mappable-resource/test-resource.txt")
        .withFileFromClasspath("Dockerfile", "mappable-dockerfile/Dockerfile"))

Problem问题

In examples above testcontainers uses GenericContainer .在上面的示例中, testcontainers 使用GenericContainer GenericContainer exposes constructor public GenericContainer(final Future<String> image) , what allows it to be used with ImageFromDockerfile . GenericContainer公开构造函数public GenericContainer(final Future<String> image) ,它允许它与ImageFromDockerfile一起使用。 Sadly PostgreSQLContainer does not provide such constructor but I still want to use this class because it has several internal setups to support postgres well.遗憾的是PostgreSQLContainer没有提供这样的构造函数,但我仍然想使用这个 class 因为它有几个内部设置可以很好地支持 postgres。 There are two constructors in PostgreSQLContainer but they only accept image name. PostgreSQLContainer中有两个构造函数,但它们只接受图像名称。

Only solution I could think of was to essentially make a local copy of original PostgreSQLContainer and add missing constructor.我能想到的唯一解决方案是基本上制作原始PostgreSQLContainer的本地副本并添加缺少的构造函数。 That seems to work fine but it is a dirty hack for obvious reasons.这似乎工作正常,但由于显而易见的原因,它是一个肮脏的黑客。

Question问题

My question is: am I missing some other way to accomplish the task with tools testcontainers provide?我的问题是:我是否错过了使用 testcontainers 提供的工具完成任务的其他方法? Or is it an area of improvement to add such public constructor in testcontainers?还是在测试容器中添加这样的公共构造函数是一个改进的领域?

I believe the solution would be:我相信解决方案是:

import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.utility.DockerImageName;

import java.net.URI;
import java.nio.file.Paths;
import java.time.Duration;

import static java.time.temporal.ChronoUnit.SECONDS;

public class Demo {

    public static void main(String[] args) throws Exception {
        // the most buggy part - need to investigate
        // how to work properly with ImageFromDockerfile
        URI path = Demo.class.getResource("/PostgreSQLde").toURI();
        ImageFromDockerfile image = new ImageFromDockerfile()
                .withDockerfile(Paths.get(path));
        DockerImageName imageName = DockerImageName.parse(image.get())
                .asCompatibleSubstituteFor(PostgreSQLContainer.IMAGE);
        new PostgreSQLContainer<>(imageName)
                .waitingFor(new LogMessageWaitStrategy()
                        // oops
                        .withRegEx(".*Datenbanksystem ist bereit, um Verbindungen anzunehmen.*\\s")
                        .withTimes(2)
                        .withStartupTimeout(Duration.of(60, SECONDS)))
                .start();
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM