Skip to content

Commit d286f98

Browse files
committed
Change details type to dict
Align type with Test Engine, simplify implementation.
1 parent a03b99b commit d286f98

3 files changed

Lines changed: 24 additions & 29 deletions

File tree

src/buildkite_test_collector/collector/payload.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,20 @@ class TestSpan:
4040
4141
Buildkite Test Analtics supports some basic tracing to allow insight into
4242
the runtime performance your tests.
43+
44+
The detail field should be a dict matching the expected format for each section type:
45+
- sql: {"query": str}
46+
- annotation: {"content": str}
47+
- http: {"method": str, "url": str, "lib": str}
48+
- sleep: no detail required
49+
50+
See: https://buildkite.com/docs/test-engine/test-collection/importing-json#json-test-results-data-reference-detail-objects
4351
"""
4452
section: Literal['http', 'sql', 'sleep', 'annotation']
4553
duration: timedelta
4654
start_at: Optional[Instant] = None
4755
end_at: Optional[Instant] = None
48-
detail: Optional[str] = None
56+
detail: Optional[Dict[str, str]] = None
4957

5058
def as_json(self, started_at: Instant) -> JsonDict:
5159
"""Convert this span into a Dict for eventual serialisation into JSON"""
@@ -55,31 +63,7 @@ def as_json(self, started_at: Instant) -> JsonDict:
5563
}
5664

5765
if self.detail is not None:
58-
# Format detail based on section type to match the expected Avro schema
59-
# pylint: disable=C0301
60-
# See: https://buildkite.com/docs/test-analytics/importing-json#json-test-results-data-reference-span-objects
61-
if self.section == "sql":
62-
attrs["detail"] = {"query": self.detail}
63-
elif self.section == "annotation":
64-
attrs["detail"] = {"content": self.detail}
65-
elif self.section == "http":
66-
# For HTTP spans, the detail should be a dict with method, url, lib
67-
# If it's a string, handle it gracefully
68-
if isinstance(self.detail, dict):
69-
attrs["detail"] = self.detail
70-
else:
71-
# Fallback: if provided a string, treat it as a URL
72-
attrs["detail"] = {
73-
"method": "GET",
74-
"url": self.detail,
75-
"lib": "unknown"
76-
}
77-
elif self.section == "sleep":
78-
# Sleep spans don't need detail
79-
pass
80-
else:
81-
# For unknown/custom sections, keep detail as-is
82-
attrs["detail"] = self.detail
66+
attrs["detail"] = self.detail
8367

8468
if self.start_at is not None:
8569
attrs["start_at"] = (self.start_at - started_at).total_seconds()

src/buildkite_test_collector/pytest_plugin/span_collector.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,27 @@ def record(self, span: TestSpan) -> None:
3232

3333
@contextmanager
3434
def measure(self, section: Literal['http', 'sql', 'sleep', 'annotation'],
35-
detail: Optional[str] = None) -> Any:
35+
detail: Optional[dict] = None) -> Any:
3636
"""
3737
Measure the execution time of some code and record it as a span.
3838
39+
The detail parameter should be a dict matching the expected format for each section type:
40+
- sql: {"query": str}
41+
- annotation: {"content": str}
42+
- http: {"method": str, "url": str, "lib": str}
43+
- sleep: no detail required
44+
3945
Example:
4046
4147
.. code-block:: python
4248
4349
def test_measure_http_request(spans):
44-
with spans.measure('http', 'The koan of Github'):
50+
with spans.measure('http', {'method': 'GET', 'url': 'https://api.github.com/zen', 'lib': 'requests'}):
4551
requests.get("https://api.github.com/zen")
52+
53+
def test_measure_sql_query(spans):
54+
with spans.measure('sql', {'query': 'SELECT * FROM users'}):
55+
db.execute('SELECT * FROM users')
4656
"""
4757
start_at = Instant.now()
4858
try:

tests/buildkite_test_collector/pytest_plugin/test_span_collector.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
def test_record_adds_span_to_plugin(span_collector):
88
span_collector.record(TestSpan(
99
section='http',
10-
duration=timedelta(seconds=3)))
10+
duration=timedelta(seconds=3),
11+
detail={'method': 'GET', 'url': 'https://example.com', 'lib': 'requests'}))
1112

1213
assert len(span_collector.current_test().history.children) == 1
1314

0 commit comments

Comments
 (0)