diff --git a/build.sbt b/build.sbt index 68155a7ace..606784cecd 100644 --- a/build.sbt +++ b/build.sbt @@ -256,13 +256,13 @@ lazy val allAggregates: Seq[ProjectReference] = { } if (sys.env.isDefinedAt("ONLY_LOOM")) { println("[info] ONLY_LOOM defined, including only loom-based projects") - filteredByNative.filter(p => (p.toString.contains("Loom") || p.toString.contains("nima"))) + filteredByNative.filter(p => (p.toString.contains("Loom") || p.toString.contains("nima") || p.toString.contains("perfTests"))) } else if (sys.env.isDefinedAt("ALSO_LOOM")) { println("[info] ALSO_LOOM defined, including also loom-based projects") filteredByNative } else { println("[info] ONLY_LOOM *not* defined, *not* including loom-based-projects") - filteredByNative.filterNot(p => (p.toString.contains("Loom") || p.toString.contains("nima"))) + filteredByNative.filterNot(p => (p.toString.contains("Loom") || p.toString.contains("nima") || p.toString.contains("perfTests"))) } } @@ -538,7 +538,18 @@ lazy val perfTests: ProjectMatrix = (projectMatrix in file("perf-tests")) Test / run / javaOptions --= perfServerJavaOptions ) .jvmPlatform(scalaVersions = List(scala2_13)) - .dependsOn(core, pekkoHttpServer, http4sServer, nettyServer, nettyServerCats, playServer, vertxServer, vertxServerCats) + .dependsOn( + core, + pekkoHttpServer, + http4sServer, + nettyServer, + nettyServerCats, + nettyServerLoom, + playServer, + vertxServer, + vertxServerCats, + nimaServer + ) // integrations diff --git a/perf-tests/README.md b/perf-tests/README.md index 4d58194842..d6a5dc2186 100644 --- a/perf-tests/README.md +++ b/perf-tests/README.md @@ -1,5 +1,7 @@ # Performance tests +To work with performance tests, make sure you are running JDK 21+, and that the `ALSO_LOOM` environment variable is set, because the `perf-tests` project includes `tapir-netty-loom` and `tapir-nima`, which require Loom JDK feature to be available. + Performance tests are executed by running `PerfTestSuiteRunner`, which is a standard "Main" Scala application, configured by command line parameters. It executes a sequence of tests, where each test consist of: diff --git a/perf-tests/src/main/scala/sttp/tapir/perf/apis/Endpoints.scala b/perf-tests/src/main/scala/sttp/tapir/perf/apis/Endpoints.scala index 9359682160..a91ae77f22 100644 --- a/perf-tests/src/main/scala/sttp/tapir/perf/apis/Endpoints.scala +++ b/perf-tests/src/main/scala/sttp/tapir/perf/apis/Endpoints.scala @@ -3,6 +3,7 @@ package sttp.tapir.perf.apis import cats.effect.IO import sttp.tapir._ import sttp.tapir.perf.Common._ +import sttp.tapir.server.netty.loom.Id import sttp.tapir.server.ServerEndpoint import sttp.tapir.server.model.EndpointExtensions._ @@ -66,4 +67,5 @@ trait Endpoints { def genEndpointsFuture(count: Int): List[ServerEndpoint[Any, Future]] = genServerEndpoints(count)(Future.successful) def genEndpointsIO(count: Int): List[ServerEndpoint[Any, IO]] = genServerEndpoints(count)(IO.pure) + def genEndpointsId(count: Int): List[ServerEndpoint[Any, Id]] = genServerEndpoints[Id](count)(x => x: Id[String]) } diff --git a/perf-tests/src/main/scala/sttp/tapir/perf/netty/loom/NettyId.scala b/perf-tests/src/main/scala/sttp/tapir/perf/netty/loom/NettyId.scala new file mode 100644 index 0000000000..0fe76cedb6 --- /dev/null +++ b/perf-tests/src/main/scala/sttp/tapir/perf/netty/loom/NettyId.scala @@ -0,0 +1,32 @@ +package sttp.tapir.perf.netty.loom + +import cats.effect.IO +import sttp.tapir.perf.apis._ +import sttp.tapir.perf.Common._ +import sttp.tapir.server.netty.loom._ +import sttp.tapir.server.ServerEndpoint + +object Tapir extends Endpoints + +object NettyId { + + def runServer(endpoints: List[ServerEndpoint[Any, Id]], withServerLog: Boolean = false): IO[ServerRunner.KillSwitch] = { + val declaredPort = Port + val declaredHost = "0.0.0.0" + val serverOptions = buildOptions(NettyIdServerOptions.customiseInterceptors, withServerLog) + // Starting netty server + val serverBinding: NettyIdServerBinding = + NettyIdServer(serverOptions) + .port(declaredPort) + .host(declaredHost) + .addEndpoints(endpoints) + .start() + IO(IO(serverBinding.stop())) + } +} + +object TapirServer extends ServerRunner { override def start = NettyId.runServer(Tapir.genEndpointsId(1)) } +object TapirMultiServer extends ServerRunner { override def start = NettyId.runServer(Tapir.genEndpointsId(128)) } +object TapirInterceptorMultiServer extends ServerRunner { + override def start = NettyId.runServer(Tapir.genEndpointsId(128), withServerLog = true) +} diff --git a/perf-tests/src/main/scala/sttp/tapir/perf/nima/Nima.scala b/perf-tests/src/main/scala/sttp/tapir/perf/nima/Nima.scala new file mode 100644 index 0000000000..1a4cdef2b5 --- /dev/null +++ b/perf-tests/src/main/scala/sttp/tapir/perf/nima/Nima.scala @@ -0,0 +1,39 @@ +package sttp.tapir.perf.nima + +import cats.effect.IO +import io.helidon.webserver.WebServer +import sttp.tapir.perf.apis._ +import sttp.tapir.perf.Common._ +import sttp.tapir.server.nima.{Id, NimaServerInterpreter, NimaServerOptions} +import sttp.tapir.server.ServerEndpoint + +object Tapir extends Endpoints { + def genEndpointsNId(count: Int): List[ServerEndpoint[Any, Id]] = genServerEndpoints[Id](count)(x => x: Id[String]) +} + +object Nima { + + def runServer(endpoints: List[ServerEndpoint[Any, Id]], withServerLog: Boolean = false): IO[ServerRunner.KillSwitch] = { + val declaredPort = Port + val serverOptions = buildOptions(NimaServerOptions.customiseInterceptors, withServerLog) + // Starting Nima server + + val handler = NimaServerInterpreter(serverOptions).toHandler(endpoints) + val server = WebServer + .builder() + .routing { builder => + builder.any(handler) + () + } + .port(declaredPort) + .build() + .start() + IO(IO { val _ = server.stop() }) + } +} + +object TapirServer extends ServerRunner { override def start = Nima.runServer(Tapir.genEndpointsNId(1)) } +object TapirMultiServer extends ServerRunner { override def start = Nima.runServer(Tapir.genEndpointsNId(128)) } +object TapirInterceptorMultiServer extends ServerRunner { + override def start = Nima.runServer(Tapir.genEndpointsNId(128), withServerLog = true) +}