Add polaris-server-test-runner plugin#4732
Conversation
This new plugin for test purposes mainly buys us separation and faster feedback: - Test projects no longer need to build or embed a full Quarkus test app just to run against Polaris. - Tests can depend on a ready `quarkus-run.jar` via `polarisServer(...)`, so the server lifecycle is externalized from the test JVM. - Less Quarkus application builds across all checks, improving overall test runtime. - Quarkus dependencies stop leaking into test classpaths, which reduces dependency conflicts with Spark, Iceberg, Hadoop, etc. - The plugin makes `enforcedPlatform(libs.quarkus.bom)` safer because Quarkus is mostly constrained to the app/server side instead of the tests. - Each test task can get its own isolated Polaris server instance and config. - Projects can use normal `JvmTestSuite`s, which improves Gradle/IntelliJ behavior and keeps test classpaths scoped. - Custom server startup hooks still allow task-specific setup, like OPA/Testcontainers or RustFS, without baking those concerns into the plugin.
9027de6 to
880e51b
Compare
| /** Context passed to an isolated {@link PolarisServerStartupAction}. */ | ||
| public interface PolarisServerStartupContext { | ||
| /** Build-configured action parameters. */ | ||
| Map<String, String> getParameters(); |
There was a problem hiding this comment.
What are these parameters exactly? JVM parameters? Quarkus configuration properties?
| failed.set(e) | ||
| ready.countDown() | ||
| } finally { | ||
| ready.countDown() |
There was a problem hiding this comment.
nit: this would call countDown() twice in case of error.
There was a problem hiding this comment.
Oops, good catch. Was actually worse, there's been another ready.countDown. Introduced an AtomicBoolean gate. It's triggered when either the listen-urls are captured or the process terminates.
Wasn't a real problem, but not good either.
|
|
||
| private data class ListenUrls(val httpUrl: String, val managementUrl: String?) { | ||
| fun toPorts(): ServerPorts = | ||
| ServerPorts(URI.create(httpUrl).port, managementUrl?.let { URI.create(it).port }) |
There was a problem hiding this comment.
What happens if httpUrl does not have a port? Wouldn't URI.create(httpUrl).port return -1?
There was a problem hiding this comment.
Should have never happened in practice, but the code now checks for that.
| BufferedReader(InputStreamReader(process.inputStream)).useLines { lines -> | ||
| lines.forEach { line -> | ||
| logger.info("[polaris-server] {}", line) | ||
| synchronized(capturedOutput) { capturedOutput.add(line) } |
There was a problem hiding this comment.
nit: maybe cap this collection at 200 elements, if that's all we will retain?
There was a problem hiding this comment.
Good point - I let it capture only the first 200 lines.
| /.gradle | ||
| /build-logic/.gradle | ||
| /build-logic/.kotlin | ||
| /gradle/server-test-runner/.gradle |
There was a problem hiding this comment.
nit: what is the reason for placing this plugin under ./gradle rather than somewhere inside ./build-logic?
There was a problem hiding this comment.
Yea some reasons:
- it exposes a small API/SPI
- when pulling that from build-logic we'd "pollute" the build-scripts's classpath with a lot of things (other plugins, etc)
- can be tested standalone (Gradle's plugin test-kig)
This new plugin for test purposes mainly buys us separation and faster feedback:
quarkus-run.jarviapolarisServer(...), so the server lifecycle is externalized from the test JVM.enforcedPlatform(libs.quarkus.bom)safer because Quarkus is mostly constrained to the app/server side instead of the tests.JvmTestSuites, which improves Gradle/IntelliJ behavior and keeps test classpaths scoped.