Alexis Hernandez
7 years ago
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