public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting
@ 2026-02-23 20:26 Jakub Kicinski
  2026-02-23 20:26 ` [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures Jakub Kicinski
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Jakub Kicinski @ 2026-02-23 20:26 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, shuah, petrm, gal,
	leitao, linux-kselftest, Jakub Kicinski

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.

Jakub Kicinski (3):
  selftests: net: py: avoid masking exceptions in bkg() failures
  selftests: net: py: use repr(cmd) for failure exceptions
  selftests: net: py: add cmd info for ksft_wait failure

 tools/testing/selftests/net/lib/py/utils.py | 44 +++++++++++++++------
 1 file changed, 31 insertions(+), 13 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures
  2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
@ 2026-02-23 20:26 ` Jakub Kicinski
  2026-02-24 13:28   ` Petr Machata
  2026-02-23 20:26 ` [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions Jakub Kicinski
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2026-02-23 20:26 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, shuah, petrm, gal,
	leitao, linux-kselftest, Jakub Kicinski

bkg() failures are currently quite hard to debug and spot.
Often we have code along the lines of:

  with bkg("./cmd_rx_something -p PORT"):
       wait_port_listen(PORT)
       cmd("./cmd_tx_something", host=remote)

When wait_port_listen() fails we don't get to see the exit status
of bkg(). Even tho very often it's a failure in the bkg() command
that's actually to blame. Try not to interfere with the bkg()
command error checking.

With:

   with bkg("false", exit_wait=True):
        time.sleep(0.01)  # let the 'false' cmd run
        raise Exception("bla")

Before:

  .. stack trace ..
  # Exception| Exception: bla

After:

  .. stack trace ..
  # Exception| Exception: bla
  # Exception|
  # Exception| During handling of the above exception, another exception occurred:
  .. stack trace ..
  # Exception| lib.py.utils.CmdExitFailure: Command failed: false
  # Exception| STDOUT: b''
  # Exception| STDERR: b''

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/net/lib/py/utils.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 85884f3e827b..8fa1c2fabfc2 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -159,8 +159,11 @@ import time
         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)
 
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions
  2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
  2026-02-23 20:26 ` [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures Jakub Kicinski
@ 2026-02-23 20:26 ` Jakub Kicinski
  2026-02-24 13:03   ` Petr Machata
  2026-02-23 20:26 ` [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure Jakub Kicinski
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2026-02-23 20:26 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, shuah, petrm, gal,
	leitao, linux-kselftest, Jakub Kicinski

Reuse repr(cmd) instead of manually formatting a similar string.

Before:
  # Exception| lib.py.utils.CmdExitFailure: Command failed: false
  # Exception| STDOUT: b''
  # Exception| STDERR: b''

After:
  # Exception| lib.py.utils.CmdExitFailure: Command failed
  # Exception| CMD: false
  # Exception|   EXIT: 1

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/net/lib/py/utils.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 8fa1c2fabfc2..52d98ca139ff 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -11,7 +11,7 @@ import time
 
 class CmdExitFailure(Exception):
     def __init__(self, msg, cmd_obj):
-        super().__init__(msg)
+        super().__init__(msg + "\n" + repr(cmd_obj))
         self.cmd = cmd_obj
 
 
@@ -98,8 +98,7 @@ import time
         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):
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure
  2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
  2026-02-23 20:26 ` [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures Jakub Kicinski
  2026-02-23 20:26 ` [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions Jakub Kicinski
@ 2026-02-23 20:26 ` Jakub Kicinski
  2026-02-24 13:05   ` Petr Machata
  2026-02-24 11:12 ` [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Simon Horman
  2026-02-25  4:09 ` patchwork-bot+netdevbpf
  4 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2026-02-23 20:26 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, shuah, petrm, gal,
	leitao, linux-kselftest, Jakub Kicinski

Gal recently complained:

  When [ksft_wait failure] happens, the test fails with a cryptic
  message:
    # Exception| Exception: Did not receive ready message

Let's try to include the stdout/stderr of the command we tried
to start. E.g. for cmd("false", ksft_wait=True):

    # Exception| lib.py.utils.CmdInitFailure: Did not receive ready message
    # Exception| CMD: false
    # Exception|   EXIT: 1

We need to factor out _process_terminate() otherwise the exit
path may try to write to already disconnected self.ksft_term_fd.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/net/lib/py/utils.py | 30 ++++++++++++++++-----
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 52d98ca139ff..09535346c13d 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -9,7 +9,15 @@ import subprocess
 import time
 
 
+class CmdInitFailure(Exception):
+    """ Command failed to start. Only raised by bkg(). """
+    def __init__(self, msg, cmd_obj):
+        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 @@ import time
                 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,6 +100,17 @@ import time
         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]
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting
  2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
                   ` (2 preceding siblings ...)
  2026-02-23 20:26 ` [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure Jakub Kicinski
@ 2026-02-24 11:12 ` Simon Horman
  2026-02-25  4:09 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 9+ messages in thread
From: Simon Horman @ 2026-02-24 11:12 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, shuah, petrm, gal,
	leitao, linux-kselftest

On Mon, Feb 23, 2026 at 12:26:30PM -0800, Jakub Kicinski wrote:
> 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.
> 
> Jakub Kicinski (3):
>   selftests: net: py: avoid masking exceptions in bkg() failures
>   selftests: net: py: use repr(cmd) for failure exceptions
>   selftests: net: py: add cmd info for ksft_wait failure
> 
>  tools/testing/selftests/net/lib/py/utils.py | 44 +++++++++++++++------
>  1 file changed, 31 insertions(+), 13 deletions(-)

For the series,

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions
  2026-02-23 20:26 ` [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions Jakub Kicinski
@ 2026-02-24 13:03   ` Petr Machata
  0 siblings, 0 replies; 9+ messages in thread
From: Petr Machata @ 2026-02-24 13:03 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, shuah,
	petrm, gal, leitao, linux-kselftest


Jakub Kicinski <kuba@kernel.org> writes:

> Reuse repr(cmd) instead of manually formatting a similar string.
>
> Before:
>   # Exception| lib.py.utils.CmdExitFailure: Command failed: false
>   # Exception| STDOUT: b''
>   # Exception| STDERR: b''
>
> After:
>   # Exception| lib.py.utils.CmdExitFailure: Command failed
>   # Exception| CMD: false
>   # Exception|   EXIT: 1

(This seemingly omits STDOUT and STDERR, but cmd.__repr__ includes these
if they are truthy.)

> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Petr Machata <petrm@nvidia.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure
  2026-02-23 20:26 ` [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure Jakub Kicinski
@ 2026-02-24 13:05   ` Petr Machata
  0 siblings, 0 replies; 9+ messages in thread
From: Petr Machata @ 2026-02-24 13:05 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, shuah,
	petrm, gal, leitao, linux-kselftest


Jakub Kicinski <kuba@kernel.org> writes:

> Gal recently complained:
>
>   When [ksft_wait failure] happens, the test fails with a cryptic
>   message:
>     # Exception| Exception: Did not receive ready message
>
> Let's try to include the stdout/stderr of the command we tried
> to start. E.g. for cmd("false", ksft_wait=True):
>
>     # Exception| lib.py.utils.CmdInitFailure: Did not receive ready message
>     # Exception| CMD: false
>     # Exception|   EXIT: 1
>
> We need to factor out _process_terminate() otherwise the exit
> path may try to write to already disconnected self.ksft_term_fd.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Petr Machata <petrm@nvidia.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures
  2026-02-23 20:26 ` [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures Jakub Kicinski
@ 2026-02-24 13:28   ` Petr Machata
  0 siblings, 0 replies; 9+ messages in thread
From: Petr Machata @ 2026-02-24 13:28 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, shuah,
	petrm, gal, leitao, linux-kselftest


Jakub Kicinski <kuba@kernel.org> writes:

> bkg() failures are currently quite hard to debug and spot.
> Often we have code along the lines of:
>
>   with bkg("./cmd_rx_something -p PORT"):
>        wait_port_listen(PORT)
>        cmd("./cmd_tx_something", host=remote)
>
> When wait_port_listen() fails we don't get to see the exit status
> of bkg(). Even tho very often it's a failure in the bkg() command
> that's actually to blame. Try not to interfere with the bkg()
> command error checking.
>
> With:
>
>    with bkg("false", exit_wait=True):
>         time.sleep(0.01)  # let the 'false' cmd run
>         raise Exception("bla")
>
> Before:
>
>   .. stack trace ..
>   # Exception| Exception: bla
>
> After:
>
>   .. stack trace ..
>   # Exception| Exception: bla
>   # Exception|
>   # Exception| During handling of the above exception, another exception occurred:
>   .. stack trace ..
>   # Exception| lib.py.utils.CmdExitFailure: Command failed: false
>   # Exception| STDOUT: b''
>   # Exception| STDERR: b''
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Petr Machata <petrm@nvidia.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting
  2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
                   ` (3 preceding siblings ...)
  2026-02-24 11:12 ` [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Simon Horman
@ 2026-02-25  4:09 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-02-25  4:09 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, shuah,
	petrm, gal, leitao, linux-kselftest

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 23 Feb 2026 12:26:30 -0800 you wrote:
> 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.
> 
> Jakub Kicinski (3):
>   selftests: net: py: avoid masking exceptions in bkg() failures
>   selftests: net: py: use repr(cmd) for failure exceptions
>   selftests: net: py: add cmd info for ksft_wait failure
> 
> [...]

Here is the summary with links:
  - [net-next,1/3] selftests: net: py: avoid masking exceptions in bkg() failures
    https://git.kernel.org/netdev/net-next/c/d99aa5912c3a
  - [net-next,2/3] selftests: net: py: use repr(cmd) for failure exceptions
    https://git.kernel.org/netdev/net-next/c/04abab18e120
  - [net-next,3/3] selftests: net: py: add cmd info for ksft_wait failure
    https://git.kernel.org/netdev/net-next/c/6e4dff20021a

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-02-25  4:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-23 20:26 [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Jakub Kicinski
2026-02-23 20:26 ` [PATCH net-next 1/3] selftests: net: py: avoid masking exceptions in bkg() failures Jakub Kicinski
2026-02-24 13:28   ` Petr Machata
2026-02-23 20:26 ` [PATCH net-next 2/3] selftests: net: py: use repr(cmd) for failure exceptions Jakub Kicinski
2026-02-24 13:03   ` Petr Machata
2026-02-23 20:26 ` [PATCH net-next 3/3] selftests: net: py: add cmd info for ksft_wait failure Jakub Kicinski
2026-02-24 13:05   ` Petr Machata
2026-02-24 11:12 ` [PATCH net-next 0/3] selftests: net: py: improve bkg() error reporting Simon Horman
2026-02-25  4:09 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox