This is an automated email from the ASF dual-hosted git repository.

oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new aa8e54ee7833 CAMEL-24742: camel-opa - fix OpaSecurityPolicyWasmTest 
after the committed WASM fixtures were removed (#26987)
aa8e54ee7833 is described below

commit aa8e54ee783320553f81c19bbaf4e0d05d3c757b
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Sep 28 14:46:30 2026 +0200

    CAMEL-24742: camel-opa - fix OpaSecurityPolicyWasmTest after the committed 
WASM fixtures were removed (#26987)
    
    OpaSecurityPolicyWasmTest (CAMEL-24830) was written against the committed
    authz.wasm and merged a minute before CAMEL-24742 deleted it, so every test
    in the class failed at context startup once both were on main.
    
    Split it the way CAMEL-24742 split the producer tests: the three tests that
    evaluate a policy move to OpaSecurityPolicyWasmIT, which compiles authz.rego
    with OpaWasmBundleBuilder, and the five startup-failure tests stay unit
    tests. Also drop the dead classpath:authz.wasm reference in
    OpaBatchEvaluationTest, and point two comments at OpaWasmIT instead of the
    removed OpaWasmEvaluatorTest. Test code only.
    
    Closes #26987
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../component/opa/OpaBatchEvaluationTest.java      |   3 +-
 .../java/org/apache/camel/component/opa/OpaIT.java |   2 +-
 ...yWasmTest.java => OpaSecurityPolicyWasmIT.java} | 113 ++++++---------------
 .../opa/security/OpaSecurityPolicyWasmTest.java    |  79 ++------------
 .../src/test/resources/wasm-data/roles.rego        |   2 +-
 5 files changed, 44 insertions(+), 155 deletions(-)

diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
index ab5e51c91135..f2be6321d2f4 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
@@ -125,8 +125,9 @@ public class OpaBatchEvaluationTest extends 
CamelTestSupport {
 
     @Test
     void rejectsBatchInWasmModeAtStartup() {
+        // rejected before the bundle is resolved, so the location here is 
never opened
         assertThatThrownBy(() -> context.getEndpoint(
-                "opa:" + PATH + 
"?evaluationMode=wasm&policyBundle=classpath:authz.wasm&batch=true").start())
+                "opa:" + PATH + 
"?evaluationMode=wasm&policyBundle=file:unused.wasm&batch=true").start())
                 .isInstanceOf(Exception.class)
                 .hasMessageContaining("batch");
     }
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaIT.java 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaIT.java
index c2f7b1dc3720..1e5da310a5cd 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaIT.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaIT.java
@@ -126,7 +126,7 @@ public class OpaIT extends CamelTestSupport {
     @Test
     void failsClosedOnAnUndefinedDecision() {
         // authz/strict_allow has no default, so OPA answers with an empty 
result rather than false. The WASM
-        // engine sees the same rule as an empty result array - 
OpaWasmEvaluatorTest asserts the same outcome.
+        // engine sees the same rule as an empty result array - OpaWasmIT 
asserts the same outcome.
         Exchange out = template.request(opa("authz/strict_allow"), e -> 
e.getMessage().setHeader("user", "mallory"));
 
         
assertThat(out.getException()).isInstanceOf(OpaPolicyEvaluationException.class);
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmIT.java
similarity index 52%
copy from 
components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
copy to 
components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmIT.java
index 2de9e8da8c09..38f0d5aa5b0b 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmIT.java
@@ -16,17 +16,23 @@
  */
 package org.apache.camel.component.opa.security;
 
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.List;
 
 import org.apache.camel.CamelAuthorizationException;
 import org.apache.camel.CamelExecutionException;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.test.infra.opa.services.OpaWasmBundleBuilder;
 import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -35,16 +41,40 @@ import static 
org.assertj.core.api.Assertions.assertThatThrownBy;
  * {@link OpaSecurityPolicy} enforcing a route with an in-process WebAssembly 
bundle. The decision contract is the same
  * as the REST engine - a match proceeds, a non-match throws {@code 
CamelAuthorizationException} - and no server
  * readiness check is registered, because the policy is evaluated in-process 
(CAMEL-24830).
+ * <p/>
+ * The bundle is compiled from the same {@code authz.rego} that {@code OpaIT} 
uploads to a real OPA server rather than
+ * committed beside it (CAMEL-24742). The startup failures that never need a 
bundle to evaluate stay unit tests in
+ * {@link OpaSecurityPolicyWasmTest}.
  */
-public class OpaSecurityPolicyWasmTest extends CamelTestSupport {
+public class OpaSecurityPolicyWasmIT extends CamelTestSupport {
+
+    @TempDir
+    static Path bundles;
+
+    private static String bundle;
 
     private final OpaSecurityPolicy wasmPolicy = new OpaSecurityPolicy();
     private final OpaSecurityPolicy restPolicy = new OpaSecurityPolicy();
 
+    @BeforeAll
+    static void compileBundle() throws Exception {
+        String rego;
+        try (InputStream in = 
OpaSecurityPolicyWasmIT.class.getResourceAsStream("/authz.rego")) {
+            if (in == null) {
+                throw new IllegalStateException("Test resource not found on 
the classpath: /authz.rego");
+            }
+            rego = new String(in.readAllBytes(), StandardCharsets.UTF_8);
+        }
+        // the policy's entrypoint defaults to its policy path, so that is the 
one rule the bundle has to expose
+        Path path = bundles.resolve("authz-bundle.tar.gz");
+        Files.write(path, OpaWasmBundleBuilder.build("authz.rego", rego, 
"authz/allow"));
+        bundle = "file:" + path.toAbsolutePath();
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         wasmPolicy.setEvaluationMode("wasm");
-        wasmPolicy.setPolicyBundle("classpath:authz.wasm");
+        wasmPolicy.setPolicyBundle(bundle);
         wasmPolicy.setPolicyPath("authz/allow");
 
         // a rest-mode policy is the positive control for the readiness-check 
assertion: it registers a check, the
@@ -97,81 +127,4 @@ public class OpaSecurityPolicyWasmTest extends 
CamelTestSupport {
         assertThat(checks).hasSize(1);
         
assertThat(checks.get(0).getId()).startsWith("security-policy:opa-").contains("opa-rest");
     }
-
-    @Test
-    void failsRouteStartOnABundleThatLoadsButIsNotAValidModule() {
-        // OpaWasmEvaluator borrows an instance at startup so a broken bundle 
fails fast, and beforeWrap - which cannot
-        // throw a checked exception - must surface that rather than swallow 
it, or a route would start and then
-        // authorize nothing. authz.rego is the Rego source: it loads as bytes 
but is not a compiled wasm module.
-        OpaSecurityPolicy corrupt = new OpaSecurityPolicy();
-        corrupt.setEvaluationMode("wasm");
-        corrupt.setPolicyBundle("classpath:authz.rego");
-        corrupt.setPolicyPath("authz/allow");
-
-        // OpaPolicy rejects the module during the warmup borrow with an 
unchecked exception, which buildEvaluator's
-        // catch(RuntimeException) rethrows as-is; reaching the caller of 
addRoutes is what proves the route did not
-        // start (a first-exchange failure would not surface here).
-        assertThatThrownBy(() -> context.addRoutes(routeWith(corrupt)))
-                .isInstanceOf(RuntimeException.class);
-    }
-
-    @Test
-    void failsRouteStartWhenTheBundleResourceCannotBeLoaded() {
-        // a bundle location that resolves to nothing is a checked failure in 
loadPolicy, which beforeWrap wraps; the
-        // wrapper message is what proves the failure surfaced at startup 
rather than being swallowed
-        OpaSecurityPolicy missing = new OpaSecurityPolicy();
-        missing.setEvaluationMode("wasm");
-        missing.setPolicyBundle("classpath:does-not-exist.wasm");
-        missing.setPolicyPath("authz/allow");
-
-        assertThatThrownBy(() -> context.addRoutes(routeWith(missing)))
-                .isInstanceOf(RuntimeCamelException.class)
-                .hasMessageContaining("Could not load the wasm policy bundle");
-    }
-
-    @Test
-    void failsRouteStartOnAnUnknownEvaluationMode() {
-        // this path lives entirely in the policy's buildEvaluator and is 
covered by no endpoint test
-        OpaSecurityPolicy bogus = new OpaSecurityPolicy();
-        bogus.setEvaluationMode("bogus");
-        bogus.setPolicyPath("authz/allow");
-
-        assertThatThrownBy(() -> context.addRoutes(routeWith(bogus)))
-                .hasRootCauseInstanceOf(IllegalArgumentException.class)
-                .hasMessageContaining("Unknown evaluationMode");
-    }
-
-    @Test
-    void failsRouteStartWhenNoWasmBundleIsConfigured() {
-        // buildEvaluator forwards to OpaWasmEvaluator.create, so its 
validation applies through the policy too
-        OpaSecurityPolicy noBundle = new OpaSecurityPolicy();
-        noBundle.setEvaluationMode("wasm");
-        noBundle.setPolicyPath("authz/allow");
-
-        assertThatThrownBy(() -> context.addRoutes(routeWith(noBundle)))
-                .hasRootCauseInstanceOf(IllegalArgumentException.class)
-                .hasMessageContaining("policyBundle is required");
-    }
-
-    @Test
-    void failsRouteStartOnAPoolSizeBelowOne() {
-        OpaSecurityPolicy badPool = new OpaSecurityPolicy();
-        badPool.setEvaluationMode("wasm");
-        badPool.setPolicyBundle("classpath:authz.wasm");
-        badPool.setPolicyPath("authz/allow");
-        badPool.setPoolSize(0);
-
-        assertThatThrownBy(() -> context.addRoutes(routeWith(badPool)))
-                .hasRootCauseInstanceOf(IllegalArgumentException.class)
-                .hasMessageContaining("poolSize must be at least 1");
-    }
-
-    private static RouteBuilder routeWith(OpaSecurityPolicy policy) {
-        return new RouteBuilder() {
-            @Override
-            public void configure() {
-                from("direct:probe").policy(policy).to("mock:never");
-            }
-        };
-    }
 }
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
index 2de9e8da8c09..43bcdb637cb9 100644
--- 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/security/OpaSecurityPolicyWasmTest.java
@@ -16,88 +16,22 @@
  */
 package org.apache.camel.component.opa.security;
 
-import java.util.List;
-
-import org.apache.camel.CamelAuthorizationException;
-import org.apache.camel.CamelExecutionException;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.health.HealthCheck;
-import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.test.junit6.CamelTestSupport;
 import org.junit.jupiter.api.Test;
 
-import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 /**
- * {@link OpaSecurityPolicy} enforcing a route with an in-process WebAssembly 
bundle. The decision contract is the same
- * as the REST engine - a match proceeds, a non-match throws {@code 
CamelAuthorizationException} - and no server
- * readiness check is registered, because the policy is evaluated in-process 
(CAMEL-24830).
+ * The {@code wasm} misconfigurations that fail an {@link OpaSecurityPolicy} 
route at startup.
+ * <p/>
+ * These stay unit tests deliberately: none of them needs a bundle that loads 
and evaluates, so they need no compiled
+ * artifact and no container. Everything that evaluates a policy lives in 
{@link OpaSecurityPolicyWasmIT}, where the
+ * bundle is compiled from the Rego under test rather than committed beside it 
(CAMEL-24742).
  */
 public class OpaSecurityPolicyWasmTest extends CamelTestSupport {
 
-    private final OpaSecurityPolicy wasmPolicy = new OpaSecurityPolicy();
-    private final OpaSecurityPolicy restPolicy = new OpaSecurityPolicy();
-
-    @Override
-    protected RouteBuilder createRouteBuilder() {
-        wasmPolicy.setEvaluationMode("wasm");
-        wasmPolicy.setPolicyBundle("classpath:authz.wasm");
-        wasmPolicy.setPolicyPath("authz/allow");
-
-        // a rest-mode policy is the positive control for the readiness-check 
assertion: it registers a check, the
-        // wasm one must not
-        restPolicy.setServerUrl("http://opa-rest:8181";);
-        restPolicy.setPolicyPath("authz/allow");
-
-        return new RouteBuilder() {
-            @Override
-            public void configure() {
-                from("direct:wasm").policy(wasmPolicy).to("mock:allowed");
-                from("direct:rest").policy(restPolicy).to("mock:rest");
-            }
-        };
-    }
-
-    @Test
-    void allowsWhenTheWasmPolicyMatches() throws Exception {
-        MockEndpoint allowed = getMockEndpoint("mock:allowed");
-        allowed.expectedMessageCount(1);
-
-        template.sendBodyAndHeader("direct:wasm", "payload", "user", "alice");
-
-        allowed.assertIsSatisfied();
-    }
-
-    @Test
-    void deniesWhenTheWasmPolicyDoesNotMatch() throws Exception {
-        MockEndpoint allowed = getMockEndpoint("mock:allowed");
-        allowed.expectedMessageCount(0);
-
-        assertThatThrownBy(() -> template.sendBodyAndHeader("direct:wasm", 
"payload", "user", "mallory"))
-                .isInstanceOf(CamelExecutionException.class)
-                .hasCauseInstanceOf(CamelAuthorizationException.class);
-
-        allowed.assertIsSatisfied();
-    }
-
-    @Test
-    void registersOnlyTheRestPolicysReadinessCheck() {
-        HealthCheckRegistry registry = HealthCheckRegistry.get(context);
-        assertThat(registry).isNotNull();
-        List<HealthCheck> checks = registry.stream()
-                .filter(hc -> hc.getId().startsWith("security-policy:opa-"))
-                .toList();
-
-        // exactly one, and it is the rest policy's - the wasm policy 
evaluates in-process with no server to probe.
-        // Assert the full ID contract, not just the hostname, so a refactor 
of the ID-building logic cannot pass here
-        // silently: OpaSecurityPolicyHealthCheck builds it as 
"security-policy:opa-" + sanitized serverUrl/policyPath.
-        assertThat(checks).hasSize(1);
-        
assertThat(checks.get(0).getId()).startsWith("security-policy:opa-").contains("opa-rest");
-    }
-
     @Test
     void failsRouteStartOnABundleThatLoadsButIsNotAValidModule() {
         // OpaWasmEvaluator borrows an instance at startup so a broken bundle 
fails fast, and beforeWrap - which cannot
@@ -155,9 +89,10 @@ public class OpaSecurityPolicyWasmTest extends 
CamelTestSupport {
 
     @Test
     void failsRouteStartOnAPoolSizeBelowOne() {
+        // rejected before the bundle is resolved, so the location here is 
never opened
         OpaSecurityPolicy badPool = new OpaSecurityPolicy();
         badPool.setEvaluationMode("wasm");
-        badPool.setPolicyBundle("classpath:authz.wasm");
+        badPool.setPolicyBundle("file:unused.wasm");
         badPool.setPolicyPath("authz/allow");
         badPool.setPoolSize(0);
 
diff --git a/components/camel-opa/src/test/resources/wasm-data/roles.rego 
b/components/camel-opa/src/test/resources/wasm-data/roles.rego
index b7f2f6e63e52..72f9bf8a9320 100644
--- a/components/camel-opa/src/test/resources/wasm-data/roles.rego
+++ b/components/camel-opa/src/test/resources/wasm-data/roles.rego
@@ -20,7 +20,7 @@
 # `opa build` packs the data.json sitting beside this file into the bundle, 
and a server that
 # loads the bundle answers against it. The WebAssembly module carries no data 
of its own, so
 # camel-opa has to apply the bundle's data to every evaluation for the two to 
agree - which is
-# what OpaWasmEvaluatorTest.appliesTheDataDocumentPackedInTheBundle asserts.
+# what OpaWasmIT.appliesTheDataDocumentPackedInTheBundle asserts.
 
 package roles
 

Reply via email to