Skip to content

Commit cb0eb8e

Browse files
committed
More fetch_normalized_spans
1 parent cd9b9ab commit cb0eb8e

File tree

3 files changed

+56
-53
lines changed

3 files changed

+56
-53
lines changed

tests/test_tracing.py

+51-50
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Any
55

66
import pytest
7+
from inline_snapshot import snapshot
78

89
from agents.tracing import (
910
Span,
@@ -17,7 +18,13 @@
1718
)
1819
from 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

130137
async 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

135142
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"):
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():
142149
async 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

162166
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
171175

172176

173177
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"):
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
188190
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+
)
218219

219220

220221
def spans_with_setters():

tests/testing_processor.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def fetch_events() -> list[TestSpanProcessorEvent]:
8080
return SPAN_PROCESSOR_TESTING._events
8181

8282

83-
def fetch_normalized_spans():
83+
def fetch_normalized_spans(keep_span_id: bool = False):
8484
nodes: dict[tuple[str, str | None], dict[str, Any]] = {}
8585
traces = []
8686
for trace_obj in fetch_traces():
@@ -99,7 +99,9 @@ def fetch_normalized_spans():
9999
span = span_obj.export()
100100
assert span
101101
assert span.pop("object") == "trace.span"
102-
assert span.pop("id").startswith("span_")
102+
assert span["id"].startswith("span_")
103+
if not keep_span_id:
104+
del span["id"]
103105
assert datetime.fromisoformat(span.pop("started_at"))
104106
assert datetime.fromisoformat(span.pop("ended_at"))
105107
parent_id = span.pop("parent_id")

uv.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)