diff mbox

[U-Boot] test/py: support running sandbox under gdbserver

Message ID 1454627510-30981-1-git-send-email-swarren@wwwdotorg.org
State Accepted
Commit 89ab841088f5ccc78f0d501641fc99ea4d8c26f2
Delegated to: Tom Rini
Headers show

Commit Message

Stephen Warren Feb. 4, 2016, 11:11 p.m. UTC
From: Stephen Warren <swarren@nvidia.com>

Implement command--line option --gdbserver COMM, which does two things:

a) Run the sandbox process under gdbserver, using COMM as gdbserver's
   communication channel.

b) Disables all timeouts, so that if U-Boot is halted under the debugger,
   tests don't fail. If the user gives up in the middle of a debugging
   session, they can simply CTRL-C the test script to abort it.

This allows easy debugging of test failures without having to manually
re-create the failure conditions. Usage is:

Window 1:
./test/py/test.py --bd sandbox --gdbserver localhost:1234

Window 2:
gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'

When using this option, it likely makes sense to use pytest's -k option
to limit the set of tests that are executed.

Simply running U-Boot directly under gdb (rather than gdbserver) was
also considered. However, this was rejected because:

a) gdb's output would then be processed by the test script, and likely
   confuse it causing false failures.

b) pytest by default hides stdout from tests, which would prevent the
   user from interacting with gdb.

   While gdb can be told to redirect the debugee's stdio to a separate
   PTY, this would appear to leave gdb's stdio directed at the test
   scripts and the debugee's stdio directed elsewhere, which is the
   opposite of the desired effect. Perhaps some complicated PTY muxing
   and process hierarchy could invert this. However, the current scheme
   is simple to implement and use, so it doesn't seem worth complicating
   matters.

c) Using gdbserver allows arbitrary debuggers to be used, even those with
   a GUI. If the test scripts invoked the debugger themselves, they'd have
   to know how to execute arbitary applications. While the user could hide
   this all in a wrapper script, this feels like extra complication.

An interesting future idea might be a --gdb-screen option, which could
spawn both U-Boot and gdb separately, and spawn the screen into a newly
created window under screen. Similar options could be envisaged for
creating a new xterm/... too.

--gdbserver  currently only supports sandbox, and not real hardware.
That's primarily because the test hooks are responsible for all aspects of
hardware control, so there's nothing for the test scripts themselves can
do to enable gdbserver on real hardware. We might consider introducing a
separate --disable-timeouts option to support use of debuggers on real
hardware, and having --gdbserver imply that option.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
 test/py/conftest.py               |  8 ++++++++
 test/py/tests/test_sleep.py       |  7 ++++---
 test/py/u_boot_console_base.py    |  3 ++-
 test/py/u_boot_console_sandbox.py |  5 ++++-
 test/py/u_boot_spawn.py           | 12 ++++++++----
 5 files changed, 26 insertions(+), 9 deletions(-)

Comments

Simon Glass Feb. 6, 2016, 8:30 p.m. UTC | #1
Hi Stephen,

On 4 February 2016 at 16:11, Stephen Warren <swarren@wwwdotorg.org> wrote:
> From: Stephen Warren <swarren@nvidia.com>
>
> Implement command--line option --gdbserver COMM, which does two things:
>
> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>    communication channel.
>
> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>    tests don't fail. If the user gives up in the middle of a debugging
>    session, they can simply CTRL-C the test script to abort it.
>
> This allows easy debugging of test failures without having to manually
> re-create the failure conditions. Usage is:
>
> Window 1:
> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
>
> Window 2:
> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
>
> When using this option, it likely makes sense to use pytest's -k option
> to limit the set of tests that are executed.
>
> Simply running U-Boot directly under gdb (rather than gdbserver) was
> also considered. However, this was rejected because:
>
> a) gdb's output would then be processed by the test script, and likely
>    confuse it causing false failures.
>
> b) pytest by default hides stdout from tests, which would prevent the
>    user from interacting with gdb.
>
>    While gdb can be told to redirect the debugee's stdio to a separate
>    PTY, this would appear to leave gdb's stdio directed at the test
>    scripts and the debugee's stdio directed elsewhere, which is the
>    opposite of the desired effect. Perhaps some complicated PTY muxing
>    and process hierarchy could invert this. However, the current scheme
>    is simple to implement and use, so it doesn't seem worth complicating
>    matters.
>
> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>    a GUI. If the test scripts invoked the debugger themselves, they'd have
>    to know how to execute arbitary applications. While the user could hide
>    this all in a wrapper script, this feels like extra complication.
>
> An interesting future idea might be a --gdb-screen option, which could
> spawn both U-Boot and gdb separately, and spawn the screen into a newly
> created window under screen. Similar options could be envisaged for
> creating a new xterm/... too.
>
> --gdbserver  currently only supports sandbox, and not real hardware.
> That's primarily because the test hooks are responsible for all aspects of
> hardware control, so there's nothing for the test scripts themselves can
> do to enable gdbserver on real hardware. We might consider introducing a
> separate --disable-timeouts option to support use of debuggers on real
> hardware, and having --gdbserver imply that option.
>
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
>  test/py/conftest.py               |  8 ++++++++
>  test/py/tests/test_sleep.py       |  7 ++++---
>  test/py/u_boot_console_base.py    |  3 ++-
>  test/py/u_boot_console_sandbox.py |  5 ++++-
>  test/py/u_boot_spawn.py           | 12 ++++++++----
>  5 files changed, 26 insertions(+), 9 deletions(-)

Can you please add info about this to the docs?

Also for me this worked up to the point where it ran the
test_sandbox_exit.py test. Then the gdb process said that U-Boot
exited normally. Is that test not compatible with this feature?

Regards
Simon
Stephen Warren Feb. 6, 2016, 8:34 p.m. UTC | #2
On 02/06/2016 01:30 PM, Simon Glass wrote:
> On 4 February 2016 at 16:11, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> Implement command--line option --gdbserver COMM, which does two things:
>>
>> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>>    communication channel.
>>
>> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>>    tests don't fail. If the user gives up in the middle of a debugging
>>    session, they can simply CTRL-C the test script to abort it.
>>
>> This allows easy debugging of test failures without having to manually
>> re-create the failure conditions. Usage is:
>>
>> Window 1:
>> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
>>
>> Window 2:
>> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
>>
>> When using this option, it likely makes sense to use pytest's -k option
>> to limit the set of tests that are executed.
>>
>> Simply running U-Boot directly under gdb (rather than gdbserver) was
>> also considered. However, this was rejected because:
>>
>> a) gdb's output would then be processed by the test script, and likely
>>    confuse it causing false failures.
>>
>> b) pytest by default hides stdout from tests, which would prevent the
>>    user from interacting with gdb.
>>
>>    While gdb can be told to redirect the debugee's stdio to a separate
>>    PTY, this would appear to leave gdb's stdio directed at the test
>>    scripts and the debugee's stdio directed elsewhere, which is the
>>    opposite of the desired effect. Perhaps some complicated PTY muxing
>>    and process hierarchy could invert this. However, the current scheme
>>    is simple to implement and use, so it doesn't seem worth complicating
>>    matters.
>>
>> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>>    a GUI. If the test scripts invoked the debugger themselves, they'd have
>>    to know how to execute arbitary applications. While the user could hide
>>    this all in a wrapper script, this feels like extra complication.
>>
>> An interesting future idea might be a --gdb-screen option, which could
>> spawn both U-Boot and gdb separately, and spawn the screen into a newly
>> created window under screen. Similar options could be envisaged for
>> creating a new xterm/... too.
>>
>> --gdbserver  currently only supports sandbox, and not real hardware.
>> That's primarily because the test hooks are responsible for all aspects of
>> hardware control, so there's nothing for the test scripts themselves can
>> do to enable gdbserver on real hardware. We might consider introducing a
>> separate --disable-timeouts option to support use of debuggers on real
>> hardware, and having --gdbserver imply that option.
>>
>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>> ---
>>  test/py/conftest.py               |  8 ++++++++
>>  test/py/tests/test_sleep.py       |  7 ++++---
>>  test/py/u_boot_console_base.py    |  3 ++-
>>  test/py/u_boot_console_sandbox.py |  5 ++++-
>>  test/py/u_boot_spawn.py           | 12 ++++++++----
>>  5 files changed, 26 insertions(+), 9 deletions(-)
> 
> Can you please add info about this to the docs?
> 
> Also for me this worked up to the point where it ran the
> test_sandbox_exit.py test. Then the gdb process said that U-Boot
> exited normally. Is that test not compatible with this feature?

The sandbox_exit test deliberately causes the sandbox process to exit,
to make sure that the "reset" command and "typing" Ctrl-C work. To
continue the test, simply re-run gdb to re-attach to the new gdbserver
and U-Boot process.
Simon Glass Feb. 6, 2016, 8:39 p.m. UTC | #3
Hi Stephen,

On 6 February 2016 at 13:34, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 02/06/2016 01:30 PM, Simon Glass wrote:
>> On 4 February 2016 at 16:11, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> Implement command--line option --gdbserver COMM, which does two things:
>>>
>>> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>>>    communication channel.
>>>
>>> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>>>    tests don't fail. If the user gives up in the middle of a debugging
>>>    session, they can simply CTRL-C the test script to abort it.
>>>
>>> This allows easy debugging of test failures without having to manually
>>> re-create the failure conditions. Usage is:
>>>
>>> Window 1:
>>> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
>>>
>>> Window 2:
>>> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
>>>
>>> When using this option, it likely makes sense to use pytest's -k option
>>> to limit the set of tests that are executed.
>>>
>>> Simply running U-Boot directly under gdb (rather than gdbserver) was
>>> also considered. However, this was rejected because:
>>>
>>> a) gdb's output would then be processed by the test script, and likely
>>>    confuse it causing false failures.
>>>
>>> b) pytest by default hides stdout from tests, which would prevent the
>>>    user from interacting with gdb.
>>>
>>>    While gdb can be told to redirect the debugee's stdio to a separate
>>>    PTY, this would appear to leave gdb's stdio directed at the test
>>>    scripts and the debugee's stdio directed elsewhere, which is the
>>>    opposite of the desired effect. Perhaps some complicated PTY muxing
>>>    and process hierarchy could invert this. However, the current scheme
>>>    is simple to implement and use, so it doesn't seem worth complicating
>>>    matters.
>>>
>>> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>>>    a GUI. If the test scripts invoked the debugger themselves, they'd have
>>>    to know how to execute arbitary applications. While the user could hide
>>>    this all in a wrapper script, this feels like extra complication.
>>>
>>> An interesting future idea might be a --gdb-screen option, which could
>>> spawn both U-Boot and gdb separately, and spawn the screen into a newly
>>> created window under screen. Similar options could be envisaged for
>>> creating a new xterm/... too.
>>>
>>> --gdbserver  currently only supports sandbox, and not real hardware.
>>> That's primarily because the test hooks are responsible for all aspects of
>>> hardware control, so there's nothing for the test scripts themselves can
>>> do to enable gdbserver on real hardware. We might consider introducing a
>>> separate --disable-timeouts option to support use of debuggers on real
>>> hardware, and having --gdbserver imply that option.
>>>
>>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>>> ---
>>>  test/py/conftest.py               |  8 ++++++++
>>>  test/py/tests/test_sleep.py       |  7 ++++---
>>>  test/py/u_boot_console_base.py    |  3 ++-
>>>  test/py/u_boot_console_sandbox.py |  5 ++++-
>>>  test/py/u_boot_spawn.py           | 12 ++++++++----
>>>  5 files changed, 26 insertions(+), 9 deletions(-)
>>
>> Can you please add info about this to the docs?
>>
>> Also for me this worked up to the point where it ran the
>> test_sandbox_exit.py test. Then the gdb process said that U-Boot
>> exited normally. Is that test not compatible with this feature?
>
> The sandbox_exit test deliberately causes the sandbox process to exit,
> to make sure that the "reset" command and "typing" Ctrl-C work. To
> continue the test, simply re-run gdb to re-attach to the new gdbserver
> and U-Boot process.

That's a bit annoying. Perhaps we should have a flag that disabled
such tests? Or perhaps a way to specify what tests are run?

Anyway, can you add this to the docs too?

Regards,
Simon
Stephen Warren Feb. 8, 2016, 6 p.m. UTC | #4
On 02/06/2016 01:39 PM, Simon Glass wrote:
> Hi Stephen,
>
> On 6 February 2016 at 13:34, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 02/06/2016 01:30 PM, Simon Glass wrote:
>>> On 4 February 2016 at 16:11, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>>> Implement command--line option --gdbserver COMM, which does two things:
>>>>
>>>> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>>>>     communication channel.
>>>>
>>>> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>>>>     tests don't fail. If the user gives up in the middle of a debugging
>>>>     session, they can simply CTRL-C the test script to abort it.
>>>>
>>>> This allows easy debugging of test failures without having to manually
>>>> re-create the failure conditions. Usage is:
>>>>
>>>> Window 1:
>>>> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
>>>>
>>>> Window 2:
>>>> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
>>>>
>>>> When using this option, it likely makes sense to use pytest's -k option
>>>> to limit the set of tests that are executed.
>>>>
>>>> Simply running U-Boot directly under gdb (rather than gdbserver) was
>>>> also considered. However, this was rejected because:
>>>>
>>>> a) gdb's output would then be processed by the test script, and likely
>>>>     confuse it causing false failures.
>>>>
>>>> b) pytest by default hides stdout from tests, which would prevent the
>>>>     user from interacting with gdb.
>>>>
>>>>     While gdb can be told to redirect the debugee's stdio to a separate
>>>>     PTY, this would appear to leave gdb's stdio directed at the test
>>>>     scripts and the debugee's stdio directed elsewhere, which is the
>>>>     opposite of the desired effect. Perhaps some complicated PTY muxing
>>>>     and process hierarchy could invert this. However, the current scheme
>>>>     is simple to implement and use, so it doesn't seem worth complicating
>>>>     matters.
>>>>
>>>> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>>>>     a GUI. If the test scripts invoked the debugger themselves, they'd have
>>>>     to know how to execute arbitary applications. While the user could hide
>>>>     this all in a wrapper script, this feels like extra complication.
>>>>
>>>> An interesting future idea might be a --gdb-screen option, which could
>>>> spawn both U-Boot and gdb separately, and spawn the screen into a newly
>>>> created window under screen. Similar options could be envisaged for
>>>> creating a new xterm/... too.
>>>>
>>>> --gdbserver  currently only supports sandbox, and not real hardware.
>>>> That's primarily because the test hooks are responsible for all aspects of
>>>> hardware control, so there's nothing for the test scripts themselves can
>>>> do to enable gdbserver on real hardware. We might consider introducing a
>>>> separate --disable-timeouts option to support use of debuggers on real
>>>> hardware, and having --gdbserver imply that option.
>>>>
>>>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>>>> ---
>>>>   test/py/conftest.py               |  8 ++++++++
>>>>   test/py/tests/test_sleep.py       |  7 ++++---
>>>>   test/py/u_boot_console_base.py    |  3 ++-
>>>>   test/py/u_boot_console_sandbox.py |  5 ++++-
>>>>   test/py/u_boot_spawn.py           | 12 ++++++++----
>>>>   5 files changed, 26 insertions(+), 9 deletions(-)
>>>
>>> Can you please add info about this to the docs?
>>>
>>> Also for me this worked up to the point where it ran the
>>> test_sandbox_exit.py test. Then the gdb process said that U-Boot
>>> exited normally. Is that test not compatible with this feature?
>>
>> The sandbox_exit test deliberately causes the sandbox process to exit,
>> to make sure that the "reset" command and "typing" Ctrl-C work. To
>> continue the test, simply re-run gdb to re-attach to the new gdbserver
>> and U-Boot process.
>
> That's a bit annoying. Perhaps we should have a flag that disabled
> such tests? Or perhaps a way to specify what tests are run?

I would expect the user to only run the specific test that needed 
debugging in order to speed up the whole process. So, unless someone was 
debugging the reset tests, they wouldn't notice this.

There's already a standard pytest option to select which tests to run; -k.

> Anyway, can you add this to the docs too?

Sure.
Tom Rini Feb. 8, 2016, 8:49 p.m. UTC | #5
On Thu, Feb 04, 2016 at 04:11:50PM -0700, Stephen Warren wrote:

> From: Stephen Warren <swarren@nvidia.com>
> 
> Implement command--line option --gdbserver COMM, which does two things:
> 
> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>    communication channel.
> 
> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>    tests don't fail. If the user gives up in the middle of a debugging
>    session, they can simply CTRL-C the test script to abort it.
> 
> This allows easy debugging of test failures without having to manually
> re-create the failure conditions. Usage is:
> 
> Window 1:
> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
> 
> Window 2:
> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
> 
> When using this option, it likely makes sense to use pytest's -k option
> to limit the set of tests that are executed.
> 
> Simply running U-Boot directly under gdb (rather than gdbserver) was
> also considered. However, this was rejected because:
> 
> a) gdb's output would then be processed by the test script, and likely
>    confuse it causing false failures.
> 
> b) pytest by default hides stdout from tests, which would prevent the
>    user from interacting with gdb.
> 
>    While gdb can be told to redirect the debugee's stdio to a separate
>    PTY, this would appear to leave gdb's stdio directed at the test
>    scripts and the debugee's stdio directed elsewhere, which is the
>    opposite of the desired effect. Perhaps some complicated PTY muxing
>    and process hierarchy could invert this. However, the current scheme
>    is simple to implement and use, so it doesn't seem worth complicating
>    matters.
> 
> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>    a GUI. If the test scripts invoked the debugger themselves, they'd have
>    to know how to execute arbitary applications. While the user could hide
>    this all in a wrapper script, this feels like extra complication.
> 
> An interesting future idea might be a --gdb-screen option, which could
> spawn both U-Boot and gdb separately, and spawn the screen into a newly
> created window under screen. Similar options could be envisaged for
> creating a new xterm/... too.
> 
> --gdbserver  currently only supports sandbox, and not real hardware.
> That's primarily because the test hooks are responsible for all aspects of
> hardware control, so there's nothing for the test scripts themselves can
> do to enable gdbserver on real hardware. We might consider introducing a
> separate --disable-timeouts option to support use of debuggers on real
> hardware, and having --gdbserver imply that option.
> 
> Signed-off-by: Stephen Warren <swarren@nvidia.com>

Applied to u-boot/master, thanks!
Stephen Warren Feb. 8, 2016, 8:55 p.m. UTC | #6
On 02/08/2016 01:49 PM, Tom Rini wrote:
> On Thu, Feb 04, 2016 at 04:11:50PM -0700, Stephen Warren wrote:
>
>> From: Stephen Warren <swarren@nvidia.com>
>>
>> Implement command--line option --gdbserver COMM, which does two things:
>>
>> a) Run the sandbox process under gdbserver, using COMM as gdbserver's
>>     communication channel.
>>
>> b) Disables all timeouts, so that if U-Boot is halted under the debugger,
>>     tests don't fail. If the user gives up in the middle of a debugging
>>     session, they can simply CTRL-C the test script to abort it.
>>
>> This allows easy debugging of test failures without having to manually
>> re-create the failure conditions. Usage is:
>>
>> Window 1:
>> ./test/py/test.py --bd sandbox --gdbserver localhost:1234
>>
>> Window 2:
>> gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
>>
>> When using this option, it likely makes sense to use pytest's -k option
>> to limit the set of tests that are executed.
>>
>> Simply running U-Boot directly under gdb (rather than gdbserver) was
>> also considered. However, this was rejected because:
>>
>> a) gdb's output would then be processed by the test script, and likely
>>     confuse it causing false failures.
>>
>> b) pytest by default hides stdout from tests, which would prevent the
>>     user from interacting with gdb.
>>
>>     While gdb can be told to redirect the debugee's stdio to a separate
>>     PTY, this would appear to leave gdb's stdio directed at the test
>>     scripts and the debugee's stdio directed elsewhere, which is the
>>     opposite of the desired effect. Perhaps some complicated PTY muxing
>>     and process hierarchy could invert this. However, the current scheme
>>     is simple to implement and use, so it doesn't seem worth complicating
>>     matters.
>>
>> c) Using gdbserver allows arbitrary debuggers to be used, even those with
>>     a GUI. If the test scripts invoked the debugger themselves, they'd have
>>     to know how to execute arbitary applications. While the user could hide
>>     this all in a wrapper script, this feels like extra complication.
>>
>> An interesting future idea might be a --gdb-screen option, which could
>> spawn both U-Boot and gdb separately, and spawn the screen into a newly
>> created window under screen. Similar options could be envisaged for
>> creating a new xterm/... too.
>>
>> --gdbserver  currently only supports sandbox, and not real hardware.
>> That's primarily because the test hooks are responsible for all aspects of
>> hardware control, so there's nothing for the test scripts themselves can
>> do to enable gdbserver on real hardware. We might consider introducing a
>> separate --disable-timeouts option to support use of debuggers on real
>> hardware, and having --gdbserver imply that option.
>>
>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>
> Applied to u-boot/master, thanks!

Oh. I was just about to send V2 to address some of Simon's comments...
Tom Rini Feb. 8, 2016, 9:23 p.m. UTC | #7
On Mon, Feb 08, 2016 at 01:55:10PM -0700, Stephen Warren wrote:
> On 02/08/2016 01:49 PM, Tom Rini wrote:
> >On Thu, Feb 04, 2016 at 04:11:50PM -0700, Stephen Warren wrote:
> >
> >>From: Stephen Warren <swarren@nvidia.com>
> >>
> >>Implement command--line option --gdbserver COMM, which does two things:
> >>
> >>a) Run the sandbox process under gdbserver, using COMM as gdbserver's
> >>    communication channel.
> >>
> >>b) Disables all timeouts, so that if U-Boot is halted under the debugger,
> >>    tests don't fail. If the user gives up in the middle of a debugging
> >>    session, they can simply CTRL-C the test script to abort it.
> >>
> >>This allows easy debugging of test failures without having to manually
> >>re-create the failure conditions. Usage is:
> >>
> >>Window 1:
> >>./test/py/test.py --bd sandbox --gdbserver localhost:1234
> >>
> >>Window 2:
> >>gdb ./build-sandbox/u-boot -ex 'target remote localhost:1234'
> >>
> >>When using this option, it likely makes sense to use pytest's -k option
> >>to limit the set of tests that are executed.
> >>
> >>Simply running U-Boot directly under gdb (rather than gdbserver) was
> >>also considered. However, this was rejected because:
> >>
> >>a) gdb's output would then be processed by the test script, and likely
> >>    confuse it causing false failures.
> >>
> >>b) pytest by default hides stdout from tests, which would prevent the
> >>    user from interacting with gdb.
> >>
> >>    While gdb can be told to redirect the debugee's stdio to a separate
> >>    PTY, this would appear to leave gdb's stdio directed at the test
> >>    scripts and the debugee's stdio directed elsewhere, which is the
> >>    opposite of the desired effect. Perhaps some complicated PTY muxing
> >>    and process hierarchy could invert this. However, the current scheme
> >>    is simple to implement and use, so it doesn't seem worth complicating
> >>    matters.
> >>
> >>c) Using gdbserver allows arbitrary debuggers to be used, even those with
> >>    a GUI. If the test scripts invoked the debugger themselves, they'd have
> >>    to know how to execute arbitary applications. While the user could hide
> >>    this all in a wrapper script, this feels like extra complication.
> >>
> >>An interesting future idea might be a --gdb-screen option, which could
> >>spawn both U-Boot and gdb separately, and spawn the screen into a newly
> >>created window under screen. Similar options could be envisaged for
> >>creating a new xterm/... too.
> >>
> >>--gdbserver  currently only supports sandbox, and not real hardware.
> >>That's primarily because the test hooks are responsible for all aspects of
> >>hardware control, so there's nothing for the test scripts themselves can
> >>do to enable gdbserver on real hardware. We might consider introducing a
> >>separate --disable-timeouts option to support use of debuggers on real
> >>hardware, and having --gdbserver imply that option.
> >>
> >>Signed-off-by: Stephen Warren <swarren@nvidia.com>
> >
> >Applied to u-boot/master, thanks!
> 
> Oh. I was just about to send V2 to address some of Simon's comments...

Feh.  Please send 'em as an iterative patch then :)
diff mbox

Patch

diff --git a/test/py/conftest.py b/test/py/conftest.py
index f55bf68686ba..bf8d735b83cb 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -72,6 +72,9 @@  def pytest_addoption(parser):
         help='U-Boot board identity/instance')
     parser.addoption('--build', default=False, action='store_true',
         help='Compile U-Boot before running tests')
+    parser.addoption('--gdbserver', default=None,
+        help='Run sandbox under gdbserver. The argument is the channel '+
+        'over which gdbserver should communicate, e.g. localhost:1234')
 
 def pytest_configure(config):
     """pytest hook: Perform custom initialization at startup time.
@@ -111,6 +114,10 @@  def pytest_configure(config):
         persistent_data_dir = build_dir + '/persistent-data'
     mkdir_p(persistent_data_dir)
 
+    gdbserver = config.getoption('gdbserver')
+    if gdbserver and board_type != 'sandbox':
+        raise Exception('--gdbserver only supported with sandbox')
+
     import multiplexed_log
     log = multiplexed_log.Logfile(result_dir + '/test-log.html')
 
@@ -172,6 +179,7 @@  def pytest_configure(config):
     ubconfig.persistent_data_dir = persistent_data_dir
     ubconfig.board_type = board_type
     ubconfig.board_identity = board_identity
+    ubconfig.gdbserver = gdbserver
 
     env_vars = (
         'board_type',
diff --git a/test/py/tests/test_sleep.py b/test/py/tests/test_sleep.py
index 74add891c333..5c1a2623fefa 100644
--- a/test/py/tests/test_sleep.py
+++ b/test/py/tests/test_sleep.py
@@ -15,6 +15,7 @@  def test_sleep(u_boot_console):
     u_boot_console.run_command('sleep %d' % sleep_time)
     tend = time.time()
     elapsed = tend - tstart
-    delta_to_expected = abs(elapsed - sleep_time)
-    # 0.25s margin is hopefully enough to account for any system overhead.
-    assert delta_to_expected < 0.25
+    assert elapsed >= sleep_time
+    if not u_boot_console.config.gdbserver:
+        # 0.25s margin is hopefully enough to account for any system overhead.
+        assert elapsed < (sleep_time + 0.25)
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 392f8cb88532..cc5427335177 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -300,7 +300,8 @@  class ConsoleBase(object):
             # text if LCD is enabled. This value may need tweaking in the
             # future, possibly per-test to be optimal. This works for 'help'
             # on board 'seaboard'.
-            self.p.timeout = 30000
+            if not self.config.gdbserver:
+                self.p.timeout = 30000
             self.p.logfile_read = self.logstream
             if self.config.buildconfig.get('CONFIG_SPL', False) == 'y':
                 m = self.p.expect([pattern_u_boot_spl_signon] + self.bad_patterns)
diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py
index a7263f30b8ca..3de0fe4a3b6d 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -39,7 +39,10 @@  class ConsoleSandbox(ConsoleBase):
             A u_boot_spawn.Spawn object that is attached to U-Boot.
         """
 
-        cmd = [
+        cmd = []
+        if self.config.gdbserver:
+            cmd += ['gdbserver', self.config.gdbserver]
+        cmd += [
             self.config.build_dir + '/u-boot',
             '-d',
             self.config.build_dir + '/arch/sandbox/dts/test.dtb'
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index 0f52d3e945c7..4b9e81af3efb 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -148,10 +148,14 @@  class Spawn(object):
                     self.buf = self.buf[posafter:]
                     return earliest_pi
                 tnow_s = time.time()
-                tdelta_ms = (tnow_s - tstart_s) * 1000
-                if tdelta_ms > self.timeout:
-                    raise Timeout()
-                events = self.poll.poll(self.timeout - tdelta_ms)
+                if self.timeout:
+                    tdelta_ms = (tnow_s - tstart_s) * 1000
+                    poll_maxwait = self.timeout - tdelta_ms
+                    if tdelta_ms > self.timeout:
+                        raise Timeout()
+                else:
+                    poll_maxwait = None
+                events = self.poll.poll(poll_maxwait)
                 if not events:
                     raise Timeout()
                 c = os.read(self.fd, 1024)