diff mbox series

[v8,22/23] test/py: add HTTP (wget) test for the EFI loader

Message ID 9b055b18f84755d775bf0cf4064e66801608839c.1723050310.git.jerome.forissier@linaro.org
State Superseded
Headers show
Series Introduce the lwIP network stack | expand

Commit Message

Jerome Forissier Aug. 7, 2024, 5:12 p.m. UTC
Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
with the wget command.

Suggested-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
---
 test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 15 deletions(-)

Comments

Tom Rini Aug. 7, 2024, 5:52 p.m. UTC | #1
On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:

> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
> with the wget command.
> 
> Suggested-by: Tom Rini <trini@konsulko.com>
> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
[snip]
> +@pytest.mark.buildconfigspec('of_control')
> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> +def test_efi_helloworld_net_tftp(u_boot_console):

This should also depend on cmd_tftpboot (existing bug).

> +    """Run the helloworld.efi binary via TFTP.
> +
> +    The helloworld.efi file is downloaded from the TFTP server and is executed
> +    using the fallback device tree at $fdtcontroladdr.
> +    """
> +
> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
> +
> +@pytest.mark.buildconfigspec('of_control')
> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> +def test_efi_helloworld_net_http(u_boot_console):

Then this needs to depend on cmd_wget as well. Kicking my local build
scripts to add wget and moving on...
Tom Rini Aug. 7, 2024, 5:57 p.m. UTC | #2
On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
> with the wget command.
> 
> Suggested-by: Tom Rini <trini@konsulko.com>
> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
> ---
>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
>  1 file changed, 37 insertions(+), 15 deletions(-)
> 
> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
> index 85473a9049b..64c994fdf95 100644
> --- a/test/py/tests/test_efi_loader.py
> +++ b/test/py/tests/test_efi_loader.py
> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
>  import pytest
>  import u_boot_utils
>  
> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
> +
>  net_set_up = False
>  
>  def test_efi_pre_commands(u_boot_console):
> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
>      global net_set_up
>      net_set_up = True
>  
> -def fetch_tftp_file(u_boot_console, env_conf):
> -    """Grab an env described file via TFTP and return its address
> +def fetch_file(u_boot_console, env_conf, proto):
> +    """Grab an env described file via TFTP or HTTP and return its address
>  
> -    A file as described by an env config <env_conf> is downloaded from the TFTP
> +    A file as described by an env config <env_conf> is downloaded from the
>      server. The address to that file is returned.
>      """
>      if not net_set_up:
> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
>          addr = u_boot_utils.find_ram_base(u_boot_console)
>  
>      fn = f['fn']
> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
> +    if proto == PROTO_TFTP:
> +        cmd = 'tftpboot'
> +    elif proto == PROTO_HTTP:
> +        cmd = 'wget'
> +    else:
> +        assert False
> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
>      expected_text = 'Bytes transferred = '
>      sz = f.get('size', None)
>      if sz:
> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
>  
>      return addr
>  
> -@pytest.mark.buildconfigspec('of_control')
> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> -def test_efi_helloworld_net(u_boot_console):
> -    """Run the helloworld.efi binary via TFTP.
> -
> -    The helloworld.efi file is downloaded from the TFTP server and is executed
> -    using the fallback device tree at $fdtcontroladdr.
> -    """
> -
> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
> +def do_test_efi_helloworld_net(u_boot_console, proto):
> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
>  
>      output = u_boot_console.run_command('bootefi %x' % addr)
>      expected_text = 'Hello, world'
> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
>      expected_text = '## Application failed'
>      assert expected_text not in output
>  
> +@pytest.mark.buildconfigspec('of_control')
> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> +def test_efi_helloworld_net_tftp(u_boot_console):
> +    """Run the helloworld.efi binary via TFTP.
> +
> +    The helloworld.efi file is downloaded from the TFTP server and is executed
> +    using the fallback device tree at $fdtcontroladdr.
> +    """
> +
> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
> +
> +@pytest.mark.buildconfigspec('of_control')
> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> +def test_efi_helloworld_net_http(u_boot_console):
> +    """Run the helloworld.efi binary via HTTP.
> +
> +    The helloworld.efi file is downloaded from the HTTP server and is executed
> +    using the fallback device tree at $fdtcontroladdr.
> +    """
> +
> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
> +
>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
>  def test_efi_helloworld_builtin(u_boot_console):
>      """Run the builtin helloworld.efi binary.
> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
>      executed.
>      """
>  
> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
>  
>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)

Looking at this now that I've added wget to my Pi builds, erm:
U-Boot> wget 200000 EFI/arm64/helloworld.efi

That's not going to work. That's what works fine for a tftp server. I
think the test is going to need to require some http specific
configuration added (and I'll locally start firing off the python
trivial http server or something, for tests).
Jerome Forissier Aug. 8, 2024, 1:06 p.m. UTC | #3
On 8/7/24 19:57, Tom Rini wrote:
> On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
>> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
>> with the wget command.
>>
>> Suggested-by: Tom Rini <trini@konsulko.com>
>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
>> ---
>>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
>>  1 file changed, 37 insertions(+), 15 deletions(-)
>>
>> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
>> index 85473a9049b..64c994fdf95 100644
>> --- a/test/py/tests/test_efi_loader.py
>> +++ b/test/py/tests/test_efi_loader.py
>> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
>>  import pytest
>>  import u_boot_utils
>>  
>> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
>> +
>>  net_set_up = False
>>  
>>  def test_efi_pre_commands(u_boot_console):
>> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
>>      global net_set_up
>>      net_set_up = True
>>  
>> -def fetch_tftp_file(u_boot_console, env_conf):
>> -    """Grab an env described file via TFTP and return its address
>> +def fetch_file(u_boot_console, env_conf, proto):
>> +    """Grab an env described file via TFTP or HTTP and return its address
>>  
>> -    A file as described by an env config <env_conf> is downloaded from the TFTP
>> +    A file as described by an env config <env_conf> is downloaded from the
>>      server. The address to that file is returned.
>>      """
>>      if not net_set_up:
>> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>          addr = u_boot_utils.find_ram_base(u_boot_console)
>>  
>>      fn = f['fn']
>> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
>> +    if proto == PROTO_TFTP:
>> +        cmd = 'tftpboot'
>> +    elif proto == PROTO_HTTP:
>> +        cmd = 'wget'
>> +    else:
>> +        assert False
>> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
>>      expected_text = 'Bytes transferred = '
>>      sz = f.get('size', None)
>>      if sz:
>> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>  
>>      return addr
>>  
>> -@pytest.mark.buildconfigspec('of_control')
>> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>> -def test_efi_helloworld_net(u_boot_console):
>> -    """Run the helloworld.efi binary via TFTP.
>> -
>> -    The helloworld.efi file is downloaded from the TFTP server and is executed
>> -    using the fallback device tree at $fdtcontroladdr.
>> -    """
>> -
>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
>> +def do_test_efi_helloworld_net(u_boot_console, proto):
>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
>>  
>>      output = u_boot_console.run_command('bootefi %x' % addr)
>>      expected_text = 'Hello, world'
>> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
>>      expected_text = '## Application failed'
>>      assert expected_text not in output
>>  
>> +@pytest.mark.buildconfigspec('of_control')
>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>> +def test_efi_helloworld_net_tftp(u_boot_console):
>> +    """Run the helloworld.efi binary via TFTP.
>> +
>> +    The helloworld.efi file is downloaded from the TFTP server and is executed
>> +    using the fallback device tree at $fdtcontroladdr.
>> +    """
>> +
>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
>> +
>> +@pytest.mark.buildconfigspec('of_control')
>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>> +def test_efi_helloworld_net_http(u_boot_console):
>> +    """Run the helloworld.efi binary via HTTP.
>> +
>> +    The helloworld.efi file is downloaded from the HTTP server and is executed
>> +    using the fallback device tree at $fdtcontroladdr.
>> +    """
>> +
>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
>> +
>>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
>>  def test_efi_helloworld_builtin(u_boot_console):
>>      """Run the builtin helloworld.efi binary.
>> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
>>      executed.
>>      """
>>  
>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
>>  
>>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
> 
> Looking at this now that I've added wget to my Pi builds, erm:
> U-Boot> wget 200000 EFI/arm64/helloworld.efi
> 
> That's not going to work. That's what works fine for a tftp server. I
> think the test is going to need to require some http specific
> configuration added (and I'll locally start firing off the python
> trivial http server or something, for tests).

It should work because 'wget <addr> <file>' is a valid syntax for the legacy
wget as well as for the new one, now that I have added support for it. It
takes the address of the http server from ${serverip}. Of course you need a
http server listening on the same host as the tfp server, yes.
I have tested this on the RPi3.
Jerome Forissier Aug. 8, 2024, 1:15 p.m. UTC | #4
On 8/7/24 19:52, Tom Rini wrote:
> On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
> 
>> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
>> with the wget command.
>>
>> Suggested-by: Tom Rini <trini@konsulko.com>
>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
> [snip]
>> +@pytest.mark.buildconfigspec('of_control')
>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>> +def test_efi_helloworld_net_tftp(u_boot_console):
> 
> This should also depend on cmd_tftpboot (existing bug).

Patch added to v9.
 
>> +    """Run the helloworld.efi binary via TFTP.
>> +
>> +    The helloworld.efi file is downloaded from the TFTP server and is executed
>> +    using the fallback device tree at $fdtcontroladdr.
>> +    """
>> +
>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
>> +
>> +@pytest.mark.buildconfigspec('of_control')
>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>> +def test_efi_helloworld_net_http(u_boot_console):
> 
> Then this needs to depend on cmd_wget as well.

Right. Fixed in v9.

> Kicking my local build
> scripts to add wget and moving on...

Thanks for testing!
Tom Rini Aug. 8, 2024, 3:52 p.m. UTC | #5
On Thu, Aug 08, 2024 at 03:06:05PM +0200, Jerome Forissier wrote:
> 
> 
> On 8/7/24 19:57, Tom Rini wrote:
> > On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
> >> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
> >> with the wget command.
> >>
> >> Suggested-by: Tom Rini <trini@konsulko.com>
> >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
> >> ---
> >>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
> >>  1 file changed, 37 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
> >> index 85473a9049b..64c994fdf95 100644
> >> --- a/test/py/tests/test_efi_loader.py
> >> +++ b/test/py/tests/test_efi_loader.py
> >> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
> >>  import pytest
> >>  import u_boot_utils
> >>  
> >> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
> >> +
> >>  net_set_up = False
> >>  
> >>  def test_efi_pre_commands(u_boot_console):
> >> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
> >>      global net_set_up
> >>      net_set_up = True
> >>  
> >> -def fetch_tftp_file(u_boot_console, env_conf):
> >> -    """Grab an env described file via TFTP and return its address
> >> +def fetch_file(u_boot_console, env_conf, proto):
> >> +    """Grab an env described file via TFTP or HTTP and return its address
> >>  
> >> -    A file as described by an env config <env_conf> is downloaded from the TFTP
> >> +    A file as described by an env config <env_conf> is downloaded from the
> >>      server. The address to that file is returned.
> >>      """
> >>      if not net_set_up:
> >> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
> >>          addr = u_boot_utils.find_ram_base(u_boot_console)
> >>  
> >>      fn = f['fn']
> >> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
> >> +    if proto == PROTO_TFTP:
> >> +        cmd = 'tftpboot'
> >> +    elif proto == PROTO_HTTP:
> >> +        cmd = 'wget'
> >> +    else:
> >> +        assert False
> >> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
> >>      expected_text = 'Bytes transferred = '
> >>      sz = f.get('size', None)
> >>      if sz:
> >> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
> >>  
> >>      return addr
> >>  
> >> -@pytest.mark.buildconfigspec('of_control')
> >> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> -def test_efi_helloworld_net(u_boot_console):
> >> -    """Run the helloworld.efi binary via TFTP.
> >> -
> >> -    The helloworld.efi file is downloaded from the TFTP server and is executed
> >> -    using the fallback device tree at $fdtcontroladdr.
> >> -    """
> >> -
> >> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
> >> +def do_test_efi_helloworld_net(u_boot_console, proto):
> >> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
> >>  
> >>      output = u_boot_console.run_command('bootefi %x' % addr)
> >>      expected_text = 'Hello, world'
> >> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
> >>      expected_text = '## Application failed'
> >>      assert expected_text not in output
> >>  
> >> +@pytest.mark.buildconfigspec('of_control')
> >> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> +def test_efi_helloworld_net_tftp(u_boot_console):
> >> +    """Run the helloworld.efi binary via TFTP.
> >> +
> >> +    The helloworld.efi file is downloaded from the TFTP server and is executed
> >> +    using the fallback device tree at $fdtcontroladdr.
> >> +    """
> >> +
> >> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
> >> +
> >> +@pytest.mark.buildconfigspec('of_control')
> >> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> +def test_efi_helloworld_net_http(u_boot_console):
> >> +    """Run the helloworld.efi binary via HTTP.
> >> +
> >> +    The helloworld.efi file is downloaded from the HTTP server and is executed
> >> +    using the fallback device tree at $fdtcontroladdr.
> >> +    """
> >> +
> >> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
> >> +
> >>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
> >>  def test_efi_helloworld_builtin(u_boot_console):
> >>      """Run the builtin helloworld.efi binary.
> >> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
> >>      executed.
> >>      """
> >>  
> >> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
> >> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
> >>  
> >>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
> > 
> > Looking at this now that I've added wget to my Pi builds, erm:
> > U-Boot> wget 200000 EFI/arm64/helloworld.efi
> > 
> > That's not going to work. That's what works fine for a tftp server. I
> > think the test is going to need to require some http specific
> > configuration added (and I'll locally start firing off the python
> > trivial http server or something, for tests).
> 
> It should work because 'wget <addr> <file>' is a valid syntax for the legacy
> wget as well as for the new one, now that I have added support for it. It
> takes the address of the http server from ${serverip}. Of course you need a
> http server listening on the same host as the tfp server, yes.
> I have tested this on the RPi3.

Oh, neat, OK, thanks. The lack of error message was confusing, does lwIP
wget say something when it fails to fetch? Throwing the trivial http
server up lets me pass the test.

Tested-by: Tom Rini <trini@konsulko.com>
Jerome Forissier Aug. 8, 2024, 4:10 p.m. UTC | #6
On 8/8/24 17:52, Tom Rini wrote:
> On Thu, Aug 08, 2024 at 03:06:05PM +0200, Jerome Forissier wrote:
>>
>>
>> On 8/7/24 19:57, Tom Rini wrote:
>>> On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
>>>> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
>>>> with the wget command.
>>>>
>>>> Suggested-by: Tom Rini <trini@konsulko.com>
>>>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
>>>> ---
>>>>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
>>>>  1 file changed, 37 insertions(+), 15 deletions(-)
>>>>
>>>> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
>>>> index 85473a9049b..64c994fdf95 100644
>>>> --- a/test/py/tests/test_efi_loader.py
>>>> +++ b/test/py/tests/test_efi_loader.py
>>>> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
>>>>  import pytest
>>>>  import u_boot_utils
>>>>  
>>>> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
>>>> +
>>>>  net_set_up = False
>>>>  
>>>>  def test_efi_pre_commands(u_boot_console):
>>>> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
>>>>      global net_set_up
>>>>      net_set_up = True
>>>>  
>>>> -def fetch_tftp_file(u_boot_console, env_conf):
>>>> -    """Grab an env described file via TFTP and return its address
>>>> +def fetch_file(u_boot_console, env_conf, proto):
>>>> +    """Grab an env described file via TFTP or HTTP and return its address
>>>>  
>>>> -    A file as described by an env config <env_conf> is downloaded from the TFTP
>>>> +    A file as described by an env config <env_conf> is downloaded from the
>>>>      server. The address to that file is returned.
>>>>      """
>>>>      if not net_set_up:
>>>> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>>>          addr = u_boot_utils.find_ram_base(u_boot_console)
>>>>  
>>>>      fn = f['fn']
>>>> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
>>>> +    if proto == PROTO_TFTP:
>>>> +        cmd = 'tftpboot'
>>>> +    elif proto == PROTO_HTTP:
>>>> +        cmd = 'wget'
>>>> +    else:
>>>> +        assert False
>>>> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
>>>>      expected_text = 'Bytes transferred = '
>>>>      sz = f.get('size', None)
>>>>      if sz:
>>>> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>>>  
>>>>      return addr
>>>>  
>>>> -@pytest.mark.buildconfigspec('of_control')
>>>> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> -def test_efi_helloworld_net(u_boot_console):
>>>> -    """Run the helloworld.efi binary via TFTP.
>>>> -
>>>> -    The helloworld.efi file is downloaded from the TFTP server and is executed
>>>> -    using the fallback device tree at $fdtcontroladdr.
>>>> -    """
>>>> -
>>>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
>>>> +def do_test_efi_helloworld_net(u_boot_console, proto):
>>>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
>>>>  
>>>>      output = u_boot_console.run_command('bootefi %x' % addr)
>>>>      expected_text = 'Hello, world'
>>>> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
>>>>      expected_text = '## Application failed'
>>>>      assert expected_text not in output
>>>>  
>>>> +@pytest.mark.buildconfigspec('of_control')
>>>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> +def test_efi_helloworld_net_tftp(u_boot_console):
>>>> +    """Run the helloworld.efi binary via TFTP.
>>>> +
>>>> +    The helloworld.efi file is downloaded from the TFTP server and is executed
>>>> +    using the fallback device tree at $fdtcontroladdr.
>>>> +    """
>>>> +
>>>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
>>>> +
>>>> +@pytest.mark.buildconfigspec('of_control')
>>>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> +def test_efi_helloworld_net_http(u_boot_console):
>>>> +    """Run the helloworld.efi binary via HTTP.
>>>> +
>>>> +    The helloworld.efi file is downloaded from the HTTP server and is executed
>>>> +    using the fallback device tree at $fdtcontroladdr.
>>>> +    """
>>>> +
>>>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
>>>> +
>>>>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
>>>>  def test_efi_helloworld_builtin(u_boot_console):
>>>>      """Run the builtin helloworld.efi binary.
>>>> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
>>>>      executed.
>>>>      """
>>>>  
>>>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
>>>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
>>>>  
>>>>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
>>>
>>> Looking at this now that I've added wget to my Pi builds, erm:
>>> U-Boot> wget 200000 EFI/arm64/helloworld.efi
>>>
>>> That's not going to work. That's what works fine for a tftp server. I
>>> think the test is going to need to require some http specific
>>> configuration added (and I'll locally start firing off the python
>>> trivial http server or something, for tests).
>>
>> It should work because 'wget <addr> <file>' is a valid syntax for the legacy
>> wget as well as for the new one, now that I have added support for it. It
>> takes the address of the http server from ${serverip}. Of course you need a
>> http server listening on the same host as the tfp server, yes.
>> I have tested this on the RPi3.
> 
> Oh, neat, OK, thanks. The lack of error message was confusing, does lwIP
> wget say something when it fails to fetch? 

Yes, it will print: "HTTP (client|server) error xxx". Typically:

"HTTP client error 4" -> TCP connection refused
"HTTP client error 5" -> TCP connection timeout
"HTTP server error 404" -> file not found

> Throwing the trivial http
> server up lets me pass the test.
> Tested-by: Tom Rini <trini@konsulko.com>


Nice! T-b added. Thanks.
Tom Rini Aug. 8, 2024, 4:20 p.m. UTC | #7
On Thu, Aug 08, 2024 at 03:06:05PM +0200, Jerome Forissier wrote:
> 
> 
> On 8/7/24 19:57, Tom Rini wrote:
> > On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
> >> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
> >> with the wget command.
> >>
> >> Suggested-by: Tom Rini <trini@konsulko.com>
> >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
> >> ---
> >>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
> >>  1 file changed, 37 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
> >> index 85473a9049b..64c994fdf95 100644
> >> --- a/test/py/tests/test_efi_loader.py
> >> +++ b/test/py/tests/test_efi_loader.py
> >> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
> >>  import pytest
> >>  import u_boot_utils
> >>  
> >> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
> >> +
> >>  net_set_up = False
> >>  
> >>  def test_efi_pre_commands(u_boot_console):
> >> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
> >>      global net_set_up
> >>      net_set_up = True
> >>  
> >> -def fetch_tftp_file(u_boot_console, env_conf):
> >> -    """Grab an env described file via TFTP and return its address
> >> +def fetch_file(u_boot_console, env_conf, proto):
> >> +    """Grab an env described file via TFTP or HTTP and return its address
> >>  
> >> -    A file as described by an env config <env_conf> is downloaded from the TFTP
> >> +    A file as described by an env config <env_conf> is downloaded from the
> >>      server. The address to that file is returned.
> >>      """
> >>      if not net_set_up:
> >> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
> >>          addr = u_boot_utils.find_ram_base(u_boot_console)
> >>  
> >>      fn = f['fn']
> >> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
> >> +    if proto == PROTO_TFTP:
> >> +        cmd = 'tftpboot'
> >> +    elif proto == PROTO_HTTP:
> >> +        cmd = 'wget'
> >> +    else:
> >> +        assert False
> >> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
> >>      expected_text = 'Bytes transferred = '
> >>      sz = f.get('size', None)
> >>      if sz:
> >> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
> >>  
> >>      return addr
> >>  
> >> -@pytest.mark.buildconfigspec('of_control')
> >> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> -def test_efi_helloworld_net(u_boot_console):
> >> -    """Run the helloworld.efi binary via TFTP.
> >> -
> >> -    The helloworld.efi file is downloaded from the TFTP server and is executed
> >> -    using the fallback device tree at $fdtcontroladdr.
> >> -    """
> >> -
> >> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
> >> +def do_test_efi_helloworld_net(u_boot_console, proto):
> >> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
> >>  
> >>      output = u_boot_console.run_command('bootefi %x' % addr)
> >>      expected_text = 'Hello, world'
> >> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
> >>      expected_text = '## Application failed'
> >>      assert expected_text not in output
> >>  
> >> +@pytest.mark.buildconfigspec('of_control')
> >> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> +def test_efi_helloworld_net_tftp(u_boot_console):
> >> +    """Run the helloworld.efi binary via TFTP.
> >> +
> >> +    The helloworld.efi file is downloaded from the TFTP server and is executed
> >> +    using the fallback device tree at $fdtcontroladdr.
> >> +    """
> >> +
> >> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
> >> +
> >> +@pytest.mark.buildconfigspec('of_control')
> >> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> >> +def test_efi_helloworld_net_http(u_boot_console):
> >> +    """Run the helloworld.efi binary via HTTP.
> >> +
> >> +    The helloworld.efi file is downloaded from the HTTP server and is executed
> >> +    using the fallback device tree at $fdtcontroladdr.
> >> +    """
> >> +
> >> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
> >> +
> >>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
> >>  def test_efi_helloworld_builtin(u_boot_console):
> >>      """Run the builtin helloworld.efi binary.
> >> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
> >>      executed.
> >>      """
> >>  
> >> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
> >> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
> >>  
> >>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
> > 
> > Looking at this now that I've added wget to my Pi builds, erm:
> > U-Boot> wget 200000 EFI/arm64/helloworld.efi
> > 
> > That's not going to work. That's what works fine for a tftp server. I
> > think the test is going to need to require some http specific
> > configuration added (and I'll locally start firing off the python
> > trivial http server or something, for tests).
> 
> It should work because 'wget <addr> <file>' is a valid syntax for the legacy
> wget as well as for the new one, now that I have added support for it. It
> takes the address of the http server from ${serverip}. Of course you need a
> http server listening on the same host as the tfp server, yes.
> I have tested this on the RPi3.

OK, so problem. This is intermittent (first I saw it on rpi_3_32b built with
clang (LLVM-17) and lwIP and the second was rpi_3_32b with gcc and lwIP):
========================================== FAILURES ===========================================
________________________________ test_efi_helloworld_net_http _________________________________
test/py/tests/test_efi_loader.py:187: in test_efi_helloworld_net_http
    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
test/py/tests/test_efi_loader.py:159: in do_test_efi_helloworld_net
    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
test/py/tests/test_efi_loader.py:139: in fetch_file
    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
test/py/u_boot_console_base.py:288: in run_command
    raise Exception('Bad pattern found on console: ' +
E   Exception: Bad pattern found on console: error_please_reset
------------------------------------ Captured stdout call -------------------------------------
U-Boot> wget 200000 EFI/arm/helloworld.efi
2320 bytes transferred in 0 ms (### ERROR ### Please RESET the board ###
=================================== short test summary info ===================================

My first guess is the "in 0 ms" leads to a divide by zero later on?
Jerome Forissier Aug. 8, 2024, 4:30 p.m. UTC | #8
On 8/8/24 18:20, Tom Rini wrote:
> On Thu, Aug 08, 2024 at 03:06:05PM +0200, Jerome Forissier wrote:
>>
>>
>> On 8/7/24 19:57, Tom Rini wrote:
>>> On Wed, Aug 07, 2024 at 07:12:06PM +0200, Jerome Forissier wrote:
>>>> Add a test to test_efi_loader.py similar to the TFTP test but for HTTP
>>>> with the wget command.
>>>>
>>>> Suggested-by: Tom Rini <trini@konsulko.com>
>>>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
>>>> ---
>>>>  test/py/tests/test_efi_loader.py | 52 +++++++++++++++++++++++---------
>>>>  1 file changed, 37 insertions(+), 15 deletions(-)
>>>>
>>>> diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
>>>> index 85473a9049b..64c994fdf95 100644
>>>> --- a/test/py/tests/test_efi_loader.py
>>>> +++ b/test/py/tests/test_efi_loader.py
>>>> @@ -50,6 +50,8 @@ env__efi_loader_helloworld_file = {
>>>>  import pytest
>>>>  import u_boot_utils
>>>>  
>>>> +PROTO_TFTP, PROTO_HTTP = range(0, 2)
>>>> +
>>>>  net_set_up = False
>>>>  
>>>>  def test_efi_pre_commands(u_boot_console):
>>>> @@ -110,10 +112,10 @@ def test_efi_setup_static(u_boot_console):
>>>>      global net_set_up
>>>>      net_set_up = True
>>>>  
>>>> -def fetch_tftp_file(u_boot_console, env_conf):
>>>> -    """Grab an env described file via TFTP and return its address
>>>> +def fetch_file(u_boot_console, env_conf, proto):
>>>> +    """Grab an env described file via TFTP or HTTP and return its address
>>>>  
>>>> -    A file as described by an env config <env_conf> is downloaded from the TFTP
>>>> +    A file as described by an env config <env_conf> is downloaded from the
>>>>      server. The address to that file is returned.
>>>>      """
>>>>      if not net_set_up:
>>>> @@ -128,7 +130,13 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>>>          addr = u_boot_utils.find_ram_base(u_boot_console)
>>>>  
>>>>      fn = f['fn']
>>>> -    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
>>>> +    if proto == PROTO_TFTP:
>>>> +        cmd = 'tftpboot'
>>>> +    elif proto == PROTO_HTTP:
>>>> +        cmd = 'wget'
>>>> +    else:
>>>> +        assert False
>>>> +    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
>>>>      expected_text = 'Bytes transferred = '
>>>>      sz = f.get('size', None)
>>>>      if sz:
>>>> @@ -147,16 +155,8 @@ def fetch_tftp_file(u_boot_console, env_conf):
>>>>  
>>>>      return addr
>>>>  
>>>> -@pytest.mark.buildconfigspec('of_control')
>>>> -@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> -def test_efi_helloworld_net(u_boot_console):
>>>> -    """Run the helloworld.efi binary via TFTP.
>>>> -
>>>> -    The helloworld.efi file is downloaded from the TFTP server and is executed
>>>> -    using the fallback device tree at $fdtcontroladdr.
>>>> -    """
>>>> -
>>>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
>>>> +def do_test_efi_helloworld_net(u_boot_console, proto):
>>>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
>>>>  
>>>>      output = u_boot_console.run_command('bootefi %x' % addr)
>>>>      expected_text = 'Hello, world'
>>>> @@ -164,6 +164,28 @@ def test_efi_helloworld_net(u_boot_console):
>>>>      expected_text = '## Application failed'
>>>>      assert expected_text not in output
>>>>  
>>>> +@pytest.mark.buildconfigspec('of_control')
>>>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> +def test_efi_helloworld_net_tftp(u_boot_console):
>>>> +    """Run the helloworld.efi binary via TFTP.
>>>> +
>>>> +    The helloworld.efi file is downloaded from the TFTP server and is executed
>>>> +    using the fallback device tree at $fdtcontroladdr.
>>>> +    """
>>>> +
>>>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
>>>> +
>>>> +@pytest.mark.buildconfigspec('of_control')
>>>> +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
>>>> +def test_efi_helloworld_net_http(u_boot_console):
>>>> +    """Run the helloworld.efi binary via HTTP.
>>>> +
>>>> +    The helloworld.efi file is downloaded from the HTTP server and is executed
>>>> +    using the fallback device tree at $fdtcontroladdr.
>>>> +    """
>>>> +
>>>> +    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
>>>> +
>>>>  @pytest.mark.buildconfigspec('cmd_bootefi_hello')
>>>>  def test_efi_helloworld_builtin(u_boot_console):
>>>>      """Run the builtin helloworld.efi binary.
>>>> @@ -185,7 +207,7 @@ def test_efi_grub_net(u_boot_console):
>>>>      executed.
>>>>      """
>>>>  
>>>> -    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
>>>> +    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
>>>>  
>>>>      u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
>>>
>>> Looking at this now that I've added wget to my Pi builds, erm:
>>> U-Boot> wget 200000 EFI/arm64/helloworld.efi
>>>
>>> That's not going to work. That's what works fine for a tftp server. I
>>> think the test is going to need to require some http specific
>>> configuration added (and I'll locally start firing off the python
>>> trivial http server or something, for tests).
>>
>> It should work because 'wget <addr> <file>' is a valid syntax for the legacy
>> wget as well as for the new one, now that I have added support for it. It
>> takes the address of the http server from ${serverip}. Of course you need a
>> http server listening on the same host as the tfp server, yes.
>> I have tested this on the RPi3.
> 
> OK, so problem. This is intermittent (first I saw it on rpi_3_32b built with
> clang (LLVM-17) and lwIP and the second was rpi_3_32b with gcc and lwIP):
> ========================================== FAILURES ===========================================
> ________________________________ test_efi_helloworld_net_http _________________________________
> test/py/tests/test_efi_loader.py:187: in test_efi_helloworld_net_http
>     do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
> test/py/tests/test_efi_loader.py:159: in do_test_efi_helloworld_net
>     addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
> test/py/tests/test_efi_loader.py:139: in fetch_file
>     output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
> test/py/u_boot_console_base.py:288: in run_command
>     raise Exception('Bad pattern found on console: ' +
> E   Exception: Bad pattern found on console: error_please_reset
> ------------------------------------ Captured stdout call -------------------------------------
> U-Boot> wget 200000 EFI/arm/helloworld.efi
> 2320 bytes transferred in 0 ms (### ERROR ### Please RESET the board ###
> =================================== short test summary info ===================================
> 
> My first guess is the "in 0 ms" leads to a divide by zero later on?

Oops! Yes, that is clearly the reason. Fixed in v9.

Thanks,
diff mbox series

Patch

diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
index 85473a9049b..64c994fdf95 100644
--- a/test/py/tests/test_efi_loader.py
+++ b/test/py/tests/test_efi_loader.py
@@ -50,6 +50,8 @@  env__efi_loader_helloworld_file = {
 import pytest
 import u_boot_utils
 
+PROTO_TFTP, PROTO_HTTP = range(0, 2)
+
 net_set_up = False
 
 def test_efi_pre_commands(u_boot_console):
@@ -110,10 +112,10 @@  def test_efi_setup_static(u_boot_console):
     global net_set_up
     net_set_up = True
 
-def fetch_tftp_file(u_boot_console, env_conf):
-    """Grab an env described file via TFTP and return its address
+def fetch_file(u_boot_console, env_conf, proto):
+    """Grab an env described file via TFTP or HTTP and return its address
 
-    A file as described by an env config <env_conf> is downloaded from the TFTP
+    A file as described by an env config <env_conf> is downloaded from the
     server. The address to that file is returned.
     """
     if not net_set_up:
@@ -128,7 +130,13 @@  def fetch_tftp_file(u_boot_console, env_conf):
         addr = u_boot_utils.find_ram_base(u_boot_console)
 
     fn = f['fn']
-    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
+    if proto == PROTO_TFTP:
+        cmd = 'tftpboot'
+    elif proto == PROTO_HTTP:
+        cmd = 'wget'
+    else:
+        assert False
+    output = u_boot_console.run_command('%s %x %s' % (cmd, addr, fn))
     expected_text = 'Bytes transferred = '
     sz = f.get('size', None)
     if sz:
@@ -147,16 +155,8 @@  def fetch_tftp_file(u_boot_console, env_conf):
 
     return addr
 
-@pytest.mark.buildconfigspec('of_control')
-@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
-def test_efi_helloworld_net(u_boot_console):
-    """Run the helloworld.efi binary via TFTP.
-
-    The helloworld.efi file is downloaded from the TFTP server and is executed
-    using the fallback device tree at $fdtcontroladdr.
-    """
-
-    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
+def do_test_efi_helloworld_net(u_boot_console, proto):
+    addr = fetch_file(u_boot_console, 'env__efi_loader_helloworld_file', proto)
 
     output = u_boot_console.run_command('bootefi %x' % addr)
     expected_text = 'Hello, world'
@@ -164,6 +164,28 @@  def test_efi_helloworld_net(u_boot_console):
     expected_text = '## Application failed'
     assert expected_text not in output
 
+@pytest.mark.buildconfigspec('of_control')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+def test_efi_helloworld_net_tftp(u_boot_console):
+    """Run the helloworld.efi binary via TFTP.
+
+    The helloworld.efi file is downloaded from the TFTP server and is executed
+    using the fallback device tree at $fdtcontroladdr.
+    """
+
+    do_test_efi_helloworld_net(u_boot_console, PROTO_TFTP);
+
+@pytest.mark.buildconfigspec('of_control')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+def test_efi_helloworld_net_http(u_boot_console):
+    """Run the helloworld.efi binary via HTTP.
+
+    The helloworld.efi file is downloaded from the HTTP server and is executed
+    using the fallback device tree at $fdtcontroladdr.
+    """
+
+    do_test_efi_helloworld_net(u_boot_console, PROTO_HTTP);
+
 @pytest.mark.buildconfigspec('cmd_bootefi_hello')
 def test_efi_helloworld_builtin(u_boot_console):
     """Run the builtin helloworld.efi binary.
@@ -185,7 +207,7 @@  def test_efi_grub_net(u_boot_console):
     executed.
     """
 
-    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
+    addr = fetch_file(u_boot_console, 'env__efi_loader_grub_file', PROTO_TFTP)
 
     u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)