Mariusz
Mariusz

Reputation: 1985

How to restart testcontainers container?

I have server and client applications. Server is launched inside docker container. I want to test scenario that server crashes and comes back. Client is connected to server before crash and automatically connects to server when server is back. The problem is that testcontainers maps ports randomly and server listens on different port after come back.

I use org.testcontainers.containers.GenericContainer#withExposedPorts method to expose ports. I kill and start container using following code:

container.getDockerClient()
            .killContainerCmd( container.getContainerId() )
            .exec();
container.getDockerClient()
            .startContainerCmd( container.getContainerId() )
            .exec();

or

container.stop();
container.start();

I tried to set port binding but it does not work.

setBinding(container)
container.getDockerClient()
            .killContainerCmd( container.getContainerId() )
            .exec();
container.getDockerClient()
            .startContainerCmd( container.getContainerId() )
            .exec();
...
  private void setBinding( GenericContainer aContainer )
    {
        List< Integer > exposedPorts = aContainer.getExposedPorts();
        List< String > bindings = new ArrayList<>();
        exposedPorts.forEach( e -> bindings.add( aContainer.getMappedPort( e ) + ":" + e ) );
        aContainer.setPortBindings( bindings );
    }

How to kill and start again container? I would like to note that I do not want to start other container with the same port mapping. I want to start the same container with the same port mapping.

Upvotes: 4

Views: 5493

Answers (1)

Shmayro
Shmayro

Reputation: 1

I have found a solution:

  1. Create a snapshot of your current running container using (docker commit via the dockerClient)
  2. stop your container
  3. Set the new image name to your same container object
  4. then call start method again

Example: (this refers to a GenericContainer object)

public void restart() {
        String tag = this.getContainerId();
        String snapshotId = dockerClient.commitCmd(this.getContainerId())
                .withRepository("tempImg")
                .withTag(tag).exec();
        this.stop();
        this.setDockerImageName("tempImg:" + tag);
        this.start();
}

Some advantages:

  • You will keep getting the benefit of the WaitStrategy (if defined).
  • The temp image will be removed after the end of the test.
  • The new exposed port will be mapped again to your GenericContainer object.

Upvotes: 0

Related Questions