* [PATCH v2] pytest: Show a message when sandbox crashes
@ 2021-10-08 15:15 Simon Glass
2021-10-15 11:52 ` Tom Rini
0 siblings, 1 reply; 2+ messages in thread
From: Simon Glass @ 2021-10-08 15:15 UTC (permalink / raw)
To: U-Boot Mailing List
Cc: Marek Vasut, Simon Glass, Heinrich Schuchardt, Stephen Warren
When a test hands on a real board there is no way on the console to obtain
any information about why it hung.
With sandbox we can actually find out that it died and get a signal or
exit code. Add this to make it easier to figure out what happened.
So instead of:
test/py/u_boot_spawn.py:171: in expect
c = os.read(self.fd, 1024).decode(errors='replace')
E OSError: [Errno 5] Input/output error
We get:
test/py/u_boot_spawn.py:171: in expect
c = os.read(self.fd, 1024).decode(errors='replace')
E ValueError: U-Boot exited with signal 11 (Signals.SIGSEGV)
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Fix a few test failure it causes
doc/develop/py_testing.rst | 8 ++++++
test/py/u_boot_spawn.py | 56 ++++++++++++++++++++++++++++++--------
2 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst
index 52238ca54d3..06f919609b5 100644
--- a/doc/develop/py_testing.rst
+++ b/doc/develop/py_testing.rst
@@ -103,6 +103,14 @@ will be written to `${build_dir}/test-log.html`. This is best viewed in a web
browser, but may be read directly as plain text, perhaps with the aid of the
`html2text` utility.
+If sandbox crashes (e.g. with a segfault) you will see message like this::
+
+
+ test/py/u_boot_spawn.py:171: in expect
+ c = os.read(self.fd, 1024).decode(errors='replace')
+ E ValueError: U-Boot exited with signal 11 (Signals.SIGSEGV)
+
+
Controlling output
~~~~~~~~~~~~~~~~~~
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index 6991b78cca8..e34cb217e84 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -35,6 +35,8 @@ class Spawn(object):
"""
self.waited = False
+ self.exit_code = 0
+ self.exit_info = ''
self.buf = ''
self.output = ''
self.logfile_read = None
@@ -80,25 +82,44 @@ class Spawn(object):
os.kill(self.pid, sig)
- def isalive(self):
+ def checkalive(self):
"""Determine whether the child process is still running.
- Args:
- None.
-
Returns:
- Boolean indicating whether process is alive.
+ tuple:
+ True if process is alive, else False
+ 0 if process is alive, else exit code of process
+ string describing what happened ('' or 'status/signal n')
"""
if self.waited:
- return False
+ return False, self.exit_code, self.exit_info
w = os.waitpid(self.pid, os.WNOHANG)
if w[0] == 0:
- return True
-
+ return True, 0, 'running'
+ status = w[1]
+
+ if os.WIFEXITED(status):
+ self.exit_code = os.WEXITSTATUS(status)
+ self.exit_info = 'status %d' % self.exit_code
+ elif os.WIFSIGNALED(status):
+ signum = os.WTERMSIG(status)
+ self.exit_code = -signum
+ self.exit_info = 'signal %d (%s)' % (signum, signal.Signals(signum))
self.waited = True
- return False
+ return False, self.exit_code, self.exit_info
+
+ def isalive(self):
+ """Determine whether the child process is still running.
+
+ Args:
+ None.
+
+ Returns:
+ Boolean indicating whether process is alive.
+ """
+ return self.checkalive()[0]
def send(self, data):
"""Send data to the sub-process's stdin.
@@ -168,9 +189,20 @@ class Spawn(object):
events = self.poll.poll(poll_maxwait)
if not events:
raise Timeout()
- c = os.read(self.fd, 1024).decode(errors='replace')
- if not c:
- raise EOFError()
+ try:
+ c = os.read(self.fd, 1024).decode(errors='replace')
+ except OSError as err:
+ # With sandbox, try to detect when U-Boot exits when it
+ # shouldn't and explain why. This is much more friendly than
+ # just dying with an I/O error
+ if err.errno == 5: # Input/output error
+ alive, exit_code, info = self.checkalive()
+ if alive:
+ raise
+ else:
+ raise ValueError('U-Boot exited with %s' % info)
+ else:
+ raise
if self.logfile_read:
self.logfile_read.write(c)
self.buf += c
--
2.33.0.882.g93a45727a2-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2] pytest: Show a message when sandbox crashes
2021-10-08 15:15 [PATCH v2] pytest: Show a message when sandbox crashes Simon Glass
@ 2021-10-15 11:52 ` Tom Rini
0 siblings, 0 replies; 2+ messages in thread
From: Tom Rini @ 2021-10-15 11:52 UTC (permalink / raw)
To: Simon Glass
Cc: U-Boot Mailing List, Marek Vasut, Heinrich Schuchardt, Stephen Warren
[-- Attachment #1: Type: text/plain, Size: 788 bytes --]
On Fri, Oct 08, 2021 at 09:15:23AM -0600, Simon Glass wrote:
> When a test hands on a real board there is no way on the console to obtain
> any information about why it hung.
>
> With sandbox we can actually find out that it died and get a signal or
> exit code. Add this to make it easier to figure out what happened.
>
> So instead of:
>
> test/py/u_boot_spawn.py:171: in expect
> c = os.read(self.fd, 1024).decode(errors='replace')
> E OSError: [Errno 5] Input/output error
>
> We get:
>
> test/py/u_boot_spawn.py:171: in expect
> c = os.read(self.fd, 1024).decode(errors='replace')
> E ValueError: U-Boot exited with signal 11 (Signals.SIGSEGV)
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/master, thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-10-15 11:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-08 15:15 [PATCH v2] pytest: Show a message when sandbox crashes Simon Glass
2021-10-15 11:52 ` Tom Rini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.