All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [PATCH v5 16/17] test/py: add a test for uefi firmware update capsule of FIT image
Date: Tue, 1 Sep 2020 14:20:11 +0900	[thread overview]
Message-ID: <20200901052011.GA927084@laputa> (raw)
In-Reply-To: <267f399a-eb2a-79bf-794e-9aee4ada0498@gmx.de>

Heinrich,

On Mon, Aug 31, 2020 at 01:44:44PM +0200, Heinrich Schuchardt wrote:
> On 03.08.20 07:43, AKASHI Takahiro wrote:
> > The test can run on sandbox build and it attempts to execute a firmware
> > update via a capsule-on-disk, using a FIT image capsule,
> > CONFIG_EFI_CAPSULE_FIT.
> >
> > To run this test successfully, you need configure U-Boot specifically;
> > See test_capsule_firmware.py for requirements, and hence it won't run
> > on Travis CI.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  test/py/tests/test_efi_capsule/conftest.py    |  69 +++++++
> >  test/py/tests/test_efi_capsule/defs.py        |  12 ++
> >  .../test_efi_capsule/test_capsule_firmware.py | 178 ++++++++++++++++++
> >  .../tests/test_efi_capsule/uboot_bin_env.its  |  36 ++++
> >  4 files changed, 295 insertions(+)
> >  create mode 100644 test/py/tests/test_efi_capsule/conftest.py
> >  create mode 100644 test/py/tests/test_efi_capsule/defs.py
> >  create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware.py
> >  create mode 100644 test/py/tests/test_efi_capsule/uboot_bin_env.its
> >
> > diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py
> > new file mode 100644
> > index 000000000000..4e7c36f04ba5
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_capsule/conftest.py
> > @@ -0,0 +1,69 @@
> > +# SPDX-License-Identifier:      GPL-2.0+
> > +# Copyright (c) 2020, Linaro Limited
> > +# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > +
> > +import os
> > +import os.path
> > +import re
> > +from subprocess import call, check_call, check_output, CalledProcessError
> > +import pytest
> > +from defs import *
> > +
> > +#
> > +# Fixture for UEFI secure boot test
> > +#
> > +
> > +
> > + at pytest.fixture(scope='session')
> > +def efi_capsule_data(request, u_boot_config):
> > +    """Set up a file system to be used in UEFI capsule test.
> > +
> > +    Args:
> > +        request: Pytest request object.
> > +        u_boot_config: U-boot configuration.
> > +
> > +    Return:
> > +        A path to disk image to be used for testing
> > +    """
> > +    mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
> > +    data_dir = mnt_point + CAPSULE_DATA_DIR
> > +    install_dir = mnt_point + CAPSULE_INSTALL_DIR
> > +    image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img'
> > +
> > +    try:
> > +        # Create a target device
> > +        check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True)
> > +
> > +        check_call('rm -rf %s' % mnt_point, shell=True)
> > +        check_call('mkdir -p %s' % data_dir, shell=True)
> > +        check_call('mkdir -p %s' % install_dir, shell=True)
> > +
> > +        # Create capsule files
> > +        # two regions: one for u-boot.bin and the other for u-boot.env
> > +        check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir,
> > +                   shell=True)
> > +        check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' %
> > +                   (u_boot_config.source_dir, data_dir),
> > +                   shell=True)
> > +        check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' %
> > +                   (data_dir, u_boot_config.build_dir),
> > +                   shell=True)
> > +        check_call('cd %s; %s/tools/mkeficapsule --fit uboot_bin_env.itb --version 1 --index 1 Test01' %
> > +                   (data_dir, u_boot_config.build_dir),
> > +                   shell=True)
> > +
> > +        # Create a disk image with EFI system partition
> > +        check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' %
> > +                   (mnt_point, image_path), shell=True)
> > +        check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' %
> > +                   image_path, shell=True)
> > +
> > +    except CalledProcessError as exception:
> > +        pytest.skip('Setup failed: %s' % exception.cmd)
> > +        return
> > +    else:
> > +        yield image_path
> > +    finally:
> > +        call('rm -rf %s' % mnt_point, shell=True)
> > +        call('rm -f %s' % image_path, shell=True)
> > +        call('rm -f ./spi.bin', shell=True)
> > diff --git a/test/py/tests/test_efi_capsule/defs.py b/test/py/tests/test_efi_capsule/defs.py
> > new file mode 100644
> > index 000000000000..2c5b0ee49beb
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_capsule/defs.py
> > @@ -0,0 +1,12 @@
> > +# SPDX-License-Identifier:      GPL-2.0+
> > +
> > +# Size in MiB
> > +EFI_BOOTDEV_IMAGE_SIZE = 16
> > +EFI_BOOTDEV_PART_SIZE = 8
> > +
> > +# Owner guid
> > +GUID = '11111111-2222-3333-4444-123456789abc'
> > +
> > +# Directories
> > +CAPSULE_DATA_DIR = '/EFI/CapsuleTestData'
> > +CAPSULE_INSTALL_DIR = '/EFI/UpdateCapsule'
> > diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
> > new file mode 100644
> > index 000000000000..1673a4877778
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
> > @@ -0,0 +1,178 @@
> > +# SPDX-License-Identifier:      GPL-2.0+
> > +# Copyright (c) 2020, Linaro Limited
> > +# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > +#
> > +# U-Boot UEFI: Firmware Update Test
> > +
> > +"""
> > +This test verifies capsule-on-disk firmware update
> > +"""
> > +
> > +from subprocess import check_call, check_output, CalledProcessError
> > +import pytest
> > +from defs import *
> > +
> > +
> > + at pytest.mark.boardspec('sandbox')
> > + at pytest.mark.buildconfigspec('efi_capsule_firmware_fit')
> > + at pytest.mark.buildconfigspec('efi_capsule_on_disk')
> > + at pytest.mark.buildconfigspec('dfu')
> > + at pytest.mark.buildconfigspec('dfu_sf')
> > + at pytest.mark.buildconfigspec('cmd_efidebug')
> > + at pytest.mark.buildconfigspec('cmd_fat')
> > + at pytest.mark.buildconfigspec('cmd_memory')
> > + at pytest.mark.buildconfigspec('cmd_nvedit_efi')
> > + at pytest.mark.buildconfigspec('cmd_sf')
> > + at pytest.mark.slow
> > +class TestEfiCapsuleFirmwareFit(object):
> > +    def test_efi_capsule_fw1(
> > +            self, u_boot_config, u_boot_console, efi_capsule_data):
> > +        """
> > +        Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash
> > +                      but with OsIndications unset
> > +                      No update should happen
> > +                      0x100000-0x150000: U-Boot binary (but dummy)
> > +                      0x150000-0x200000: U-Boot environment (but dummy)
> > +        """
> > +        # "-T" (or "-D") is required to enable spi flash on sandbox
> > +        u_boot_console.restart_uboot_with_flags('-T')
> > +
> > +        disk_img = efi_capsule_data
> > +        with u_boot_console.log.section('Test Case 1-a, before reboot'):
> > +            output = u_boot_console.run_command_list([
> > +                'host bind 0 %s' % disk_img,
> > +                'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
> > +                'efidebug boot order 1',
> > +                'env set -e OsIndications',
> > +                'env set dfu_alt_info sf 0:0=u-boot-bin raw 0x100000 0x50000\;u-boot-env raw 0x150000 0x200000',
> 
> This results in a warning:
> 
> DeprecationWarning: invalid escape sequence \;

I don't think that such a warning eventually prevent running tests,
but will fix them anyway in the next version.

> The test is never executed on Gitlab:
> 
> https://gitlab.denx.de/u-boot/custodians/u-boot-efi/-/jobs/144884
> test/py/tests/test_efi_capsule/test_capsule_firmware.py sss

This is because, as I mentioned briefly in the cover letter,
some specific configurations, i.e. CONFIG_DFU and CONFIG_DFU_SF,
are mandatory to run tests successfully.

I'm not sure whether we should add them to sandbox*_defconfig
just for this purpose.

# We have another issue on virt-make-fs.

## Same comment on patch#17.

-Takahiro Akashi


> 
> 
> > +                'env save'])
> > +
> > +            # initialize contents
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
> > +                'sf write 4000000 100000 10',
> > +                'sf read 5000000 100000 10',
> > +                'md.b 5000000 10'])
> > +            assert 'Old' in ''.join(output)
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
> > +                'sf write 4000000 150000 10',
> > +                'sf read 5000000 150000 10',
> > +                'md.b 5000000 10'])
> > +            assert 'Old' in ''.join(output)
> > +
> > +            # place a capsule file
> > +            output = u_boot_console.run_command_list([
> > +                'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
> > +                'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
> > +                'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +            assert 'Test01' in ''.join(output)
> > +
> > +        # reboot
> > +        u_boot_console.restart_uboot_with_flags('-T')
> > +
> > +        capsule_early = u_boot_config.buildconfig.get(
> > +            'config_efi_capsule_on_disk_early')
> > +        with u_boot_console.log.section('Test Case 1-b, after reboot'):
> > +            if not capsule_early:
> > +                output = u_boot_console.run_command_list([
> > +                    'host bind 0 %s' % disk_img,
> > +                    'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +                assert 'Test01' in ''.join(output)
> > +
> > +                # need to run uefi command to initiate capsule handling
> > +                output = u_boot_console.run_command(
> > +                    'env print -e -all Capsule0000')
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'host bind 0 %s' % disk_img,
> > +                'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +            assert 'Test01' in ''.join(output)
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'sf read 4000000 100000 10',
> > +                'md.b 4000000 10'])
> > +            assert 'u-boot:Old' in ''.join(output)
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'sf read 4000000 150000 10',
> > +                'md.b 4000000 10'])
> > +            assert 'u-boot-env:Old' in ''.join(output)
> > +
> > +    def test_efi_capsule_fw2(
> > +            self, u_boot_config, u_boot_console, efi_capsule_data):
> > +        """
> > +        Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash
> > +                      0x100000-0x150000: U-Boot binary (but dummy)
> > +                      0x150000-0x200000: U-Boot environment (but dummy)
> > +        """
> > +        # "-T" (or "-D") is required to enable spi flash on sandbox
> > +        u_boot_console.restart_uboot_with_flags('-T')
> > +
> > +        disk_img = efi_capsule_data
> > +        with u_boot_console.log.section('Test Case 2-a, before reboot'):
> > +            output = u_boot_console.run_command_list([
> > +                'host bind 0 %s' % disk_img,
> > +                'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""',
> > +                'efidebug boot order 1',
> > +                'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
> > +                'env set dfu_alt_info sf 0:0=u-boot-bin raw 0x100000 0x50000\;u-boot-env raw 0x150000 0x200000',
> 
> Invalid escape sequence \;
> 
> Best regards
> 
> Heinrich
> 
> > +                'env save'])
> > +
> > +            # initialize contents
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
> > +                'sf write 4000000 100000 10',
> > +                'sf read 5000000 100000 10',
> > +                'md.b 5000000 10'])
> > +            assert 'Old' in ''.join(output)
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
> > +                'sf write 4000000 150000 10',
> > +                'sf read 5000000 150000 10',
> > +                'md.b 5000000 10'])
> > +            assert 'Old' in ''.join(output)
> > +
> > +            # place a capsule file
> > +            output = u_boot_console.run_command_list([
> > +                'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
> > +                'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
> > +                'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +            assert 'Test01' in ''.join(output)
> > +
> > +        # reboot
> > +        u_boot_console.restart_uboot_with_flags('-T')
> > +
> > +        capsule_early = u_boot_config.buildconfig.get(
> > +            'config_efi_capsule_on_disk_early')
> > +        with u_boot_console.log.section('Test Case 2-b, after reboot'):
> > +            if not capsule_early:
> > +                output = u_boot_console.run_command_list([
> > +                    'host bind 0 %s' % disk_img,
> > +                    'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +                assert 'Test01' in ''.join(output)
> > +
> > +                # need to run uefi command to initiate capsule handling
> > +                output = u_boot_console.run_command(
> > +                    'env print -e -all Capsule0000')
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'host bind 0 %s' % disk_img,
> > +                'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
> > +            assert 'Test01' not in ''.join(output)
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'sf probe 0:0',
> > +                'sf read 4000000 100000 10',
> > +                'md.b 4000000 10'])
> > +            assert 'u-boot:New' in ''.join(output)
> > +
> > +            output = u_boot_console.run_command_list([
> > +                'sf read 4000000 150000 10',
> > +                'md.b 4000000 10'])
> > +            assert 'u-boot-env:New' in ''.join(output)
> > diff --git a/test/py/tests/test_efi_capsule/uboot_bin_env.its b/test/py/tests/test_efi_capsule/uboot_bin_env.its
> > new file mode 100644
> > index 000000000000..31e2f8049f9a
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_capsule/uboot_bin_env.its
> > @@ -0,0 +1,36 @@
> > +/*
> > + * Automatic software update for U-Boot
> > + * Make sure the flashing addresses ('load' prop) is correct for your board!
> > + */
> > +
> > +/dts-v1/;
> > +
> > +/ {
> > +	description = "Automatic U-Boot environment update";
> > +	#address-cells = <2>;
> > +
> > +	images {
> > +		u-boot-bin at 100000 {
> > +			description = "U-Boot binary on SPI Flash";
> > +			data = /incbin/("BINFILE1");
> > +			compression = "none";
> > +			type = "firmware";
> > +			arch = "sandbox";
> > +			load = <0>;
> > +			hash-1 {
> > +				algo = "sha1";
> > +			};
> > +		};
> > +		u-boot-env at 150000 {
> > +			description = "U-Boot environment on SPI Flash";
> > +			data = /incbin/("BINFILE2");
> > +			compression = "none";
> > +			type = "firmware";
> > +			arch = "sandbox";
> > +			load = <0>;
> > +			hash-1 {
> > +				algo = "sha1";
> > +			};
> > +		};
> > +	};
> > +};
> >
> 

  reply	other threads:[~2020-09-01  5:20 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-03  5:43 [PATCH v5 00/17] efi_loader: add capsule update support AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 01/17] dfu: rename dfu_tftp_write() to dfu_write_by_name() AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 02/17] dfu: modify an argument type for an address AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 03/17] common: update: add a generic interface for FIT image AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 04/17] dfu: export dfu_list AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 05/17] efi_loader: add option to initialise EFI subsystem early AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 06/17] efi_loader: add efi_create_indexed_name() AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 07/17] efi_loader: define UpdateCapsule api AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 08/17] efi_loader: capsule: add capsule_on_disk support AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 09/17] efi_loader: capsule: add memory range capsule definitions AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 10/17] efi_loader: capsule: support firmware update AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 11/17] efi_loader: add firmware management protocol for FIT image AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 12/17] dfu: add dfu_write_by_alt() AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 13/17] efi_loader: add firmware management protocol for raw image AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 14/17] cmd: add "efidebug capsule" command AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 15/17] tools: add mkeficapsule command for UEFI capsule update AKASHI Takahiro
2020-08-28  3:58   ` Heinrich Schuchardt
2020-08-31  4:54     ` AKASHI Takahiro
2020-08-03  5:43 ` [PATCH v5 16/17] test/py: add a test for uefi firmware update capsule of FIT image AKASHI Takahiro
2020-08-31 11:44   ` Heinrich Schuchardt
2020-09-01  5:20     ` AKASHI Takahiro [this message]
2020-08-03  5:43 ` [PATCH v5 17/17] test/py: add a test for uefi firmware update capsule of raw image AKASHI Takahiro
2020-08-28  4:07   ` Heinrich Schuchardt
2020-08-31  5:15     ` AKASHI Takahiro
2020-08-31 11:45     ` Heinrich Schuchardt
2020-08-17 10:42 ` [PATCH v5 00/17] efi_loader: add capsule update support Heinrich Schuchardt
2020-08-25  5:42 ` AKASHI Takahiro
2020-08-31  4:32   ` AKASHI Takahiro
2020-08-31 20:15     ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200901052011.GA927084@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.