mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
Merge branch 'selftests-net-py-improve-bkg-error-reporting'
Jakub Kicinski says: ==================== selftests: net: py: improve bkg() error reporting bkg() is a helper for running commands in the background. When init or body of a with() block fails check if the bkg() process already exited and report its status (including stdout/ /stderr). This significantly improves debugability. ==================== Link: https://patch.msgid.link/20260223202633.4126087-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
7235555e9a
|
|
@ -9,9 +9,17 @@ import subprocess
|
|||
import time
|
||||
|
||||
|
||||
class CmdExitFailure(Exception):
|
||||
class CmdInitFailure(Exception):
|
||||
""" Command failed to start. Only raised by bkg(). """
|
||||
def __init__(self, msg, cmd_obj):
|
||||
super().__init__(msg)
|
||||
super().__init__(msg + "\n" + repr(cmd_obj))
|
||||
self.cmd = cmd_obj
|
||||
|
||||
|
||||
class CmdExitFailure(Exception):
|
||||
""" Command failed (returned non-zero exit code). """
|
||||
def __init__(self, msg, cmd_obj):
|
||||
super().__init__(msg + "\n" + repr(cmd_obj))
|
||||
self.cmd = cmd_obj
|
||||
|
||||
|
||||
|
|
@ -76,16 +84,13 @@ class cmd:
|
|||
msg = fd_read_timeout(rfd, ksft_wait)
|
||||
os.close(rfd)
|
||||
if not msg:
|
||||
raise Exception("Did not receive ready message")
|
||||
terminate = self.proc.poll() is None
|
||||
self._process_terminate(terminate=terminate, timeout=1)
|
||||
raise CmdInitFailure("Did not receive ready message", self)
|
||||
if not background:
|
||||
self.process(terminate=False, fail=fail, timeout=timeout)
|
||||
|
||||
def process(self, terminate=True, fail=None, timeout=5):
|
||||
if fail is None:
|
||||
fail = not terminate
|
||||
|
||||
if self.ksft_term_fd:
|
||||
os.write(self.ksft_term_fd, b"1")
|
||||
def _process_terminate(self, terminate, timeout):
|
||||
if terminate:
|
||||
self.proc.terminate()
|
||||
stdout, stderr = self.proc.communicate(timeout)
|
||||
|
|
@ -95,11 +100,21 @@ class cmd:
|
|||
self.proc.stderr.close()
|
||||
self.ret = self.proc.returncode
|
||||
|
||||
return stdout, stderr
|
||||
|
||||
def process(self, terminate=True, fail=None, timeout=5):
|
||||
if fail is None:
|
||||
fail = not terminate
|
||||
|
||||
if self.ksft_term_fd:
|
||||
os.write(self.ksft_term_fd, b"1")
|
||||
|
||||
stdout, stderr = self._process_terminate(terminate=terminate,
|
||||
timeout=timeout)
|
||||
if self.proc.returncode != 0 and fail:
|
||||
if len(stderr) > 0 and stderr[-1] == "\n":
|
||||
stderr = stderr[:-1]
|
||||
raise CmdExitFailure("Command failed: %s\nSTDOUT: %s\nSTDERR: %s" %
|
||||
(self.proc.args, stdout, stderr), self)
|
||||
raise CmdExitFailure("Command failed", self)
|
||||
|
||||
def __repr__(self):
|
||||
def str_fmt(name, s):
|
||||
|
|
@ -159,8 +174,11 @@ class bkg(cmd):
|
|||
return self
|
||||
|
||||
def __exit__(self, ex_type, ex_value, ex_tb):
|
||||
# Force termination on exception
|
||||
terminate = self.terminate or (self._exit_wait and ex_type is not None)
|
||||
terminate = self.terminate
|
||||
# Force termination on exception, but only if bkg() didn't already exit
|
||||
# since forcing termination silences failures with fail=None
|
||||
if self.proc.poll() is None:
|
||||
terminate = terminate or (self._exit_wait and ex_type is not None)
|
||||
return self.process(terminate=terminate, fail=self.check_fail)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user