Git Product home page Git Product logo

testcontainers-scala's Introduction

Logo

Build Status Maven Central

Testcontainers-scala

Scala wrapper for testcontainers-java that allows using docker containers for functional/integration/unit testing.

TestContainers is a Java 8 library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Slack

Slack channel

Invite link for slack

Documentation

The following test frameworks are supported:

Release notes

See release notes

testcontainers-scala's People

Contributors

8bitreid avatar adrianrafo avatar alejandrohdezma avatar benkio avatar bplommer avatar busybyte avatar desbo avatar dimafeng avatar faustin0 avatar greshny avatar guizmaii avatar ivmikhail avatar jczuchnowski avatar jesusmtnez avatar jsoizo avatar lazybun avatar lmnet avatar markarasev avatar matsluni avatar necosta avatar nryanov avatar pan3793 avatar pbylicki avatar psisoyev avatar schrepfler avatar scoquelin avatar sullis avatar sv3ndk avatar tobiasroland avatar tpolecat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

testcontainers-scala's Issues

Start container for particular scenario

Hi all
I would like to know, if it is possible to start a container for particular scenario.

For example:

import akka.testkit._
import com.dimafeng.testcontainers.{FixedHostPortGenericContainer, ForAllTestContainer}
import com.sweetsoft._
import org.testcontainers.containers.wait.strategy.Wait

import concurrent.duration._

final class DetectorSpec extends BddSpec with ForAllTestContainer {

  private val listener1 = TestProbe()
  private val listener2 = TestProbe()

  private val detector = system.actorOf(DetectorSupervisor.props)

  override val container = FixedHostPortGenericContainer("zerocoder/sapmock:2.1.1",
    exposedHostPort = 8080,
    exposedContainerPort = 9090,
    waitStrategy = Wait.forHttp("/")
  )

  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
  }

  override def afterStart(): Unit = {

  }

  feature("Detect Kafka and SAP availability") {
    info("As a technical user, I want to be notified in real time, if Kafka and SAP is up and running or not.")
    scenario("SAP and Kafka are offline") {
      Given("I am registering two listeners")
      detector ! AddNewListener(listener1.ref)
      detector ! AddNewListener(listener2.ref)
      When("I am receive the state message")
      Then("it should contain `Kafka and SAP are offline`")
      listener1.expectMsgPF(1.second) {
        case status: ServerStatus =>
          status.health should be(ServersOffline)
      }
      listener2.expectMsgPF(1.second) {
        case status: ServerStatus =>
          status.health should be(ServersOffline)
      }

    }

    scenario("SAP is online and Kafka is offline") {
      Given("I am waiting for the current state message")
      detector ! AddNewListener(listener1.ref)
      When("I am receive the state message")
      Then("it should contain `Kafka is offline`")
      cancel()
    }

    scenario("SAP is offline and Kafka is online") {
      Given("I am waiting for the current state message")
      When("I am receive the state message")
      Then("it should contain `SAP is offline`")
      cancel()
    }

    scenario("SAP and Kafka are available") {
      Given("I am waiting for the current state message")
      When("I am receive the state message")
      Then("it should contain `SAP and Kafka are online`")
      cancel()
    }
  }
}

I would like to start the container only on the scenarios 2 and 4.

Thanks

Containers continue to run also after test completed

Hello,

I'm getting an issue using test container on a sbt project, here some info:

  • Operating System: Mac OS 10.15.4
  • Docker version: 19.03.8
  • testcontainers-scala version: 0.36.1

The issue is that after all my test are completed some containers continue to run, in my test I'm using a Multiple Container setting with a waitStrategy on some endpoint.

After some test executions using the docker ps I see something like this:

CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                     NAMES
875384b96490        quay.io/testcontainers/ryuk:0.2.3   "/app"                   6 minutes ago       Up 6 minutes        0.0.0.0:33069->8080/tcp   testcontainers-ryuk-ec38bb2b-c989-4a56-bd24-024540f20ce6
1cdfba4769b8        quay.io/testcontainers/ryuk:0.2.3   "/app"                   7 minutes ago       Up 7 minutes        0.0.0.0:33064->8080/tcp   testcontainers-ryuk-f0fbbec8-4ada-4278-a3e9-c8cf0f07a6e9
cc8e4966df4d        quay.io/testcontainers/ryuk:0.2.3   "/app"                   9 minutes ago       Up 9 minutes        0.0.0.0:33059->8080/tcp   testcontainers-ryuk-42206725-b571-4f15-8ba3-53f4d5849cf8
017e1477cd65        quay.io/testcontainers/ryuk:0.2.3   "/app"                   10 minutes ago      Up 10 minutes       0.0.0.0:33054->8080/tcp   testcontainers-ryuk-a9775fc8-d4ae-4ad5-beff-ecbcb797812e

All the quay.io/testcontainers/ryuk containers continue to run.
Note that if I use only a single container(POSTGRES for example) this problem is not present.

Running gradle test on CircleCI

The test containers work perfectly when running locally but seem to have an issue spinning up on CircleCI even with machine level access. Testcontainers is able to determine the docker version and machine status but can't seem to deploy a container. Copying some of the debug log and the CircleCI config. Any assistance is appreciated ๐Ÿ˜„

    2019-02-08 15:50:03,059 0] ERROR: Could not start container
    org.testcontainers.containers.ContainerLaunchException: Timed out waiting for URL to be accessible (http://localhost:32770/ should return HTTP 200)
    	at org.testcontainers.containers.wait.strategy.HttpWaitStrategy.waitUntilReady(HttpWaitStrategy.java:197)
    	at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:35)
    	at org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:606)
    	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:292)
    	at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:237)
    	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:76)
    	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:235)
    	at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:220)
    	at org.testcontainers.containers.GenericContainer.starting(GenericContainer.java:738)
    	at org.testcontainers.containers.TestContainerAccessor$.starting(TestContainerAccessor.scala:13)
    	at com.dimafeng.testcontainers.TestContainerProxy$class.starting(TestContainer.scala:106)
    	at com.dimafeng.testcontainers.SingleContainer.starting(TestContainer.scala:111)
    	at com.dimafeng.testcontainers.ForEachTestContainer$class.runTest(TestContainer.scala:26)
version: 2.0
executorType: machine

jobs:
  build:
    machine: true

    steps:
      # Clone git repository
      - checkout

      # Build Jar
      - run: ./gradlew test

Example Dockerfile usage

I'm trying to use a Dockerfile with GenericContainer, but can't seem to get it to work. The unit test shows it using .withFileFromClasspath(), but my Dockerfile is not on the classpath. I tried .withFileFromFile(), but it errors out with something like:

{"message":"No such image: testcontainers/b3ewhisadljlsccu:latest"}

Are the other .withFileFromXXX()'s supported?

Parity with testcontainers-java containers

At the current moment, testcontainers-scala is lagging behind java library in terms of containers number and containers configuration options. We need to catch up with the java library.

Dependent containers

I'm trying to use ForAllTestContainer trait to test my application. This app depends on PosgtreSQL. So, I'm doing something like this:

val pgContainer = PostgreSQLContainer()
val appContainer = AppContainer(pgContainer.jdbcUrl, pgContainer.username, pgContainer.password)

override val container = MultipleContainers(appContainer, pgContainer)

And when I start this I get an error:

Exception encountered when invoking run on a nested suite - Mapped port can only be obtained after the container is started

What is the correct way to test dependent containers?

Any love for specs2?

We are using specs2 for our tests. Is it possible to use this library with it? Do you think we should try to bend the java version of testcontainers to our will?

Not recognizing DockerComposeContainer with any upper case identifier as started

I created a DockerComposeContainer and gave it an explicit identifier of SomeCamelCaseName.

  override val container: Container = DockerComposeContainer(
    composeFiles = new File("../docker/docker-compose-it.yml"),
    exposedServices = Seq(ExposedService("my-service", 9109)),
    identifier = "SomeCamelCaseName",
    env = dockerEnv,
    pull = false,
  )

When the test runs, the container actually started, but docker identifies it having the all-lowercase name somecamelcasename... So, TestContainers thinks the container never started.

Something along the docker start path is converting the name to lowercase, but the live-checking code doesn't do the same.

info] com.acme.DockerItSpec *** ABORTED ***
[info]   org.testcontainers.containers.ContainerLaunchException: Container startup failed
[info]   at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:307)
[info]   at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:287)
[info]   at org.testcontainers.containers.DockerComposeContainer.startAmbassadorContainers(DockerComposeContainer.java:316)
[info]   at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:157)
[info]   at com.dimafeng.testcontainers.DockerComposeContainer.start(DockerComposeContainer.scala:112)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run(ForAllTestContainer.scala:17)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run$(ForAllTestContainer.scala:13)
[info]   at com.acme.DockerItSpec.run(DockerItSpec.scala:13)
[info]   at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:314)
[info]   at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:507)
[info]   ...
[info]   Cause: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
[info]   at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
[info]   at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:300)
[info]   at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:287)
[info]   at org.testcontainers.containers.DockerComposeContainer.startAmbassadorContainers(DockerComposeContainer.java:316)
[info]   at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:157)
[info]   at com.dimafeng.testcontainers.DockerComposeContainer.start(DockerComposeContainer.scala:112)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run(ForAllTestContainer.scala:17)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run$(ForAllTestContainer.scala:13)
[info]   at com.acme.DockerItSpec.run(DockerItSpec.scala:13)
[info]   at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:314)
[info]   ...
[info]   Cause: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
[info]   at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:418)
[info]   at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:302)
[info]   at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
[info]   at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:300)
[info]   at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:287)
[info]   at org.testcontainers.containers.DockerComposeContainer.startAmbassadorContainers(DockerComposeContainer.java:316)
[info]   at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:157)
[info]   at com.dimafeng.testcontainers.DockerComposeContainer.start(DockerComposeContainer.scala:112)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run(ForAllTestContainer.scala:17)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run$(ForAllTestContainer.scala:13)
[info]   ...
[info]   Cause: org.testcontainers.containers.ContainerLaunchException: Aborting attempt to link to container SomeCamelCaseNameyybsfu_my-service_1 as it is not running
[info]   at org.testcontainers.containers.GenericContainer.applyConfiguration(GenericContainer.java:654)
[info]   at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:336)
[info]   at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:302)
[info]   at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
[info]   at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:300)
[info]   at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:287)
[info]   at org.testcontainers.containers.DockerComposeContainer.startAmbassadorContainers(DockerComposeContainer.java:316)
[info]   at org.testcontainers.containers.DockerComposeContainer.start(DockerComposeContainer.java:157)
[info]   at com.dimafeng.testcontainers.DockerComposeContainer.start(DockerComposeContainer.scala:112)
[info]   at com.dimafeng.testcontainers.ForAllTestContainer.run(ForAllTestContainer.scala:17)
[info]   ...

Even after the test exits, the container is still running, but it has an all-lowercase name:

$ docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                    NAMES
fc9bea4d86f0        my-service:0.1.0-SNAPSHOT   "/opt/docker/bin/my-โ€ฆ"   5 minutes ago       Up 5 minutes        0.0.0.0:9109->9109/tcp   somecamelcasenameyybsfu_my-service_1

SSL Cert Invalid for Slack Invite

$ curl https://slack.testcontainers.org/
curl: (60) SSL: no alternative certificate subject name matches target host name 'slack.testcontainers.org'
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Local Docker Compose exited abnormally with code 1 whilst running command: up -d

Hello, I am trying to use the DockerComposeContainer but I keep getting the error below:
I verified that docker-compose up -d works locally.

INFO ๐Ÿณ [docker-compose] - Local Docker Compose is running command: pull
INFO ๐Ÿณ [docker-compose] - Docker Compose has finished running
INFO ๐Ÿณ [docker-compose] - Local Docker Compose is running command: up -d

Exception encountered when invoking run on a nested suite - Local Docker Compose exited abnormally with code 1 whilst running command: up -d
org.testcontainers.containers.ContainerLaunchException: Local Docker Compose exited abnormally with code 1 whilst running command: up -d
at org.testcontainers.containers.LocalDockerCompose.invoke(DockerComposeContainer.java:656)
at org.testcontainers.containers.DockerComposeContainer.runWithCompose(DockerComposeContainer.java:216)
compose file

version: "2.2"
services:

  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.0.0
    container_name: es01
    environment:
      - node.name=es01
      - cluster.initial_master_nodes=es01
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet

volumes:
  esdata01:
    driver: local

networks:
  esnet:

creating my test container like so

  val container = new DockerComposeContainer(new File("elastic-api/src/test/resources/docker-compose.yml"),exposedServices = Seq(
    ExposedService("es01", 9200)
  ))

MacOS error scala

An error like:
An exception or error caused a run to abort: Login failed for user 'SA'. ClientConnectionId:ea23e4f1-fd45-4b8e-b2c5-292cb4a66f3d com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'SA'. ClientConnectionId:ea23e4f1-fd45-4b8e-b2c5-292cb4a66f3d at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:259) at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:256) at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:108) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:4548) at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3409) at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$100(SQLServerConnection.java:85) at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:3373) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7344) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2713) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2261) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1921) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1762) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1077) at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:623) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:270) at eu.scrm.dataplatform.etl.lib.utils.sqlserver.SqlConnection.connection$lzycompute(SqlConnection.scala:17) at eu.scrm.dataplatform.etl.lib.utils.sqlserver.SqlConnection.connection(SqlConnection.scala:17) at eu.scrm.dataplatform.etl.lib.utils.sqlserver.SqlConnection.execute(SqlConnection.scala:21) at PipelineTest.setup(PipelineTest.scala:14) at infra.LocalBaseTest$$anonfun$1.apply$mcV$sp(LocalBaseTest.scala:20) at infra.LocalBaseTest$$anonfun$1.apply(LocalBaseTest.scala:20) at infra.LocalBaseTest$$anonfun$1.apply(LocalBaseTest.scala:20) at org.scalatest.BeforeAndAfter$class.runTest(BeforeAndAfter.scala:200) at PipelineTest.com$dimafeng$testcontainers$ForAllTestContainer$$super$runTest(PipelineTest.scala:14) at com.dimafeng.testcontainers.ForAllTestContainer$class.runTest(ForAllTestContainer.scala:40) at PipelineTest.runTest(PipelineTest.scala:14) at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1750) at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1750) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:396) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:384) at scala.collection.immutable.List.foreach(List.scala:392) at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:384) at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:373) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:410) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:384) at scala.collection.immutable.List.foreach(List.scala:392) at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:384) at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:379) at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:461) at org.scalatest.FlatSpecLike$class.runTests(FlatSpecLike.scala:1750) at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1685) at org.scalatest.Suite$class.run(Suite.scala:1147) at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1685) at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1795) at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1795) at org.scalatest.SuperEngine.runImpl(Engine.scala:521) at org.scalatest.FlatSpecLike$class.run(FlatSpecLike.scala:1795) at PipelineTest.org$scalatest$BeforeAndAfter$$super$run(PipelineTest.scala:14) at org.scalatest.BeforeAndAfter$class.run(BeforeAndAfter.scala:258) at PipelineTest.org$scalatest$BeforeAndAfterAll$$super$run(PipelineTest.scala:14) at org.scalatest.BeforeAndAfterAll$class.liftedTree1$1(BeforeAndAfterAll.scala:213) at org.scalatest.BeforeAndAfterAll$class.run(BeforeAndAfterAll.scala:210) at PipelineTest.com$dimafeng$testcontainers$ForAllTestContainer$$super$run(PipelineTest.scala:14) at com.dimafeng.testcontainers.ForAllTestContainer$class.run(ForAllTestContainer.scala:20) at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45) at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$1.apply(Runner.scala:1346) at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$1.apply(Runner.scala:1340) at scala.collection.immutable.List.foreach(List.scala:392) at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1340) at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1011) at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1010) at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1506) at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1010) at org.scalatest.tools.Runner$.run(Runner.scala:850) at org.scalatest.tools.Runner.run(Runner.scala) at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:133) at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)

hooks in the new API

when using the posgresql container and the new testcontainers-scala API get the configuration of the container (jdbcURL, username and password) only when you are running the tests

the beforeStop() and afterStart() hooks are not there any more

i would like to use the TestConainterForAll trait and still being able to run a after-start hook to prepare the posgresql database (run some flyway migration) before start running the tests.

is it possible at the moment?

Compilation problems when using GenericContainer

@dimafeng

The moment I touch GenericContainer class I get the following errors:

[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.
[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.
[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.

[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.
[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.
[error] Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.

Scala Version: 2.11.8
Sbt version: 0.13.8

Have tried changing scala and sbt versions without much success. This error really does not tell me much of what I need (e.g. where is this class needed at all ?). Is this some conflict with other libraries. For example is lombock's NonNull getting mixed up with findbug's NonNull. If that is the case I have excluded the latter dependency but still get errors. A bit of help will be greatly appreciated

Port are not obtainable

I have used code from example. Mapped port are getting obtained inside test after container already started. Version 0.36.2

[pool-26-thread-7] INFO  o.t.DockerClientFactory - โœ”๏ธŽ Docker server version should be at least 1.6.0 
[pool-26-thread-7] INFO  o.t.DockerClientFactory - โœ”๏ธŽ Docker environment should have more than 2GB free disk space 
[pool-26-thread-7] INFO  ?.6.12] - Creating container for image: postgres:9.6.12 
[pool-26-thread-7] INFO  ?.6.12] - Starting container with ID: 05ab24445187b9f115602c316786eae8bd63a7d6628ebed6247ba5bc1ccd5a5a 
[pool-26-thread-7] INFO  ?.6.12] - Container postgres:9.6.12 is starting: 05ab24445187b9f115602c316786eae8bd63a7d6628ebed6247ba5bc1ccd5a5a 
[pool-26-thread-7] INFO  ?.6.12] - Container postgres:9.6.12 started in PT8.234S 
[info]   java.lang.IllegalStateException: Mapped port can only be obtained after the container is started

ClassCastException while constructing PostgreSQL container with new API

I'm trying to use PostgreSQL container with new API with testcontainers-scala 0.38.0 and I'm getting a ClassCastException:

An exception or error caused a run to abort: org.testcontainers.containers.PostgreSQLContainer cannot be cast to scala.runtime.Nothing$ 
java.lang.ClassCastException: org.testcontainers.containers.PostgreSQLContainer cannot be cast to scala.runtime.Nothing$
	at com.dimafeng.testcontainers.PostgreSQLContainer.$anonfun$container$1(PostgreSQLContainer.scala:23)
	at scala.Option.map(Option.scala:242)
	at com.dimafeng.testcontainers.PostgreSQLContainer.<init>(PostgreSQLContainer.scala:23)
	at com.dimafeng.testcontainers.PostgreSQLContainer$Def.createContainer(PostgreSQLContainer.scala:90)

Following code is enough to replicate.

PostgreSQLContainer
      .Def()
      .createContainer()

Same code on 0.37.0 seems to work fine.

Kafka testcontainers

not really an issue, just wanted to provide a simple Kafka test container

package testing.testcontainers

import com.dimafeng.testcontainers.GenericContainer
import org.testcontainers.containers.{ Network, SocatContainer }
import org.testcontainers.utility.Base58

class KafkaContainer(version: String) extends GenericContainer(
  dockerImage = s"confluentinc/cp-kafka:$version",
  env = KafkaContainer.defaultEnv(KafkaContainer.KAFKA_PORT)) {

  import KafkaContainer._

  val kafkaNetwork: Network = Network.newNetwork

  var proxy: SocatContainer = new SocatContainer()
    .withNetwork(kafkaNetwork)
    .withTarget(KAFKA_PORT, networkAliases.head)
    .withTarget(ZOOKEEPER_PORT, networkAliases.head)

  proxy.start()

  configure(containerSettings => {

    containerSettings.withNetwork(kafkaNetwork)
    containerSettings.withNetworkAliases("kafka-" + Base58.randomString(6))
    containerSettings.withExposedPorts(KAFKA_PORT)

    containerSettings.addExposedPort(ZOOKEEPER_PORT)
    containerSettings.withEnv("KAFKA_ZOOKEEPER_CONNECT", "localhost:2181")

    containerSettings.withCommand("sh", "-c",
      "printf 'clientPort=2181\ndataDir=/var/lib/zookeeper/data\ndataLogDir=/var/lib/zookeeper/log' > /zookeeper.properties"
        + " && zookeeper-server-start /zookeeper.properties"
        + " & /etc/confluent/docker/run")

    containerSettings.withEnv("KAFKA_ADVERTISED_LISTENERS", "BROKER://" + networkAliases.head + ":9092" + "," + getBootstrapServers)

  })

  def getBootstrapServers: String =
    String.format("PLAINTEXT://%s:%s", proxy.getContainerIpAddress, proxy.getFirstMappedPort)

}

object KafkaContainer {
  val KAFKA_PORT = 9093
  val ZOOKEEPER_PORT = 2181

  def apply(version: String = "3.2.1"): KafkaContainer = new KafkaContainer(version)

  def defaultEnv(kafkaPort: Int): Map[String, String] = Map(
    "KAFKA_LISTENERS" -> s"PLAINTEXT://0.0.0.0:$kafkaPort,BROKER://0.0.0.0:9092",
    "KAFKA_LISTENER_SECURITY_PROTOCOL_MAP" -> "BROKER:PLAINTEXT,PLAINTEXT:PLAINTEXT",
    "KAFKA_INTER_BROKER_LISTENER_NAME" -> "BROKER",
    "KAFKA_BROKER_ID" -> "1",
    "KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR" -> "1",
    "KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS" -> "1",
    "KAFKA_LOG_FLUSH_INTERVAL_MESSAGES" -> Long.MaxValue.toString,
    "KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS" -> "0")
}

containerIpAddress returns the gateway

The call to container.containerIpAddress seems to return the gateway instead of the container's ip address.

Working example (this is modified from the docs):

class nginxtest extends FlatSpec
  with ForAllTestContainer
  with Logging {
  override val container = GenericContainer("nginx:latest",
    exposedPorts = Seq(80),
    waitStrategy = Wait.forHttp("/")
  )

  "GenericContainer" should "start nginx and expose 80 port" in {
    logger.error(s"Returned IP is ${container.containerIpAddress}")
    logger.error(s"Actual IP is ${container.containerInfo.getNetworkSettings.getIpAddress}")
    assert(Source.fromInputStream(
      new URL(s"http://${container.containerIpAddress}:${container.mappedPort(80)}/").openConnection().getInputStream
    ).mkString.contains("If you see this page, the nginx web server is successfully installed"))
    Thread.sleep(60000) // time for running docker commands on the CLI
  }
}

It should return something like:

18:33:53.208 [nginxtest] ERROR - Returned IP is 172.17.0.1
18:33:53.212 [nginxtest] ERROR - Actual IP is 172.17.0.5

To see the actual network settings, I ran docker network inspect <MAIN BRIDGE ID> while the test was running. The outputs looked like this:

> docker network inspect <MAIN BRIDGE ID>
...
"Containers": {
    "8e294d6e7588ae3e23bfbde871abed309ec12a82a47362721e5312e27f6e5d29": {
        "Name": "friendly_dubinsky",
        ...
        "IPv4Address": "172.17.0.5/16",    <----- note IP address that I want
        "IPv6Address": ""
    },
    "ca69c03c979b981da2f6b18aa275de074041b4a6f5e7b41ca2b703ac730db536": {
        "Name": "testcontainers-ryuk-a657e7c9-3cbc-4548-8745-4da652ef7df7",
        ...
        "IPv4Address": "172.17.0.4/16",
        "IPv6Address": ""
    },
    ...
},
...

The workaround seems to be using container.containerInfo.getNetworkSettings.getIpAddress, but this method is marked as deprecated, so I'm worried about relying on it. I think containerIpAddress should return the v6IP if available, and the v4IP if not.

It's worth noting that I ran this test from within another docker container with -v /var/run/docker.sock:/var/run/docker.sock mounted so that I can create sibling containers.

Unable to pull from private Google Container Registry (gcr)

I'm trying to pull from a private registry in the google cloud with testcontainers. Up until now, I've used short-lived credentials generated via gcloud docker -a and it worked flawlessly.
For docker versions > 18.03, this has been deprecated.

I'm now trying to move to use gcloud as a credential helper for docker (according to the documentation here).
This does not work, because when I do not yet have the image locally, it fails to pull it from the registry with the following exception:

org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=eu.gcr.io/projectName/gcloud-emulators-datastore:latest)

When i manually docker pull eu.gcr.io/projectName/gcloud-emulators-datastore:latest it works without the need to do any more authentication etc, because I'm already authenticated via gcloud.

Could `val container` by lazy by default?

Hello, and thanks for your great work! Using it on a daily basis, works like a charm.

Here's the (mini) problem I ran into.

I have a set of standard test that are run through the test (and thus build task) => they're pure unit tests or PBT, they don't need testcontainers (the faster they run the faster the feedback-loop...)

I have a set of integrationTest using testcontainers-scala. They're quite heavy-on-ressources (docker-compose, etc.). They're simply here to assert that "in a real environment, things should work". They're run through a dedicated task, not every build.

I chose to use an annotation for these integration test classes so that I can exclude them through ScalaTest tags (I'm using scalatest-gradle-plugin). But even when excluded, they're still instanciated, and thus val container = /* ... */ is still executed (checking Docker version etc.).

This is not a real problem for me, since everywhere test are run, there's a docker daemon, but it could be problematic if not.

The very simple fix for me was to declare:

@IntegrationTest
class SomeIntegrationTestNeedingTestContainers extends FeatureSpec with ForAllTestContainers {
  override lazy val container: DockerComposeContainer =  /* declaration */ 
}

This seems to work perfectly fine and achieve what I need it to achieve.
I was just wondering if other people ran into this issue? And if yes, could it be "lazy" by default?

wdyt?

Crash with Docker 2.4 on MacOs Catalina 10.15.7

After updating to last docker version, 2.40 (released yesterday), my test environment crashes.
[testcontainers-ryuk] WARN org.testcontainers.utility.ResourceReaper - Can not connect to Ryuk at localhost:32770
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:606)
at java.net.Socket.connect(Socket.java:555)
at java.net.Socket.(Socket.java:451)
at java.net.Socket.(Socket.java:228)
at org.testcontainers.utility.ResourceReaper.lambda$null$1(ResourceReaper.java:138)
at org.rnorth.ducttape.ratelimits.RateLimiter.doWhenReady(RateLimiter.java:27)
at org.testcontainers.utility.ResourceReaper.lambda$start$2(ResourceReaper.java:136)
at java.lang.Thread.run(Thread.java:748)
The only solution was to return to downgrade docker.

quay.io/testcontainers/ryuk does not die after running the tests on multiple containers

I tried to develop test cases using MultipleContainers but it seems that ryuk does not exit after the test finishes. Could anyone help point out what might be the problem ? Thanks a lot !

platform: Mac 10.13.5
Docker version 18.09.0, build 4d60db4
docker-compose version 1.22.0, build f46880f
Scala 2.12.6
java 10.0.1 2018-04-17
import com.dimafeng.testcontainers._
import org.junit.runner.Description
import org.scalatest.mockito.MockitoSugar
import org.scalatest.{FlatSpec, Matchers}
import org.testcontainers.containers.wait.strategy.Wait

//problem: quay.io/testcontainers/ryuk:0.2.2 doesn't die.
class MultipleContainerTest extends FlatSpec with Matchers
  with MockitoSugar with ForAllTestContainer {
  lazy val ganache = new GenericContainer(dockerImage = "trufflesuite/ganache-cli:latest",
    exposedPorts = Seq(8545),
    command = Seq("node",
      "/app/ganache.core.cli.js",
      "--deterministic",
      "--mnemonic",
      "minimum symptom minute gloom tragic situate silver mechanic salad amused elite beef",
      "--debug",
      "--verbose",
      "--networkId",
      "5777",
      "--hostname",
      "0.0.0.0"
    ),
    waitStrategy = Some(Wait.forLogMessage(".*Listening.*\n", 1))
  )

  lazy val nginx = GenericContainer("nginx:latest",
    exposedPorts = Seq(80),
    waitStrategy = Wait.forHttp("/")
  )

  lazy val redis = new DependentContainer("foo")
  override val container: Container = MultipleContainers(ganache, nginx, redis)

  "Multiple container test" should "do something" in {
    1 should ===(1)
  }

  "Multiple container test" should "do something else" in {
    1 should ===(1)
  }
}

import org.testcontainers.containers.{GenericContainer => OTCGenericContainer}

class OTCContainer4S(imageName: String) extends OTCGenericContainer(imageName)

class DependentContainer(input: String) extends SingleContainer[OTCContainer4S] {
  override implicit val container: OTCContainer4S = new OTCContainer4S("redis:latest").withEnv("key", "value")

  override def starting()(implicit description: Description): Unit = {
    println("Hey!!!! just started!")
  }
}

Multiple docker-compose files?

Can I define a DockerComposeContainer from multiple docker-compose files? In general this is possible with docker-compose.

Missing modules, release not found

Hi,

I've noticed that release 0.35.0 is present in the Readme but it's not published on Maven central. The release notes mention that missing modules have been added, I hope that's the case because the rabbitmq module is not found for version 0.34.3.

How are the packages published? Is there a way for me to help getting the modules published? Please let me know once the release is available

cannot connect to mysql containers

I tried to set up the example in my repo but it does not work. can any one help ? Thanks a lot!

version information

test container scala version: 0.21.0
mysql container version: 1.9.1

code

class MysqlSpec extends FlatSpec with ForAllTestContainer {

  override val container = MySQLContainer()

  "Mysql container" should "be started" in {
    Class.forName(container.driverClassName)
    val connection = DriverManager.getConnection(container.jdbcUrl, container.username, container.password)

    val prepareStatement = connection.prepareStatement("select 1")
    try {
      val resultSet = prepareStatement.executeQuery()
      resultSet.next()
      assert(1 == resultSet.getInt(1))
      resultSet.close()
    } finally {
      prepareStatement.close()
    }

    connection.close()
  }
}

log

2018-11-07 16:47:52:002 [ScalaTest-run] INFO  [o.t.d.DockerClientProviderStrategy] Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2018-11-07 16:47:52:035 [ScalaTest-run] INFO  [o.t.d.DockerClientProviderStrategy] Will use 'okhttp' transport
2018-11-07 16:47:52:452 [ScalaTest-run] INFO  [o.t.d.UnixSocketClientProviderStrategy] Accessing docker with local Unix socket
2018-11-07 16:47:52:452 [ScalaTest-run] INFO  [o.t.d.DockerClientProviderStrategy] Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2018-11-07 16:47:52:454 [ScalaTest-run] INFO  [o.t.DockerClientFactory] Docker host IP address is localhost
2018-11-07 16:47:52:577 [ScalaTest-run] INFO  [o.t.DockerClientFactory] Connected to docker: 
  Server Version: 18.06.1-ce
  API Version: 1.38
  Operating System: Docker for Mac
  Total Memory: 3003 MB
2018-11-07 16:47:53:256 [ScalaTest-run] INFO  [o.t.DockerClientFactory] Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
        โ„น๏ธŽ Checking the system...
        โœ” Docker version should be at least 1.6.0
        โœ” Docker environment should have more than 2GB free disk space
2018-11-07 16:47:53:443 [ScalaTest-run] INFO  [๐Ÿณ [mysql:5]] Creating container for image: mysql:5
2018-11-07 16:47:53:796 [ScalaTest-run] INFO  [๐Ÿณ [mysql:5]] Starting container with ID: f19e44f844899018d5a62ec0c1febead586bf078dc5fa6a6616c7d7b8f03298a
2018-11-07 16:47:54:300 [ScalaTest-run] INFO  [๐Ÿณ [mysql:5]] Container mysql:5 is starting: f19e44f844899018d5a62ec0c1febead586bf078dc5fa6a6616c7d7b8f03298a
2018-11-07 16:47:54:319 [ScalaTest-run] INFO  [๐Ÿณ [mysql:5]] Waiting for database connection to become available at jdbc:mysql://localhost:32790/test using query 'SELECT 1'
2018-11-07 16:49:54:318 [ScalaTest-run] ERROR [๐Ÿณ [mysql:5]] Could not start container
org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:51)
	at org.testcontainers.containers.JdbcDatabaseContainer.waitUntilContainerStarted(JdbcDatabaseContainer.java:119)
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:292)
	at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:237)
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:76)
	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:235)
	at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:220)
	at org.testcontainers.containers.GenericContainer.starting(GenericContainer.java:738)
	at org.testcontainers.containers.TestContainerAccessor$.starting(TestContainerAccessor.scala:13)
	at com.dimafeng.testcontainers.TestContainerProxy.starting(TestContainer.scala:106)
	at com.dimafeng.testcontainers.TestContainerProxy.starting$(TestContainer.scala:106)
	at com.dimafeng.testcontainers.SingleContainer.starting(TestContainer.scala:111)
	at com.dimafeng.testcontainers.ForAllTestContainer.run(TestContainer.scala:67)
	at com.dimafeng.testcontainers.ForAllTestContainer.run$(TestContainer.scala:63)
	at plutux.dws.eth.MysqlSpec.run(MysqlSpec.scala:10)
	at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
	at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1346)
	at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1340)
	at scala.collection.immutable.List.foreach(List.scala:389)
	at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1340)
	at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:1031)
	at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:1010)
	at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1506)
	at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1010)
	at org.scalatest.tools.Runner$.run(Runner.scala:850)
	at org.scalatest.tools.Runner.run(Runner.scala)
	at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:131)
	at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:28)
Caused by: java.lang.RuntimeException: Could not get Driver
	at org.testcontainers.containers.JdbcDatabaseContainer.getJdbcDriverInstance(JdbcDatabaseContainer.java:150)
	at org.testcontainers.containers.JdbcDatabaseContainer.createConnection(JdbcDatabaseContainer.java:172)
	at org.testcontainers.containers.JdbcDatabaseContainer.lambda$waitUntilContainerStarted$0(JdbcDatabaseContainer.java:125)
	at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:41)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at org.testcontainers.containers.JdbcDatabaseContainer.getJdbcDriverInstance(JdbcDatabaseContainer.java:148)
	... 7 common frames omitted
2018-11-07 16:49:54:318 [ScalaTest-run] ERROR [๐Ÿณ [mysql:5]] Container log output (if any) will follow:
2018-11-07 16:49:54:336 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: Initializing database
2018-11-07 16:49:54:336 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:54.387476Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2018-11-07 16:49:54:336 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:54.578865Z 0 [Warning] InnoDB: New log files created, LSN=45790
2018-11-07 16:49:54:336 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:55.200168Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2018-11-07 16:49:54:336 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:55.262743Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: d1b6464b-e269-11e8-95d7-0242ac110003.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:55.265178Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:55.265761Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491679Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491721Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491751Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491777Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491797Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.491850Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.492195Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:56.492210Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: Database initialized
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: Initializing certificates
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Generating a 2048 bit RSA private key
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: ......................+++
2018-11-07 16:49:54:337 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: .....................................................................................+++
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: unable to write 'random state'
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: writing new private key to 'ca-key.pem'
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: -----
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Generating a 2048 bit RSA private key
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: ......+++
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: ............................................................................+++
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: unable to write 'random state'
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: writing new private key to 'server-key.pem'
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: -----
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Generating a 2048 bit RSA private key
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: .......................................................+++
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: ...................+++
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: unable to write 'random state'
2018-11-07 16:49:54:338 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: writing new private key to 'client-key.pem'
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: -----
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: Certificates initialized
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: MySQL init process in progress...
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.267133Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.268226Z 0 [Note] mysqld (mysqld 5.7.24) starting as process 89 ...
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271078Z 0 [Note] InnoDB: PUNCH HOLE support available
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271129Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271149Z 0 [Note] InnoDB: Uses event mutexes
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271155Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2018-11-07 16:49:54:339 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271162Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271169Z 0 [Note] InnoDB: Using Linux native AIO
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271333Z 0 [Note] InnoDB: Number of pools: 1
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.271449Z 0 [Note] InnoDB: Using CPU crc32 instructions
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.272584Z 0 [Note] InnoDB: Initializing buffer pool, total size = 16M, instances = 1, chunk size = 16M
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.273628Z 0 [Note] InnoDB: Completed initialization of buffer pool
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.275325Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.286859Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.295064Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.295209Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.384801Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.385951Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2018-11-07 16:49:54:340 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.385995Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.386364Z 0 [Note] InnoDB: Waiting for purge to start
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.436746Z 0 [Note] InnoDB: 5.7.24 started; log sequence number 2591555
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.437139Z 0 [Note] Plugin 'FEDERATED' is disabled.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.441235Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.441521Z 0 [Warning] CA certificate ca.pem is self signed.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.443589Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.445086Z 0 [Note] InnoDB: Buffer pool(s) load completed at 181107  8:47:59
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.446514Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448067Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448148Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448174Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:341 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448199Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448210Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.448233Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.449778Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.449819Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.457501Z 0 [Note] Event Scheduler: Loaded 0 events
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:47:59.457716Z 0 [Note] mysqld: ready for connections.
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Version: '5.7.24'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server (GPL)
2018-11-07 16:49:54:342 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880134Z 4 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880162Z 4 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880178Z 4 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880274Z 4 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880285Z 4 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:343 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880300Z 4 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880701Z 4 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.880716Z 4 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: mysql: [Warning] Using a password on the command line interface can be insecure.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: mysql: [Warning] Using a password on the command line interface can be insecure.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: mysql: [Warning] Using a password on the command line interface can be insecure.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: mysql: [Warning] Using a password on the command line interface can be insecure.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.924637Z 8 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.924675Z 8 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.924692Z 8 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.924723Z 8 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.924740Z 8 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:344 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.925196Z 8 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.925636Z 8 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.925651Z 8 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: 
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.928782Z 0 [Note] Giving 0 client threads a chance to die gracefully
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.928816Z 0 [Note] Shutting down slave threads
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.928826Z 0 [Note] Forcefully disconnecting 0 remaining clients
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.928837Z 0 [Note] Event Scheduler: Purging the queue. 0 events
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.928895Z 0 [Note] Binlog end
2018-11-07 16:49:54:345 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929073Z 0 [Note] Shutting down plugin 'ngram'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929106Z 0 [Note] Shutting down plugin 'partition'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929116Z 0 [Note] Shutting down plugin 'BLACKHOLE'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929125Z 0 [Note] Shutting down plugin 'ARCHIVE'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929131Z 0 [Note] Shutting down plugin 'PERFORMANCE_SCHEMA'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929156Z 0 [Note] Shutting down plugin 'MRG_MYISAM'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929162Z 0 [Note] Shutting down plugin 'MyISAM'
2018-11-07 16:49:54:346 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929172Z 0 [Note] Shutting down plugin 'INNODB_SYS_VIRTUAL'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929182Z 0 [Note] Shutting down plugin 'INNODB_SYS_DATAFILES'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929207Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESPACES'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929216Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN_COLS'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929224Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929253Z 0 [Note] Shutting down plugin 'INNODB_SYS_FIELDS'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929262Z 0 [Note] Shutting down plugin 'INNODB_SYS_COLUMNS'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929271Z 0 [Note] Shutting down plugin 'INNODB_SYS_INDEXES'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929277Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESTATS'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929283Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLES'
2018-11-07 16:49:54:347 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929288Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_TABLE'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929293Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_CACHE'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929298Z 0 [Note] Shutting down plugin 'INNODB_FT_CONFIG'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929305Z 0 [Note] Shutting down plugin 'INNODB_FT_BEING_DELETED'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929313Z 0 [Note] Shutting down plugin 'INNODB_FT_DELETED'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929319Z 0 [Note] Shutting down plugin 'INNODB_FT_DEFAULT_STOPWORD'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929324Z 0 [Note] Shutting down plugin 'INNODB_METRICS'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929330Z 0 [Note] Shutting down plugin 'INNODB_TEMP_TABLE_INFO'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929339Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_POOL_STATS'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929363Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE_LRU'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929372Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929381Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX_RESET'
2018-11-07 16:49:54:348 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929403Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929411Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM_RESET'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929419Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929427Z 0 [Note] Shutting down plugin 'INNODB_CMP_RESET'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929432Z 0 [Note] Shutting down plugin 'INNODB_CMP'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929438Z 0 [Note] Shutting down plugin 'INNODB_LOCK_WAITS'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929443Z 0 [Note] Shutting down plugin 'INNODB_LOCKS'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929448Z 0 [Note] Shutting down plugin 'INNODB_TRX'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929454Z 0 [Note] Shutting down plugin 'InnoDB'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929621Z 0 [Note] InnoDB: FTS optimize thread exiting.
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:05.929811Z 0 [Note] InnoDB: Starting shutdown...
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:06.030296Z 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:06.030649Z 0 [Note] InnoDB: Buffer pool(s) dump completed at 181107  8:48:06
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.311491Z 0 [Note] InnoDB: Shutdown completed; log sequence number 12362130
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313700Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313739Z 0 [Note] Shutting down plugin 'MEMORY'
2018-11-07 16:49:54:349 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313750Z 0 [Note] Shutting down plugin 'CSV'
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313760Z 0 [Note] Shutting down plugin 'sha256_password'
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313819Z 0 [Note] Shutting down plugin 'mysql_native_password'
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.313926Z 0 [Note] Shutting down plugin 'binlog'
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.316454Z 0 [Note] mysqld: Shutdown complete
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: 
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: MySQL init process done. Ready for start up.
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDOUT: 
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.572498Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.573617Z 0 [Note] mysqld (mysqld 5.7.24) starting as process 1 ...
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576580Z 0 [Note] InnoDB: PUNCH HOLE support available
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576623Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576635Z 0 [Note] InnoDB: Uses event mutexes
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576646Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576652Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576660Z 0 [Note] InnoDB: Using Linux native AIO
2018-11-07 16:49:54:350 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576861Z 0 [Note] InnoDB: Number of pools: 1
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.576947Z 0 [Note] InnoDB: Using CPU crc32 instructions
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.578037Z 0 [Note] InnoDB: Initializing buffer pool, total size = 16M, instances = 1, chunk size = 16M
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.579134Z 0 [Note] InnoDB: Completed initialization of buffer pool
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.580040Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.591782Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.607192Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.607269Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.661330Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.662289Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.662323Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.662993Z 0 [Note] InnoDB: Waiting for purge to start
2018-11-07 16:49:54:351 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.713301Z 0 [Note] InnoDB: 5.7.24 started; log sequence number 12362130
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.713631Z 0 [Note] Plugin 'FEDERATED' is disabled.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.717796Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.717997Z 0 [Warning] CA certificate ca.pem is self signed.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.719658Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.719747Z 0 [Note] IPv6 is available.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.719760Z 0 [Note]   - '::' resolves to '::';
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.719912Z 0 [Note] Server socket created on IP: '::'.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.720266Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.722206Z 0 [Note] InnoDB: Buffer pool(s) load completed at 181107  8:48:07
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.722579Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723691Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723728Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723740Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:352 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723764Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723789Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.723805Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.725626Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.725677Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.731834Z 0 [Note] Event Scheduler: Loaded 0 events
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: 2018-11-07T08:48:07.732351Z 0 [Note] mysqld: ready for connections.
2018-11-07 16:49:54:353 [tc-okhttp-stream-1677458155] INFO  [๐Ÿณ [mysql:5]] STDERR: Version: '5.7.24'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

Wrong readme file content for FixedHostPortGenericContainer

Within the readme file rather than FixedHostPortGenericContainer, FixedHostPortGenericGenericContainer (with the typo) is used.

Fixed Host Port Containers
This container will allow you to map container ports to statically defined ports on the docker host.

...
val container = FixedHostPortGenericGenericContainer("nginx:latest",
waitStrategy = Wait.forHttp("/"),
exposedHostPort = 8090,
exposedContainerPort = 80
)

Containers not cleaned up after tests are ran?

I'm using the docker compose functionality, and after the tests complete I see the dangling containers with docker ps. Is there some kind of cleanup hook I need to call? I'm running on Mac OSX Mojave, and running the tests through sbt.

Contributing new containers?

I'd like to contribute back to this project, but not really sure of where to put the code. I've got a working Hadoop HDFS container, implemented as a trait. See below:

import java.time.Duration
import java.time.temporal.ChronoUnit.SECONDS

import com.dimafeng.testcontainers.GenericContainer
import org.testcontainers.containers.wait.{LogMessageWaitStrategy, Wait, WaitAllStrategy}
import java.util.function.{Predicate => JPredicate}

/** Mix this container in to integration tests.
  *
  * Usage:
  * After the container is up (in afterStart()), you can get a handle to the filesystem with
  *
  *   val hdfsuri = s"hdfs://${container.containerIpAddress}:${container.mappedPort(9000)}"
      val hadoopConfig = new Configuration()
      hadoopConfig.set("fs.defaultFS", hdfsuri)
      fs = FileSystem.newInstance(new URI(hdfsuri), hadoopConfig)
  *
  */
trait HadoopContainer {

  /** Helper method for writing Java Predicates
    * See testForSafeMode for example usage.
    * */
  implicit def toJavaPredicate[A](f: Function1[A, Boolean]) =
    new JPredicate[A] {
      override def test(a: A): Boolean = f(a)
    }

  private val WaitForNameNode = new LogMessageWaitStrategy().withRegEx(".*localhost: starting nodemanager.*\n")
  private val testForSafeMode: String => Boolean = (s: String) => !s.contains("Safe mode is ON.")
  private val WaitForSafeModeOff = Wait.forHttp("/dfshealth.jsp").forResponsePredicate(testForSafeMode)

  lazy val container = GenericContainer(
    "sequenceiq/hadoop-docker:2.6.0",
    command = Seq("/etc/bootstrap.sh", "-d"),
    exposedPorts = Seq(50070, 50010, 50020, 50075, 50090, 8020, 9000),
    waitStrategy = new WaitAllStrategy()
      .withStrategy(WaitForNameNode)
      .withStrategy(WaitForSafeModeOff)
      .withStartupTimeout(Duration.of(60, SECONDS))
  )
}

and example usage:

class IntegrationTestsHadoop
    extends FunSpec
    with ForEachTestContainer
    with Logging
    with HadoopContainer {

  var fs: FileSystem = _

  /** Setup the container with the proper fixture */
  override def afterStart: Unit = {
    logger.info("Starting...")
    val hdfsuri = s"hdfs://${container.containerIpAddress}:${container.mappedPort(9000)}"
    val hadoopConfig = new Configuration()
    hadoopConfig.set("fs.defaultFS", hdfsuri)
    fs = FileSystem.newInstance(new URI(hdfsuri), hadoopConfig)

    // Setup all the data needed for testing
    logger.info("Making directory...")
    fs.mkdirs(new Path("/whatever/newdirectory"))
    logger.info("Copying fixture to HDFS...")
    fs.copyFromLocalFile(new Path("src/test/resources/fixtures/data"),
                         new Path("/"))
...

I think it might be useful to have additional "pre-baked" images for people to use, but this isn't really implemented in the same way as the others (MySQL, Postgres, Selenium...). Thoughts?

Get https://quay.io/v2/ request canceled while waiting for connection

This is more a question about documentation / how to.

In my testcase, I am currently instantiating the container via
override val container = PostgreSQLContainer(dockerImageNameOverride = "dockerio.bin.t-mobile.at/postgres:11.0")

When running testcontainers, I get the exception:
com.github.dockerjava.api.exception.InternalServerErrorException: {"message":"Get https://quay.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"}

Since this dependency is only reachable via a private repository for me, I guess I would need to overwrite "getRyukImage" in https://github.com/testcontainers/testcontainers-java/blob/master/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java somehow to point to my private repository.

How can I override this configuration to point to my private repository?

Wait for 0.0.0.0:8080 instead of localhost:8080

Hi all

Wait for 0.0.0.0:8080 instead of localhost:8080

In GenericContainer class, it exists a method waitingFor, that waits for status code 200 as reponse from the server.
I am running a web application in a container and use 0.0.0.0 as host instead of localhost.
When I try to run the sbt test, I've got following timeout:

[sweetsoft/sapmock:latest] - Could not start container
org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [8080] should be listening)  

I am using the test container as the following:

final class MessageSpec extends BddSpec
  with ForAllTestContainer
  with BeforeAndAfterAll {


  override val container = FixedHostPortGenericContainer("sweetsoft/sapmock",
    waitStrategy = Wait.forHttp("/"),
    exposedHostPort = 8080,
    exposedContainerPort = 8080,
  )


  override def beforeAll(): Unit = {

  }


  feature("Process incoming messages") {
    info("As a user, I want that incoming messages is going to process appropriately.")
    info("A message should contain the following properties: `sap_id`, `sap_event`, `payload`")

When I would remove waitStrategy = Wait.forHttp("/"), then it works fine but with waitStrategy = Wait.forHttp("/")
it goes into the timeout.

How to tell the Testcontainer to listen on 0.0.0.0 instead of the localhost?
I have described the problem with the localhost here: https://stackoverflow.com/questions/56201718/why-does-the-client-can-not-connect-to-localhost8080/56201938?noredirect=1#comment99027626_56201938

Thanks

Error using ClickHouseContainer

I got the following error using ClickHouseContainer.

Exception encountered when invoking run on a nested suite.
java.lang.UnsupportedOperationException
	at org.testcontainers.containers.JdbcDatabaseContainer.withPassword(JdbcDatabaseContainer.java:80)
	at com.dimafeng.testcontainers.ClickHouseContainer.<init>(ClickHouseContainer.scala:12)
	at com.dimafeng.testcontainers.ClickHouseContainer$Def.createContainer(ClickHouseContainer.scala:34)
	at com.dimafeng.testcontainers.ClickHouseContainer$Def.createContainer(ClickHouseContainer.scala:24)
	at com.dimafeng.testcontainers.ContainerDef.start(ContainerDef.scala:13)
	at com.dimafeng.testcontainers.ContainerDef.start$(ContainerDef.scala:12)
	at com.dimafeng.testcontainers.ClickHouseContainer$Def.start(ClickHouseContainer.scala:24)
	at com.dimafeng.testcontainers.scalatest.TestContainerForAll.startContainers(TestContainerForAll.scala:31)
	at com.dimafeng.testcontainers.scalatest.TestContainerForAll.startContainers$(TestContainerForAll.scala:30)
	at ClickHouseSpec.startContainers(ClickHouseSpec.scala:5)
	at ClickHouseSpec.startContainers(ClickHouseSpec.scala:5)
	at com.dimafeng.testcontainers.scalatest.TestContainersForAll.run(TestContainersForAll.scala:39)
	at com.dimafeng.testcontainers.scalatest.TestContainersForAll.run$(TestContainersForAll.scala:35)
	at ClickHouseSpec.run(ClickHouseSpec.scala:5)
	at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
	at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1349)
	at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1343)
	at scala.collection.immutable.List.foreach(List.scala:305)
	at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1343)
	at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:1033)
	at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:1011)
	at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1509)
	at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1011)
	at org.scalatest.tools.Runner$.run(Runner.scala:850)
	at org.scalatest.tools.Runner.run(Runner.scala)
	at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:133)
	at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)

Test spec to reproduce error.

import com.dimafeng.testcontainers.ClickHouseContainer
import com.dimafeng.testcontainers.scalatest.TestContainerForAll
import org.scalatest.FlatSpec

class ClickHouseSpec extends FlatSpec with TestContainerForAll {

  override val containerDef = ClickHouseContainer.Def()

  it should "test" in withContainers { clickHouseContainer =>
    assert(clickHouseContainer.containerIpAddress.nonEmpty)
  }
}

Versions used.

scalaVersion := "2.13.1"

libraryDependencies += "org.scalatest"  %% "scalatest"            % "3.0.8"  % "test"
libraryDependencies += "com.dimafeng"   %% "testcontainers-scala" % "0.35.2" % "test"
libraryDependencies += "com.dimafeng"   %% "testcontainers-scala-clickhouse" % "0.35.2" % "test"

NPE when using MariaDB

When i try to test something with MariaDB using testcontainers i get java.lang.NullPointerException.

Code to reproduce:
gradle.build:

plugins {
    id 'java'
    id 'scala'
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.scala-lang:scala-library:2.12.8'

    compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.5.4'

    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile group: 'org.scalatest', name: 'scalatest_2.12', version: '3.0.8'

    testCompile group: 'com.dimafeng', name: 'testcontainers-scala-mariadb_2.12', version: '0.35.0'
    testCompile group: 'com.dimafeng', name: 'testcontainers-scala_2.12', version: '0.35.0'
    testCompile group: 'com.dimafeng', name: 'testcontainers-scala-postgresql_2.12', version: '0.35.0'
}

Test:

import com.dimafeng.testcontainers.{Container, ForAllTestContainer, MariaDBContainer, PostgreSQLContainer}
import org.junit.runner.RunWith
import org.scalatest.WordSpec
import org.scalatestplus.junit.JUnitRunner

@RunWith(classOf[JUnitRunner])
class MariaDBTestScala extends WordSpec with ForAllTestContainer {
//  override val container: PostgreSQLContainer = PostgreSQLContainer()
  override val container: MariaDBContainer = MariaDBContainer()

  "test" should {
    "run" in {
      println("test")
    }
  }
}

When i change MariaDB to PostgreSQL or MySQL it works fine.

The full log:

java.lang.NullPointerException
at com.dimafeng.testcontainers.JdbcDatabaseContainer.databaseName(JdbcDatabaseContainer.scala:13)
at com.dimafeng.testcontainers.JdbcDatabaseContainer.databaseName$(JdbcDatabaseContainer.scala:13)
at com.dimafeng.testcontainers.MariaDBContainer.databaseName(MariaDBContainer.scala:5)
at com.dimafeng.testcontainers.MariaDBContainer.(MariaDBContainer.scala:15)
at sample.MariaDBTestScala.(MariaDBTestScala.scala:11)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.scalatestplus.junit.JUnitRunner.(JUnitRunner.scala:64)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)

Java equivalent also works fine

Cannot start spotify/cassandra container

Hi.

I think I set up the test according to the manual:

class SomeTest extends FlatSpec with ForAllTestContainer {
  
  override val container = GenericContainer(
    "spotify/cassandra:latest",
    exposedPorts = Seq(9042, 9060)
  )  
...
}

And I can even stop with a debugger in my test, and I can see the container running, for example:

CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                                                                                                                                                                                                            NAMES
6a6c884b7a1f        spotify/cassandra:latest   "cassandra-singlenode"   8 seconds ago       Up 7 seconds        0.0.0.0:32965->22/tcp, 0.0.0.0:32964->7000/tcp, 0.0.0.0:32963->7001/tcp, 0.0.0.0:32962->7199/tcp, 0.0.0.0:32961->8012/tcp, 0.0.0.0:32960->9042/tcp, 0.0.0.0:32959->9060/tcp, 0.0.0.0:32958->9160/tcp, 0.0.0.0:32957->61621/tcp   inspiring_wozniak
2c2b6702da07        bsideup/moby-ryuk:0.2.2    "/app"                   9 seconds ago       Up 8 seconds        0.0.0.0:32956->8080/tcp                                                                                                                                                                                                          testcontainers-ryuk-0999123e-27d9-4828-87c1-a2a9c3b51edd

First I think exposedPorts are not working, becuase I expected 9042 and 9060 to be available on 0.0.0.0, and they are mapped to some stange ports... but continuing...

atais@pc ๎‚ฐ ~ sudo ss -lntp | grep 32919         
LISTEN     0      128         :::32960                   :::*                   users:(("docker-proxy",pid=13971,fd=4))
atais@pc ๎‚ฐ ~ sudo ss -lntp | grep 32929
LISTEN     0      128         :::32959                   :::*                   users:(("docker-proxy",pid=21320,fd=4))

So some random ports are open on my computer... and yet the test fail with:

Caused by: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [32959, 32960] should be listening)
	at org.testcontainers.containers.wait.strategy.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:47)
	at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:32)
	at org.testcontainers.containers.wait.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:23)
	at org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:32)
	at org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:531)
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:258)
	... 22 more

what am I doing wrong here ?

Symbol 'type org.junit.runner.Description' is missing from the classpath

Hello, just got this error at compilation time from a scalatest suite using ForAllTestContainer trait.

The install has been just:

"com.dimafeng" %% "testcontainers-scala" % "0.33.0" % "test"

Not sure what to do to fix it. It looks like the junit4 dependency should be included in the tests, but somehow it isn't.

Full error:

[error]      Symbol 'type org.junit.runner.Description' is missing from the classpath.
[error]      This symbol is required by 'value com.dimafeng.testcontainers.TestContainers.TestContainersSuite.suiteDescription'.
[error]      Make sure that type Description is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
[error]      A full rebuild may help if 'TestContainers.class' was compiled against an incompatible version of org.junit.runner.
[error]      L8:   override val container = PostgreSQLContainer()

afterStart()/beforeStop() called only once?

Test setup:

A suite with multiple tests, using the ForEachTestContainer trait and overriding afterStart() and beforeStop()

Expected Behavior:

  1. Containers are started/stopped before and after each test.
  2. afterStart() and beforeStop() are called before and after each test.

Actual Behaviour:

  1. Works.
  2. afterStart() and beforeStop() seem to be called only once

Comments

Is this behavior intentional? (And if so, is there a better hook I can use to do container setup every time a container is started?)

Upgrade to latest testcontainers version

The version of testcontainers this is using is behind by a few versions and I'd like to upgrade it to the most recent version. I'll try and do it on my own when I have some free time but any direction and guidance would be really appreciated.

Shading issue with javax

Hi, I have pulled the following dependency with sbt successfully:
"com.dimafeng" % "testcontainers-scala_2.12" % "0.6.0",

However upon running my unit tests, I am seeing the following errors in compiling when trying to run my scalatest specs:

Error:scalac: Class org.testcontainers.shaded.javax.annotation.CheckForNull not found - continuing with a stub.

DockerComposeContainer with "new API"

How can I create a ContainerDef for a DockerComposeContainer in the "new API"?

(Aside: the README says to write on your slack channel with questions, but it appears I need an invitation to log in there.)

How to load container from tar?

How to load a container from a tar file?
For running directly I do docker load --input
I don't find a way to do this using testcontainers.

Testcontainers hanging when using docker-compose on GitHub actions

Hi all,

I have problems using test containers with GitHub workflows, any suggestion of how could I fix it ?

14:12:26.105 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 31 extracted, (8 GB/8 GB)
46
14:12:27.356 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 32 extracted, (8 GB/8 GB)
47
14:12:27.481 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 33 extracted, (8 GB/8 GB)
48
14:12:27.544 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 34 extracted, (8 GB/8 GB)
49
14:12:27.606 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 35 extracted, (8 GB/8 GB)
50
14:12:31.966 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  0 pending, 38 downloaded, 36 extracted, (8 GB/8 GB)
51
...
...
...
...
...
...
14:16:46.800 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  4 pending, 194 downloaded, 177 extracted, (12 GB/? MB)
626
14:16:49.444 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pulling image layers:  3 pending, 195 downloaded, 177 extracted, (12 GB/? MB)
627
14:16:54.521 INFO  [tp-stream-1949294811] o.testcontainers.DockerClientFactory Pull complete. 198 layers, pulled in 711s (downloaded 12 GB at 18 MB/s)
628
14:16:54.521 WARN  [pool-13-thread-5    ] o.t.c.DockerComposeContainer         Unable to pre-fetch an image (localstack/localstack) depended upon by Docker Compose build - startup will continue but may fail. Exception message was: Could not pull image: write /var/lib/docker/tmp/GetImageBlob417295136: no space left on device

https://github.com/mvillafuertem/scala/runs/981935480?check_suite_focus=true

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.