mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 12:08:19 +00:00 
			
		
		
		
	If env__pxe_boot_test_skip is not present, it defaults to True not False. Therefore fix the comment. Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> Reviewed-by: Peter Robinson <pbrobinson@gmail.com> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
		
			
				
	
	
		
			401 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			401 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # SPDX-License-Identifier: GPL-2.0
 | |
| # (C) Copyright 2023, Advanced Micro Devices, Inc.
 | |
| 
 | |
| import pytest
 | |
| import u_boot_utils
 | |
| import test_net
 | |
| import re
 | |
| 
 | |
| """
 | |
| Note: This test relies on boardenv_* containing configuration values to define
 | |
| which the network environment available for testing. Without this, this test
 | |
| will be automatically skipped.
 | |
| 
 | |
| For example:
 | |
| 
 | |
| # Details regarding a boot image file that may be read from a TFTP server. This
 | |
| # variable may be omitted or set to None if TFTP boot testing is not possible
 | |
| # or desired.
 | |
| env__net_tftp_bootable_file = {
 | |
|     'fn': 'image.ub',
 | |
|     'addr': 0x10000000,
 | |
|     'size': 5058624,
 | |
|     'crc32': 'c2244b26',
 | |
|     'pattern': 'Linux',
 | |
|     'config': 'config@2',
 | |
|     'timeout': 50000,
 | |
|     'check_type': 'boot_error',
 | |
|     'check_pattern': 'ERROR',
 | |
| }
 | |
| 
 | |
| # False or omitted if a TFTP boot test should be tested.
 | |
| # If TFTP boot testing is not possible or desired, set this variable to True.
 | |
| # For example: If FIT image is not proper to boot
 | |
| env__tftp_boot_test_skip = False
 | |
| 
 | |
| # Here is the example of FIT image configurations:
 | |
| configurations {
 | |
|     default = "config@1";
 | |
|     config@1 {
 | |
|         description = "Boot Linux kernel with config@1";
 | |
|         kernel = "kernel@0";
 | |
|         fdt = "fdt@0";
 | |
|         ramdisk = "ramdisk@0";
 | |
|         hash@1 {
 | |
|             algo = "sha1";
 | |
|         };
 | |
|     };
 | |
|     config@2 {
 | |
|         description = "Boot Linux kernel with config@2";
 | |
|         kernel = "kernel@1";
 | |
|         fdt = "fdt@1";
 | |
|         ramdisk = "ramdisk@1";
 | |
|         hash@1 {
 | |
|             algo = "sha1";
 | |
|         };
 | |
|     };
 | |
| };
 | |
| 
 | |
| # Details regarding a file that may be read from a TFTP server. This variable
 | |
| # may be omitted or set to None if PXE testing is not possible or desired.
 | |
| env__net_pxe_bootable_file = {
 | |
|     'fn': 'default',
 | |
|     'addr': 0x10000000,
 | |
|     'size': 74,
 | |
|     'timeout': 50000,
 | |
|     'pattern': 'Linux',
 | |
|     'valid_label': '1',
 | |
|     'invalid_label': '2',
 | |
|     'exp_str_invalid': 'Skipping install for failure retrieving',
 | |
|     'local_label': '3',
 | |
|     'exp_str_local': 'missing environment variable: localcmd',
 | |
|     'empty_label': '4',
 | |
|     'exp_str_empty': 'No kernel given, skipping boot',
 | |
|     'check_type': 'boot_error',
 | |
|     'check_pattern': 'ERROR',
 | |
| }
 | |
| 
 | |
| # False if a PXE boot test should be tested.
 | |
| # If PXE boot testing is not possible or desired, set this variable to True.
 | |
| # For example: If pxe configuration file is not proper to boot
 | |
| env__pxe_boot_test_skip = False
 | |
| 
 | |
| # Here is the example of pxe configuration file ordered based on the execution
 | |
| # flow:
 | |
| 1) /tftpboot/pxelinux.cfg/default-arm-zynqmp
 | |
| 
 | |
|     menu include pxelinux.cfg/default-arm
 | |
|     timeout 50
 | |
| 
 | |
|     default Linux
 | |
| 
 | |
| 2) /tftpboot/pxelinux.cfg/default-arm
 | |
| 
 | |
|     menu title Linux boot selections
 | |
|     menu include pxelinux.cfg/default
 | |
| 
 | |
|     label install
 | |
|         menu label Invalid boot
 | |
|         kernel kernels/install.bin
 | |
|         append console=ttyAMA0,38400 debug earlyprintk
 | |
|         initrd initrds/uzInitrdDebInstall
 | |
| 
 | |
|     label local
 | |
|         menu label Local boot
 | |
|         append root=/dev/sdb1
 | |
|         localboot 1
 | |
| 
 | |
|     label boot
 | |
|         menu label Empty boot
 | |
| 
 | |
| 3) /tftpboot/pxelinux.cfg/default
 | |
| 
 | |
|     label Linux
 | |
|         menu label Boot kernel
 | |
|         kernel Image
 | |
|         fdt system.dtb
 | |
|         initrd rootfs.cpio.gz.u-boot
 | |
| """
 | |
| 
 | |
| def setup_networking(u_boot_console):
 | |
|     test_net.test_net_dhcp(u_boot_console)
 | |
|     if not test_net.net_set_up:
 | |
|         test_net.test_net_setup_static(u_boot_console)
 | |
| 
 | |
| def setup_tftpboot_boot(u_boot_console):
 | |
|     f = u_boot_console.config.env.get('env__net_tftp_bootable_file', None)
 | |
|     if not f:
 | |
|         pytest.skip('No TFTP bootable file to read')
 | |
| 
 | |
|     setup_networking(u_boot_console)
 | |
|     addr = f.get('addr', None)
 | |
|     if not addr:
 | |
|         addr = u_boot_utils.find_ram_base(u_boot_console)
 | |
| 
 | |
|     fn = f['fn']
 | |
|     timeout = f.get('timeout', 50000)
 | |
| 
 | |
|     with u_boot_console.temporary_timeout(timeout):
 | |
|         output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
 | |
| 
 | |
|     expected_text = 'Bytes transferred = '
 | |
|     sz = f.get('size', None)
 | |
|     if sz:
 | |
|         expected_text += '%d' % sz
 | |
|     assert expected_text in output
 | |
| 
 | |
|     expected_crc = f.get('crc32', None)
 | |
|     output = u_boot_console.run_command('crc32 %x $filesize' % addr)
 | |
|     if expected_crc:
 | |
|         assert expected_crc in output
 | |
| 
 | |
|     pattern = f.get('pattern')
 | |
|     chk_type = f.get('check_type', 'boot_error')
 | |
|     chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
 | |
|     config = f.get('config', None)
 | |
| 
 | |
|     return addr, timeout, pattern, chk_type, chk_pattern, config
 | |
| 
 | |
| @pytest.mark.buildconfigspec('cmd_tftpboot')
 | |
| def test_net_tftpboot_boot(u_boot_console):
 | |
|     """Boot the loaded image
 | |
| 
 | |
|     A boot file (fit image) is downloaded from the TFTP server and booted using
 | |
|     bootm command with the default fit configuration, its boot log pattern are
 | |
|     validated.
 | |
| 
 | |
|     The details of the file to download are provided by the boardenv_* file;
 | |
|     see the comment at the beginning of this file.
 | |
|     """
 | |
|     if u_boot_console.config.env.get('env__tftp_boot_test_skip', True):
 | |
|         pytest.skip('TFTP boot test is not enabled!')
 | |
| 
 | |
|     addr, timeout, pattern, chk_type, chk_pattern, imcfg = setup_tftpboot_boot(
 | |
|         u_boot_console
 | |
|     )
 | |
| 
 | |
|     if imcfg:
 | |
|         bootcmd = 'bootm %x#%s' % (addr, imcfg)
 | |
|     else:
 | |
|         bootcmd = 'bootm %x' % addr
 | |
| 
 | |
|     with u_boot_console.enable_check(
 | |
|         chk_type, chk_pattern
 | |
|     ), u_boot_console.temporary_timeout(timeout):
 | |
|         try:
 | |
|             # wait_for_prompt=False makes the core code not wait for the U-Boot
 | |
|             # prompt code to be seen, since it won't be on a successful kernel
 | |
|             # boot
 | |
|             u_boot_console.run_command(bootcmd, wait_for_prompt=False)
 | |
| 
 | |
|             # Wait for boot log pattern
 | |
|             u_boot_console.wait_for(pattern)
 | |
|         finally:
 | |
|             # This forces the console object to be shutdown, so any subsequent
 | |
|             # test will reset the board back into U-Boot. We want to force this
 | |
|             # no matter whether the kernel boot passed or failed.
 | |
|             u_boot_console.drain_console()
 | |
|             u_boot_console.cleanup_spawn()
 | |
| 
 | |
| def setup_pxe_boot(u_boot_console):
 | |
|     f = u_boot_console.config.env.get('env__net_pxe_bootable_file', None)
 | |
|     if not f:
 | |
|         pytest.skip('No PXE bootable file to read')
 | |
| 
 | |
|     setup_networking(u_boot_console)
 | |
|     bootfile = u_boot_console.run_command('echo $bootfile')
 | |
|     if not bootfile:
 | |
|         bootfile = '<NULL>'
 | |
| 
 | |
|     return f, bootfile
 | |
| 
 | |
| @pytest.mark.buildconfigspec('cmd_pxe')
 | |
| def test_net_pxe_boot(u_boot_console):
 | |
|     """Test the pxe boot command.
 | |
| 
 | |
|     A pxe configuration file is downloaded from the TFTP server and interpreted
 | |
|     to boot the images mentioned in pxe configuration file.
 | |
| 
 | |
|     The details of the file to download are provided by the boardenv_* file;
 | |
|     see the comment at the beginning of this file.
 | |
|     """
 | |
|     if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
 | |
|         pytest.skip('PXE boot test is not enabled!')
 | |
| 
 | |
|     f, bootfile = setup_pxe_boot(u_boot_console)
 | |
|     addr = f.get('addr', None)
 | |
|     timeout = f.get('timeout', u_boot_console.p.timeout)
 | |
|     fn = f['fn']
 | |
| 
 | |
|     if addr:
 | |
|         u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
 | |
| 
 | |
|     with u_boot_console.temporary_timeout(timeout):
 | |
|         output = u_boot_console.run_command('pxe get')
 | |
| 
 | |
|     expected_text = 'Bytes transferred = '
 | |
|     sz = f.get('size', None)
 | |
|     if sz:
 | |
|         expected_text += '%d' % sz
 | |
|     assert 'TIMEOUT' not in output
 | |
|     assert expected_text in output
 | |
|     assert f"Config file '{bootfile}' found" in output
 | |
| 
 | |
|     pattern = f.get('pattern')
 | |
|     chk_type = f.get('check_type', 'boot_error')
 | |
|     chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
 | |
| 
 | |
|     if not addr:
 | |
|         pxe_boot_cmd = 'pxe boot'
 | |
|     else:
 | |
|         pxe_boot_cmd = 'pxe boot %x' % addr
 | |
| 
 | |
|     with u_boot_console.enable_check(
 | |
|         chk_type, chk_pattern
 | |
|     ), u_boot_console.temporary_timeout(timeout):
 | |
|         try:
 | |
|             u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
 | |
|             u_boot_console.wait_for(pattern)
 | |
|         finally:
 | |
|             u_boot_console.drain_console()
 | |
|             u_boot_console.cleanup_spawn()
 | |
| 
 | |
| @pytest.mark.buildconfigspec('cmd_pxe')
 | |
| def test_net_pxe_boot_config(u_boot_console):
 | |
|     """Test the pxe boot command by selecting different combination of labels
 | |
| 
 | |
|     A pxe configuration file is downloaded from the TFTP server and interpreted
 | |
|     to boot the images mentioned in pxe configuration file.
 | |
| 
 | |
|     The details of the file to download are provided by the boardenv_* file;
 | |
|     see the comment at the beginning of this file.
 | |
|     """
 | |
|     if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
 | |
|         pytest.skip('PXE boot test is not enabled!')
 | |
| 
 | |
|     f, bootfile = setup_pxe_boot(u_boot_console)
 | |
|     addr = f.get('addr', None)
 | |
|     timeout = f.get('timeout', u_boot_console.p.timeout)
 | |
|     fn = f['fn']
 | |
|     local_label = f['local_label']
 | |
|     empty_label = f['empty_label']
 | |
|     exp_str_local = f['exp_str_local']
 | |
|     exp_str_empty = f['exp_str_empty']
 | |
| 
 | |
|     if addr:
 | |
|         u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
 | |
| 
 | |
|     with u_boot_console.temporary_timeout(timeout):
 | |
|         output = u_boot_console.run_command('pxe get')
 | |
| 
 | |
|     expected_text = 'Bytes transferred = '
 | |
|     sz = f.get('size', None)
 | |
|     if sz:
 | |
|         expected_text += '%d' % sz
 | |
|     assert 'TIMEOUT' not in output
 | |
|     assert expected_text in output
 | |
|     assert f"Config file '{bootfile}' found" in output
 | |
| 
 | |
|     pattern = f.get('pattern')
 | |
|     chk_type = f.get('check_type', 'boot_error')
 | |
|     chk_pattern = re.compile(f.get('check_pattern', 'ERROR'))
 | |
| 
 | |
|     if not addr:
 | |
|         pxe_boot_cmd = 'pxe boot'
 | |
|     else:
 | |
|         pxe_boot_cmd = 'pxe boot %x' % addr
 | |
| 
 | |
|     with u_boot_console.enable_check(
 | |
|         chk_type, chk_pattern
 | |
|     ), u_boot_console.temporary_timeout(timeout):
 | |
|         try:
 | |
|             u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
 | |
| 
 | |
|             # pxe config is loaded where multiple labels are there and need to
 | |
|             # select particular label to boot and check for expected string
 | |
|             # In this case, local label is selected and it should look for
 | |
|             # localcmd env variable and if that variable is not defined it
 | |
|             # should not boot it and come out to u-boot prompt
 | |
|             u_boot_console.wait_for('Enter choice:')
 | |
|             u_boot_console.run_command(local_label, wait_for_prompt=False)
 | |
|             expected_str = u_boot_console.p.expect([exp_str_local])
 | |
|             assert (
 | |
|                 expected_str == 0
 | |
|             ), f'Expected string: {exp_str_local} did not match!'
 | |
| 
 | |
|             # In this case, empty label is selected and it should look for
 | |
|             # kernel image path and if it is not set it should fail it and load
 | |
|             # default label to boot
 | |
|             u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
 | |
|             u_boot_console.wait_for('Enter choice:')
 | |
|             u_boot_console.run_command(empty_label, wait_for_prompt=False)
 | |
|             expected_str = u_boot_console.p.expect([exp_str_empty])
 | |
|             assert (
 | |
|                 expected_str == 0
 | |
|             ), f'Expected string: {exp_str_empty} did not match!'
 | |
| 
 | |
|             u_boot_console.wait_for(pattern)
 | |
|         finally:
 | |
|             u_boot_console.drain_console()
 | |
|             u_boot_console.cleanup_spawn()
 | |
| 
 | |
| @pytest.mark.buildconfigspec('cmd_pxe')
 | |
| def test_net_pxe_boot_config_invalid(u_boot_console):
 | |
|     """Test the pxe boot command by selecting invalid label
 | |
| 
 | |
|     A pxe configuration file is downloaded from the TFTP server and interpreted
 | |
|     to boot the images mentioned in pxe configuration file.
 | |
| 
 | |
|     The details of the file to download are provided by the boardenv_* file;
 | |
|     see the comment at the beginning of this file.
 | |
|     """
 | |
|     if u_boot_console.config.env.get('env__pxe_boot_test_skip', True):
 | |
|         pytest.skip('PXE boot test is not enabled!')
 | |
| 
 | |
|     f, bootfile = setup_pxe_boot(u_boot_console)
 | |
|     addr = f.get('addr', None)
 | |
|     timeout = f.get('timeout', u_boot_console.p.timeout)
 | |
|     fn = f['fn']
 | |
|     invalid_label = f['invalid_label']
 | |
|     exp_str_invalid = f['exp_str_invalid']
 | |
| 
 | |
|     if addr:
 | |
|         u_boot_console.run_command('setenv pxefile_addr_r %x' % addr)
 | |
| 
 | |
|     with u_boot_console.temporary_timeout(timeout):
 | |
|         output = u_boot_console.run_command('pxe get')
 | |
| 
 | |
|     expected_text = 'Bytes transferred = '
 | |
|     sz = f.get('size', None)
 | |
|     if sz:
 | |
|         expected_text += '%d' % sz
 | |
|     assert 'TIMEOUT' not in output
 | |
|     assert expected_text in output
 | |
|     assert f"Config file '{bootfile}' found" in output
 | |
| 
 | |
|     pattern = f.get('pattern')
 | |
|     if not addr:
 | |
|         pxe_boot_cmd = 'pxe boot'
 | |
|     else:
 | |
|         pxe_boot_cmd = 'pxe boot %x' % addr
 | |
| 
 | |
|     with u_boot_console.temporary_timeout(timeout):
 | |
|         try:
 | |
|             u_boot_console.run_command(pxe_boot_cmd, wait_for_prompt=False)
 | |
| 
 | |
|             # pxe config is loaded where multiple labels are there and need to
 | |
|             # select particular label to boot and check for expected string
 | |
|             # In this case invalid label is selected, it should load invalid
 | |
|             # label and if it fails it should load the default label to boot
 | |
|             u_boot_console.wait_for('Enter choice:')
 | |
|             u_boot_console.run_command(invalid_label, wait_for_prompt=False)
 | |
|             expected_str = u_boot_console.p.expect([exp_str_invalid])
 | |
|             assert (
 | |
|                 expected_str == 0
 | |
|             ), f'Expected string: {exp_str_invalid} did not match!'
 | |
| 
 | |
|             u_boot_console.wait_for(pattern)
 | |
|         finally:
 | |
|             u_boot_console.drain_console()
 | |
|             u_boot_console.cleanup_spawn()
 |