Skip to content

Commit

Permalink
ATL-7315: Replace docker library for tests
Browse files Browse the repository at this point in the history
This commit replaces the old docker-it-scala library with test-containers
library, fixing the incompatibility issues with docker server 26.1.3
  • Loading branch information
EzequielPostan committed Jul 3, 2024
1 parent 7bf57d9 commit 51d113a
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 92 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ env:
jobs:
build-and-test:
name: "Unit tests"
runs-on: self-hosted
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
15 changes: 6 additions & 9 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ lazy val versions = new {
val circe = "0.14.1"
val circeOptics = "0.14.1"
val diffx = "0.7.0"
val dockerClient = "8.16.0"
val dockerTestkit = "0.9.9"
val doobie = "1.0.0-RC2"
val enumeratum = "1.7.0"
val enumeratumDoobie = "1.7.1"
Expand All @@ -50,6 +48,7 @@ lazy val versions = new {
val typesafeConfig = "1.4.2"
val fs2 = "3.8.0"
val scalaUri = "4.0.0"
val testContainers = "0.41.4"
}

lazy val Dependencies = new {
Expand Down Expand Up @@ -105,12 +104,6 @@ lazy val Dependencies = new {
"com.ironcorelabs" %% "cats-scalatest" % versions.catsScalatest % Test
val diffx =
"com.softwaremill.diffx" %% "diffx-scalatest-must" % versions.diffx % Test
val dockerClient =
"com.spotify" % "docker-client" % versions.dockerClient % Test
val dockerTestkitScalatest =
"com.whisk" %% "docker-testkit-scalatest" % versions.dockerTestkit % Test
val dockerTestkitSpotify =
"com.whisk" %% "docker-testkit-impl-spotify" % versions.dockerTestkit % Test
val doobieScalatest =
"org.tpolecat" %% "doobie-scalatest" % versions.doobie % Test
val mockito = "org.mockito" %% "mockito-scala" % versions.mockito % Test
Expand All @@ -121,12 +114,16 @@ lazy val Dependencies = new {
"org.scalatest" %% "scalatest-wordspec" % versions.scalatest % Test
val scalatestplus =
"org.scalatestplus" %% "scalacheck-1-15" % versions.scalatestplus % Test
val testContainersScalaTest =
"com.dimafeng" %% "testcontainers-scala-scalatest" % versions.testContainers % Test
val testContainersPSQL =
"com.dimafeng" %% "testcontainers-scala-postgresql" % versions.testContainers % Test

val bouncyDependencies = Seq(bouncyBcpkix, bouncyBcprov)
val circeDependencies =
Seq(circeCore, circeGeneric, circeGenericExtras, circeParser, circeOptics)
val dockerDependencies =
Seq(dockerClient, dockerTestkitScalatest, dockerTestkitSpotify)
Seq(testContainersScalaTest, testContainersPSQL)
val doobieDependencies =
Seq(doobieCore, doobiePostgresCirce, doobieHikari, doobieScalatest)
val enumeratumDependencies =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package io.iohk.atala.prism.node

import cats.effect.IO
import com.dimafeng.testcontainers.ContainerDef
import doobie.util.transactor.Transactor
import io.iohk.atala.prism.node.logging.TraceId
import io.iohk.atala.prism.node.logging.TraceId.IOWithTraceIdContext
import io.iohk.atala.prism.node.repositories.PostgresRepositorySpec
import io.iohk.atala.prism.node.repositories.{DockerPostgresService, PostgresRepositorySpec}
import org.scalatest.concurrent.ScalaFutures

import scala.concurrent.ExecutionContext
Expand All @@ -17,4 +18,5 @@ class AtalaWithPostgresSpec extends PostgresRepositorySpec[IO] with ScalaFutures
val dbLiftedToTraceIdIO: Transactor[IOWithTraceIdContext] =
db.mapK(TraceId.liftToIOWithTraceId)

override val containerDef: ContainerDef = DockerPostgresService.containerDef
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,23 @@
package io.iohk.atala.prism.node.repositories

import com.spotify.docker.client.DefaultDockerClient
import com.whisk.docker._
import com.whisk.docker.impl.spotify.SpotifyDockerFactory
import org.scalatest.concurrent.ScalaFutures._
import org.scalatest.matchers.must.Matchers._
import com.dimafeng.testcontainers.PostgreSQLContainer
import org.testcontainers.utility.DockerImageName

import java.sql.DriverManager
import scala.concurrent.{ExecutionContext, Future}
object DockerPostgresService {

object DockerPostgresService extends DockerKit {
private val postgresImage = "postgres:13"
private val postgresUsername = "postgres"
private val postgresPassword = "postgres"
private val databaseName = "db"

import scala.concurrent.duration._

override val PullImagesTimeout = 120.minutes
override val StartContainersTimeout = 120.seconds
override val StopContainersTimeout = 120.seconds

override implicit val dockerFactory: DockerFactory = new SpotifyDockerFactory(
DefaultDockerClient.fromEnv().build()
val containerDef: PostgreSQLContainer.Def = PostgreSQLContainer.Def(
dockerImageName = DockerImageName.parse(postgresImage),
databaseName = databaseName,
username = postgresUsername,
password = postgresPassword
)

val PostgresImage = "postgres:13"
val PostgresUsername = "postgres"
val PostgresPassword = "postgres"
val DatabaseName = "db"

val postgresContainer = DockerContainer(PostgresImage)
.withCommand("-N 1000")
.withPorts((PostgresAdvertisedPort, Some(PostgresExposedPort)))
.withEnv(
s"POSTGRES_USER=$PostgresUsername",
s"POSTGRES_PASSWORD=$PostgresPassword"
)
.withReadyChecker(
new PostgresReadyChecker().looped(15, 1.second)
)

override val dockerContainers: List[DockerContainer] =
postgresContainer :: super.dockerContainers

def PostgresAdvertisedPort = 5432
def PostgresExposedPort = 44444
lazy private val postgresContainer = containerDef.start()

private var isRunning = false

Expand All @@ -52,59 +28,24 @@ object DockerPostgresService extends DockerKit {
override def run(): Unit = {

println("Stopping Docker container with Postgres")
stopAllQuietly()
postgresContainer.stop()
println("Stopped Docker container with Postgres")
}
})

println("Starting Docker container with Postgres")
startAllOrFail()
isContainerReady(postgresContainer).futureValue mustEqual true
postgresContainer
isRunning = true
println("Started Docker container with Postgres")
}

val hostname = postgresContainer.hostname.getOrElse("localhost")
val host = postgresContainer.host
val port = postgresContainer.mappedPort(5432)
PostgresConfig(
s"$hostname:$PostgresExposedPort",
DatabaseName,
PostgresUsername,
PostgresPassword
s"$host:$port",
postgresContainer.databaseName,
postgresContainer.username,
postgresContainer.password
)
}

class PostgresReadyChecker extends DockerReadyChecker {

override def apply(
container: DockerContainerState
)(implicit
dockerExecutor: DockerCommandExecutor,
ec: ExecutionContext
): Future[Boolean] = {

container
.getPorts()(dockerExecutor, ec)
.map { _ =>
try {
Class.forName("org.postgresql.Driver")
val url =
s"jdbc:postgresql://${dockerExecutor.host}:$PostgresExposedPort/"
Option(
DriverManager
.getConnection(url, PostgresUsername, PostgresPassword)
)
.foreach { conn =>
// NOTE: For some reason the result is always false
conn.createStatement().execute(s"CREATE DATABASE $DatabaseName")
conn.close()
}

true
} catch {
case _: Throwable =>
false
}
}(ec)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.iohk.atala.prism.node.repositories

import cats.effect.unsafe.implicits.global
import cats.effect.IO
import com.dimafeng.testcontainers.scalatest.TestContainerForAll
import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach}
Expand Down Expand Up @@ -43,7 +44,8 @@ abstract class PostgresRepositorySpec[F[_]]
extends AnyWordSpec
with Matchers
with BeforeAndAfterAll
with BeforeAndAfterEach {
with BeforeAndAfterEach
with TestContainerForAll {

val POSTGRES_HOST_ENVNAME = "POSTGRES_TEST_HOST"
val POSTGRES_DB_ENVNAME = "POSTGRES_TEST_DB"
Expand Down

0 comments on commit 51d113a

Please sign in to comment.