summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2017-04-09 18:16:20 -0700
committerJakob Odersky <jakob@odersky.com>2017-04-09 18:16:20 -0700
commit30c3990d25293c01a380fc8715679e7f618a4cae (patch)
tree5ff399510001123382a9cb8770b72abc527bfaa6
parent2e67fc2ca823e8dc3616ce4a7305175bef58ff9b (diff)
downloadcrashbox-ci-30c3990d25293c01a380fc8715679e7f618a4cae.tar.gz
crashbox-ci-30c3990d25293c01a380fc8715679e7f618a4cae.tar.bz2
crashbox-ci-30c3990d25293c01a380fc8715679e7f618a4cae.zip
Add test for builders
-rw-r--r--crashboxd/src/main/scala/io/crashbox/ci/defs.scala2
-rw-r--r--crashboxd/src/test/scala/io/crashbox/ci/BuildStageSpec.scala122
-rw-r--r--crashboxd/src/test/scala/io/crashbox/ci/DockerExecutorSpec.scala5
3 files changed, 97 insertions, 32 deletions
diff --git a/crashboxd/src/main/scala/io/crashbox/ci/defs.scala b/crashboxd/src/main/scala/io/crashbox/ci/defs.scala
index 24ed530..a17d713 100644
--- a/crashboxd/src/main/scala/io/crashbox/ci/defs.scala
+++ b/crashboxd/src/main/scala/io/crashbox/ci/defs.scala
@@ -1,6 +1,6 @@
package io.crashbox.ci
-sealed trait Environment
+trait Environment
case class DockerEnvironment(image: String) extends Environment
case class TaskDef[+E <: Environment](environment: E, script: String)
diff --git a/crashboxd/src/test/scala/io/crashbox/ci/BuildStageSpec.scala b/crashboxd/src/test/scala/io/crashbox/ci/BuildStageSpec.scala
index eb77c40..dd79f72 100644
--- a/crashboxd/src/test/scala/io/crashbox/ci/BuildStageSpec.scala
+++ b/crashboxd/src/test/scala/io/crashbox/ci/BuildStageSpec.scala
@@ -1,55 +1,123 @@
package io.crashbox.ci
+import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.scaladsl.Keep
import akka.stream.{ ClosedShape, KillSwitch }
import akka.stream.scaladsl.{ GraphDSL, RunnableGraph, Sink, Source }
import akka.stream.{ ActorMaterializer, FanInShape2 }
-import java.io.{ ByteArrayOutputStream, File }
+import java.io.{ ByteArrayOutputStream, File, OutputStream }
import java.nio.file.Files
import org.scalatest._
-import scala.concurrent.Await
+import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._
+import Builder._
+
class BuildStageSpec extends FlatSpec with Matchers with BeforeAndAfterAll {
implicit val system = ActorSystem("crashboxd-buildstage")
implicit val materializer = ActorMaterializer()
- val executor = new DockerExecutor
+ import system.dispatcher
+
+ case class DummyEnv() extends Environment {
+ val id = DummyId()
+ }
+
+ case class DummyId() extends ExecutionId {
+ import DummyId._
+ private var _state: State = Starting
+ def state = _state.synchronized{ _state}
+ def state_=(value: State) = _state.synchronized{_state = value}
- override def beforeAll(): Unit = {
- DockerUtil.ensureImage(executor.dockerClient)
}
+ object DummyId {
+ sealed trait State
+ case object Starting extends State
+ case object Running extends State
+ case object Result extends State
+ case object Stopped extends State
+ }
+
+ class DummyExecutor(
+ startDelay: Duration = 0.seconds,
+ resultDelay: Duration = 0.seconds,
+ stopDelay: Duration = 0.seconds
+ ) extends Executor[DummyEnv, DummyId] {
+
+ override def start(env: DummyEnv, script: String, dir: File, out: OutputStream) = Future {
+ Thread.sleep(startDelay.toMillis)
+ env.id.state = DummyId.Running
+ env.id
+ }
+
+ override def result(id: DummyId) = Future {
+ Thread.sleep(resultDelay.toMillis)
+ id.state = DummyId.Result
+ 0
+ }
+
+ override def stop(id: DummyId) = {
+ Thread.sleep(stopDelay.toMillis)
+ id.state = DummyId.Stopped
+ }
- override def afterAll(): Unit = {
- assert(executor.clean(), "Spawned containers were not removed")
- system.terminate()
}
+ def dummySource(
+ executor: DummyExecutor,
+ env: DummyEnv
+ ): Source[BuildState, NotUsed] = {
+ val stage = new BuildSource(
+ TaskId("dummy", 0),
+ TaskDef(env, ""),
+ executor,
+ new File("nonexistant"),
+ new ByteArrayOutputStream(0)
+ )
+ Source.fromGraph(stage)
+ }
- "BuildStage" should "have a test!" in {
- IOUtil.withTemp{ (dir, out) =>
+ "BuildStage" should "transition states and emit in the correct order" in {
+ val delay = 0.5.seconds
- val taskDef = TaskDef(DockerEnvironment("crashbox"), "sleep 10; exit 0")
- val resultSink = Sink.foreach[Builder.BuildState](x => println(x))
+ val executor = new DummyExecutor(delay, delay, delay)
+ val env = new DummyEnv()
- val stage = new BuildSource(
- TaskId("build", 0),
- taskDef,
- executor,
- dir,
- out
- )
- val src = Source.fromGraph(stage)
+ val taskId = TaskId("dummy", 0)
+ val taskDef = TaskDef(env, "dummy script")
+ val stage = new BuildSource(
+ taskId,
+ taskDef,
+ executor,
+ new File("nonexistant"),
+ new ByteArrayOutputStream(0)
+ )
+ val source = Source.fromGraph(stage)
+ val eventFuture = source.toMat(Sink.seq)(Keep.right).run()
- //val done = src.toMat(resultSink)(Keep.right).run()
+ Thread.sleep((delay / 2).toMillis)
+ assert(env.id.state == DummyId.Starting)
+
+ Thread.sleep(delay.toMillis)
+ assert(env.id.state == DummyId.Running)
+
+ Thread.sleep(delay.toMillis)
+ assert(env.id.state == DummyId.Result)
+
+ Thread.sleep(delay.toMillis)
+ assert(env.id.state == DummyId.Stopped)
+
+
+ val expectedEvents = Seq(
+ TaskStarting(taskId, taskDef),
+ TaskRunning(taskId, env.id),
+ TaskFinished(taskId, 0)
+ )
+ val events = Await.result(eventFuture, 10.seconds)
+ assert(events.toList === expectedEvents.toList)
- //executor.start("crashbox", "sleep 10000", dir, out)
- Thread.sleep(1000)
- assert(executor.clean())
- //Await.ready(done, 30.seconds)
- println("eot")
- }
}
+
}
diff --git a/crashboxd/src/test/scala/io/crashbox/ci/DockerExecutorSpec.scala b/crashboxd/src/test/scala/io/crashbox/ci/DockerExecutorSpec.scala
index 3c47edf..6794908 100644
--- a/crashboxd/src/test/scala/io/crashbox/ci/DockerExecutorSpec.scala
+++ b/crashboxd/src/test/scala/io/crashbox/ci/DockerExecutorSpec.scala
@@ -31,14 +31,11 @@ class DockerExecutorSpec
val exec = new DockerExecutor
override def beforeAll: Unit = {
- sys.addShutdownHook {
- println("------------------- fooooo")
- exec.clean()
- }
DockerUtil.ensureImage(exec.dockerClient)
}
override def afterAll: Unit = {
+ exec.clean() // in case something goes wrong
system.terminate()
}