Skip to content

Commit

Permalink
Fix reporting exit due to (real) signal
Browse files Browse the repository at this point in the history
`subprocess` reports a negative exit code for signals.

Still handle "128 + X" for processes indicating that they received a
signal themselves.
  • Loading branch information
blueyed committed Aug 20, 2019
1 parent 2e2855a commit 3cf4adc
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/changelog/1401.bugfix.rst
@@ -0,0 +1 @@
fix reporting of exiting due to (real) signals - by :user:`blueyed`
24 changes: 15 additions & 9 deletions src/tox/exception.py
Expand Up @@ -17,18 +17,24 @@ def exit_code_str(exception_name, command, exit_code):
"""
str_ = "{} for command {}".format(exception_name, command)
if exit_code is not None:
str_ += " (exited with code {:d})".format(exit_code)
if (os.name == "posix") and (exit_code > 128):
if (exit_code < 0 or (os.name == "posix" and exit_code > 128)):
signals = {
number: name for name, number in vars(signal).items() if name.startswith("SIG")
}
number = exit_code - 128
name = signals.get(number)
if name:
str_ += (
"\nNote: this might indicate a fatal error signal "
"({:d} - 128 = {:d}: {})".format(number + 128, number, name)
)
if exit_code < 0:
# Signal reported via subprocess.Popen.
sig_name = signals.get(-exit_code)
str_ += " (exited with code {:d} ({}))".format(exit_code, sig_name)
else:
str_ += " (exited with code {:d})".format(exit_code)
number = exit_code - 128
name = signals.get(number)
if name:
str_ += (
")\nNote: this might indicate a fatal error signal "
"({:d} - 128 = {:d}: {})".format(exit_code, number, name)
)
str_ += " (exited with code {:d})".format(exit_code)
return str_


Expand Down
4 changes: 3 additions & 1 deletion tests/unit/test_result.py
Expand Up @@ -72,7 +72,7 @@ def test_get_commandlog(pkg):
assert setuplog2.list == setuplog.list


@pytest.mark.parametrize("exit_code", [None, 0, 5, 128 + signal.SIGTERM, 1234])
@pytest.mark.parametrize("exit_code", [None, 0, 5, 128 + signal.SIGTERM, 1234, -15])
@pytest.mark.parametrize("os_name", ["posix", "nt"])
def test_invocation_error(exit_code, os_name, mocker, monkeypatch):
monkeypatch.setattr(os, "name", value=os_name)
Expand All @@ -85,6 +85,8 @@ def test_invocation_error(exit_code, os_name, mocker, monkeypatch):
assert call_args == mocker.call("InvocationError", "<command>", exit_code)
if exit_code is None:
assert "(exited with code" not in result
elif exit_code is -15:
assert "(exited with code -15 (SIGTERM))" in result
else:
assert "(exited with code %d)" % exit_code in result
note = "Note: this might indicate a fatal error signal"
Expand Down

0 comments on commit 3cf4adc

Please sign in to comment.