Skip to content

Commit 11222ec

Browse files
committed
refactor: run_command now asserts about the exit status
1 parent 576c5eb commit 11222ec

File tree

3 files changed

+26
-25
lines changed

3 files changed

+26
-25
lines changed

tests/coveragetest.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,21 +401,24 @@ def command_line(self, args: str, ret: int = OK) -> None:
401401
# https://salsa.debian.org/debian/pkg-python-coverage/-/blob/master/debian/patches/02.rename-public-programs.patch
402402
coverage_command = "coverage"
403403

404-
def run_command(self, cmd: str) -> str:
404+
def run_command(self, cmd: str, *, status: int = 0) -> str:
405405
"""Run the command-line `cmd` in a subprocess.
406406
407407
`cmd` is the command line to invoke in a subprocess. Returns the
408408
combined content of `stdout` and `stderr` output streams from the
409409
subprocess.
410410
411+
Asserts that the exit status is `status` (default 0).
412+
411413
See `run_command_status` for complete semantics.
412414
413415
Use this when you need to test the process behavior of coverage.
414416
415417
Compare with `command_line`.
416418
417419
"""
418-
_, output = self.run_command_status(cmd)
420+
actual_status, output = self.run_command_status(cmd)
421+
assert actual_status == status
419422
return output
420423

421424
def run_command_status(self, cmd: str) -> tuple[int, str]:

tests/test_concurrency.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def try_some_code(
222222
self.make_file("try_it.py", code)
223223

224224
cmd = f"coverage run --concurrency={concurrency} try_it.py"
225-
out = self.run_command(cmd)
225+
_, out = self.run_command_status(cmd)
226226

227227
expected_cant_trace = cant_trace_msg(concurrency, the_module)
228228

@@ -342,7 +342,7 @@ def gwork(q):
342342
answer = q.get()
343343
assert answer == 1
344344
""")
345-
out = self.run_command("coverage run --concurrency=thread,gevent both.py")
345+
_, out = self.run_command_status("coverage run --concurrency=thread,gevent both.py")
346346
if gevent is None:
347347
assert out == (
348348
"Couldn't trace with concurrency=gevent, the module isn't installed.\n"
@@ -475,7 +475,7 @@ def try_multiprocessing_code(
475475
""")
476476

477477
cmd = f"coverage run {args} multi.py {start_method}"
478-
out = self.run_command(cmd)
478+
_, out = self.run_command_status(cmd)
479479
expected_cant_trace = cant_trace_msg(concurrency, the_module)
480480

481481
if expected_cant_trace is not None:
@@ -591,7 +591,7 @@ def test_multiprocessing_bootstrap_error_handling(self) -> None:
591591
concurrency = multiprocessing
592592
_crash = _bootstrap
593593
""")
594-
out = self.run_command("coverage run multi.py")
594+
out = self.run_command("coverage run multi.py", status=1)
595595
assert "Exception during multiprocessing bootstrap init" in out
596596
assert "RuntimeError: Crashing because called by _bootstrap" in out
597597

@@ -770,7 +770,8 @@ def test_sigterm_threading_saves_data(self) -> None:
770770
concurrency = thread
771771
sigterm = true
772772
""")
773-
out = self.run_command("coverage run handler.py")
773+
status, out = self.run_command_status("coverage run handler.py")
774+
assert status != 0
774775
out_lines = out.splitlines()
775776
assert len(out_lines) in [2, 3]
776777
assert out_lines[:2] == ["START", "SIGTERM"]

tests/test_process.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def test_missing_source_file(self) -> None:
270270

271271
self.run_command("coverage run fleeting.py")
272272
os.remove("fleeting.py")
273-
out = self.run_command("coverage html -d htmlcov")
273+
out = self.run_command("coverage html -d htmlcov", status=1)
274274
assert re.search("No source for code: '.*fleeting.py'", out)
275275
assert "Traceback" not in out
276276

@@ -282,10 +282,9 @@ def test_missing_source_file(self) -> None:
282282

283283
self.run_command("coverage run fleeting")
284284
os.remove("fleeting")
285-
status, out = self.run_command_status("coverage html -d htmlcov")
285+
out = self.run_command("coverage html -d htmlcov", status=1)
286286
assert re.search("No source for code: '.*fleeting'", out)
287287
assert "Traceback" not in out
288-
assert status == 1
289288

290289
def test_running_missing_file(self) -> None:
291290
status, out = self.run_command_status("coverage run xyzzy.py")
@@ -310,8 +309,8 @@ def f2():
310309

311310
# The important thing is for "coverage run" and "python" to report the
312311
# same traceback.
313-
status, out = self.run_command_status("coverage run throw.py")
314-
out2 = self.run_command("python throw.py")
312+
out = self.run_command("coverage run throw.py", status=1)
313+
out2 = self.run_command("python throw.py", status=1)
315314
if env.PYPY:
316315
# PyPy has an extra frame in the traceback for some reason
317316
out2 = re_lines_text("toplevel", out2, match=False)
@@ -322,7 +321,6 @@ def f2():
322321
msg = f'File "{re.escape(path)}", line 8, in f2'
323322
assert re.search(msg, out)
324323
assert 'raise MyException("hey!")' in out
325-
assert status == 1
326324

327325
def test_code_exits(self) -> None:
328326
self.make_file("exit.py", """\
@@ -483,13 +481,13 @@ def test_warns_if_never_run(self) -> None:
483481
# Note: the name of the function can't have "warning" in it, or the
484482
# absolute path of the file will have "warning" in it, and an assertion
485483
# will fail.
486-
out = self.run_command("coverage run i_dont_exist.py")
484+
out = self.run_command("coverage run i_dont_exist.py", status=1)
487485
path = python_reported_file('i_dont_exist.py')
488486
assert f"No file to run: '{path}'" in out
489487
assert "warning" not in out
490488
assert "Exception" not in out
491489

492-
out = self.run_command("coverage run -m no_such_module")
490+
out = self.run_command("coverage run -m no_such_module", status=1)
493491
assert (
494492
("No module named no_such_module" in out) or
495493
("No module named 'no_such_module'" in out)
@@ -873,8 +871,8 @@ def test_pythonsafepath_dashm(self) -> None:
873871
self.make_file("with_main/__main__.py", f.read())
874872

875873
self.set_environ("PYTHONSAFEPATH", "1")
876-
expected = self.run_command("python -m with_main")
877-
actual = self.run_command("coverage run -m with_main")
874+
expected = self.run_command("python -m with_main", status=1)
875+
actual = self.run_command("coverage run -m with_main", status=1)
878876
assert re.search("No module named '?with_main'?", actual)
879877
assert re.search("No module named '?with_main'?", expected)
880878

@@ -1039,10 +1037,8 @@ def excepthook(*args):
10391037
10401038
raise RuntimeError('Error Outside')
10411039
""")
1042-
cov_st, cov_out = self.run_command_status("coverage run excepthook_throw.py")
1043-
py_st, py_out = self.run_command_status("python excepthook_throw.py")
1044-
assert cov_st == py_st
1045-
assert cov_st == 1
1040+
cov_out = self.run_command("coverage run excepthook_throw.py", status=1)
1041+
py_out = self.run_command("python excepthook_throw.py", status=1)
10461042
assert "in excepthook" in py_out
10471043
assert cov_out == py_out
10481044

@@ -1062,8 +1058,9 @@ def test_wrong_alias_doesnt_work(self) -> None:
10621058
# "coverage2" doesn't work on py3
10631059
assert sys.version_info[0] == 3 # Let us know when Python 4 is out...
10641060
badcmd = "coverage2"
1065-
out = self.run_command(badcmd)
1061+
status, out = self.run_command_status(badcmd)
10661062
assert "Code coverage for Python" not in out
1063+
assert status != 0
10671064

10681065
def test_specific_alias_works(self) -> None:
10691066
# "coverage-3.9" works on py3.9
@@ -1077,7 +1074,7 @@ def test_specific_alias_works(self) -> None:
10771074
"coverage-%d.%d" % sys.version_info[:2],
10781075
])
10791076
def test_aliases_used_in_messages(self, cmd: str) -> None:
1080-
out = self.run_command(f"{cmd} foobar")
1077+
out = self.run_command(f"{cmd} foobar", status=1)
10811078
assert "Unknown command: 'foobar'" in out
10821079
assert f"Use '{cmd} help' for help" in out
10831080

@@ -1228,7 +1225,7 @@ def test_core_request_sysmon(self) -> None:
12281225
def test_core_request_nosuchcore(self) -> None:
12291226
self.set_environ("COVERAGE_CORE", "nosuchcore")
12301227
self.make_file("numbers.py", "print(123, 456)")
1231-
out = self.run_command("coverage run numbers.py")
1228+
out = self.run_command("coverage run numbers.py", status=1)
12321229
assert "Unknown core value: 'nosuchcore'\n" in out
12331230
assert "123 456" not in out
12341231

@@ -1276,7 +1273,7 @@ def test_removing_directory(self) -> None:
12761273

12771274
def test_removing_directory_with_error(self) -> None:
12781275
self.make_file("bug806.py", self.BUG_806)
1279-
out = self.run_command("coverage run bug806.py")
1276+
out = self.run_command("coverage run bug806.py", status=1)
12801277
path = python_reported_file('bug806.py')
12811278
# Python 3.11 adds an extra line to the traceback.
12821279
# Check that the lines we expect are there.

0 commit comments

Comments
 (0)