Postgres docker-compose 使用测试容器不起作用

Posted

技术标签:

【中文标题】Postgres docker-compose 使用测试容器不起作用【英文标题】:Postgres docker-compose using testcontainers not working 【发布时间】:2020-10-22 04:36:29 【问题描述】:

这是我的抽象测试容器类

@Configuration
@Testcontainers
@ContextConfiguration(initializers = DockerConfig.Initializer.class)
public abstract class DockerConfig 

    static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> 
        @Override
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) 
            TestPropertyValues.of(String.format("spring.datasource.url=jdbc:postgresql://%s:%s/integration-test-db",
                            environment.getServiceHost("postgres", 5432),
                            environment.getServicePort("postgres", 5432))).applyTo(configurableApplicationContext.getEnvironment());
        
    

    @Container
    public static DockerComposeContainer<?> environment =
            new DockerComposeContainer<>(new File("src/test/resources/docker-compose-test.yml"))
                    .withExposedService("redis", 6379, Wait.forListeningPort()) //lets ignore this for now
                    .withExposedService("postgres", 5432, Wait.forListeningPort())
                    .withLocalCompose(true);

以及扩展它的测试类:

@SpringBootTest
@ActiveProfiles("integration-test")
class SomeIntegrationTest extends DockerConfig 

docker-compose-test.yml

version: "3.8"

services:
  redis:
    image: "redis:alpine"
    ports:
      - 6379:6379
  postgres:
    image: "postgres:12.3"
    ports:
      - 5432:5432
    environment:
      - POSTGRES_MULTIPLE_DATABASES="integration-test-db"
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - ./database:/var/lib/postgresql/data
      - ../../../.docker/create-multiple-postgresql-databases.sh:/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh

这是运行测试时的输出:

too big for stack overflow

(只是堆栈跟踪部分)

SEVERE: Caught exception while closing extension context: org.junit.jupiter.engine.descriptor.ClassExtensionContext@59532566
java.lang.RuntimeException: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [5432, 32826] should be listening)
    at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:68)
    at org.rnorth.ducttape.timeouts.Timeouts.doWithTimeout(Timeouts.java:60)
    at org.testcontainers.containers.wait.strategy.WaitAllStrategy.waitUntilReady(WaitAllStrategy.java:53)
    at org.testcontainers.containers.DockerComposeContainer.waitUntilServiceStarted(DockerComposeContainer.java:254)
    at java.base/java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1603)
    at org.testcontainers.containers.DockerComposeContainer.waitUntilServiceStarted(DockerComposeContainer.java:234)
    at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:173)
    at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.start(TestcontainersExtension.java:242)
    at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.access$200(TestcontainersExtension.java:229)
    at org.testcontainers.junit.jupiter.TestcontainersExtension.lambda$null$1(TestcontainersExtension.java:59)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$0(ExtensionValuesStore.java:80)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:185)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.closeAllStoredCloseableValues(ExtensionValuesStore.java:57)
    at org.junit.jupiter.engine.descriptor.AbstractExtensionContext.close(AbstractExtensionContext.java:73)
    at org.junit.jupiter.engine.descriptor.ClassExtensionContext.close(ClassExtensionContext.java:29)
    at org.junit.jupiter.engine.execution.JupiterEngineExecutionContext.close(JupiterEngineExecutionContext.java:53)
    at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.cleanUp(JupiterTestDescriptor.java:202)
    at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.cleanUp(JupiterTestDescriptor.java:54)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$cleanUp$6(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.cleanUp(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:77)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [5432, 32826] should be listening)
    at org.testcontainers.containers.wait.strategy.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:49)
    at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:35)
    at org.testcontainers.containers.wait.strategy.WaitAllStrategy.waitUntilNestedStrategiesAreReady(WaitAllStrategy.java:61)
    at org.testcontainers.containers.wait.strategy.WaitAllStrategy.lambda$waitUntilReady$0(WaitAllStrategy.java:54)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:835)

会发生什么是我运行测试,一切都运行到这一点

12:33:38.031 [ducttape-0] DEBUG com.github.dockerjava.core.exec.InspectContainerCmdExec - GET: com.github.dockerjava.okhttp.OkHttpWebTarget@3c472f7a

然后它似乎会挂起一分钟,然后自行终止,如您在以下堆栈跟踪中看到的那样。

我真的不知道发生了什么,但我有预感有些东西配置不正确。

有什么想法吗?

如果有人在我很乐意尝试之前做过相同/相似的事情。

【问题讨论】:

你试过打开端口32826 吗? 你能详细说明一下吗?据我所知,testcontainers 在随机 localhost 端口上启动 docker 容器,我通过在 DockerConfig 中动态分配这些端口来解决这个问题? @FedericoPiazza 您的错误显示为localhost ports: [5432, 32826] should be listening,但您在代码的任何地方都映射了此端口。我想你必须这样做.withExposedService("whateverGoesHere", 32826, Wait.forListeningPort()) 【参考方案1】:

尝试将 docker-compose 版本从原来的 3.8 降级到 3.7。

【讨论】:

以上是关于Postgres docker-compose 使用测试容器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

docker springboot 仅通过 docker-compose 在 postgres 5432 上连接

从 docker-compose 文件连接到 Postgres docker 容器 [重复]

docker-compose 与 postgres 的 Django 连接

docker-compose:nodejs容器不与postgres容器通信

无法从 docker-compose 启动 postgres docker 容器

docker-compose ECONNREFUSED 用于 nodeJS 上的 Postgres