Skip to content

Commit 87114cf

Browse files
committed
test
1 parent 64b1fd1 commit 87114cf

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import unittest
1010
from collections import defaultdict
1111

12+
from test.support import captured_stderr
13+
1214
try:
1315
import _remote_debugging
1416
from _remote_debugging import (
@@ -994,6 +996,74 @@ def test_writer_total_samples_after_close_returns_zero(self):
994996
w.close()
995997
self.assertEqual(w.total_samples, 0)
996998

999+
def test_binary_collector_stops_gracefully_on_overflow(self):
1000+
"""OverflowError from the writer stops collection via the running
1001+
protocol instead of propagating and corrupting the file.
1002+
See gh-151292."""
1003+
with tempfile.NamedTemporaryFile(suffix=".bin", delete=False) as f:
1004+
filename = f.name
1005+
self.temp_files.append(filename)
1006+
1007+
collector = BinaryCollector(filename, 1000, compression="none")
1008+
self.assertTrue(collector.running)
1009+
1010+
sample = [
1011+
make_interpreter(0, [make_thread(1, [make_frame("a.py", 1, "f")])])
1012+
]
1013+
1014+
# Collect real samples first, then hit the limit.
1015+
for i in range(3):
1016+
collector.collect(sample, timestamp_us=(i + 1) * 1000)
1017+
self.assertTrue(collector.running)
1018+
1019+
real_writer = collector._writer
1020+
1021+
class _OverflowingWriter:
1022+
def write_sample(self, stack_frames, timestamp_us):
1023+
raise OverflowError("too many samples for binary format")
1024+
1025+
collector._writer = _OverflowingWriter()
1026+
with captured_stderr() as stderr:
1027+
collector.collect(sample, timestamp_us=4000)
1028+
1029+
self.assertFalse(collector.running)
1030+
self.assertIn("too many samples", stderr.getvalue())
1031+
1032+
# The real writer can still be finalized into a valid file that
1033+
# keeps the samples collected before the limit was hit.
1034+
collector._writer = real_writer
1035+
collector.export(None)
1036+
reader_collector = RawCollector()
1037+
with BinaryReader(filename) as reader:
1038+
self.assertEqual(reader.replay_samples(reader_collector), 3)
1039+
1040+
def test_interpreter_id_overflow_rejected(self):
1041+
"""An interpreter_id wider than u32 raises OverflowError before any
1042+
writer state is mutated: subsequent valid samples are still accepted
1043+
and finalize produces a readable file."""
1044+
with tempfile.NamedTemporaryFile(suffix=".bin", delete=False) as f:
1045+
filename = f.name
1046+
self.temp_files.append(filename)
1047+
1048+
good = [
1049+
make_interpreter(0, [make_thread(1, [make_frame("a.py", 1, "f")])])
1050+
]
1051+
bad = [
1052+
make_interpreter(2**32, [make_thread(1, [make_frame("a.py", 1, "f")])])
1053+
]
1054+
1055+
writer = _remote_debugging.BinaryWriter(filename, 1000, 0, compression=0)
1056+
writer.write_sample(good, 1000)
1057+
with self.assertRaises(OverflowError):
1058+
writer.write_sample(bad, 2000)
1059+
writer.write_sample(good, 3000)
1060+
writer.finalize()
1061+
self.assertEqual(writer.total_samples, 2)
1062+
1063+
reader_collector = RawCollector()
1064+
with BinaryReader(filename) as reader:
1065+
self.assertEqual(reader.replay_samples(reader_collector), 2)
1066+
9971067

9981068
class TestBinaryFormatValidation(BinaryFormatTestBase):
9991069
"""Tests for malformed binary files."""

0 commit comments

Comments
 (0)