You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/02/11 15:01:09 UTC
(skywalking) 10/21: Add comprehensive filter verification tests for OAL V2
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch oal-v2
in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit c5b61bb0f942ee40792e7333f757afb5621f1c1e
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Tue Feb 10 09:36:09 2026 +0800
Add comprehensive filter verification tests for OAL V2
Add tests to verify filter expressions are correctly processed and
generated as runnable bytecode:
- testFilterExpressionProcessing: Unit test for filter enrichment
- testMetricsWithFilterGeneration: Full bytecode generation test
using ServiceRelation source with single and multi-filter chains
The tests verify:
- Filter expressions are converted to template-ready format
- Generated dispatcher classes load correctly in JVM
- doMetrics methods with filter logic are generated
- Metrics classes can be instantiated
Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
.../oal/v2/generator/OALClassGeneratorV2Test.java | 118 +++++++++++++++++++++
1 file changed, 118 insertions(+)
diff --git a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2Test.java b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2Test.java
index ee5df06f31..49136fe7f9 100644
--- a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2Test.java
+++ b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2Test.java
@@ -38,6 +38,7 @@ import org.apache.skywalking.oap.server.core.oal.rt.OALDefine;
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
import org.apache.skywalking.oap.server.core.source.Endpoint;
import org.apache.skywalking.oap.server.core.source.Service;
+import org.apache.skywalking.oap.server.core.source.ServiceRelation;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
import org.junit.jupiter.api.BeforeAll;
@@ -71,6 +72,7 @@ public class OALClassGeneratorV2Test {
DefaultScopeDefine.Listener listener = new DefaultScopeDefine.Listener();
listener.notify(Service.class);
listener.notify(Endpoint.class);
+ listener.notify(ServiceRelation.class);
}
/**
@@ -270,6 +272,122 @@ public class OALClassGeneratorV2Test {
assertNotNull(findMethodByName(dispatcherClass, "doEndpointCalls"));
}
+ /**
+ * Test that filter expressions are correctly processed by the enricher.
+ * This is a unit test for filter processing - doesn't generate bytecode.
+ */
+ @Test
+ public void testFilterExpressionProcessing() throws Exception {
+ // OAL with filter expression
+ String oal = "test_sla = from(Endpoint.*).filter(status == true).percent(status == true);";
+
+ MetricDefinitionEnricher enricher = new MetricDefinitionEnricher(SOURCE_PACKAGE, METRICS_PACKAGE);
+
+ // Parse and enrich
+ OALScriptParserV2 parser = OALScriptParserV2.parse(oal);
+ MetricDefinition metric = parser.getMetrics().get(0);
+ CodeGenModel model = enricher.enrich(metric);
+
+ // Verify filter expressions are converted to template-ready format
+ assertFalse(model.getFilterExpressions().isEmpty(),
+ "Filter expressions should be populated");
+ assertEquals(1, model.getFilterExpressions().size());
+
+ CodeGenModel.FilterExpressionV2 filterExpr = model.getFilterExpressions().get(0);
+ assertNotNull(filterExpr.getExpressionObject(), "Expression object should not be null");
+ assertTrue(filterExpr.getExpressionObject().contains("Match"),
+ "Expression object should be a matcher class (e.g., EqualMatch, NotEqualMatch)");
+ assertNotNull(filterExpr.getLeft(), "Left side should not be null");
+ assertTrue(filterExpr.getLeft().contains("source."),
+ "Left side should reference source");
+ assertNotNull(filterExpr.getRight(), "Right side should not be null");
+ }
+
+ /**
+ * Test full code generation for metrics with filter expressions.
+ * Uses ServiceRelation source to avoid frozen class conflicts with other tests.
+ *
+ * This test validates:
+ * - Filter expressions are correctly passed to templates
+ * - Generated dispatcher contains filter logic
+ * - Multiple filters in chain are handled correctly
+ */
+ @Test
+ public void testMetricsWithFilterGeneration() throws Exception {
+ // OAL with various filter types from core.oal
+ String oal = "service_relation_client_cpm = from(ServiceRelation.*).filter(detectPoint == DetectPoint.CLIENT).cpm();\n" +
+ "service_relation_server_cpm = from(ServiceRelation.*).filter(detectPoint == DetectPoint.SERVER).cpm();\n" +
+ "service_relation_client_call_sla = from(ServiceRelation.*).filter(detectPoint == DetectPoint.CLIENT).filter(status == true).percent(status == true);\n" +
+ "service_relation_client_resp_time = from(ServiceRelation.latency).filter(detectPoint == DetectPoint.CLIENT).longAvg();";
+
+ OALClassGeneratorV2 generator = createGenerator();
+ MetricDefinitionEnricher enricher = new MetricDefinitionEnricher(SOURCE_PACKAGE, METRICS_PACKAGE);
+
+ List<Class> metricsClasses = new ArrayList<>();
+ List<Class> dispatcherClasses = new ArrayList<>();
+
+ generateClasses(oal, generator, enricher, metricsClasses, dispatcherClasses);
+
+ // Verify 4 metrics classes generated
+ assertEquals(4, metricsClasses.size());
+
+ // Verify 1 dispatcher class for ServiceRelation source
+ assertEquals(1, dispatcherClasses.size());
+
+ Class<?> dispatcherClass = dispatcherClasses.get(0);
+ assertEquals("ServiceRelationDispatcher", dispatcherClass.getSimpleName());
+ assertTrue(SourceDispatcher.class.isAssignableFrom(dispatcherClass));
+
+ // Verify all doMetrics methods exist
+ Method doClientCpm = findMethodByName(dispatcherClass, "doServiceRelationClientCpm");
+ Method doServerCpm = findMethodByName(dispatcherClass, "doServiceRelationServerCpm");
+ Method doClientCallSla = findMethodByName(dispatcherClass, "doServiceRelationClientCallSla");
+ Method doClientRespTime = findMethodByName(dispatcherClass, "doServiceRelationClientRespTime");
+
+ assertNotNull(doClientCpm, "doServiceRelationClientCpm should be generated");
+ assertNotNull(doServerCpm, "doServiceRelationServerCpm should be generated");
+ assertNotNull(doClientCallSla, "doServiceRelationClientCallSla should be generated");
+ assertNotNull(doClientRespTime, "doServiceRelationClientRespTime should be generated");
+
+ // Verify filter expressions were correctly enriched
+ OALScriptParserV2 parser = OALScriptParserV2.parse(oal);
+
+ // Check single filter metric
+ MetricDefinition clientCpmMetric = parser.getMetrics().get(0);
+ CodeGenModel clientCpmModel = enricher.enrich(clientCpmMetric);
+ assertEquals(1, clientCpmModel.getFilterExpressions().size());
+ assertTrue(clientCpmModel.getFilterExpressions().get(0).getExpressionObject().contains("Match"));
+ assertTrue(clientCpmModel.getFilterExpressions().get(0).getLeft().contains("getDetectPoint"));
+ assertTrue(clientCpmModel.getFilterExpressions().get(0).getRight().contains("DetectPoint.CLIENT"));
+
+ // Check multi-filter metric (filter chain)
+ MetricDefinition clientCallSlaMetric = parser.getMetrics().get(2);
+ CodeGenModel clientCallSlaModel = enricher.enrich(clientCallSlaMetric);
+ assertEquals(2, clientCallSlaModel.getFilterExpressions().size(),
+ "Multi-filter metric should have 2 filter expressions");
+
+ // First filter: detectPoint == DetectPoint.CLIENT
+ CodeGenModel.FilterExpressionV2 filter1 = clientCallSlaModel.getFilterExpressions().get(0);
+ assertTrue(filter1.getLeft().contains("getDetectPoint"));
+
+ // Second filter: status == true (boolean)
+ CodeGenModel.FilterExpressionV2 filter2 = clientCallSlaModel.getFilterExpressions().get(1);
+ assertTrue(filter2.getLeft().contains("isStatus") || filter2.getLeft().contains("getStatus"));
+ assertEquals("true", filter2.getRight());
+
+ // Verify metrics classes are properly generated
+ Class<?> clientCpmClass = findClassBySimpleName(metricsClasses, "ServiceRelationClientCpmMetrics");
+ Class<?> slaClass = findClassBySimpleName(metricsClasses, "ServiceRelationClientCallSlaMetrics");
+
+ assertNotNull(clientCpmClass);
+ assertNotNull(slaClass);
+
+ // Test instantiation
+ Object clientCpmInstance = clientCpmClass.getDeclaredConstructor().newInstance();
+ assertNotNull(clientCpmInstance);
+ assertTrue(clientCpmInstance instanceof Metrics);
+ }
+
/**
* Create a configured OALClassGeneratorV2 instance.
*/