4
4
from typing import Any
5
5
6
6
import pytest
7
+ from inline_snapshot import snapshot
7
8
8
9
from agents .tracing import (
9
10
Span ,
17
18
)
18
19
from agents .tracing .spans import SpanError
19
20
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
+ )
21
28
22
29
### HELPERS
23
30
@@ -129,11 +136,11 @@ def test_ctxmanager_spans() -> None:
129
136
130
137
async def run_subtask (span_id : str | None = None ) -> None :
131
138
with generation_span (span_id = span_id ):
132
- await asyncio .sleep (0.01 )
139
+ await asyncio .sleep (0.0001 )
133
140
134
141
135
142
async 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 " ):
137
144
await run_subtask (span_id = "span_1" )
138
145
await run_subtask (span_id = "span_2" )
139
146
@@ -142,21 +149,18 @@ async def simple_async_tracing():
142
149
async def test_async_tracing () -> None :
143
150
await simple_async_tracing ()
144
151
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
+ )
160
164
161
165
162
166
async 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
171
175
172
176
173
177
async 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" ):
176
179
await asyncio .gather (
177
180
run_tasks_parallel (["span_1" , "span_2" ]),
178
181
run_tasks_parallel (["span_3" , "span_4" ]),
179
182
)
180
- await asyncio .sleep (0.01 )
181
183
await asyncio .gather (
182
184
run_tasks_as_children ("span_5" , "span_6" ),
183
185
run_tasks_as_children ("span_7" , "span_8" ),
@@ -186,35 +188,34 @@ async def complex_async_tracing():
186
188
187
189
@pytest .mark .asyncio
188
190
async 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
+ )
218
219
219
220
220
221
def spans_with_setters ():
0 commit comments