This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-7561-a353b71c231f89d4d33a5fffa69be84d1ef675c5 in repository https://gitbox.apache.org/repos/asf/texera.git
commit cd3872a3a68393644ac28227532ae181b8a01b8f Author: Meng Wang <[email protected]> AuthorDate: Tue Aug 11 20:58:11 2026 -0700 test(workflow-compiling-service): cover WorkflowCompilingService.run (#7561) ### What changes were proposed in this PR? Extends `WorkflowCompilingServiceRunSpec` to actually exercise `WorkflowCompilingService.run`, which had no coverage — the spec previously only asserted role annotations on the resource classes. No production code was changed. Following `AccessControlServiceRunSpec` (the template the issue points at), a mocked Dropwizard `Environment` is handed to `run(config, env)` and the wiring it installs is verified, without starting a server: - `jersey.setUrlPattern("/api/*")` - `jersey.register(classOf[HealthCheckResource])` and `jersey.register(classOf[WorkflowCompilationResource])` - the auth stack from `AuthFeatures.register` — asserted through the `RolesAllowedDynamicFeature` and `UnauthorizedExceptionMapper` it registers (without the former Jersey silently ignores `@RolesAllowed`) - the request-logging filter added to the application context The existing role-annotation assertion is kept. Per the issue's scope note, only `run()` is covered — `initialize()`, `main()` and the config/connection helpers are left alone since #5983 moves that boilerplate into a shared `ServiceBootstrap`. One thing worth noting for reviewers: `run()` calls `SqlServer.initConnection`, which is safe here because it only constructs the `SqlServer` (the pool connects lazily) — the same call is made by `AccessControlService.run`, whose spec already runs this way in CI. ### Any related issues, documentation, discussions? Closes #7557 ### How was this PR tested? Unit tests, run locally. All pass, and the failure path was verified by breaking an assertion to confirm the suite goes red: ``` sbt "WorkflowCompilingService/testOnly *WorkflowCompilingServiceRunSpec" # Tests: succeeded 5, failed 0 sbt "WorkflowCompilingService/Test/scalafmtCheck" # clean sbt "WorkflowCompilingService/Test/scalafix --check" # clean ``` ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 4.8 [1M context]) --- .../service/WorkflowCompilingServiceRunSpec.scala | 55 +++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/workflow-compiling-service/src/test/scala/org/apache/texera/service/WorkflowCompilingServiceRunSpec.scala b/workflow-compiling-service/src/test/scala/org/apache/texera/service/WorkflowCompilingServiceRunSpec.scala index 898d32a9b4..f9b4162247 100644 --- a/workflow-compiling-service/src/test/scala/org/apache/texera/service/WorkflowCompilingServiceRunSpec.scala +++ b/workflow-compiling-service/src/test/scala/org/apache/texera/service/WorkflowCompilingServiceRunSpec.scala @@ -19,13 +19,66 @@ package org.apache.texera.service -import org.apache.texera.auth.RoleAnnotationEnforcer +import io.dropwizard.core.setup.Environment +import io.dropwizard.jersey.DropwizardResourceConfig +import io.dropwizard.jersey.setup.JerseyEnvironment +import io.dropwizard.jetty.MutableServletContextHandler +import io.dropwizard.jetty.setup.ServletEnvironment +import org.apache.texera.auth.{RoleAnnotationEnforcer, UnauthorizedExceptionMapper} import org.apache.texera.service.resource.{HealthCheckResource, WorkflowCompilationResource} +import org.eclipse.jetty.servlet.FilterHolder +import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature +import org.mockito.ArgumentMatchers.{any, eq => eqTo, isA} +import org.mockito.Mockito.{mock, verify, when} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class WorkflowCompilingServiceRunSpec extends AnyFlatSpec with Matchers { + // Mirrors AccessControlServiceRunSpec: run() is driven against a mocked Dropwizard + // environment so the wiring it installs can be asserted without starting a server. + // run() starts an operator-metadata warmup thread and swaps the global SqlServer + // instance, so it is executed once for the whole suite and the resulting mocks are + // shared; the assertions below only read recorded interactions. + private lazy val ranService: (JerseyEnvironment, MutableServletContextHandler) = { + val jersey = mock(classOf[JerseyEnvironment]) + val servlets = mock(classOf[ServletEnvironment]) + val context = mock(classOf[MutableServletContextHandler]) + val env = mock(classOf[Environment]) + when(env.jersey).thenReturn(jersey) + when(env.servlets).thenReturn(servlets) + when(env.getApplicationContext).thenReturn(context) + when(jersey.getResourceConfig).thenReturn(DropwizardResourceConfig.forTesting()) + + val service = new WorkflowCompilingService + service.run(mock(classOf[WorkflowCompilingServiceConfiguration]), env) + + (jersey, context) + } + + "WorkflowCompilingService.run" should "serve the API under /api/*" in { + val (jersey, _) = ranService + verify(jersey).setUrlPattern("/api/*") + } + + it should "register the health check and compilation endpoints" in { + val (jersey, _) = ranService + verify(jersey).register(classOf[HealthCheckResource]) + verify(jersey).register(classOf[WorkflowCompilationResource]) + } + + it should "install the auth stack" in { + val (jersey, _) = ranService + // AuthFeatures.register: without RolesAllowedDynamicFeature Jersey ignores @RolesAllowed + verify(jersey).register(classOf[RolesAllowedDynamicFeature]) + verify(jersey).register(classOf[UnauthorizedExceptionMapper]) + } + + it should "add the request-logging filter to the application context" in { + val (_, context) = ranService + verify(context).addFilter(isA(classOf[FilterHolder]), eqTo("/*"), any()) + } + // Every endpoint this service registers declares @RolesAllowed/@PermitAll/@DenyAll. "WorkflowCompilingService's registered resources" should "all declare access control" in { RoleAnnotationEnforcer.findUnannotatedEndpoints(
