Skip to content

Commit

Permalink
WIP: Stubber is working with http4s18 Stub implementation. Tests brok…
Browse files Browse the repository at this point in the history
…en though, other http4s version not updated.
  • Loading branch information
Dave Smith committed Apr 20, 2018
1 parent 0475b70 commit 031a390
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 70 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ lazy val testsWithDeps =
)
.dependsOn(framework)
.dependsOn(argonaut62)
.dependsOn(http4s016a)
.dependsOn(http4s018)

lazy val docs =
(project in file("scalapact-docs"))
Expand Down
2 changes: 1 addition & 1 deletion example/consumer/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ libraryDependencies ++=
"org.scalatest" %% "scalatest" % "3.0.1" % "test"
)

scalaPactEnv := ScalaPactEnv.default.withPort(8080)
scalaPactEnv := ScalaPactEnv.defaults.withPort(8080)
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ object ProviderClient {
.headers(("Accept", "application/json"), ("Name", name))
.asString match {
case r: HttpResponse[String] if r.is2xx =>
println(">> " + r)
parse(r.body).extractOpt[Token]

case r: HttpResponse[String] =>
println("<< " + r)
None
}

Expand Down
61 changes: 61 additions & 0 deletions pacts/Consumer_Provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"provider" : {
"name" : "Provider"
},
"consumer" : {
"name" : "Consumer"
},
"interactions" : [
{
"request" : {
"method" : "GET",
"path" : "/auth_token",
"matchingRules" : {
"$.headers.Name" : {
"match" : "regex",
"regex" : "^([a-zA-Z]+)$"
}
},
"headers" : {
"Accept" : "application/json",
"Name" : "Bob"
}
},
"description" : "Fetching least secure auth token ever",
"response" : {
"status" : 202,
"headers" : {
"Content-Type" : "application/json; charset=UTF-8"
},
"body" : {
"token" : "abcABC123"
},
"matchingRules" : {
"$.body.token" : {
"match" : "regex",
"regex" : "^([a-zA-Z0-9]+)$"
}
}
}
},
{
"request" : {
"method" : "GET",
"path" : "/results"
},
"description" : "Fetching results",
"response" : {
"status" : 200,
"body" : {
"count" : 3,
"results" : [
"Bob",
"Fred",
"Harry"
]
}
},
"providerState" : "Results: Bob, Fred, Harry"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ object ScalaPactPlugin extends AutoPlugin {
versionedConsumerNames := Seq.empty[(String, String)],
pactContractVersion := "",
allowSnapshotPublish := false,
scalaPactEnv := ScalaPactEnv.default
scalaPactEnv := ScalaPactEnv.empty
)

@SuppressWarnings(Array("org.wartremover.warts.Any"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.itv.scalapact.plugin

import com.itv.scalapact.shared.ScalaPactSettings

import scala.concurrent.duration.Duration
import scala.concurrent.duration._

case class ScalaPactEnv(protocol: Option[String],
host: Option[String],
Expand Down Expand Up @@ -46,9 +46,23 @@ case class ScalaPactEnv(protocol: Option[String],

object ScalaPactEnv {

def apply: ScalaPactEnv = default
def apply: ScalaPactEnv = defaults

def default: ScalaPactEnv = ScalaPactEnv(None, None, None, None, None, None, None)
def apply(protocol: String, host: String, port: Int): ScalaPactEnv =
ScalaPactEnv(
Option(protocol),
Option(host),
Option(port),
None, // "pacts"
None, // false
Option(Duration(1, SECONDS)),
None // "target/pacts"
)

def defaults: ScalaPactEnv =
ScalaPactEnv("http", "localhost", 1234)

def empty: ScalaPactEnv = ScalaPactEnv(None, None, None, None, None, None, None)

def append(a: ScalaPactEnv, b: ScalaPactEnv): ScalaPactEnv =
ScalaPactEnv(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ object ScalaPactStubberCommand {
pactWriter: IPactWriter,
pactStubber: IPactStubber,
sslContextMap: SslContextMap
): Unit = {
(loadPactFiles(pactReader)(true)(scalaPactSettings.giveOutputPath) andThen interactionManager.addToInteractionManager andThen pactStubber
.startServer(interactionManager, 2, None, None)(pactReader, pactWriter, sslContextMap))(scalaPactSettings)
()
): IPactStubber = {
val loadPacts = loadPactFiles(pactReader)(true)(scalaPactSettings.giveOutputPath)
val addToManager = interactionManager.addToInteractionManager
val launchStub = pactStubber.startServer(interactionManager, 2, None, scalaPactSettings.port)(pactReader,
pactWriter,
sslContextMap)

(loadPacts andThen addToManager andThen launchStub)(scalaPactSettings)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.itv.scalapact.json._
import com.itv.scalapact.http._
import com.itv.scalapact.plugin.shared._
import com.itv.scalapact.shared.ScalaPactSettings

import sbt.Keys._
import sbt.plugins.JvmPlugin
import sbt.{Def, _}
Expand Down Expand Up @@ -83,7 +84,7 @@ object ScalaPactPlugin extends AutoPlugin {
versionedConsumerNames := Seq.empty[(String, String)],
pactContractVersion := "",
allowSnapshotPublish := false,
scalaPactEnv := ScalaPactEnv.default
scalaPactEnv := ScalaPactEnv.empty
)

@SuppressWarnings(Array("org.wartremover.warts.Any"))
Expand All @@ -94,11 +95,16 @@ object ScalaPactPlugin extends AutoPlugin {
] with String with Seq[String] with PartialFunction[String, Boolean] with Task[Unit] with InputTask[Unit]
]] = {
pactSettings ++ Seq(
// Tasks
pactPack := pactPackTask.value,
pactPush := pactPushTask.evaluated,
pactCheck := pactCheckTask.evaluated,
pactStub := pactStubTask.evaluated,
pactTest := pactTestTask.value
// Classic
pactTest := pactTestTask.value,
pactPublish := pactPublishTask.evaluated,
pactVerify := pactCheckTask.evaluated,
pactStubber := pactStubberTask.evaluated
)
}

Expand All @@ -109,7 +115,7 @@ object ScalaPactPlugin extends AutoPlugin {
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactPushTask: Def.Initialize[InputTask[Unit]] =
def pactPushTask: Def.Initialize[InputTask[Unit]] =
Def.inputTask {
ScalaPactPublishCommand.doPactPublish(
scalaPactEnv.value.toSettings + ScalaPactSettings.parseArguments(spaceDelimited("<arg>").parsed),
Expand All @@ -122,7 +128,7 @@ object ScalaPactPlugin extends AutoPlugin {
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactCheckTask: Def.Initialize[InputTask[Unit]] =
def pactCheckTask: Def.Initialize[InputTask[Unit]] =
Def.inputTask {
ScalaPactVerifyCommand.doPactVerify(
scalaPactEnv.value.toSettings + ScalaPactSettings.parseArguments(spaceDelimited("<arg>").parsed),
Expand All @@ -137,35 +143,28 @@ object ScalaPactPlugin extends AutoPlugin {
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactStubTask: Def.Initialize[InputTask[Unit]] =
def pactStubTask: Def.Initialize[InputTask[Unit]] =
Def.inputTask {
val args: Seq[String] = spaceDelimited("<arg>").parsed
println("Stub me! Args: " + args.mkString(", "))
// ScalaPactStubberCommand.runStubber(
// scalaPactEnv.value.toSettings + ScalaPactSettings.parseArguments(spaceDelimited("<arg>").parsed),
// ScalaPactStubberCommand.interactionManagerInstance
// )
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactTestTask: Def.Initialize[Task[Unit]] =
pactPack.dependsOn((test in Test).dependsOn((compile in Compile).dependsOn(clean in Compile)))
ScalaPactStubberCommand.runStubber(
scalaPactEnv.value.toSettings + ScalaPactSettings.parseArguments(spaceDelimited("<arg>").parsed),
ScalaPactStubberCommand.interactionManagerInstance
)
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactPublishTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
pactTest.value
pactPush.evaluated
}
def pactTestTask: Def.Initialize[Task[Unit]] =
pactPackTask.dependsOn((test in Test).dependsOn((compile in Compile).dependsOn(clean in Compile)))

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactVerifyTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
pactCheck.evaluated
def pactPublishTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
pactPushTask.dependsOn(pactTestTask)
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
lazy val pactStubberTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
pactTest.value
pactStub.evaluated
def pactStubberTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
pactStubTask.dependsOn(pactTestTask)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import com.itv.scalapact.http4s18.impl.HeaderImplicitConversions._
import com.itv.scalapact.shared.ColourOuput._
import com.itv.scalapact.shared.typeclasses.{IPactReader, IPactStubber, IPactWriter}
import com.itv.scalapact.shared.{PactLogger, _}
import fs2.async
import fs2.async.mutable
import javax.net.ssl.SSLContext
import org.http4s.dsl.io._
import org.http4s.server.Server
import org.http4s.server.blaze.BlazeBuilder
import org.http4s.util.CaseInsensitiveString
import org.http4s.{HttpService, Request, Response, Status}
Expand Down Expand Up @@ -151,7 +152,10 @@ object PactStubService {

class PactServer extends IPactStubber {

private var instance: Option[Server[IO]] = None
import scala.concurrent.ExecutionContext.Implicits.global

private val terminator: mutable.Signal[IO, Boolean] =
async.signalOf[IO, Boolean](false).unsafeRunSync()

private def blazeBuilder(
scalaPactSettings: ScalaPactSettings,
Expand All @@ -174,26 +178,23 @@ class PactServer extends IPactStubber {
port: Option[Int])(implicit pactReader: IPactReader,
pactWriter: IPactWriter,
sslContextMap: SslContextMap): ScalaPactSettings => IPactStubber =
scalaPactSettings =>
instance match {
case Some(_) =>
this

case None =>
instance = Option(
blazeBuilder(scalaPactSettings, interactionManager, connectionPoolSize, sslContextName, port).start
.unsafeRunSync()
)
this
}
scalaPactSettings => {

def awaitShutdown(): Unit =
instance.foreach(_.shutdown.unsafeRunSync())
blazeBuilder(scalaPactSettings, interactionManager, connectionPoolSize, sslContextName, port).serve
.interruptWhen(terminator)
.compile
.drain
.unsafeToFuture()

def shutdown(): Unit = {
instance.foreach(_.shutdown.unsafeRunSync())
instance = None
()
this
}

def awaitShutdown(): Unit = {
scala.io.StdIn.readLine()
terminator.set(true).unsafeRunSync()
}

def shutdown(): Unit =
terminator.set(true).unsafeRunSync()

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ case class ScalaPactSettings(protocol: Option[String],
clientTimeout.map(p => ("--clientTimeout", p.toSeconds.toString)),
outputPath.map(p => ("--out", p))
).collect { case Some(s) => s }.toMap

def renderAsString: String =
toArguments.mkString(", ")
}

object ScalaPactSettings {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.itv.standalonestubber

import com.itv.scalapact.circe09.{pactReaderInstance, pactWriterInstance}
import com.itv.scalapact.http4s18.serverInstance
import com.itv.scalapact.http.serverInstance
import com.itv.scalapact.json.{pactReaderInstance, pactWriterInstance}
import com.itv.scalapact.shared.ColourOuput._
import com.itv.scalapact.shared.{PactLogger, ScalaPactSettings, SslContextMap}
import com.itv.scalapact.shared.typeclasses.IPactStubber
import com.itv.scalapact.shared.{PactLogger, ScalaPactSettings}
import com.itv.scalapactcore.common.LocalPactFileLoader._
import com.itv.scalapactcore.common.stubber.InteractionManager

Expand All @@ -15,14 +16,18 @@ object PactStubber {
PactLogger.message("** ScalaPact: Running Stubber **".white.bold)
PactLogger.message("*************************************".white.bold)

val interactionManager: InteractionManager = new InteractionManager
val interactionManager = new InteractionManager

(ScalaPactSettings.parseArguments andThen loadPactFiles(pactReaderInstance)(true)("pacts") andThen interactionManager.addToInteractionManager andThen serverInstance
.startServer(interactionManager, 5, sslContextName = None, port = None)(
pactReaderInstance,
pactWriterInstance,
SslContextMap.defaultEmptyContextMap
))(args)
val parseArgs = ScalaPactSettings.parseArguments
val loadPacts = loadPactFiles(pactReaderInstance)(true)("pacts")
val addInteractions = interactionManager.addToInteractionManager
val startUp = serverInstance
.startServer(interactionManager, 5, sslContextName = None, port = None)

val launch: Seq[String] => IPactStubber =
parseArgs andThen loadPacts andThen addInteractions andThen startUp

launch(args).awaitShutdown()

()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,6 @@ object SimpleClient {
try {
val response = request.asString

// if(!response.is2xx) {
// println("Request: \n" + request)
// println("Response: \n" + response)
// }

SimpleResponse(response.code, response.headers, response.body)
} catch {
case e: Throwable =>
Expand Down

0 comments on commit 031a390

Please sign in to comment.