Last active
February 12, 2019 14:22
-
-
Save vyshane/3ac679d1c57d194e00ed004b27d5133c to your computer and use it in GitHub Desktop.
docker-it-scala trait that provides a FDBDatabase via the foundationdb/foundationdb Docker image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
docker:docker@127.0.0.1:4500 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2019 Vy-Shane Xie | |
package mu.node.sample.fdb | |
import com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory | |
import com.spotify.docker.client.messages.PortBinding | |
import com.whisk.docker.testkit.ContainerState.{HasId, Ready} | |
import com.whisk.docker.testkit.{ | |
BaseContainer, | |
ContainerCommandExecutor, | |
ContainerSpec, | |
DockerReadyChecker, | |
FailFastCheckException, | |
ManagedContainers | |
} | |
import com.whisk.docker.testkit.scalatest.DockerTestKitForAll | |
import org.scalatest.Suite | |
import scala.concurrent.{ExecutionContext, Future} | |
/* | |
* Provides a FoundationDB Docker container for integration tests | |
*/ | |
trait FoundationDbDockerTestKit extends DockerTestKitForAll { | |
self: Suite => | |
val fdb = FDBDatabaseFactory | |
.instance() | |
// Assumes a src/test/resources/fdb.cluster file with the following contents: | |
// docker:docker@127.0.0.1:4500 | |
.getDatabase(getClass.getResource("/fdb.cluster").getPath) | |
private val fdbPort = 4500 | |
private lazy val fdbContainer = ContainerSpec("foundationdb/foundationdb:latest") | |
.withPortBindings(fdbPort -> PortBinding.of("0.0.0.0", fdbPort)) | |
.withEnv("FDB_NETWORKING_MODE=host", s"FDB_PORT=$fdbPort") | |
// The FoundationDB Docker image doesn't come with a pre-configured database | |
.withReadyChecker(new FdbDockerReadyChecker("configure new single memory")) | |
override val managedContainers: ManagedContainers = fdbContainer.toManagedContainer | |
} | |
/* | |
* Ready checker for FoundationDB container, with the ability to run a fdbcli --exec command | |
* once FoundationDB has started. | |
*/ | |
class FdbDockerReadyChecker(onReadyFdbcliExec: String = "status") extends DockerReadyChecker { | |
override def apply(container: BaseContainer)(implicit docker: ContainerCommandExecutor, | |
ec: ExecutionContext): Future[Unit] = { | |
val execOnReady: (String) => Future[Unit] = (containerId) => { | |
Future { | |
docker.client.execCreate(containerId, Array("/usr/bin/fdbcli", "--exec", onReadyFdbcliExec)) | |
} map { exec => | |
docker.client.execStart(exec.id()).readFully() | |
} map (_ => ()) | |
} | |
container.state() match { | |
case Ready(info) => | |
execOnReady(info.id()) | |
case state: HasId => | |
docker | |
.withLogStreamLinesRequirement(state.id, withErr = true)(_.contains("FDBD joined cluster.")) | |
.flatMap(_ => execOnReady(state.id)) | |
case _ => | |
Future.failed(new FailFastCheckException("Can't initialize LogStream to container without ID")) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2019 Vy-Shane Xie | |
package mu.node.sample.fdb | |
import org.scalatest.{AsyncWordSpec, Matchers} | |
import monix.execution.Scheduler.Implicits.global | |
/* | |
* Integration tests for a SampleRepository | |
* The tests in this spec need a Docker engine to run FoundationDB | |
*/ | |
class SampleRepositorySpec extends AsyncWordSpec with Matchers with FoundationDbDockerTestKit { | |
val repository = new SampleRepository(fdb) | |
"SampleRepository" when { | |
"asked to get a record that doesn't exist" should { | |
"return empty option" in { | |
repository.get("inexistant").runAsync map { r => | |
r shouldEqual None | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment