Report stdout/stderr of failed subprocesses.

This commit is contained in:
Florian Bruhin 2015-12-18 21:23:33 +01:00
parent d3dc90cb2a
commit 5c769d8000
3 changed files with 43 additions and 0 deletions

View File

@ -84,6 +84,8 @@ Changed
- `general -> log-javascript-console` got changed from a boolean to an option - `general -> log-javascript-console` got changed from a boolean to an option
taking a loglevel (`none`, `info`, `debug`). taking a loglevel (`none`, `info`, `debug`).
- `:tab-move +/-` now wraps around if `tabs -> wrap` is `true`. - `:tab-move +/-` now wraps around if `tabs -> wrap` is `true`.
- When a subprocess (like launched by `:spawn`) fails, its stdout/stderr is now
logged to the console.
Deprecated Deprecated
~~~~~~~~~~ ~~~~~~~~~~

View File

@ -109,9 +109,18 @@ class GUIProcess(QObject):
self._what.capitalize())) self._what.capitalize()))
else: else:
assert status == QProcess.NormalExit assert status == QProcess.NormalExit
# We call this 'status' here as it makes more sense to the user -
# it's actually 'code'.
message.error(self._win_id, "{} exited with status {}.".format( message.error(self._win_id, "{} exited with status {}.".format(
self._what.capitalize(), code)) self._what.capitalize(), code))
stderr = bytes(self._proc.readAllStandardError()).decode('utf-8')
stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8')
if stdout:
log.procs.error("Process stdout:\n" + stdout.strip())
if stderr:
log.procs.error("Process stderr:\n" + stderr.strip())
@pyqtSlot() @pyqtSlot()
def on_started(self): def on_started(self):
"""Called when the process started successfully.""" """Called when the process started successfully."""

View File

@ -93,6 +93,8 @@ def test_start_env(monkeypatch, qtbot, py_proc):
argv = py_proc(""" argv = py_proc("""
import os import os
import json import json
import sys
env = dict(os.environ) env = dict(os.environ)
print(json.dumps(env)) print(json.dumps(env))
sys.exit(0) sys.exit(0)
@ -201,3 +203,33 @@ def test_exit_unsuccessful(qtbot, proc, guiprocess_message_mock, py_proc):
msg = guiprocess_message_mock.getmsg(guiprocess_message_mock.Level.error) msg = guiprocess_message_mock.getmsg(guiprocess_message_mock.Level.error)
assert msg.text == "Testprocess exited with status 1." assert msg.text == "Testprocess exited with status 1."
@pytest.mark.not_frozen
@pytest.mark.parametrize('stream', ['stdout', 'stderr'])
def test_exit_unsuccessful_output(qtbot, proc, caplog, py_proc, stream):
"""When a process fails, its output should be logged."""
with caplog.atLevel(logging.ERROR):
with qtbot.waitSignal(proc.finished, raising=True, timeout=10000):
proc.start(*py_proc("""
import sys
print("test", file=sys.{})
sys.exit(1)
""".format(stream)))
assert len(caplog.records) == 2
assert caplog.records[1].msg == 'Process {}:\ntest'.format(stream)
@pytest.mark.parametrize('stream', ['stdout', 'stderr'])
def test_exit_successful_output(qtbot, proc, py_proc, stream):
"""When a process suceeds, no output should be logged.
The test doesn't actually check the log as it'd fail because of the error
logging.
"""
with qtbot.waitSignal(proc.finished, raising=True, timeout=10000):
proc.start(*py_proc("""
import sys
print("test", file=sys.{})
sys.exit(0)
""".format(stream)))