Skip to content

Commit 7c85d47

Browse files
committed
test synthetic frames
1 parent 67cd39a commit 7c85d47

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

Lib/test/test_profiling/test_sampling_profiler/test_collectors.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,6 +2145,7 @@ def test_gecko_collector_with_location_info(self):
21452145
# Verify function name is in string table
21462146
self.assertIn("handle_request", string_array)
21472147

2148+
21482149
def test_jsonl_collector_with_location_info(self):
21492150
"""Test JsonlCollector handles LocationInfo properly."""
21502151
collapsed_out = tempfile.NamedTemporaryFile(delete=False)
@@ -2196,6 +2197,59 @@ def jsonl(obj):
21962197
self.assertIn(exp, lines)
21972198

21982199

2200+
def test_jsonl_collector_with_none_location(self):
2201+
"""Test JsonlCollector handles None location (synthetic frames)."""
2202+
collapsed_out = tempfile.NamedTemporaryFile(delete=False)
2203+
self.addCleanup(close_and_unlink, collapsed_out)
2204+
2205+
collector = JsonlCollector(sample_interval_usec=1000)
2206+
run_id = collector.run_id
2207+
2208+
# Create frame with None location (like GC frame)
2209+
frame = MockFrameInfo("~", 0, "<GC>")
2210+
frame.location = None # Synthetic frame has no location
2211+
frames = [
2212+
MockInterpreterInfo(
2213+
0,
2214+
[MockThreadInfo(1, [frame], status=THREAD_STATUS_HAS_GIL)]
2215+
)
2216+
]
2217+
collector.collect(frames)
2218+
2219+
# Should handle None location as synthetic frame
2220+
with captured_stdout(), captured_stderr():
2221+
collector.export(collapsed_out.name)
2222+
2223+
# Check file contents
2224+
with open(collapsed_out.name, "r") as f:
2225+
content = f.read()
2226+
2227+
lines = content.strip().split("\n")
2228+
self.assertEqual(len(lines), 5)
2229+
2230+
def jsonl(obj):
2231+
return json.dumps(obj, separators=(",", ":"))
2232+
2233+
expected = [
2234+
jsonl({"type": "meta", "v": 1, "run_id": run_id,
2235+
"sample_interval_usec": 1000}),
2236+
jsonl({"type": "str_def", "v": 1, "run_id": run_id,
2237+
"defs": [{"str_id": 1, "value": "<GC>"},
2238+
{"str_id": 2, "value": "~"}]}),
2239+
jsonl({"type": "frame_def", "v": 1, "run_id": run_id,
2240+
"defs": [{"frame_id": 1, "path_str_id": 2, "func_str_id": 1,
2241+
"line": 0, "synthetic": True}]}),
2242+
jsonl({"type": "agg", "v": 1, "run_id": run_id,
2243+
"kind": "frame", "scope": "final", "samples_total": 1,
2244+
"entries": [{"frame_id": 1, "self": 1, "cumulative": 1}]}),
2245+
jsonl({"type": "end", "v": 1, "run_id": run_id,
2246+
"samples_total": 1}),
2247+
]
2248+
2249+
for exp in expected:
2250+
self.assertIn(exp, lines)
2251+
2252+
21992253
class TestOpcodeHandling(unittest.TestCase):
22002254
"""Tests for opcode field handling in collectors."""
22012255

0 commit comments

Comments
 (0)