11"""Tests for Phase 2 — Telemetry Hardening (TEL-01 through TEL-04)."""
22
3+ from typing import Any
34from unittest .mock import MagicMock , patch
45
56from fastapi .testclient import TestClient
@@ -110,12 +111,13 @@ def test_all_loop_stages_share_one_trace_without_prompt_or_output_attributes() -
110111 pass
111112
112113 spans = exporter .get_finished_spans ()
113- assert {span .attributes ["cas.stage" ] for span in spans } == {stage .value for stage in LoopStage }
114+ stage_values = {stage .value for stage in LoopStage }
115+ assert {span .attributes ["cas.stage" ] for span in spans if span .attributes } == stage_values
114116 assert len ({span .context .trace_id for span in spans }) == 1
115117 assert all (
116118 "prompt" not in key and "output" not in key
117119 for span in spans
118- for key in span .attributes
120+ for key in ( span .attributes or {})
119121 )
120122
121123
@@ -140,7 +142,9 @@ def test_install_propagator_sets_w3c_propagator() -> None:
140142# ---------------------------------------------------------------------------
141143
142144
143- def test_workflow_endpoint_creates_span (in_memory_exporter : InMemorySpanExporter , envelope ) -> None :
145+ def test_workflow_endpoint_creates_span (
146+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
147+ ) -> None :
144148 client = TestClient (create_app (Settings ()))
145149 response = client .post ("/api/v1/workflows" , json = envelope .model_dump (mode = "json" ))
146150
@@ -157,12 +161,15 @@ def test_workflow_endpoint_creates_span(in_memory_exporter: InMemorySpanExporter
157161# ---------------------------------------------------------------------------
158162
159163
160- def test_workflow_span_attributes (in_memory_exporter : InMemorySpanExporter , envelope ) -> None :
164+ def test_workflow_span_attributes (
165+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
166+ ) -> None :
161167 client = TestClient (create_app (Settings ()))
162168 client .post ("/api/v1/workflows" , json = envelope .model_dump (mode = "json" ))
163169
164170 spans = in_memory_exporter .get_finished_spans ()
165171 api_span = next (s for s in spans if s .name == "cas.api.workflows.execute" )
172+ assert api_span .attributes
166173 assert api_span .attributes .get ("cas.correlation_id" ) == envelope .correlationId
167174 assert api_span .attributes .get ("cas.run_id" ) == envelope .runId
168175 assert api_span .attributes .get ("cas.intent" ) == envelope .intent
@@ -174,7 +181,7 @@ def test_workflow_span_attributes(in_memory_exporter: InMemorySpanExporter, enve
174181
175182
176183def test_workflow_span_events_started_and_completed (
177- in_memory_exporter : InMemorySpanExporter , envelope
184+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
178185) -> None :
179186 client = TestClient (create_app (Settings ()))
180187 client .post ("/api/v1/workflows" , json = envelope .model_dump (mode = "json" ))
@@ -188,12 +195,12 @@ def test_workflow_span_events_started_and_completed(
188195
189196
190197def test_workflow_span_events_started_and_failed (
191- in_memory_exporter : InMemorySpanExporter , envelope
198+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
192199) -> None :
193200 from cas_reference_product .workflow import WorkflowAgentServiceError
194201
195202 class FailingService :
196- def run (self , _env ) -> str :
203+ def run (self : "Any" , _env : "Any" ) -> str :
197204 raise WorkflowAgentServiceError ("backend down" )
198205
199206 with patch (
@@ -213,14 +220,15 @@ def run(self, _env) -> str:
213220
214221
215222def test_span_event_carries_correlation_id (
216- in_memory_exporter : InMemorySpanExporter , envelope
223+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
217224) -> None :
218225 client = TestClient (create_app (Settings ()))
219226 client .post ("/api/v1/workflows" , json = envelope .model_dump (mode = "json" ))
220227
221228 spans = in_memory_exporter .get_finished_spans ()
222229 api_span = next (s for s in spans if s .name == "cas.api.workflows.execute" )
223230 started_event = next (e for e in api_span .events if e .name == "workflow.started" )
231+ assert started_event .attributes
224232 assert started_event .attributes .get ("cas.correlation_id" ) == envelope .correlationId
225233 assert started_event .attributes .get ("cas.run_id" ) == envelope .runId
226234
@@ -231,7 +239,7 @@ def test_span_event_carries_correlation_id(
231239
232240
233241def test_w3c_traceparent_propagated_inbound (
234- in_memory_exporter : InMemorySpanExporter , envelope
242+ in_memory_exporter : InMemorySpanExporter , envelope : "Any"
235243) -> None :
236244 """Request with a W3C traceparent header links the API span as a child."""
237245 incoming_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
0 commit comments