Skip to content

nats-streaming container won't start as Testcontainer #1733

Closed

Description

Hi!

I am using testcontainers for Java in version 1.11.3.

When I use the redis container like this

    @ClassRule
    public static GenericContainer redis =
            new GenericContainer("redis:3.0.2")
                    .withExposedPorts(6379);

it starts without problems.

However when I start a nats-streaming container like this

    @ClassRule
    public static GenericContainer natsStreaming =
            new GenericContainer("nats-streaming:latest")
                    .withExposedPorts(4222);

it fails with this error message:

Caused by: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [32791] should be listening)
	at org.testcontainers.containers.wait.strategy.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:47)
	at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:35)
	at org.testcontainers.containers.wait.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:23)
	at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:35)
	at org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:582)
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:259)
	... 21 more

Starting the nats-streaming container with @Rule results in the same error.

What could I be doing wrong?

Activity

  1. rnorth commented on Aug 12, 2019

    @rnorth
    Member

    Ah, this is interesting - the first time I've seen this occur. I can reproduce.

    The reason this is failing is that Testcontainers relies on being able to execute commands inside the container in order to detect when the process starts listening.

    It seems that the nats-streaming container image is extremely slimmed down and does not contain any of the programs that Testcontainers typically uses to perform this detection.

    With the image slimmed down as it is, there's just going to be no way to do this in-container listening socket detection.

    Fortunately, you can change the wait strategy to instead wait for the successful log output, as follows:

    @ClassRule
    public static GenericContainer natsStreaming =
        new GenericContainer("nats-streaming:latest")
            .withExposedPorts(4222)
            .waitingFor(new LogMessageWaitStrategy().withRegEx(".*Server is ready.*"));

    This seems to work for me, and hopefully should also for you.

    (You might be wondering why we execute commands inside the container at all to detect listening sockets - why not just check the listening state from the JVM process on the outside? The reason is that Docker for Mac/Windows has a race behaviour between its Mac-side network code and the container itself, meaning that it's possible for the container to look like it's listening from the outside before the process within the container is actually listening. We work around this by checking for the listening socket from both inside and outside the container).

    Does this help?

  2. rnorth commented on Aug 12, 2019

    @rnorth
    Member

    Even better! That sounds great - I'm happy that you were able to find a solution that works for you.

  3. ghost closed this as completedon Aug 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions