[U-Boot] sandbox does not complete efi_selftest

Heinrich Schuchardt xypron.glpk at gmx.de
Mon Sep 17 22:44:42 UTC 2018


On 09/16/2018 07:45 AM, Simon Glass wrote:
> Hi Heinrich,
> 
> On 15 September 2018 at 22:02, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
>> Hello Simon,
>>
>> in the chat with Alex you indicated that you see a problem with
>> efi_selftest expecting an input before resetting the board.
>>
>> I do not understand why this should be a problem with sandbox. There
>> never was a problem with the Python tests for any other board.
>>
>> Could you, please, detail where the issue is and how it can be reproduced.
> 
> Using u-boot-dm/ef-working I see this:
> 
> $ make tests
> ./test/run
> +make O=build-sandbox -s sandbox_defconfig
> +make O=build-sandbox -s -j8
> ============================= test session starts ==============================
> platform linux2 -- Python 2.7.13, pytest-3.0.6, py-1.4.34, pluggy-0.4.0
> rootdir: test/py, inifile: pytest.ini
> collected 326 items
> 
> test/py/tests/test_000_version.py .
> test/py/tests/test_avb.py sssss
> test/py/tests/test_bind.py ..
> test/py/tests/test_dfu.py s
> test/py/tests/test_efi_loader.py .sssss
> test/py/tests/test_efi_selftest.py FF
> INTERNALERROR> Traceback (most recent call last):
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/main.py", line 98, in
> wrap_session
> INTERNALERROR>     session.exitstatus = doit(config, session) or 0
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/main.py", line 133, in _main
> INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 745, in __call__
> INTERNALERROR>     return self._hookexec(self, self._nonwrappers +
> self._wrappers, kwargs)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 339, in _hookexec
> INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 334, in <lambda>
> INTERNALERROR>     _MultiCall(methods, kwargs, hook.spec_opts).execute()
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 614, in execute
> INTERNALERROR>     res = hook_impl.function(*args)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/main.py", line 154, in
> pytest_runtestloop
> INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item,
> nextitem=nextitem)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 745, in __call__
> INTERNALERROR>     return self._hookexec(self, self._nonwrappers +
> self._wrappers, kwargs)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 339, in _hookexec
> INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 334, in <lambda>
> INTERNALERROR>     _MultiCall(methods, kwargs, hook.spec_opts).execute()
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 613, in execute
> INTERNALERROR>     return _wrapped_call(hook_impl.function(*args), self.execute)
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 254, in _wrapped_call
> INTERNALERROR>     return call_outcome.get_result()
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 280, in get_result
> INTERNALERROR>     _reraise(*ex)  # noqa
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 265, in __init__
> INTERNALERROR>     self.result = func()
> INTERNALERROR>   File
> "/usr/lib/python2.7/dist-packages/_pytest/vendored_packages/pluggy.py",
> line 614, in execute
> INTERNALERROR>     res = hook_impl.function(*args)
> INTERNALERROR>   File "test/py/conftest.py", line 577, in
> pytest_runtest_protocol
> INTERNALERROR>     console.drain_console()
> INTERNALERROR>   File "test/py/u_boot_console_base.py", line 306, in
> drain_console
> INTERNALERROR>     self.p.expect(['This should never match U-Boot output'])
> INTERNALERROR>   File "test/py/u_boot_spawn.py", line 174, in expect
> INTERNALERROR>     c = os.read(self.fd, 1024)
> INTERNALERROR> OSError: [Errno 5] Input/output error
> 


With https://patchwork.ozlabs.org/patch/965315/ we can see where the
problem occurs. The ConsoleSandbox seems to hang on the detection of the
console size (172*42 is the size of my console). This problem does not
occur when running the same interactively.


$ rm build-sandbox -rf && make tests
./test/run
+make O=/home/zfsdt/workspace/u-boot-build/denx/build-sandbox -s
sandbox_defconfig
+make O=/home/zfsdt/workspace/u-boot-build/denx/build-sandbox -s -j8
===========================================================================
test session starts
============================================================================
platform linux2 -- Python 2.7.15+, pytest-3.6.4, py-1.6.0, pluggy-0.6.0
rootdir: /home/zfsdt/workspace/u-boot-build/denx/test/py, inifile:
pytest.ini
collected 411 items



test/py/tests/test_000_version.py .

                   [  0%]
test/py/tests/test_avb.py sssss

                   [  0%]
test/py/tests/test_bind.py ..

                   [  0%]
test/py/tests/test_dfu.py s

                   [  0%]
test/py/tests/test_efi_loader.py .sssss

                   [  0%]
test/py/tests/test_efi_selftest.py FFFFF

                   [  0%]
test/py/tests/test_env.py ............

                   [  0%]
test/py/tests/test_fit.py F

                   [  0%]
test/py/tests/test_fpga.py sssssssssssssssssssssssssss

                   [  0%]
test/py/tests/test_gpt.py sssssss

                   [  0%]
test/py/tests/test_help.py .

                   [  0%]
test/py/tests/test_hush_if_test.py
.......................................................
                                                         [  0%]
test/py/tests/test_log.py ..

                   [  0%]
test/py/tests/test_md.py ..

                   [  0%]
test/py/tests/test_mmc_rd.py s

                   [  0%]
test/py/tests/test_net.py .sssss

                   [  0%]
test/py/tests/test_ofplatdata.py s

                   [  0%]
test/py/tests/test_sandbox_exit.py ..

                   [  0%]
test/py/tests/test_sf.py ssss

                   [  0%]
test/py/tests/test_shell_basics.py ....

                   [  0%]
test/py/tests/test_sleep.py .

                   [  0%]
test/py/tests/test_tpm2.py ...........

                   [  0%]
test/py/tests/test_ums.py s

                   [  0%]
test/py/tests/test_unknown_cmd.py .

                   [  0%]
test/py/tests/test_ut.py
........................................................................................................................................................................
[  0%]
test/py/tests/test_vboot.py F

                   [  0%]
test/py/tests/test_fs/test_basic.py
sssssssssssssssssssssssssssssssssssssss
                                                        [  0%]
test/py/tests/test_fs/test_ext.py ssssssssssssssssss

                   [  0%]
test/py/tests/test_fs/test_mkdir.py ssssssssssss

                   [  0%]
test/py/tests/test_fs/test_unlink.py ssssssssssssss

=================================================================================
FAILURES
=================================================================================
____________________________________________________________________________
test_efi_selftest
_____________________________________________________________________________

u_boot_console = <u_boot_console_sandbox.ConsoleSandbox object at
0x7fb1b5ef50d0>

    @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
    def test_efi_selftest(u_boot_console):
        """
        Run bootefi selftest
        """

        u_boot_console.run_command(cmd='setenv efi_selftest')
        u_boot_console.run_command(cmd='bootefi selftest',
wait_for_prompt=False)
        m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any
key'])
        if m != 0:
>               raise Exception('Failures occurred during the EFI selftest')
E     Exception: Failures occurred during the EFI selftest

test/py/tests/test_efi_selftest.py:19: Exception
---------------------------------------------------------------------------
Captured stdout call
---------------------------------------------------------------------------
=> setenv efi_selftest
=> => bootefi selftest
Scanning disk mmc2.blk...
^[[42;172R______________________________________________________________________
test_efi_selftest_device_tree
_______________________________________________________________________

u_boot_console = <u_boot_console_sandbox.ConsoleSandbox object at
0x7fb1b5ef50d0>

    @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
    @pytest.mark.buildconfigspec('of_control')
    def test_efi_selftest_device_tree(u_boot_console):
        u_boot_console.run_command(cmd='setenv efi_selftest list')
>       output = u_boot_console.run_command('bootefi selftest')

test/py/tests/test_efi_selftest.py:30:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <u_boot_console_sandbox.ConsoleSandbox object at 0x7fb1b5ef50d0>,
cmd = '', wait_for_echo = True, send_nl = True, wait_for_prompt = True

    def run_command(self, cmd, wait_for_echo=True, send_nl=True,
            wait_for_prompt=True):
        """Execute a command via the U-Boot console.

            The command is always sent to U-Boot.

            U-Boot echoes any command back to its output, and this function
            typically waits for that to occur. The wait can be disabled
by setting
            wait_for_echo=False, which is useful e.g. when sending CTRL-C to
            interrupt a long-running command such as "ums".

            Command execution is typically triggered by sending a newline
            character. This can be disabled by setting send_nl=False,
which is
            also useful when sending CTRL-C.

            This function typically waits for the command to finish
executing, and
            returns the console output that it generated. This can be
disabled by
            setting wait_for_prompt=False, which is useful when invoking
a long-
            running command such as "ums".

            Args:
                cmd: The command to send.
                wait_for_echo: Boolean indicating whether to wait for
U-Boot to
                    echo the command text back to its output.
                send_nl: Boolean indicating whether to send a newline
character
                    after the command string.
                wait_for_prompt: Boolean indicating whether to wait for the
                    command prompt to be sent by U-Boot. This typically
occurs
                    immediately after the command has been executed.

            Returns:
                If wait_for_prompt == False:
                    Nothing.
                Else:
                    The output from U-Boot during command execution. In
other
                    words, the text U-Boot emitted between the point it
echod the
                    command string and emitted the subsequent command
prompts.
            """

        if self.at_prompt and \
                self.at_prompt_logevt != self.logstream.logfile.cur_evt:
            self.logstream.write(self.prompt, implicit=True)

        try:
            self.at_prompt = False
            if send_nl:
                cmd += '\n'
            while cmd:
                # Limit max outstanding data, so UART FIFOs don't overflow
                chunk = cmd[:self.max_fifo_fill]
                cmd = cmd[self.max_fifo_fill:]
                self.p.send(chunk)
                if not wait_for_echo:
                    continue
                chunk = re.escape(chunk)
                chunk = chunk.replace('\\\n', '[\r\n]')
                m = self.p.expect([chunk] + self.bad_patterns)
                if m != 0:
                    self.at_prompt = False
                    raise Exception('Bad pattern found on console: ' +
                                    self.bad_pattern_ids[m - 1])
            if not wait_for_prompt:
                return
            m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
            if m != 0:
                self.at_prompt = False
                raise Exception('Bad pattern found on console: ' +
>                               self.bad_pattern_ids[m - 1])
E                               TypeError: unsupported operand type(s)
for -: 'NoneType' and 'int'

test/py/u_boot_console_base.py:207: TypeError
--------------------------------------------------------------------------
Captured stdout setup
---------------------------------------------------------------------------
/u-boot


U-Boot 2018.09-00267-gfa2a852294-dirty (Sep 18 2018 - 00:13:30 +0200)

Model: sandbox
DRAM:  128 MiB
MMC:   mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
In:    serial
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:   eth0: eth at 10002000, eth5: eth at 10003000, eth3: sbe5, eth1:
eth at 10004000
Hit any key to stop autoboot:  0
=>
---------------------------------------------------------------------------
Captured stdout call
---------------------------------------------------------------------------
=> setenv efi_selftest list
=> => bootefi selftest
Scanning disk mmc2.blk...
^[[42;172R____________________________________________________________________
test_efi_selftest_watchdog_reboot
_____________________________________________________________________

u_boot_console = <u_boot_console_sandbox.ConsoleSandbox object at
0x7fb1b5ef50d0>

    @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
    def test_efi_selftest_watchdog_reboot(u_boot_console):
        u_boot_console.run_command(cmd='setenv efi_selftest list')
>       output = u_boot_console.run_command('bootefi selftest')

test/py/tests/test_efi_selftest.py:43:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <u_boot_console_sandbox.ConsoleSandbox object at 0x7fb1b5ef50d0>,
cmd = '', wait_for_echo = True, send_nl = True, wait_for_prompt = True

    def run_command(self, cmd, wait_for_echo=True, send_nl=True,
            wait_for_prompt=True):
        """Execute a command via the U-Boot console.

            The command is always sent to U-Boot.

            U-Boot echoes any command back to its output, and this function
            typically waits for that to occur. The wait can be disabled
by setting
            wait_for_echo=False, which is useful e.g. when sending CTRL-C to
            interrupt a long-running command such as "ums".

            Command execution is typically triggered by sending a newline
            character. This can be disabled by setting send_nl=False,
which is
            also useful when sending CTRL-C.

            This function typically waits for the command to finish
executing, and
            returns the console output that it generated. This can be
disabled by
            setting wait_for_prompt=False, which is useful when invoking
a long-
            running command such as "ums".

            Args:
                cmd: The command to send.
                wait_for_echo: Boolean indicating whether to wait for
U-Boot to
                    echo the command text back to its output.
                send_nl: Boolean indicating whether to send a newline
character
                    after the command string.
                wait_for_prompt: Boolean indicating whether to wait for the
                    command prompt to be sent by U-Boot. This typically
occurs
                    immediately after the command has been executed.

            Returns:
                If wait_for_prompt == False:
                    Nothing.
                Else:
                    The output from U-Boot during command execution. In
other
                    words, the text U-Boot emitted between the point it
echod the
                    command string and emitted the subsequent command
prompts.
            """

        if self.at_prompt and \
                self.at_prompt_logevt != self.logstream.logfile.cur_evt:
            self.logstream.write(self.prompt, implicit=True)

        try:
            self.at_prompt = False
            if send_nl:
                cmd += '\n'
            while cmd:
                # Limit max outstanding data, so UART FIFOs don't overflow
                chunk = cmd[:self.max_fifo_fill]
                cmd = cmd[self.max_fifo_fill:]
                self.p.send(chunk)
                if not wait_for_echo:
                    continue
                chunk = re.escape(chunk)
                chunk = chunk.replace('\\\n', '[\r\n]')
                m = self.p.expect([chunk] + self.bad_patterns)
                if m != 0:
                    self.at_prompt = False
                    raise Exception('Bad pattern found on console: ' +
                                    self.bad_pattern_ids[m - 1])
            if not wait_for_prompt:
                return
            m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
            if m != 0:
                self.at_prompt = False
                raise Exception('Bad pattern found on console: ' +
>                               self.bad_pattern_ids[m - 1])
E                               TypeError: unsupported operand type(s)
for -: 'NoneType' and 'int'

test/py/u_boot_console_base.py:207: TypeError
--------------------------------------------------------------------------
Captured stdout setup
---------------------------------------------------------------------------
/u-boot


U-Boot 2018.09-00267-gfa2a852294-dirty (Sep 18 2018 - 00:13:30 +0200)

Model: sandbox
DRAM:  128 MiB
MMC:   mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
In:    serial
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:   eth0: eth at 10002000, eth5: eth at 10003000, eth3: sbe5, eth1:
eth at 10004000
Hit any key to stop autoboot:  0
=>
---------------------------------------------------------------------------
Captured stdout call
---------------------------------------------------------------------------
=> setenv efi_selftest list
=> => bootefi selftest
Scanning disk mmc2.blk...
^[[42;172R_______________________________________________________________________


Best regards

Heinrich Schuchardt


More information about the U-Boot mailing list