Skip to content

Commit c9f944d

Browse files
ATL-7315: Replace docker library for tests
This commit replaces the old docker-it-scala library with test-containers library, fixing the incompatibility issues with docker server 26.1.3
1 parent 2fbaa3d commit c9f944d

File tree

4 files changed

+33
-91
lines changed

4 files changed

+33
-91
lines changed

build.sbt

+6-9
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ lazy val versions = new {
2525
val circe = "0.14.1"
2626
val circeOptics = "0.14.1"
2727
val diffx = "0.7.0"
28-
val dockerClient = "8.16.0"
29-
val dockerTestkit = "0.9.9"
3028
val doobie = "1.0.0-RC2"
3129
val enumeratum = "1.7.0"
3230
val enumeratumDoobie = "1.7.1"
@@ -50,6 +48,7 @@ lazy val versions = new {
5048
val typesafeConfig = "1.4.2"
5149
val fs2 = "3.8.0"
5250
val scalaUri = "4.0.0"
51+
val testContainers = "0.41.4"
5352
}
5453

5554
lazy val Dependencies = new {
@@ -105,12 +104,6 @@ lazy val Dependencies = new {
105104
"com.ironcorelabs" %% "cats-scalatest" % versions.catsScalatest % Test
106105
val diffx =
107106
"com.softwaremill.diffx" %% "diffx-scalatest-must" % versions.diffx % Test
108-
val dockerClient =
109-
"com.spotify" % "docker-client" % versions.dockerClient % Test
110-
val dockerTestkitScalatest =
111-
"com.whisk" %% "docker-testkit-scalatest" % versions.dockerTestkit % Test
112-
val dockerTestkitSpotify =
113-
"com.whisk" %% "docker-testkit-impl-spotify" % versions.dockerTestkit % Test
114107
val doobieScalatest =
115108
"org.tpolecat" %% "doobie-scalatest" % versions.doobie % Test
116109
val mockito = "org.mockito" %% "mockito-scala" % versions.mockito % Test
@@ -121,12 +114,16 @@ lazy val Dependencies = new {
121114
"org.scalatest" %% "scalatest-wordspec" % versions.scalatest % Test
122115
val scalatestplus =
123116
"org.scalatestplus" %% "scalacheck-1-15" % versions.scalatestplus % Test
117+
val testContainersScalaTest =
118+
"com.dimafeng" %% "testcontainers-scala-scalatest" % versions.testContainers % Test
119+
val testContainersPSQL =
120+
"com.dimafeng" %% "testcontainers-scala-postgresql" % versions.testContainers % Test
124121

125122
val bouncyDependencies = Seq(bouncyBcpkix, bouncyBcprov)
126123
val circeDependencies =
127124
Seq(circeCore, circeGeneric, circeGenericExtras, circeParser, circeOptics)
128125
val dockerDependencies =
129-
Seq(dockerClient, dockerTestkitScalatest, dockerTestkitSpotify)
126+
Seq(testContainersScalaTest, testContainersPSQL)
130127
val doobieDependencies =
131128
Seq(doobieCore, doobiePostgresCirce, doobieHikari, doobieScalatest)
132129
val enumeratumDependencies =

src/test/scala/io/iohk/atala/prism/node/AtalaWithPostgresSpec.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package io.iohk.atala.prism.node
22

33
import cats.effect.IO
4+
import com.dimafeng.testcontainers.ContainerDef
45
import doobie.util.transactor.Transactor
56
import io.iohk.atala.prism.node.logging.TraceId
67
import io.iohk.atala.prism.node.logging.TraceId.IOWithTraceIdContext
7-
import io.iohk.atala.prism.node.repositories.PostgresRepositorySpec
8+
import io.iohk.atala.prism.node.repositories.{DockerPostgresService, PostgresRepositorySpec}
89
import org.scalatest.concurrent.ScalaFutures
910

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

21+
override val containerDef: ContainerDef = DockerPostgresService.containerDef
2022
}
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,23 @@
11
package io.iohk.atala.prism.node.repositories
22

3-
import com.spotify.docker.client.DefaultDockerClient
4-
import com.whisk.docker._
5-
import com.whisk.docker.impl.spotify.SpotifyDockerFactory
6-
import org.scalatest.concurrent.ScalaFutures._
7-
import org.scalatest.matchers.must.Matchers._
3+
import com.dimafeng.testcontainers.PostgreSQLContainer
4+
import org.testcontainers.utility.DockerImageName
85

9-
import java.sql.DriverManager
10-
import scala.concurrent.{ExecutionContext, Future}
6+
object DockerPostgresService {
117

12-
object DockerPostgresService extends DockerKit {
8+
private val postgresImage = "postgres:13"
9+
private val postgresUsername = "postgres"
10+
private val postgresPassword = "postgres"
11+
private val databaseName = "db"
1312

14-
import scala.concurrent.duration._
15-
16-
override val PullImagesTimeout = 120.minutes
17-
override val StartContainersTimeout = 120.seconds
18-
override val StopContainersTimeout = 120.seconds
19-
20-
override implicit val dockerFactory: DockerFactory = new SpotifyDockerFactory(
21-
DefaultDockerClient.fromEnv().build()
13+
val containerDef: PostgreSQLContainer.Def = PostgreSQLContainer.Def(
14+
dockerImageName = DockerImageName.parse(postgresImage),
15+
databaseName = databaseName,
16+
username = postgresUsername,
17+
password = postgresPassword
2218
)
2319

24-
val PostgresImage = "postgres:13"
25-
val PostgresUsername = "postgres"
26-
val PostgresPassword = "postgres"
27-
val DatabaseName = "db"
28-
29-
val postgresContainer = DockerContainer(PostgresImage)
30-
.withCommand("-N 1000")
31-
.withPorts((PostgresAdvertisedPort, Some(PostgresExposedPort)))
32-
.withEnv(
33-
s"POSTGRES_USER=$PostgresUsername",
34-
s"POSTGRES_PASSWORD=$PostgresPassword"
35-
)
36-
.withReadyChecker(
37-
new PostgresReadyChecker().looped(15, 1.second)
38-
)
39-
40-
override val dockerContainers: List[DockerContainer] =
41-
postgresContainer :: super.dockerContainers
42-
43-
def PostgresAdvertisedPort = 5432
44-
def PostgresExposedPort = 44444
20+
lazy private val postgresContainer = containerDef.start()
4521

4622
private var isRunning = false
4723

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

5430
println("Stopping Docker container with Postgres")
55-
stopAllQuietly()
31+
postgresContainer.stop()
5632
println("Stopped Docker container with Postgres")
5733
}
5834
})
5935

6036
println("Starting Docker container with Postgres")
61-
startAllOrFail()
62-
isContainerReady(postgresContainer).futureValue mustEqual true
37+
postgresContainer
6338
isRunning = true
6439
println("Started Docker container with Postgres")
6540
}
6641

67-
val hostname = postgresContainer.hostname.getOrElse("localhost")
42+
val host = postgresContainer.host
43+
val port = postgresContainer.mappedPort(5432)
6844
PostgresConfig(
69-
s"$hostname:$PostgresExposedPort",
70-
DatabaseName,
71-
PostgresUsername,
72-
PostgresPassword
45+
s"$host:$port",
46+
postgresContainer.databaseName,
47+
postgresContainer.username,
48+
postgresContainer.password
7349
)
7450
}
75-
76-
class PostgresReadyChecker extends DockerReadyChecker {
77-
78-
override def apply(
79-
container: DockerContainerState
80-
)(implicit
81-
dockerExecutor: DockerCommandExecutor,
82-
ec: ExecutionContext
83-
): Future[Boolean] = {
84-
85-
container
86-
.getPorts()(dockerExecutor, ec)
87-
.map { _ =>
88-
try {
89-
Class.forName("org.postgresql.Driver")
90-
val url =
91-
s"jdbc:postgresql://${dockerExecutor.host}:$PostgresExposedPort/"
92-
Option(
93-
DriverManager
94-
.getConnection(url, PostgresUsername, PostgresPassword)
95-
)
96-
.foreach { conn =>
97-
// NOTE: For some reason the result is always false
98-
conn.createStatement().execute(s"CREATE DATABASE $DatabaseName")
99-
conn.close()
100-
}
101-
102-
true
103-
} catch {
104-
case _: Throwable =>
105-
false
106-
}
107-
}(ec)
108-
}
109-
}
11051
}

src/test/scala/io/iohk/atala/prism/node/repositories/PostgresRepositorySpec.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.iohk.atala.prism.node.repositories
22

33
import cats.effect.unsafe.implicits.global
44
import cats.effect.IO
5+
import com.dimafeng.testcontainers.scalatest.TestContainerForAll
56
import org.scalatest.matchers.must.Matchers
67
import org.scalatest.wordspec.AnyWordSpec
78
import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach}
@@ -43,7 +44,8 @@ abstract class PostgresRepositorySpec[F[_]]
4344
extends AnyWordSpec
4445
with Matchers
4546
with BeforeAndAfterAll
46-
with BeforeAndAfterEach {
47+
with BeforeAndAfterEach
48+
with TestContainerForAll {
4749

4850
val POSTGRES_HOST_ENVNAME = "POSTGRES_TEST_HOST"
4951
val POSTGRES_DB_ENVNAME = "POSTGRES_TEST_DB"

0 commit comments

Comments
 (0)