diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/bloblist.c | 8 | ||||
-rw-r--r-- | test/boot/bootflow.c | 2 | ||||
-rw-r--r-- | test/boot/bootstd_common.c | 3 | ||||
-rw-r--r-- | test/cmd/mbr.c | 6 | ||||
-rw-r--r-- | test/cmd/setexpr.c | 10 | ||||
-rw-r--r-- | test/dm/acpi.c | 6 | ||||
-rw-r--r-- | test/dm/button.c | 96 | ||||
-rw-r--r-- | test/py/tests/test_net.py | 58 | ||||
-rw-r--r-- | test/py/tests/test_reset.py | 63 | ||||
-rw-r--r-- | test/py/tests/test_saveenv.py | 137 |
10 files changed, 379 insertions, 10 deletions
diff --git a/test/bloblist.c b/test/bloblist.c index 17d9dd03d07..1c60bbac36c 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -207,7 +207,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts) hdr->flags++; hdr->total_size--; - ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->total_size++; hdr->spare++; @@ -376,13 +376,12 @@ static int bloblist_test_reloc(struct unit_test_state *uts) { const uint large_size = TEST_BLOBLIST_SIZE; const uint small_size = 0x20; - void *old_ptr, *new_ptr; + void *new_ptr; void *blob1, *blob2; ulong new_addr; ulong new_size; ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); - old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Add one blob and then one that won't fit */ blob1 = bloblist_add(TEST_TAG, small_size, 0); @@ -394,8 +393,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts) new_addr = TEST_ADDR + TEST_BLOBLIST_SIZE; new_size = TEST_BLOBLIST_SIZE + 0x100; new_ptr = map_sysmem(new_addr, TEST_BLOBLIST_SIZE); - bloblist_reloc(new_ptr, new_size, old_ptr, TEST_BLOBLIST_SIZE); - gd->bloblist = new_ptr; + ut_assertok(bloblist_reloc(new_ptr, new_size)); /* Check the old blob is there and that we can now add the bigger one */ ut_assertnonnull(bloblist_find(TEST_TAG, small_size)); diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index fa54dde661c..4845b7121c8 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -544,7 +544,7 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev, "bootmeth_script", 0, ofnode_null(), &dev)); /* Enable the cros bootmeth if needed */ - if (bind_cros) { + if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros) { ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros), "cros", 0, ofnode_null(), &dev)); diff --git a/test/boot/bootstd_common.c b/test/boot/bootstd_common.c index e71a2975c53..cc97e255e5c 100644 --- a/test/boot/bootstd_common.c +++ b/test/boot/bootstd_common.c @@ -74,6 +74,9 @@ int bootstd_test_check_mmc_hunter(struct unit_test_state *uts) struct bootstd_priv *std; uint seq; + if (!IS_ENABLED(CONFIG_MMC)) + return 0; + /* get access to the used hunters */ ut_assertok(bootstd_get_priv(&std)); diff --git a/test/cmd/mbr.c b/test/cmd/mbr.c index 46b78e706ca..235b363290e 100644 --- a/test/cmd/mbr.c +++ b/test/cmd/mbr.c @@ -240,7 +240,11 @@ static int mbr_test_run(struct unit_test_state *uts) ut_assert(ofnode_valid(node)); ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false)); - mbr_parts_max = sizeof('\0') + 2 + + /* + * 1 byte for null character + * 2 reserved bytes + */ + mbr_parts_max = 1 + 2 + strlen(mbr_parts_header) + strlen(mbr_parts_p1) + strlen(mbr_parts_p2) + diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c index 312593e1e32..ee329e94b85 100644 --- a/test/cmd/setexpr.c +++ b/test/cmd/setexpr.c @@ -179,6 +179,16 @@ static int setexpr_test_regex(struct unit_test_state *uts) val = env_get("mary"); ut_asserteq_str("this is a test", val); + /* No match */ + ut_assertok(run_command("setenv fred 'this is a test'", 0)); + ut_assertok(run_command("setenv mary ''", 0)); + ut_assertok(run_command("setexpr fred gsub us is \"${fred}\"", 0)); + ut_assertok(run_command("setexpr mary gsub us is \"${fred}\"", 0)); + val = env_get("fred"); + ut_asserteq_str("this is a test", val); + val = env_get("mary"); + ut_asserteq_str("this is a test", val); + unmap_sysmem(buf); return 0; diff --git a/test/dm/acpi.c b/test/dm/acpi.c index c53ebcdb1c1..f14b3962f84 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -237,7 +237,7 @@ static int dm_test_acpi_fill_header(struct unit_test_state *uts) hdr.length = 0x11; hdr.revision = 0x22; hdr.checksum = 0x33; - hdr.aslc_revision = 0x44; + hdr.creator_revision = 0x44; acpi_fill_header(&hdr, "ABCD"); ut_asserteq_mem("ABCD", hdr.signature, sizeof(hdr.signature)); @@ -248,8 +248,8 @@ static int dm_test_acpi_fill_header(struct unit_test_state *uts) ut_asserteq_mem(OEM_TABLE_ID, hdr.oem_table_id, sizeof(hdr.oem_table_id)); ut_asserteq(OEM_REVISION, hdr.oem_revision); - ut_asserteq_mem(ASLC_ID, hdr.aslc_id, sizeof(hdr.aslc_id)); - ut_asserteq(0x44, hdr.aslc_revision); + ut_asserteq_mem(ASLC_ID, hdr.creator_id, sizeof(hdr.creator_id)); + ut_asserteq(0x44, hdr.creator_revision); return 0; } diff --git a/test/dm/button.c b/test/dm/button.c index 3318668df25..830d96fbef3 100644 --- a/test/dm/button.c +++ b/test/dm/button.c @@ -131,3 +131,99 @@ static int dm_test_button_keys_adc(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_button_keys_adc, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test of the button uclass using the button_gpio driver */ +static int dm_test_button_cmd(struct unit_test_state *uts) +{ + struct udevice *btn1_dev, *btn2_dev, *gpio; + const char *envstr; + +#define BTN1_GPIO 3 +#define BTN2_GPIO 4 +#define BTN1_PASS_VAR "test_button_cmds_0" +#define BTN2_PASS_VAR "test_button_cmds_1" + + /* + * Buttons 1 and 2 are connected to gpio_a gpios 3 and 4 respectively. + * set the GPIOs to known values and then check that the appropriate + * commands are run when invoking process_button_cmds(). + */ + ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &btn1_dev)); + ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &btn2_dev)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); + + /* + * Map a command to button 1 and check that it process_button_cmds() + * runs it if called with button 1 pressed. + */ + ut_assertok(env_set("button_cmd_0_name", "button1")); + ut_assertok(env_set("button_cmd_0", "env set " BTN1_PASS_VAR " PASS")); + ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 1)); + /* Sanity check that the button is actually pressed */ + ut_asserteq(BUTTON_ON, button_get_state(btn1_dev)); + process_button_cmds(); + ut_assertnonnull((envstr = env_get(BTN1_PASS_VAR))); + ut_asserteq_str(envstr, "PASS"); + + /* Clear result */ + ut_assertok(env_set(BTN1_PASS_VAR, NULL)); + + /* + * Map a command for button 2, press it, check that only the command + * for button 1 runs because it comes first and is also pressed. + */ + ut_assertok(env_set("button_cmd_1_name", "button2")); + ut_assertok(env_set("button_cmd_1", "env set " BTN2_PASS_VAR " PASS")); + ut_assertok(sandbox_gpio_set_value(gpio, BTN2_GPIO, 1)); + ut_asserteq(BUTTON_ON, button_get_state(btn2_dev)); + process_button_cmds(); + /* Check that button 1 triggered again */ + ut_assertnonnull((envstr = env_get(BTN1_PASS_VAR))); + ut_asserteq_str(envstr, "PASS"); + /* And button 2 didn't */ + ut_assertnull(env_get(BTN2_PASS_VAR)); + + /* Clear result */ + ut_assertok(env_set(BTN1_PASS_VAR, NULL)); + + /* + * Release button 1 and check that the command for button 2 is run + */ + ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 0)); + process_button_cmds(); + ut_assertnull(env_get(BTN1_PASS_VAR)); + /* Check that the command for button 2 ran */ + ut_assertnonnull((envstr = env_get(BTN2_PASS_VAR))); + ut_asserteq_str(envstr, "PASS"); + + /* Clear result */ + ut_assertok(env_set(BTN2_PASS_VAR, NULL)); + + /* + * Unset "button_cmd_0_name" and check that no commands run even + * with both buttons pressed. + */ + ut_assertok(env_set("button_cmd_0_name", NULL)); + /* Press button 1 (button 2 is already pressed )*/ + ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 1)); + ut_asserteq(BUTTON_ON, button_get_state(btn1_dev)); + process_button_cmds(); + ut_assertnull(env_get(BTN1_PASS_VAR)); + ut_assertnull(env_get(BTN2_PASS_VAR)); + + /* + * Check that no command is run if the button name is wrong. + */ + ut_assertok(env_set("button_cmd_0_name", "invalid_button")); + process_button_cmds(); + ut_assertnull(env_get(BTN1_PASS_VAR)); + ut_assertnull(env_get(BTN2_PASS_VAR)); + +#undef BTN1_PASS_VAR +#undef BTN2_PASS_VAR +#undef BTN1_GPIO +#undef BTN2_GPIO + + return 0; +} +DM_TEST(dm_test_button_cmd, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/py/tests/test_net.py b/test/py/tests/test_net.py index 4ff3dafd629..038a473b239 100644 --- a/test/py/tests/test_net.py +++ b/test/py/tests/test_net.py @@ -8,6 +8,7 @@ import pytest import u_boot_utils import uuid import datetime +import re """ Note: This test relies on boardenv_* containing configuration values to define @@ -31,6 +32,12 @@ env__net_uses_pci = True # set to False. env__net_dhcp_server = True +# False or omitted if a DHCP server is attached to the network, and dhcp abort +# case should be tested. +# If DHCP abort testing is not possible or desired, set this variable to True. +# For example: On some setup, dhcp is too fast and this case may not work. +env__dhcp_abort_test_skip = True + # True if a DHCPv6 server is attached to the network, and should be tested. # If DHCPv6 testing is not possible or desired, this variable may be omitted or # set to False. @@ -120,6 +127,57 @@ def test_net_dhcp(u_boot_console): global net_set_up net_set_up = True +@pytest.mark.buildconfigspec('cmd_dhcp') +@pytest.mark.buildconfigspec('cmd_mii') +def test_net_dhcp_abort(u_boot_console): + """Test the dhcp command by pressing ctrl+c in the middle of dhcp request + + The boardenv_* file may be used to enable/disable this test; see the + comment at the beginning of this file. + """ + + test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False) + if not test_dhcp: + pytest.skip('No DHCP server available') + + if u_boot_console.config.env.get('env__dhcp_abort_test_skip', True): + pytest.skip('DHCP abort test is not enabled!') + + u_boot_console.run_command('setenv autoload no') + + # Phy reset before running dhcp command + output = u_boot_console.run_command('mii device') + if not re.search(r"Current device: '(.+?)'", output): + pytest.skip('PHY device does not exist!') + eth_num = re.search(r"Current device: '(.+?)'", output).groups()[0] + u_boot_console.run_command(f'mii device {eth_num}') + output = u_boot_console.run_command('mii info') + eth_addr = hex(int(re.search(r'PHY (.+?):', output).groups()[0], 16)) + u_boot_console.run_command(f'mii modify {eth_addr} 0 0x8000 0x8000') + + u_boot_console.run_command('dhcp', wait_for_prompt=False) + try: + u_boot_console.wait_for('Waiting for PHY auto negotiation to complete') + except: + pytest.skip('Timeout waiting for PHY auto negotiation to complete') + + u_boot_console.wait_for('done') + + try: + # Sending Ctrl-C + output = u_boot_console.run_command( + chr(3), wait_for_echo=False, send_nl=False + ) + assert 'TIMEOUT' not in output + assert 'DHCP client bound to address ' not in output + assert 'Abort' in output + finally: + # Provide a time to recover from Abort - if it is not performed + # There is message like: ethernet@ff0e0000: No link. + u_boot_console.run_command('sleep 1') + # Run the dhcp test to setup the network configuration + test_net_dhcp(u_boot_console) + @pytest.mark.buildconfigspec('cmd_dhcp6') def test_net_dhcp6(u_boot_console): """Test the dhcp6 command. diff --git a/test/py/tests/test_reset.py b/test/py/tests/test_reset.py new file mode 100644 index 00000000000..00fc31da57d --- /dev/null +++ b/test/py/tests/test_reset.py @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +""" +Note: This test doesn't rely on boardenv_* configuration value but they can +change test behavior. + +For example: + +# Setup env__reset_test_skip to True if reset test is not possible or desired +# and should be skipped. +env__reset_test_skip = True + +# Setup env__reset_test to set the bootmode if 'modeboot' u-boot environment +# variable is not set. Test will be skipped if bootmode is not set in both +# places i.e, boardenv and modeboot u-boot environment variable +env__reset_test = { + 'bootmode': 'qspiboot', +} + +# This test will be also skipped if the bootmode is detected to JTAG. +""" + +import pytest +import test_000_version + +def setup_reset_env(u_boot_console): + if u_boot_console.config.env.get('env__reset_test_skip', False): + pytest.skip('reset test is not enabled') + + output = u_boot_console.run_command('echo $modeboot') + if output: + bootmode = output + else: + f = u_boot_console.config.env.get('env__reset_test', None) + if not f: + pytest.skip('bootmode cannot be determined') + bootmode = f.get('bootmode', 'jtagboot') + + if 'jtag' in bootmode: + pytest.skip('skipping reset test due to jtag bootmode') + +@pytest.mark.buildconfigspec('hush_parser') +def test_reset(u_boot_console): + """Test the reset command in non-JTAG bootmode. + It does COLD reset, which resets CPU, DDR and peripherals + """ + setup_reset_env(u_boot_console) + u_boot_console.run_command('reset', wait_for_reboot=True) + + # Checks the u-boot command prompt's functionality after reset + test_000_version.test_version(u_boot_console) + +@pytest.mark.buildconfigspec('hush_parser') +def test_reset_w(u_boot_console): + """Test the reset -w command in non-JTAG bootmode. + It does WARM reset, which resets CPU but keep DDR/peripherals active. + """ + setup_reset_env(u_boot_console) + u_boot_console.run_command('reset -w', wait_for_reboot=True) + + # Checks the u-boot command prompt's functionality after reset + test_000_version.test_version(u_boot_console) diff --git a/test/py/tests/test_saveenv.py b/test/py/tests/test_saveenv.py new file mode 100644 index 00000000000..7faa3bdf93d --- /dev/null +++ b/test/py/tests/test_saveenv.py @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +""" +Note: This test doesn't rely on boardenv_* configuration value but they can +change test behavior. + +For example: + +# Setup env__saveenv_test_skip to True if saveenv test is not possible or +# desired and should be skipped. +env__saveenv_test_skip = True + +# Setup env__saveenv_test to set the bootmode if 'modeboot' u-boot environment +# variable is not set. Test will be skipped if bootmode is not set in both +# places i.e, boardenv and modeboot u-boot environment variable +env__saveenv_test = { + 'bootmode': 'qspiboot', +} + +# This test will be also skipped if the bootmode is detected to JTAG. +""" + +import pytest +import random +import ipaddress +import string +import uuid + +# Setup the env +def setup_saveenv_env(u_boot_console): + if u_boot_console.config.env.get('env__saveenv_test_skip', False): + pytest.skip('saveenv test is not enabled') + + output = u_boot_console.run_command('echo $modeboot') + if output: + bootmode = output + else: + f = u_boot_console.config.env.get('env__saveenv_test', None) + if not f: + pytest.skip('bootmode cannot be determined') + bootmode = f.get('bootmode', 'jtagboot') + + if 'jtag' in bootmode: + pytest.skip('skipping saveenv test due to jtag bootmode') + +# Check return code +def ret_code(u_boot_console): + return u_boot_console.run_command('echo $?') + +# Verify env variable +def check_env(u_boot_console, var_name, var_value): + if var_value: + output = u_boot_console.run_command(f'printenv {var_name}') + var_value = str(var_value) + if (var_value.startswith("'") and var_value.endswith("'")) or ( + var_value.startswith('"') and var_value.endswith('"') + ): + var_value = var_value.split(var_value[-1])[1] + assert var_value in output + assert ret_code(u_boot_console).endswith('0') + else: + u_boot_console.p.send(f'printenv {var_name}\n') + output = u_boot_console.p.expect(['not defined']) + assert output == 0 + assert ret_code(u_boot_console).endswith('1') + +# Set env variable +def set_env(u_boot_console, var_name, var_value): + u_boot_console.run_command(f'setenv {var_name} {var_value}') + assert ret_code(u_boot_console).endswith('0') + check_env(u_boot_console, var_name, var_value) + +@pytest.mark.buildconfigspec('cmd_saveenv') +@pytest.mark.buildconfigspec('hush_parser') +def test_saveenv(u_boot_console): + """Test the saveenv command in non-JTAG bootmode. + It saves the U-Boot environment in persistent storage. + """ + setup_saveenv_env(u_boot_console) + + # Set env for random mac address + rand_mac = '%02x:%02x:%02x:%02x:%02x:%02x' % ( + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + ) + set_env(u_boot_console, 'mac_addr', rand_mac) + + # Set env for random IPv4 address + rand_ipv4 = ipaddress.IPv4Address._string_from_ip_int( + random.randint(0, ipaddress.IPv4Address._ALL_ONES) + ) + set_env(u_boot_console, 'ipv4_addr', rand_ipv4) + + # Set env for random IPv6 address + rand_ipv6 = ipaddress.IPv6Address._string_from_ip_int( + random.randint(0, ipaddress.IPv6Address._ALL_ONES) + ) + set_env(u_boot_console, 'ipv6_addr', rand_ipv6) + + # Set env for random number + rand_num = random.randrange(1, 10**9) + set_env(u_boot_console, 'num_var', rand_num) + + # Set env for uuid + uuid_str = uuid.uuid4().hex.lower() + set_env(u_boot_console, 'uuid_var', uuid_str) + + # Set env for random string including special characters + sc = "!#%&()*+,-./:;<=>?@[\\]^_`{|}~" + rand_str = ''.join( + random.choices(' ' + string.ascii_letters + sc + string.digits, k=300) + ) + set_env(u_boot_console, 'str_var', f'"{rand_str}"') + + # Set env for empty string + set_env(u_boot_console, 'empty_var', '') + + # Save the env variables + u_boot_console.run_command('saveenv') + assert ret_code(u_boot_console).endswith('0') + + # Reboot + u_boot_console.run_command('reset', wait_for_reboot=True) + + # Verify the saved env variables + check_env(u_boot_console, 'mac_addr', rand_mac) + check_env(u_boot_console, 'ipv4_addr', rand_ipv4) + check_env(u_boot_console, 'ipv6_addr', rand_ipv6) + check_env(u_boot_console, 'num_var', rand_num) + check_env(u_boot_console, 'uuid_var', uuid_str) + check_env(u_boot_console, 'str_var', rand_str) + check_env(u_boot_console, 'empty_var', '') |