44from typing import Any
55
66import pytest
7+ from inline_snapshot import snapshot
78
89from agents .tracing import (
910 Span ,
1718)
1819from agents .tracing .spans import SpanError
1920
20- from .testing_processor import fetch_events , fetch_ordered_spans , fetch_traces
21+ from .testing_processor import (
22+ SPAN_PROCESSOR_TESTING ,
23+ fetch_events ,
24+ fetch_normalized_spans ,
25+ fetch_ordered_spans ,
26+ fetch_traces ,
27+ )
2128
2229### HELPERS
2330
@@ -129,11 +136,11 @@ def test_ctxmanager_spans() -> None:
129136
130137async def run_subtask (span_id : str | None = None ) -> None :
131138 with generation_span (span_id = span_id ):
132- await asyncio .sleep (0.01 )
139+ await asyncio .sleep (0.0001 )
133140
134141
135142async def simple_async_tracing ():
136- with trace (workflow_name = "test" , trace_id = "123 " , group_id = "456 " ):
143+ with trace (workflow_name = "test" , trace_id = "trace_123 " , group_id = "group_456 " ):
137144 await run_subtask (span_id = "span_1" )
138145 await run_subtask (span_id = "span_2" )
139146
@@ -142,21 +149,18 @@ async def simple_async_tracing():
142149async def test_async_tracing () -> None :
143150 await simple_async_tracing ()
144151
145- spans , traces = fetch_ordered_spans (), fetch_traces ()
146- assert len (spans ) == 2
147- assert len (traces ) == 1
148-
149- trace = traces [0 ]
150- standard_trace_checks (trace , name_check = "test" )
151- trace_id = trace .trace_id
152-
153- # We don't care about ordering here, just that they're there
154- for s in spans :
155- standard_span_checks (s , trace_id = trace_id , parent_id = None , span_type = "generation" )
156-
157- ids = [span .span_id for span in spans ]
158- assert "span_1" in ids
159- assert "span_2" in ids
152+ assert fetch_normalized_spans (keep_span_id = True ) == snapshot (
153+ [
154+ {
155+ "workflow_name" : "test" ,
156+ "group_id" : "group_456" ,
157+ "children" : [
158+ {"type" : "generation" , "id" : "span_1" },
159+ {"type" : "generation" , "id" : "span_2" },
160+ ],
161+ }
162+ ]
163+ )
160164
161165
162166async def run_tasks_parallel (span_ids : list [str ]) -> None :
@@ -171,13 +175,11 @@ async def run_tasks_as_children(first_span_id: str, second_span_id: str) -> None
171175
172176
173177async def complex_async_tracing ():
174- with trace (workflow_name = "test" , trace_id = "123" , group_id = "456" ):
175- await asyncio .sleep (0.01 )
178+ with trace (workflow_name = "test" , trace_id = "trace_123" , group_id = "456" ):
176179 await asyncio .gather (
177180 run_tasks_parallel (["span_1" , "span_2" ]),
178181 run_tasks_parallel (["span_3" , "span_4" ]),
179182 )
180- await asyncio .sleep (0.01 )
181183 await asyncio .gather (
182184 run_tasks_as_children ("span_5" , "span_6" ),
183185 run_tasks_as_children ("span_7" , "span_8" ),
@@ -186,35 +188,34 @@ async def complex_async_tracing():
186188
187189@pytest .mark .asyncio
188190async def test_complex_async_tracing () -> None :
189- await complex_async_tracing ()
190-
191- spans , traces = fetch_ordered_spans (), fetch_traces ()
192- assert len (spans ) == 8
193- assert len (traces ) == 1
194-
195- trace = traces [0 ]
196- standard_trace_checks (trace , name_check = "test" )
197- trace_id = trace .trace_id
198-
199- # First ensure 1,2,3,4 exist and are in parallel with the trace as parent
200- for span_id in ["span_1" , "span_2" , "span_3" , "span_4" ]:
201- span = next ((s for s in spans if s .span_id == span_id ), None )
202- assert span is not None
203- standard_span_checks (span , trace_id = trace_id , parent_id = None , span_type = "generation" )
204-
205- # Ensure 5 and 7 exist and have the trace as parent
206- for span_id in ["span_5" , "span_7" ]:
207- span = next ((s for s in spans if s .span_id == span_id ), None )
208- assert span is not None
209- standard_span_checks (span , trace_id = trace_id , parent_id = None , span_type = "generation" )
210-
211- # Ensure 6 and 8 exist and have 5 and 7 as parents
212- six = next ((s for s in spans if s .span_id == "span_6" ), None )
213- assert six is not None
214- standard_span_checks (six , trace_id = trace_id , parent_id = "span_5" , span_type = "generation" )
215- eight = next ((s for s in spans if s .span_id == "span_8" ), None )
216- assert eight is not None
217- standard_span_checks (eight , trace_id = trace_id , parent_id = "span_7" , span_type = "generation" )
191+ for _ in range (300 ):
192+ SPAN_PROCESSOR_TESTING .clear ()
193+ await complex_async_tracing ()
194+
195+ assert fetch_normalized_spans (keep_span_id = True ) == (
196+ [
197+ {
198+ "workflow_name" : "test" ,
199+ "group_id" : "456" ,
200+ "children" : [
201+ {"type" : "generation" , "id" : "span_1" },
202+ {"type" : "generation" , "id" : "span_2" },
203+ {"type" : "generation" , "id" : "span_3" },
204+ {"type" : "generation" , "id" : "span_4" },
205+ {
206+ "type" : "generation" ,
207+ "id" : "span_5" ,
208+ "children" : [{"type" : "generation" , "id" : "span_6" }],
209+ },
210+ {
211+ "type" : "generation" ,
212+ "id" : "span_7" ,
213+ "children" : [{"type" : "generation" , "id" : "span_8" }],
214+ },
215+ ],
216+ }
217+ ]
218+ )
218219
219220
220221def spans_with_setters ():
0 commit comments