11import Dependencies .*
2+ import com .typesafe .sbt .packager .docker .{Cmd , ExecCmd }
23import sbt .*
34
45ThisBuild / organization := " com.evolution.jgrpc.tools"
@@ -26,27 +27,53 @@ ThisBuild / scmInfo := Some(ScmInfo(
2627// not sure if bincompat check works for Java code, put it here just in case
2728ThisBuild / versionPolicyIntention := Compatibility .BinaryCompatible
2829
29- // this is a Java project, setting a fixed Scala version just in case
30- ThisBuild / scalaVersion := " 2.13.16"
31-
3230// setting pure-Java module build settings
3331ThisBuild / crossPaths := false // drop off Scala suffix from artifact names.
3432ThisBuild / autoScalaLibrary := false // exclude scala-library from dependencies
3533ThisBuild / javacOptions := Seq (" -source" , " 17" , " -target" , " 17" , " -Werror" , " -Xlint:all" )
3634ThisBuild / doc / javacOptions := Seq (" -source" , " 17" , " -Xdoclint:all" , " -Werror" )
37-
38- // common test dependencies:
39- ThisBuild / libraryDependencies ++= Seq (
40- // to be able to run JUnit 5+ tests:
41- " com.github.sbt.junit" % " jupiter-interface" % JupiterKeys .jupiterVersion.value,
42- Slf4j .simple,
43- ).map(_ % Test )
35+ ThisBuild / scalaVersion := " 2.13.18"
36+ ThisBuild / scalacOptions ++= Seq (
37+ " -release:17" ,
38+ " -deprecation" ,
39+ " -Xsource:3" ,
40+ )
4441
4542// common compile dependencies:
4643ThisBuild / libraryDependencies ++= Seq (
4744 jspecify, // JSpecify null-check annotations
4845)
4946
47+ def asJavaPublishedModule (p : Project ): Project = {
48+ p.settings(
49+ // common test dependencies for Java modules:
50+ libraryDependencies ++= Seq (
51+ // to be able to run JUnit 5+ tests:
52+ " com.github.sbt.junit" % " jupiter-interface" % JupiterKeys .jupiterVersion.value,
53+ Slf4j .simple,
54+ ).map(_ % Test ),
55+ )
56+ }
57+
58+ def asScalaIntegrationTestModule (p : Project ): Project = {
59+ p.disablePlugins(JupiterPlugin ) // using scalatest instead
60+ .settings(
61+ publish / skip := true ,
62+ autoScalaLibrary := true , // int tests are written in Scala, returning scala-library dependency
63+ Test / parallelExecution := false , // disable parallel execution between test suites
64+ Test / fork := true , // disable parallel execution between modules
65+ // tests take a long time to run, better to see the process in real time
66+ Test / logBuffered := false ,
67+ // disable scaladoc generation to avoid dealing with annoying warnings
68+ Compile / doc / sources := Seq .empty,
69+ // common test dependencies for Scala int test modules:
70+ libraryDependencies ++= Seq (
71+ scalatest,
72+ Slf4j .simple,
73+ ).map(_ % Test ),
74+ )
75+ }
76+
5077lazy val root = project.in(file(" ." ))
5178 .settings(
5279 name := " grpc-java-tools-root" ,
@@ -55,9 +82,11 @@ lazy val root = project.in(file("."))
5582 )
5683 .aggregate(
5784 k8sDnsNameResolver,
85+ k8sDnsNameResolverIt,
5886 )
5987
6088lazy val k8sDnsNameResolver = project.in(file(" k8s-dns-name-resolver" ))
89+ .configure(asJavaPublishedModule)
6190 .settings(
6291 name := " k8s-dns-name-resolver" ,
6392 description := " Evolution grpc-java tools - DNS-based name resolver for Kubernetes services" ,
@@ -68,6 +97,43 @@ lazy val k8sDnsNameResolver = project.in(file("k8s-dns-name-resolver"))
6897 ),
6998 )
7099
100+ lazy val k8sDnsNameResolverIt = project.in(file(" k8s-dns-name-resolver-it" ))
101+ .configure(asScalaIntegrationTestModule)
102+ // the module builds its own test app docker container
103+ .enablePlugins(JavaAppPackaging , DockerPlugin )
104+ .settings(
105+ name := " k8s-dns-name-resolver-it" ,
106+ description := " Evolution grpc-java tools - DNS-based name resolver for Kubernetes services - integration tests" ,
107+ Compile / PB .targets := Seq (
108+ scalapb.gen() -> (Compile / sourceManaged).value / " scalapb" ,
109+ ),
110+ dockerBaseImage := " amazoncorretto:17-alpine" ,
111+ dockerCommands ++= Seq (
112+ // root rights are needed to install additional packages, and also test client needs it
113+ // to manipulate its DNS settings
114+ Cmd (" USER" , " root" ),
115+ // bash is needed for testcontainers log watching logic
116+ // lsof and coredns are needed for the integration test logic
117+ ExecCmd (" RUN" , " apk" , " add" , " --no-cache" , " bash" , " lsof" , " coredns" ),
118+ ),
119+ dockerExposedPorts := Seq (9000 ), // Should match the test app GRPC server port.
120+ // The int test here needs the test app docker container staged before running the code.
121+ // It's then used in docker compose inside testcontainers.
122+ test := {
123+ (Docker / stage).value
124+ (Test / test).value
125+ },
126+ libraryDependencies ++= Seq (
127+ Slf4j .simple,
128+ commonsLang3,
129+ " io.grpc" % " grpc-netty" % scalapb.compiler.Version .grpcJavaVersion,
130+ " com.thesamet.scalapb" %% " scalapb-runtime-grpc" % scalapb.compiler.Version .scalapbVersion,
131+ Testcontainers .core % Test ,
132+ ),
133+ ).dependsOn(
134+ k8sDnsNameResolver,
135+ )
136+
71137addCommandAlias(" fmt" , " all scalafmtAll scalafmtSbt javafmtAll" )
72138addCommandAlias(
73139 " build" ,
0 commit comments