aboutsummaryrefslogtreecommitdiff
path: root/core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala
diff options
context:
space:
mode:
Diffstat (limited to 'core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala')
-rw-r--r--core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala74
1 files changed, 74 insertions, 0 deletions
diff --git a/core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala b/core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala
new file mode 100644
index 0000000..3e00bf5
--- /dev/null
+++ b/core-testkit/src/main/scala/xyz/driver/core/testkit/postgres/DockerPostgresFixtureDatabase.scala
@@ -0,0 +1,74 @@
+package xyz.driver.core.testkit
+package postgres
+
+import java.net.ServerSocket
+
+import org.scalatest.{BeforeAndAfterAll, Suite}
+import slick.jdbc.PostgresProfile
+import xyz.driver.core.using
+
+import scala.concurrent.Await
+import scala.concurrent.duration._
+
+trait DockerPostgresFixtureDatabase
+ extends FixtureDatabase[PostgresProfile] with DockerPostgresDatabase with BeforeAndAfterAll {
+ self: Suite =>
+ private val dbName: String = sys.env.getOrElse("TEST_DB_NAME", "postgres")
+ private val username: String = sys.env.getOrElse("TEST_DB_USERNAME", "postgres")
+ private val password: String = sys.env.getOrElse("TEST_DB_PASSWORD", "postgres")
+ private val port: Int = sys.env.get("TEST_DB_PORT").fold(getRandomPort())(_.toInt)
+
+ private val enabled: Boolean = !sys.env.get("DISABLE_DOCKER_TEST_DB").contains("true")
+
+ protected val connectionTimeout: Duration = 16.seconds
+
+ final val profile = PostgresProfile
+ final override val database = profile.backend.Database.forURL(
+ driver = "org.postgresql.Driver",
+ url = s"jdbc:postgresql://localhost:$port/$dbName",
+ user = username,
+ password = password)
+
+ object driverDatabase extends xyz.driver.core.database.Database {
+ override val profile = self.profile
+ override val database = self.database
+ }
+
+ private def getRandomPort(): Int = using(new ServerSocket(0))(_.getLocalPort())
+
+ @SuppressWarnings(Array("org.wartremover.warts.Var"))
+ private var dockerContainerId: Option[String] = None
+
+ private def waitForContainer(): Unit = {
+ import concurrent.ExecutionContext.Implicits.global
+ import profile.api._
+
+ val expiration = System.currentTimeMillis() + connectionTimeout.toMillis
+
+ val query = sql"SELECT 1;".as[Int]
+ def dbReady = Await.result(
+ database
+ .run(query)
+ .map(_ == Vector(1))
+ .recover({ case _: org.postgresql.util.PSQLException => false }),
+ connectionTimeout
+ )
+
+ while (!dbReady && System.currentTimeMillis() < expiration) {
+ Thread.sleep(100)
+ }
+ }
+
+ override protected def beforeAll(): Unit = {
+ if (enabled) {
+ dockerContainerId = Some(super.setupDockerDatabase(username, password, dbName, port))
+ waitForContainer()
+ }
+ super.beforeAll()
+ }
+
+ override protected def afterAll(): Unit = {
+ try super.afterAll()
+ finally dockerContainerId.foreach(killDockerDatabase)
+ }
+}