From a4048d858b566d0ceae1d62834d086e5e96c8099 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 12 Mar 2026 14:49:20 +0100 Subject: [PATCH] chore: Client side stats aggregates on GRPC status code * Adds a parameteric test for the grpc status code * Replace parametric test by regular for the grpc status code --- tests/stats/test_stats.py | 31 ++++++++++++++++++++++++++++- utils/docker_fixtures/spec/trace.py | 2 ++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/stats/test_stats.py b/tests/stats/test_stats.py index 83742ed2cd5..573240b1a92 100644 --- a/tests/stats/test_stats.py +++ b/tests/stats/test_stats.py @@ -1,5 +1,5 @@ import pytest -from utils import interfaces, weblog, features, scenarios, logger +from utils import context, features, interfaces, logger, missing_feature, scenarios, weblog """ Test scenarios we want: @@ -99,6 +99,35 @@ def test_disable(self): requests = list(interfaces.library.get_data("/v0.6/stats")) assert len(requests) == 0, "Client-side stats should be disabled by default" + def setup_grpc_status_code(self): + self.grpc_request = weblog.grpc("grpc stats") + + @missing_feature( + context.library != "java" or context.library < "java@1.61.0", + reason="GRPCStatusCode stats payload field was added in java@1.61.0", + force_skip=True, + ) + @missing_feature( + context.weblog_variant != "spring-boot", + reason="gRPC stats coverage requires a weblog variant with gRPC support", + force_skip=True, + ) + def test_grpc_status_code(self): + grpc_stats = [] + + for data in interfaces.library.get_data("/v0.6/stats"): + payload = data["request"]["content"] + for bucket in payload.get("Stats", []): + for stat in bucket.get("Stats", []): + if stat.get("Type") == "rpc" and stat.get("SpanKind") == "server": + grpc_stats.append(stat) + + assert grpc_stats, "Expected at least one gRPC stats entry in the v0.6/stats payload" + # 0 means OK in gRPC status codes + assert any(stat.get("GRPCStatusCode") == "0" for stat in grpc_stats), ( + f"Expected a gRPC stats entry with GRPCStatusCode=0, got: {grpc_stats}" + ) + @features.client_side_stats_supported @scenarios.trace_stats_computation diff --git a/utils/docker_fixtures/spec/trace.py b/utils/docker_fixtures/spec/trace.py index 475406c8005..1347d8a46bc 100644 --- a/utils/docker_fixtures/spec/trace.py +++ b/utils/docker_fixtures/spec/trace.py @@ -71,6 +71,7 @@ class V06StatsAggr(TypedDict): Type: str Service: str HTTPStatusCode: int + GRPCStatusCode: str Synthetics: bool Hits: int TopLevelHits: int @@ -131,6 +132,7 @@ def decode_v06_stats(data: bytes) -> V06StatsPayload: Service=raw_stats["Service"], Type=raw_stats.get("Type"), HTTPStatusCode=raw_stats.get("HTTPStatusCode"), + GRPCStatusCode=raw_stats.get("GRPCStatusCode"), Synthetics=raw_stats["Synthetics"], Hits=raw_stats["Hits"], TopLevelHits=raw_stats["TopLevelHits"],