Skip to content

Commit

Permalink
build: add e2e project for codegen verification
Browse files Browse the repository at this point in the history
 - bump scalapb to 10.9 and fix deprecation warning
   wrt. `ScalaPb` object moved to `scalapb.options`.
  • Loading branch information
ahjohannessen committed Nov 15, 2020
1 parent 373c846 commit 851ce17
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 3 deletions.
30 changes: 29 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ lazy val root = project
</developers>
}
)
.aggregate(`java-gen`, `sbt-java-gen`, `java-runtime`)
.aggregate(`java-gen`, `sbt-java-gen`, `java-runtime`, e2e)

lazy val `java-gen` = project
.enablePlugins(GitVersioning)
Expand Down Expand Up @@ -88,3 +88,31 @@ lazy val `java-runtime` = project
testFrameworks += new TestFramework("munit.Framework"),
addCompilerPlugin(kindProjector)
)

lazy val codegenFullName =
"org.lyranthe.fs2_grpc.java_runtime.sbt_gen.Fs2CodeGenerator"

lazy val protocGen = protocGenProject("protoc-gen", `java-gen`)
.settings(
Compile / mainClass := Some(codegenFullName),
scalaVersion := Scala212
)

lazy val e2e = project
.in(file("e2e"))
.dependsOn(`java-runtime`)
.enablePlugins(LocalCodeGenPlugin, BuildInfoPlugin)
.settings(
skip in publish := true,
codeGenClasspath := (`java-gen` / Compile / fullClasspath).value,
libraryDependencies ++= List(scalaPbGrpcRuntime, scalaPbRuntime, scalaPbRuntime % "protobuf", ceMunit % Test),
testFrameworks += new TestFramework("munit.Framework"),
PB.targets in Compile := Seq(
scalapb.gen() -> (sourceManaged in Compile).value / "scalapb",
genModule(codegenFullName + "$") -> (sourceManaged in Compile).value / "fs2-grpc"
),
buildInfoPackage := "io.fs2.grpc.buildinfo",
buildInfoKeys := Seq[BuildInfoKey](
"sourceManaged" -> (sourceManaged in Compile).value / "fs2-grpc"
)
)
10 changes: 10 additions & 0 deletions e2e/src/main/protobuf/package.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto2";

import "scalapb/scalapb.proto";

package io.fs2.grpc;

option (scalapb.options) = {
scope: PACKAGE
flat_package: true
};
22 changes: 22 additions & 0 deletions e2e/src/main/protobuf/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
syntax = "proto2";

package io.fs2.grpc;

enum Color {
UNKNOWN = 0;
RED = 1;
GREEN = 2;
BLUE = 3;
}

message TestMessage {

message NestedMessage {
required Color color = 1;
}

required string a = 1;
required int32 b = 2;
optional NestedMessage c = 3;

}
12 changes: 12 additions & 0 deletions e2e/src/main/protobuf/test_service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
syntax = "proto3";

import "test.proto";

package io.fs2.grpc;

service TestService {
rpc noStreaming (TestMessage) returns (TestMessage);
rpc clientStreaming (stream TestMessage) returns (TestMessage);
rpc serverStreaming (TestMessage) returns (stream TestMessage);
rpc bothStreaming (stream TestMessage) returns (stream TestMessage);
}
39 changes: 39 additions & 0 deletions e2e/src/test/resources/TestServiceFs2Grpc.scala.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.fs2.grpc

import _root_.cats.syntax.all._

trait TestServiceFs2Grpc[F[_], A] {
def noStreaming(request: io.fs2.grpc.TestMessage, ctx: A): F[io.fs2.grpc.TestMessage]
def clientStreaming(request: _root_.fs2.Stream[F, io.fs2.grpc.TestMessage], ctx: A): F[io.fs2.grpc.TestMessage]
def serverStreaming(request: io.fs2.grpc.TestMessage, ctx: A): _root_.fs2.Stream[F, io.fs2.grpc.TestMessage]
def bothStreaming(request: _root_.fs2.Stream[F, io.fs2.grpc.TestMessage], ctx: A): _root_.fs2.Stream[F, io.fs2.grpc.TestMessage]
}

object TestServiceFs2Grpc extends _root_.org.lyranthe.fs2_grpc.java_runtime.GeneratedCompanion[TestServiceFs2Grpc] {

def client[F[_]: _root_.cats.effect.Async, A](dispatcher: _root_.cats.effect.std.Dispatcher[F], channel: _root_.io.grpc.Channel, mkMeta: A => _root_.io.grpc.Metadata, coFn: _root_.io.grpc.CallOptions => _root_.io.grpc.CallOptions = identity, errorAdapter: _root_.io.grpc.StatusRuntimeException => Option[Exception] = _ => None): TestServiceFs2Grpc[F, A] = new TestServiceFs2Grpc[F, A] {
def noStreaming(request: io.fs2.grpc.TestMessage, ctx: A): F[io.fs2.grpc.TestMessage] = {
_root_.org.lyranthe.fs2_grpc.java_runtime.client.Fs2ClientCall[F](channel, io.fs2.grpc.TestServiceGrpc.METHOD_NO_STREAMING, coFn(_root_.io.grpc.CallOptions.DEFAULT), dispatcher, errorAdapter).flatMap(_.unaryToUnaryCall(request, mkMeta(ctx)))
}
def clientStreaming(request: _root_.fs2.Stream[F, io.fs2.grpc.TestMessage], ctx: A): F[io.fs2.grpc.TestMessage] = {
_root_.org.lyranthe.fs2_grpc.java_runtime.client.Fs2ClientCall[F](channel, io.fs2.grpc.TestServiceGrpc.METHOD_CLIENT_STREAMING, coFn(_root_.io.grpc.CallOptions.DEFAULT), dispatcher, errorAdapter).flatMap(_.streamingToUnaryCall(request, mkMeta(ctx)))
}
def serverStreaming(request: io.fs2.grpc.TestMessage, ctx: A): _root_.fs2.Stream[F, io.fs2.grpc.TestMessage] = {
_root_.fs2.Stream.eval(_root_.org.lyranthe.fs2_grpc.java_runtime.client.Fs2ClientCall[F](channel, io.fs2.grpc.TestServiceGrpc.METHOD_SERVER_STREAMING, coFn(_root_.io.grpc.CallOptions.DEFAULT), dispatcher, errorAdapter)).flatMap(_.unaryToStreamingCall(request, mkMeta(ctx)))
}
def bothStreaming(request: _root_.fs2.Stream[F, io.fs2.grpc.TestMessage], ctx: A): _root_.fs2.Stream[F, io.fs2.grpc.TestMessage] = {
_root_.fs2.Stream.eval(_root_.org.lyranthe.fs2_grpc.java_runtime.client.Fs2ClientCall[F](channel, io.fs2.grpc.TestServiceGrpc.METHOD_BOTH_STREAMING, coFn(_root_.io.grpc.CallOptions.DEFAULT), dispatcher, errorAdapter)).flatMap(_.streamingToStreamingCall(request, mkMeta(ctx)))
}
}

protected def serviceBinding[F[_]: _root_.cats.effect.Async, A](dispatcher: _root_.cats.effect.std.Dispatcher[F], serviceImpl: TestServiceFs2Grpc[F, A], mkCtx: _root_.io.grpc.Metadata => F[A]): _root_.io.grpc.ServerServiceDefinition = {
_root_.io.grpc.ServerServiceDefinition
.builder(io.fs2.grpc.TestServiceGrpc.SERVICE)
.addMethod(io.fs2.grpc.TestServiceGrpc.METHOD_NO_STREAMING, _root_.org.lyranthe.fs2_grpc.java_runtime.server.Fs2ServerCallHandler[F](dispatcher).unaryToUnaryCall[io.fs2.grpc.TestMessage, io.fs2.grpc.TestMessage]((r, m) => mkCtx(m).flatMap(serviceImpl.noStreaming(r, _))))
.addMethod(io.fs2.grpc.TestServiceGrpc.METHOD_CLIENT_STREAMING, _root_.org.lyranthe.fs2_grpc.java_runtime.server.Fs2ServerCallHandler[F](dispatcher).streamingToUnaryCall[io.fs2.grpc.TestMessage, io.fs2.grpc.TestMessage]((r, m) => mkCtx(m).flatMap(serviceImpl.clientStreaming(r, _))))
.addMethod(io.fs2.grpc.TestServiceGrpc.METHOD_SERVER_STREAMING, _root_.org.lyranthe.fs2_grpc.java_runtime.server.Fs2ServerCallHandler[F](dispatcher).unaryToStreamingCall[io.fs2.grpc.TestMessage, io.fs2.grpc.TestMessage]((r, m) => _root_.fs2.Stream.eval(mkCtx(m)).flatMap(serviceImpl.serverStreaming(r, _))))
.addMethod(io.fs2.grpc.TestServiceGrpc.METHOD_BOTH_STREAMING, _root_.org.lyranthe.fs2_grpc.java_runtime.server.Fs2ServerCallHandler[F](dispatcher).streamingToStreamingCall[io.fs2.grpc.TestMessage, io.fs2.grpc.TestMessage]((r, m) => _root_.fs2.Stream.eval(mkCtx(m)).flatMap(serviceImpl.bothStreaming(r, _))))
.build()
}

}
21 changes: 21 additions & 0 deletions e2e/src/test/scala/io/fs2/grpc/CodegenSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.fs2.grpc

import java.io.File
import scala.io.Source
import buildinfo.BuildInfo.sourceManaged

class Fs2CodeGeneratorSpec extends munit.FunSuite {

val sourcesGenerated = new File(sourceManaged.getAbsolutePath, "/io/fs2/grpc/")

test("code generator outputs correct service file") {

val testFileName = "TestServiceFs2Grpc.scala"
val reference = Source.fromResource(s"${testFileName}.txt").getLines().mkString("\n")
val generated = Source.fromFile(new File(sourcesGenerated, testFileName)).getLines().mkString("\n")

assertEquals(generated, reference)

}

}
2 changes: 1 addition & 1 deletion java-gen/src/main/scala/Fs2CodeGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.google.protobuf.compiler.PluginProtos
import com.google.protobuf.compiler.PluginProtos.{CodeGeneratorRequest, CodeGeneratorResponse}
import protocbridge.ProtocCodeGenerator
import scalapb.compiler.{FunctionalPrinter, GeneratorException, DescriptorImplicits, GeneratorParams}
import scalapb.options.compiler.Scalapb
import scalapb.options.Scalapb
import scala.collection.JavaConverters._

case class Fs2Params(serviceSuffix: String = "Fs2Grpc")
Expand Down
3 changes: 3 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ object Dependencies {

val sbtProtoc = "com.thesamet" % "sbt-protoc" % versions.sbtProtoc
val scalaPbCompiler = "com.thesamet.scalapb" %% "compilerplugin" % versions.scalaPb
val scalaPbRuntime = "com.thesamet.scalapb" %% "scalapb-runtime" % versions.scalaPb
val scalaPbGrpcRuntime = "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % versions.scalaPb

val kindProjector = "org.typelevel" %% "kind-projector" % versions.kindProjector cross CrossVersion.binary

}
3 changes: 2 additions & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1")
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.15")
addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.9.4")

libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.10.8"
addSbtPlugin("com.thesamet" % "sbt-protoc-gen-project" % "0.1.4")
libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.10.9"

0 comments on commit 851ce17

Please sign in to comment.