Atais
Atais

Reputation: 11275

Can't connect to Cassandra docker container in Scala Tests

I am quite desperately trying to set up docker tests in Scala.

I have created an example project on GitHub to understand how should I set up the environment. It is available here: https://github.com/atais/sbt-scala-docker-cassandra


I have selected spotify/cassandra:latest image https://github.com/spotify/docker-cassandra.

Since I am using ScalaTest I wanted to use one of the Scala wrappers, but both fail on me.

1. https://github.com/whisklabs/docker-it-scala

The container is defined as:

val cassandraContainer: DockerContainer = DockerContainer("spotify/cassandra:latest")
    .withPorts(9042 -> None, 9060 -> None)

It is CassandraDockerTest in the project.

2. https://github.com/testcontainers/testcontainers-scala

The container is defined as:

override val container = GenericContainer(
  "spotify/cassandra:latest",
  exposedPorts = Seq(9042, 9160)
) 

It is CassandraContainerTest in the project.

My assumption

What seems to be an issue (in both cases) is that the container starts, but the ports are never accessible:

CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                                                                                                                                                                                   NAMES
7cb5fc91a97d        spotify/cassandra:latest   "cassandra-singlenode"   3 seconds ago       Up 2 seconds        0.0.0.0:33121->22/tcp, 0.0.0.0:33120->7000/tcp, 0.0.0.0:33119->7001/tcp, 0.0.0.0:33118->7199/tcp, 0.0.0.0:33117->8012/tcp, 0.0.0.0:33116->9042/tcp, 0.0.0.0:33115->9160/tcp, 0.0.0.0:33114->61621/tcp   quirky_chandrasekhar

And I would like 9042 and 9160 to be available on 0.0.0.0, and for some reason, they are not, even though the configuration for them is specified.

Thanks!

Upvotes: 3

Views: 1815

Answers (3)

jcflorezr
jcflorezr

Reputation: 336

now (march 2019) exists a specific Cassandra test container module and you can get its maven or gradle dependency here: https://www.testcontainers.org/modules/databases/cassandra/. And it can be used like this:

override val container = CassandraContainer("spotify/cassandra:latest")
    .withExposedPorts(9042)
    .waitingFor(Wait.forListeningPort())

Upvotes: 2

Atais
Atais

Reputation: 11275

I have managed to find the solution(s)

docker-it-scala

Working container definition

val cassandraContainer: DockerContainer = DockerContainer("spotify/cassandra:latest")
    .withPorts(9042 -> Some(9042), 9160 -> Some(9160))
    .withReadyChecker(DockerReadyChecker.LogLineContains("Listening for thrift clients"))
  1. To bind the ports properly use (Port -> Some(Port))
  2. It is necessary to wait for the container to start (silly me)

testcontainers-scala

Working container definition

override val container = GenericContainer(
    "spotify/cassandra:latest",
    exposedPorts = Seq(9042, 9160),
    waitStrategy = new LogMessageContainsStrategy("Listening for thrift clients")
)
  1. testcontainers do not allow to define ports redirection. Instead, one must use getMappedPort method to obtain the port on host. Thanks @bsideup
  2. Wait for container is necessary.

A more detailed description is available on GitHub. Also one can use it as a reference/example. https://github.com/atais/sbt-scala-docker-cassandra

Upvotes: 4

bsideup
bsideup

Reputation: 3063

Option number 2 will use Testcontainers. In Testcontainers, ports are mapped randomly to avoid conflicts.

There are getContainerIpAddress, getMappedPort(9042) method in it to get the actual port. See https://www.testcontainers.org/usage/generic_containers.html#accessing-a-container-from-tests for the details.

Upvotes: 2

Related Questions