mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-19 16:57:40 +03:00
JSON API perf test main that starts sandbox and json-api services (#7283)
* reintroducing the main * Introducing `ledger-service/http-json-testing` * cleaning up * Starting sandbox and json-api from perf-test main changelog_begin changelog_end
This commit is contained in:
parent
1eefb4b27d
commit
20e2922b3e
@ -3,6 +3,7 @@
|
||||
|
||||
load(
|
||||
"//bazel_tools:scala.bzl",
|
||||
"da_scala_binary",
|
||||
"da_scala_library",
|
||||
"da_scala_test",
|
||||
"lf_scalacopts",
|
||||
@ -22,13 +23,70 @@ da_scala_library(
|
||||
scalacopts = hj_scalacopts,
|
||||
tags = ["maven_coordinates=com.daml:http-json-perf:__VERSION__"],
|
||||
visibility = ["//visibility:public"],
|
||||
runtime_deps = [
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
],
|
||||
deps = [
|
||||
"//language-support/scala/bindings-akka",
|
||||
"//ledger-api/rs-grpc-bridge",
|
||||
"//ledger-service/http-json",
|
||||
"//ledger-service/http-json-testing",
|
||||
"//ledger-service/jwt",
|
||||
"//libs-scala/scala-utils",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_core",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_databind",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:io_gatling_gatling_commons",
|
||||
"@maven//:io_gatling_gatling_core",
|
||||
"@maven//:io_gatling_gatling_http",
|
||||
"@maven//:io_gatling_gatling_http_client",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_slf4j_slf4j_api",
|
||||
],
|
||||
)
|
||||
|
||||
da_scala_binary(
|
||||
name = "http-json-perf-binary",
|
||||
data = [
|
||||
":release/json-api-perf-logback.xml",
|
||||
],
|
||||
jvm_flags = [
|
||||
"-Dlogback.configurationFile=$(location :release/json-api-perf-logback.xml)",
|
||||
],
|
||||
main_class = "com.daml.http.perf.Main",
|
||||
scalacopts = hj_scalacopts,
|
||||
tags = [
|
||||
"maven_coordinates=com.daml:http-json-perf-deploy:__VERSION__",
|
||||
"no_scala_version_suffix",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":http-json-perf",
|
||||
"//language-support/scala/bindings-akka",
|
||||
"//ledger-api/rs-grpc-bridge",
|
||||
"//ledger-service/http-json",
|
||||
"//ledger-service/http-json-testing",
|
||||
"//ledger-service/jwt",
|
||||
"//libs-scala/scala-utils",
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_core",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_databind",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:io_gatling_gatling_commons",
|
||||
"@maven//:io_gatling_gatling_core",
|
||||
"@maven//:io_gatling_gatling_http",
|
||||
"@maven//:io_gatling_gatling_http_client",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_slf4j_slf4j_api",
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["release/json-api-perf-logback.xml"])
|
||||
|
@ -0,0 +1,17 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoders are assigned the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="io.netty" level="WARN" />
|
||||
<logger name="io.grpc.netty" level="WARN" />
|
||||
<logger name="ch.qos.logback" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.http.perf
|
||||
|
||||
import java.io.File
|
||||
|
||||
import com.daml.jwt.JwtDecoder
|
||||
import com.daml.jwt.domain.Jwt
|
||||
import scopt.RenderingMode
|
||||
|
||||
import scala.concurrent.duration.{Duration, FiniteDuration}
|
||||
|
||||
private[perf] final case class Config(
|
||||
scenario: String,
|
||||
dars: List[File],
|
||||
jwt: Jwt,
|
||||
packageId: Option[String],
|
||||
maxDuration: Option[FiniteDuration]
|
||||
) {
|
||||
override def toString: String =
|
||||
s"Config(" +
|
||||
s"scenario=${this.scenario}, " +
|
||||
s"dars=${dars: List[File]}," +
|
||||
s"jwt=..., " + // don't print the JWT
|
||||
s"packageId=${this.packageId: Option[String]}," +
|
||||
s"maxDuration=${this.maxDuration: Option[FiniteDuration]}" +
|
||||
")"
|
||||
}
|
||||
|
||||
private[perf] object Config {
|
||||
val Empty =
|
||||
Config(scenario = "", dars = List.empty, jwt = Jwt(""), packageId = None, maxDuration = None)
|
||||
|
||||
def parseConfig(args: Seq[String]): Option[Config] =
|
||||
configParser.parse(args, Config.Empty)
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
|
||||
private val configParser: scopt.OptionParser[Config] =
|
||||
new scopt.OptionParser[Config]("http-json-perf-binary") {
|
||||
override def renderingMode: RenderingMode = RenderingMode.OneColumn
|
||||
|
||||
head("JSON API Perf Test Tool")
|
||||
|
||||
help("help").text("Print this usage text")
|
||||
|
||||
opt[String]("scenario")
|
||||
.action((x, c) => c.copy(scenario = x))
|
||||
.required()
|
||||
.text("Performance test scenario to run")
|
||||
|
||||
opt[Seq[File]]("dars")
|
||||
.action((x, c) => c.copy(dars = x.toList))
|
||||
.required()
|
||||
.text("DAR files to pass to Sandbox")
|
||||
|
||||
opt[String]("jwt")
|
||||
.action((x, c) => c.copy(jwt = Jwt(x)))
|
||||
.required()
|
||||
.validate(validateJwt)
|
||||
.text("JWT token to use when connecting to JSON API")
|
||||
|
||||
opt[String]("package-id")
|
||||
.action((x, c) => c.copy(packageId = Some(x)))
|
||||
.optional()
|
||||
.text("Optional package ID to specify in the commands sent to JSON API")
|
||||
|
||||
opt[Duration]("max-duration")
|
||||
.action((x, c) => c.copy(maxDuration = Some(FiniteDuration(x.length, x.unit))))
|
||||
.optional()
|
||||
.text(s"Optional maximum perf test duration. Default value infinity. Examples: 500ms, 5s, 10min, 1h, 1d.")
|
||||
}
|
||||
|
||||
private def validateJwt(s: String): Either[String, Unit] = {
|
||||
import scalaz.syntax.show._
|
||||
|
||||
JwtDecoder
|
||||
.decode(Jwt(s))
|
||||
.bimap(
|
||||
error => error.shows,
|
||||
_ => ()
|
||||
)
|
||||
.toEither
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.http.perf
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.stream.Materializer
|
||||
import com.daml.grpc.adapter.{AkkaExecutionSequencerPool, ExecutionSequencerFactory}
|
||||
import com.daml.http.HttpServiceTestFixture.withHttpService
|
||||
import com.daml.scalautil.Statement.discard
|
||||
import com.typesafe.scalalogging.StrictLogging
|
||||
|
||||
import scala.concurrent.duration.{Duration, _}
|
||||
import scala.concurrent.{Await, ExecutionContext, Future, TimeoutException}
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
object Main extends StrictLogging {
|
||||
|
||||
type Scenario = Config => Future[Unit]
|
||||
|
||||
sealed abstract class ExitCode(val code: Int) extends Product with Serializable
|
||||
object ExitCode {
|
||||
case object Ok extends ExitCode(0)
|
||||
case object InvalidUsage extends ExitCode(100)
|
||||
case object StartupError extends ExitCode(101)
|
||||
case object InvalidScenario extends ExitCode(102)
|
||||
case object TimedOutScenario extends ExitCode(103)
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val name = "http-json-per"
|
||||
val terminationTimeout: FiniteDuration = 30.seconds
|
||||
|
||||
implicit val asys: ActorSystem = ActorSystem(name)
|
||||
implicit val mat: Materializer = Materializer(asys)
|
||||
implicit val aesf: ExecutionSequencerFactory =
|
||||
new AkkaExecutionSequencerPool(poolName = name, terminationTimeout = terminationTimeout)
|
||||
implicit val ec: ExecutionContext = asys.dispatcher
|
||||
|
||||
def terminate(): Unit = discard { Await.result(asys.terminate(), terminationTimeout) }
|
||||
|
||||
val exitCode: ExitCode = Config.parseConfig(args) match {
|
||||
case Some(config) =>
|
||||
val exitCodeF: Future[ExitCode] = main(config)
|
||||
exitCodeF.onComplete {
|
||||
case Success(_) => logger.info(s"Scenario: ${config.scenario: String} completed")
|
||||
case Failure(e) => logger.error(s"Scenario: ${config.scenario: String} failed", e)
|
||||
}
|
||||
try {
|
||||
Await.result(exitCodeF, config.maxDuration.getOrElse(Duration.Inf))
|
||||
} catch {
|
||||
case e: TimeoutException =>
|
||||
logger.error(s"Scenario: ${config.scenario: String} failed", e)
|
||||
ExitCode.TimedOutScenario
|
||||
}
|
||||
case None =>
|
||||
// error is printed out by scopt
|
||||
ExitCode.InvalidUsage
|
||||
}
|
||||
|
||||
terminate()
|
||||
sys.exit(exitCode.code)
|
||||
}
|
||||
|
||||
private def main(config: Config)(
|
||||
implicit asys: ActorSystem,
|
||||
mat: Materializer,
|
||||
aesf: ExecutionSequencerFactory,
|
||||
ec: ExecutionContext
|
||||
): Future[ExitCode] = {
|
||||
logger.info(s"$config")
|
||||
if (config.scenario == "commands") {
|
||||
withHttpService(config.scenario, config.dars, None, None) { (_, _, _, _) =>
|
||||
runScenarioSync(config, _ => Future.unit) // TODO(Leo): scenario runner goes here
|
||||
}.map(_ => ExitCode.Ok)
|
||||
} else {
|
||||
logger.error(s"Unsupported scenario: ${config.scenario}")
|
||||
Future.successful(ExitCode.InvalidScenario)
|
||||
}
|
||||
}
|
||||
|
||||
private def runScenarioSync(config: Config, scenario: Scenario)(
|
||||
implicit ec: ExecutionContext): Future[Unit] = {
|
||||
scenario(config).map(_ => Thread.sleep(5000)) // XXX
|
||||
}
|
||||
}
|
52
ledger-service/http-json-testing/BUILD.bazel
Normal file
52
ledger-service/http-json-testing/BUILD.bazel
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
load(
|
||||
"//bazel_tools:scala.bzl",
|
||||
"da_scala_library",
|
||||
"da_scala_test",
|
||||
"lf_scalacopts",
|
||||
)
|
||||
|
||||
hj_scalacopts = lf_scalacopts + [
|
||||
"-P:wartremover:traverser:org.wartremover.warts.NonUnitStatements",
|
||||
]
|
||||
|
||||
da_scala_library(
|
||||
name = "http-json-testing",
|
||||
srcs = glob(["src/main/scala/**/*.scala"]),
|
||||
plugins = [
|
||||
"@maven//:org_spire_math_kind_projector_2_12",
|
||||
],
|
||||
scalacopts = hj_scalacopts,
|
||||
tags = ["maven_coordinates=com.daml:http-json-testing:__VERSION__"],
|
||||
visibility = ["//visibility:public"],
|
||||
runtime_deps = [
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
],
|
||||
deps = [
|
||||
"//bazel_tools/runfiles:scala_runfiles",
|
||||
"//language-support/scala/bindings-akka",
|
||||
"//ledger-api/rs-grpc-bridge",
|
||||
"//ledger-service/http-json",
|
||||
"//ledger-service/jwt",
|
||||
"//ledger-service/utils",
|
||||
"//ledger/caching",
|
||||
"//ledger/ledger-api-auth",
|
||||
"//ledger/ledger-api-common",
|
||||
"//ledger/participant-integration-api",
|
||||
"//ledger/participant-state",
|
||||
"//ledger/sandbox-classic",
|
||||
"//ledger/sandbox-common",
|
||||
"//libs-scala/auth-utils",
|
||||
"//libs-scala/ports",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:org_tpolecat_doobie_core_2_12",
|
||||
"@maven//:org_tpolecat_doobie_free_2_12",
|
||||
"@maven//:org_typelevel_cats_core_2_12",
|
||||
"@maven//:org_typelevel_cats_effect_2_12",
|
||||
"@maven//:org_typelevel_cats_free_2_12",
|
||||
],
|
||||
)
|
@ -175,20 +175,15 @@ da_scala_test(
|
||||
"//language-support/scala/bindings-akka",
|
||||
"//ledger-api/rs-grpc-bridge",
|
||||
"//ledger-service/db-backend",
|
||||
"//ledger-service/http-json-testing",
|
||||
"//ledger-service/jwt",
|
||||
"//ledger-service/utils",
|
||||
"//ledger/caching",
|
||||
"//ledger/ledger-api-auth",
|
||||
"//ledger/ledger-api-common",
|
||||
"//ledger/participant-integration-api",
|
||||
"//ledger/participant-state",
|
||||
"//ledger/sandbox-classic",
|
||||
"//ledger/sandbox-common",
|
||||
"//libs-scala/auth-utils",
|
||||
"//libs-scala/ports",
|
||||
"//libs-scala/postgresql-testing",
|
||||
"//libs-scala/scala-utils",
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
"@maven//:com_chuusai_shapeless_2_12",
|
||||
"@maven//:com_github_ghik_silencer_lib_2_12_11",
|
||||
"@maven//:com_lihaoyi_sourcecode_2_12",
|
||||
|
Loading…
Reference in New Issue
Block a user