Skip to content

Commit d7d5e87

Browse files
committed
only run the tests if curses is enabled
1 parent 0af647c commit d7d5e87

File tree

2 files changed

+76
-76
lines changed

2 files changed

+76
-76
lines changed

Lib/test/test_profiling/test_sampling_profiler/test_cli.py

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
"""Tests for sampling profiler CLI argument parsing and functionality."""
22

3-
import functools
43
import io
54
import subprocess
65
import sys
76
import unittest
87
from unittest import mock
9-
import tempfile
108

119
try:
1210
import _remote_debugging # noqa: F401
@@ -19,8 +17,6 @@
1917

2018
from profiling.sampling.cli import main
2119
from profiling.sampling.errors import SamplingScriptNotFoundError, SamplingModuleNotFoundError, SamplingUnknownProcessError
22-
from profiling.sampling.live_collector import MockDisplay
23-
2420

2521
class TestSampleProfilerCLI(unittest.TestCase):
2622
def _setup_sync_mocks(self, mock_socket, mock_popen):
@@ -725,74 +721,3 @@ def test_cli_attach_nonexistent_pid(self):
725721
main()
726722

727723
self.assertIn(fake_pid, str(cm.exception))
728-
729-
730-
class TestLiveModeErrors(unittest.TestCase):
731-
"""Tests running error commands in the live mode fails gracefully."""
732-
733-
def mock_curses_wrapper(self, func):
734-
func(mock.MagicMock())
735-
736-
def mock_init_curses_side_effect(self, n_times, mock_self, stdscr):
737-
mock_self.display = MockDisplay()
738-
# Allow the loop to run for a bit (approx 0.5s) before quitting
739-
# This ensures we don't exit too early while the subprocess is
740-
# still failing
741-
for _ in range(n_times):
742-
mock_self.display.simulate_input(-1)
743-
if n_times >= 500:
744-
mock_self.display.simulate_input(ord('q'))
745-
746-
@unittest.skipIf(is_emscripten, "subprocess not available")
747-
def test_run_failed_module_live(self):
748-
"""Test that running a existing module that fails exists with clean error."""
749-
750-
args = [
751-
"profiling.sampling.cli", "run", "--live", "-m", "test",
752-
"test_asdasd"
753-
]
754-
755-
with (
756-
mock.patch(
757-
'profiling.sampling.live_collector.collector.LiveStatsCollector.init_curses',
758-
autospec=True,
759-
side_effect=functools.partial(self.mock_init_curses_side_effect, 1000)
760-
),
761-
mock.patch('curses.wrapper', side_effect=self.mock_curses_wrapper),
762-
mock.patch("sys.argv", args),
763-
mock.patch('sys.stderr', new=io.StringIO()) as fake_stderr
764-
):
765-
main()
766-
self.assertStartsWith(
767-
fake_stderr.getvalue(),
768-
'\x1b[31mtest test_asdasd crashed -- Traceback (most recent call last):'
769-
)
770-
771-
@unittest.skipIf(is_emscripten, "subprocess not available")
772-
def test_run_failed_script_live(self):
773-
"""Test that running a failing script exits with clean error."""
774-
script = tempfile.NamedTemporaryFile(suffix=".py")
775-
script.write(b'1/0\n')
776-
script.seek(0)
777-
778-
args = ["profiling.sampling.cli", "run", "--live", script.name]
779-
780-
with (
781-
mock.patch(
782-
'profiling.sampling.live_collector.collector.LiveStatsCollector.init_curses',
783-
autospec=True,
784-
side_effect=functools.partial(self.mock_init_curses_side_effect, 200)
785-
),
786-
mock.patch('curses.wrapper', side_effect=self.mock_curses_wrapper),
787-
mock.patch("sys.argv", args),
788-
mock.patch('sys.stderr', new=io.StringIO()) as fake_stderr
789-
):
790-
main()
791-
stderr = fake_stderr.getvalue()
792-
self.assertIn(
793-
'sample(s) collected (minimum 200 required for TUI)', stderr
794-
)
795-
self.assertEndsWith(
796-
stderr,
797-
'ZeroDivisionError\x1b[0m: \x1b[35mdivision by zero\x1b[0m\n\n'
798-
)

Lib/test/test_profiling/test_sampling_profiler/test_live_collector_ui.py

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@
44
edge cases, update display, and display helpers.
55
"""
66

7+
import functools
8+
import io
79
import sys
10+
import tempfile
811
import time
912
import unittest
1013
from unittest import mock
11-
from test.support import requires
14+
from test.support import requires, is_emscripten
1215
from test.support.import_helper import import_module
1316

1417
# Only run these tests if curses is available
1518
requires("curses")
1619
curses = import_module("curses")
1720

1821
from profiling.sampling.live_collector import LiveStatsCollector, MockDisplay
22+
from profiling.sampling.cli import main
1923
from ._live_collector_helpers import (
2024
MockThreadInfo,
2125
MockInterpreterInfo,
@@ -816,5 +820,76 @@ def test_get_all_lines_full_display(self):
816820
self.assertTrue(any("PID" in line for line in lines))
817821

818822

823+
class TestLiveModeErrors(unittest.TestCase):
824+
"""Tests running error commands in the live mode fails gracefully."""
825+
826+
def mock_curses_wrapper(self, func):
827+
func(mock.MagicMock())
828+
829+
def mock_init_curses_side_effect(self, n_times, mock_self, stdscr):
830+
mock_self.display = MockDisplay()
831+
# Allow the loop to run for a bit (approx 0.5s) before quitting
832+
# This ensures we don't exit too early while the subprocess is
833+
# still failing
834+
for _ in range(n_times):
835+
mock_self.display.simulate_input(-1)
836+
if n_times >= 500:
837+
mock_self.display.simulate_input(ord('q'))
838+
839+
@unittest.skipIf(is_emscripten, "subprocess not available")
840+
def test_run_failed_module_live(self):
841+
"""Test that running a existing module that fails exists with clean error."""
842+
843+
args = [
844+
"profiling.sampling.cli", "run", "--live", "-m", "test",
845+
"test_asdasd"
846+
]
847+
848+
with (
849+
mock.patch(
850+
'profiling.sampling.live_collector.collector.LiveStatsCollector.init_curses',
851+
autospec=True,
852+
side_effect=functools.partial(self.mock_init_curses_side_effect, 1000)
853+
),
854+
mock.patch('curses.wrapper', side_effect=self.mock_curses_wrapper),
855+
mock.patch("sys.argv", args),
856+
mock.patch('sys.stderr', new=io.StringIO()) as fake_stderr
857+
):
858+
main()
859+
self.assertStartsWith(
860+
fake_stderr.getvalue(),
861+
'\x1b[31mtest test_asdasd crashed -- Traceback (most recent call last):'
862+
)
863+
864+
@unittest.skipIf(is_emscripten, "subprocess not available")
865+
def test_run_failed_script_live(self):
866+
"""Test that running a failing script exits with clean error."""
867+
script = tempfile.NamedTemporaryFile(suffix=".py")
868+
script.write(b'1/0\n')
869+
script.seek(0)
870+
871+
args = ["profiling.sampling.cli", "run", "--live", script.name]
872+
873+
with (
874+
mock.patch(
875+
'profiling.sampling.live_collector.collector.LiveStatsCollector.init_curses',
876+
autospec=True,
877+
side_effect=functools.partial(self.mock_init_curses_side_effect, 200)
878+
),
879+
mock.patch('curses.wrapper', side_effect=self.mock_curses_wrapper),
880+
mock.patch("sys.argv", args),
881+
mock.patch('sys.stderr', new=io.StringIO()) as fake_stderr
882+
):
883+
main()
884+
stderr = fake_stderr.getvalue()
885+
self.assertIn(
886+
'sample(s) collected (minimum 200 required for TUI)', stderr
887+
)
888+
self.assertEndsWith(
889+
stderr,
890+
'ZeroDivisionError\x1b[0m: \x1b[35mdivision by zero\x1b[0m\n\n'
891+
)
892+
893+
819894
if __name__ == "__main__":
820895
unittest.main()

0 commit comments

Comments
 (0)