2 changed files with 124 additions and 0 deletions
@ -0,0 +1,64 @@ |
|||
package com.xsn.explorer.data.common |
|||
|
|||
import java.sql.DriverManager |
|||
|
|||
import com.whisk.docker.{DockerCommandExecutor, DockerContainer, DockerContainerState, DockerKit, DockerReadyChecker} |
|||
|
|||
import scala.concurrent.ExecutionContext |
|||
|
|||
trait DockerPostgresService extends DockerKit { |
|||
|
|||
import DockerPostgresService._ |
|||
|
|||
import scala.concurrent.duration._ |
|||
|
|||
val postgresContainer = DockerContainer(PostgresImage) |
|||
.withPorts((PostgresAdvertisedPort, Some(PostgresExposedPort))) |
|||
.withEnv(s"POSTGRES_USER=$PostgresUsername", s"POSTGRES_PASSWORD=$PostgresPassword") |
|||
.withReadyChecker( |
|||
new PostgresReadyChecker().looped(15, 1.second) |
|||
) |
|||
|
|||
abstract override def dockerContainers: List[DockerContainer] = |
|||
postgresContainer :: super.dockerContainers |
|||
} |
|||
|
|||
object DockerPostgresService { |
|||
|
|||
val PostgresImage = "postgres:9.6" |
|||
val PostgresUsername = "postgres" |
|||
val PostgresPassword = "" |
|||
val DatabaseName = "xsn_blockchain" |
|||
|
|||
def PostgresAdvertisedPort = 5432 |
|||
def PostgresExposedPort = 44444 |
|||
|
|||
class PostgresReadyChecker extends DockerReadyChecker { |
|||
|
|||
override def apply( |
|||
container: DockerContainerState)( |
|||
implicit docker: DockerCommandExecutor, |
|||
ec: ExecutionContext) = { |
|||
|
|||
container |
|||
.getPorts() |
|||
.map { ports => |
|||
try { |
|||
Class.forName("org.postgresql.Driver") |
|||
val url = s"jdbc:postgresql://${docker.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 |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
package com.xsn.explorer.data.common |
|||
|
|||
import com.spotify.docker.client.DefaultDockerClient |
|||
import com.whisk.docker.DockerFactory |
|||
import com.whisk.docker.impl.spotify.SpotifyDockerFactory |
|||
import com.whisk.docker.scalatest.DockerTestKit |
|||
import org.scalatest.time.{Second, Seconds, Span} |
|||
import org.scalatest.{BeforeAndAfterAll, MustMatchers, WordSpec} |
|||
import play.api.db.evolutions.Evolutions |
|||
import play.api.db.{Database, Databases} |
|||
|
|||
/** |
|||
* Allow us to write integration tests depending in a postgres database. |
|||
* |
|||
* The database is launched in a docker instance using docker-it-scala library. |
|||
* |
|||
* When the database is started, play evolutions are automatically applied, the |
|||
* idea is to let you write tests like this: |
|||
* {{{ |
|||
* class UserPostgresDALSpec extends PostgresDALSpec { |
|||
* lazy val dal = new UserPostgresDAL(database) |
|||
* ... |
|||
* } |
|||
* }}} |
|||
*/ |
|||
trait PostgresDataHandlerSpec |
|||
extends WordSpec |
|||
with MustMatchers |
|||
with DockerTestKit |
|||
with DockerPostgresService |
|||
with BeforeAndAfterAll { |
|||
|
|||
import DockerPostgresService._ |
|||
|
|||
implicit val pc = PatienceConfig(Span(20, Seconds), Span(1, Second)) |
|||
|
|||
override implicit val dockerFactory: DockerFactory = new SpotifyDockerFactory( |
|||
DefaultDockerClient.fromEnv().build()) |
|||
|
|||
override def beforeAll(): Unit = { |
|||
super.beforeAll() |
|||
val _ = isContainerReady(postgresContainer).futureValue mustEqual true |
|||
} |
|||
|
|||
def database: Database = { |
|||
val database = Databases( |
|||
driver = "org.postgresql.Driver", |
|||
url = s"jdbc:postgresql://localhost:$PostgresExposedPort/$DatabaseName", |
|||
name = "default", |
|||
config = Map( |
|||
"username" -> PostgresUsername, |
|||
"password" -> PostgresPassword |
|||
) |
|||
) |
|||
|
|||
Evolutions.applyEvolutions(database) |
|||
|
|||
database |
|||
} |
|||
} |
Loading…
Reference in new issue