Skip to content

Commit 5ae4052

Browse files
committed
test: simplify and test --save-signal handling
optparse catches the problem of an incorrect signal name, we don't need to. test: a test for --save-signal test: Rename send signal test functons Signed-off-by: Arkady Gilinsky <[email protected]>
1 parent ca87161 commit 5ae4052

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

coverage/cmdline.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ def do_help(
822822

823823
def do_signal_save(self, _signum: int, _frame: types.FrameType | None) -> None:
824824
""" Signal handler to save coverage report """
825-
print("Saving coverage data ...")
825+
print("Saving coverage data ...", flush=True)
826826
self.coverage.save()
827827

828828
def do_run(self, options: optparse.Values, args: list[str]) -> int:
@@ -871,15 +871,10 @@ def do_run(self, options: optparse.Values, args: list[str]) -> int:
871871

872872
if options.save_signal:
873873
if env.WINDOWS:
874-
show_help("Signals are not supported in Windows environment.")
875-
return ERR
876-
if options.save_signal.upper() == 'USR1':
877-
signal.signal(signal.SIGUSR1, self.do_signal_save)
878-
elif options.save_signal.upper() == 'USR2':
879-
signal.signal(signal.SIGUSR2, self.do_signal_save)
880-
else:
881-
show_help(f"Unsupported signal for save coverage report: {options.save_signal}")
874+
show_help("--save-signal is not supported on Windows.")
882875
return ERR
876+
sig = getattr(signal, f"SIG{options.save_signal}")
877+
signal.signal(sig, self.do_signal_save)
883878

884879
# Run the script.
885880
self.coverage.start()

tests/helpers.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import os
1414
import os.path
1515
import re
16+
import shlex
1617
import shutil
1718
import subprocess
1819
import sys
@@ -47,7 +48,7 @@ def _correct_encoding() -> str:
4748
return encoding
4849

4950

50-
def subprocess_popen(cmd: str) -> subprocess.Popen[bytes]:
51+
def subprocess_popen(cmd: str, shell: bool=True) -> subprocess.Popen[bytes]:
5152
"""Run a command in a subprocess.
5253
5354
Returns the Popen object.
@@ -66,9 +67,12 @@ def subprocess_popen(cmd: str) -> subprocess.Popen[bytes]:
6667
sub_env = dict(os.environ)
6768
sub_env["PYTHONIOENCODING"] = _correct_encoding()
6869

70+
if not shell:
71+
cmd = shlex.split(cmd) # type: ignore[assignment]
72+
6973
proc = subprocess.Popen(
7074
cmd,
71-
shell=True,
75+
shell=shell,
7276
env=sub_env,
7377
stdin=subprocess.PIPE,
7478
stdout=subprocess.PIPE,

tests/test_cmdline.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import coverage
2222
import coverage.cmdline
23+
from coverage import env
2324
from coverage.control import DEFAULT_DATAFILE
2425
from coverage.config import CoverageConfig
2526
from coverage.exceptions import _ExceptionDuringRun
@@ -942,6 +943,19 @@ def test_no_arguments_at_all(self) -> None:
942943
def test_bad_command(self) -> None:
943944
self.cmd_help("xyzzy", "Unknown command: 'xyzzy'")
944945

946+
def test_save_signal_wrong(self) -> None:
947+
self.cmd_help(
948+
"run --save-signal=XYZ nothing.py",
949+
"option --save-signal: invalid choice: 'XYZ' (choose from 'USR1', 'USR2')",
950+
)
951+
952+
@pytest.mark.skipif(not env.WINDOWS, reason="this is a windows-only error")
953+
def test_save_signal_windows(self) -> None:
954+
self.cmd_help(
955+
"run --save-signal=USR1 nothing.py",
956+
"--save-signal is not supported on Windows.",
957+
)
958+
945959

946960
class CmdLineWithFilesTest(BaseCmdLineTest):
947961
"""Test the command line in ways that need temp files."""

tests/test_process.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import os.path
1212
import platform
1313
import re
14+
import signal
1415
import stat
1516
import sys
1617
import textwrap
18+
import time
1719

1820
from pathlib import Path
1921
from typing import Any
@@ -27,7 +29,7 @@
2729

2830
from tests import testenv
2931
from tests.coveragetest import CoverageTest, TESTS_DIR
30-
from tests.helpers import re_line, re_lines, re_lines_text
32+
from tests.helpers import re_line, re_lines, re_lines_text, subprocess_popen
3133

3234

3335
class ProcessTest(CoverageTest):
@@ -456,6 +458,33 @@ def test_os_exit(self, patch: bool) -> None:
456458
else:
457459
assert seen < total_lines
458460

461+
@pytest.mark.skipif(env.WINDOWS, reason="Windows can't do --save-signal")
462+
@pytest.mark.parametrize("send", [False, True])
463+
def test_save_signal(self, send: bool) -> None:
464+
# PyPy on Ubuntu seems to need more time for things to happen.
465+
base_time = 0.75 if (env.PYPY and env.LINUX) else 0.0
466+
self.make_file("loop.py", """\
467+
import time
468+
print("Starting", flush=True)
469+
while True:
470+
time.sleep(.02)
471+
""")
472+
proc = subprocess_popen("coverage run --save-signal=USR1 loop.py", shell=False)
473+
time.sleep(base_time + .25)
474+
if send:
475+
proc.send_signal(signal.SIGUSR1)
476+
time.sleep(base_time + .25)
477+
proc.kill()
478+
proc.wait(timeout=base_time + .25)
479+
stdout, _ = proc.communicate()
480+
assert b"Starting" in stdout
481+
if send:
482+
self.assert_exists(".coverage")
483+
assert b"Saving coverage data" in stdout
484+
else:
485+
self.assert_doesnt_exist(".coverage")
486+
assert b"Saving coverage data" not in stdout
487+
459488
def test_warnings_during_reporting(self) -> None:
460489
# While fixing issue #224, the warnings were being printed far too
461490
# often. Make sure they're not any more.
@@ -688,7 +717,7 @@ def test_module_name(self) -> None:
688717
assert "Use 'coverage help' for help" in out
689718

690719
@pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows")
691-
def test_save_signal(self) -> None:
720+
def test_save_signal_usr1(self) -> None:
692721
test_file = "dummy_hello.py"
693722
self.assert_doesnt_exist(".coverage")
694723
self.make_file(test_file, """\

0 commit comments

Comments
 (0)