testcontainer initializationError while running a test suite
Asked Answered
L

2

10

I have multiple test classes running the same docker-compose with testcontainer.

The suite fails with initializationError although each test passes when performed separately.

Here is the relevant part of the stacktrace occuring during the second test. ./gradlew e2e:test -i

io.foo.e2e.AuthTest > initializationError FAILED
    org.testcontainers.containers.ContainerLaunchException: Container startup failed
        at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:330)
        at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:311)
        at org.testcontainers.containers.DockerComposeContainer.startAmbassadorContainers(DockerComposeContainer.java:331)
        at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:178)
        at io.foo.e2e.bases.BaseE2eTest$Companion.beforeAll$e2e(BaseE2eTest.kt:62)
        at io.foo.e2e.bases.BaseE2eTest.beforeAll$e2e(BaseE2eTest.kt)
       ...

        Caused by:
        org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
            at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
            at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:323)
            ... 83 more

            Caused by:
            org.testcontainers.containers.ContainerLaunchException: Could not create/start container
                at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:497)
                at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:325)
                at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
                ... 84 more

                Caused by:
                org.testcontainers.containers.ContainerLaunchException: Aborting attempt to link to container btraq5fzahac_worker_1 as it is not running
                    at org.testcontainers.containers.GenericContainer.applyConfiguration(GenericContainer.java:779)
                    at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:359)
                    ... 86 more

It seems to me that the second test doesn't wait for the first to shutdown previous containers.

Here the base class that all tests inherit from. It is responsible for spinning up the containers.

open class BaseE2eTest {

    ...

    companion object {
        const val A = "containera_1"
        const val B = "containerb_1"
        const val C = "containerc_1"

        val dockerCompose: KDockerComposeContainer by lazy {
            defineDockerCompose()
                .withLocalCompose(true)
                .withExposedService(A, 8080, Wait.forListeningPort())
                .withExposedService(B, 8081)
                .withExposedService(C, 5672, Wait.forListeningPort())
        }

        class KDockerComposeContainer(file: File) : DockerComposeContainer<KDockerComposeContainer>(file)

        private fun defineDockerCompose() = KDockerComposeContainer(File("../docker-compose.yml"))

        @BeforeAll
        @JvmStatic
        internal fun beforeAll() {
            dockerCompose.start()
        }

        @AfterAll
        @JvmStatic
        internal fun afterAll() {
            dockerCompose.stop()
        }
    }
}
docker-compose version 1.27.4, build 40524192
testcontainer 1.15.2
testcontainers:junit-jupiter:1.15.2
Leopold answered 18/2, 2021 at 11:33 Comment(4)
Can you share your test class?Circularize
@VitalyChura I have added the part that should be relevant.Leopold
I think that if you want containers to be restarted each time, you should put start in '@BeforeEach' instead of '@BeforeAll', the same for stop. Have you tried something like this?Circularize
@VitalyChura then all tests fail.Leopold
L
0

After watching this talk, I realized that my testcontainers instantiation approach with Junit5 was wrong.

Here is the working code:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
open class BaseE2eTest {

    ...

    val A = "containera_1"
    val B = "containerb_1"
    val C = "containerc_1"

    val dockerCompose: KDockerComposeContainer by lazy {
        defineDockerCompose()
            .withLocalCompose(true)
            .withExposedService(A, 8080, Wait.forListeningPort())
            .withExposedService(B, 8081)
            .withExposedService(C, 5672, Wait.forListeningPort())
    }

    class KDockerComposeContainer(file: File) : DockerComposeContainer<KDockerComposeContainer>(file)

    private fun defineDockerCompose() = KDockerComposeContainer(File("../docker-compose.yml"))

    @BeforeAll
    fun beforeAll() {
        dockerCompose.start()
    }

    @AfterAll
    fun afterAll() {
        dockerCompose.stop()
    }
}

Now the test suite passes.

Leopold answered 28/2, 2021 at 23:15 Comment(1)
I have quite opposite scenerio where when I am running single test it failed while running test suite all test gets passed. While running sinle ContainerBasedTest, I can see on console that all containers started but after that all get stopped and then there's same error on console.Fioritura
F
0

For anyone stumbling upon this, I had a similar problem that suddenly occurred after months of working perfectly fine. It was caused by this problem: Docker "ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network"

After removing all unused networks the problem was fixed

Fought answered 13/10, 2022 at 14:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.