diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Kconfig | 2 | ||||
-rw-r--r-- | test/Makefile | 2 | ||||
-rw-r--r-- | test/boot/bootflow.c | 2 | ||||
-rw-r--r-- | test/cmd/Makefile | 1 | ||||
-rw-r--r-- | test/cmd/mem_copy.c | 168 | ||||
-rw-r--r-- | test/dm/spmi.c | 4 | ||||
-rwxr-xr-x | test/fs/fs-test.sh | 118 | ||||
-rw-r--r-- | test/hush/dollar.c | 23 | ||||
-rw-r--r-- | test/py/requirements.txt | 2 | ||||
-rw-r--r-- | test/py/tests/test_i2c.py | 116 | ||||
-rw-r--r-- | test/py/tests/test_mdio.py | 79 | ||||
-rw-r--r-- | test/py/tests/test_memtest.py | 68 | ||||
-rw-r--r-- | test/py/tests/test_mii.py | 92 | ||||
-rw-r--r-- | test/py/tests/test_net.py | 59 |
14 files changed, 651 insertions, 85 deletions
diff --git a/test/Kconfig b/test/Kconfig index e842c01308..e2ec0994a2 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -67,7 +67,7 @@ endif config UT_BOOTSTD bool "Unit tests for standard boot" - depends on UNIT_TEST && SANDBOX + depends on UNIT_TEST && BOOTSTD && SANDBOX default y config UT_COMPRESSION diff --git a/test/Makefile b/test/Makefile index 9aeef02f9e..ed312cd0a4 100644 --- a/test/Makefile +++ b/test/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_UT_TIME) += time_ut.o obj-y += ut.o ifeq ($(CONFIG_SPL_BUILD),) -obj-$(CONFIG_$(SPL_)UT_BOOTSTD) += boot/ +obj-y += boot/ obj-$(CONFIG_UNIT_TEST) += common/ obj-y += log/ obj-$(CONFIG_$(SPL_)UT_UNICODE) += unicode_ut.o diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 104f49deef..fa54dde661 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts) { struct udevice *bootstd, *dev; - if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR)) + if (!IS_ENABLED(CONFIG_EFI_BOOTMGR)) return -EAGAIN; ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr), diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 7e40e25b9e..478ef4c6f0 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_HISTORY) += history.o obj-$(CONFIG_CMD_LOADM) += loadm.o obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +obj-$(CONFIG_CMD_MEMORY) += mem_copy.o ifdef CONFIG_CMD_PCI obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o endif diff --git a/test/cmd/mem_copy.c b/test/cmd/mem_copy.c new file mode 100644 index 0000000000..1ba0cebbbe --- /dev/null +++ b/test/cmd/mem_copy.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for memory 'cp' command + */ + +#include <command.h> +#include <console.h> +#include <mapmem.h> +#include <dm/test.h> +#include <test/ut.h> + +#define BUF_SIZE 256 + +/* Declare a new mem test */ +#define MEM_TEST(_name) UNIT_TEST(_name, 0, mem_test) + +struct param { + int d, s, count; +}; + +static int do_test(struct unit_test_state *uts, + const char *suffix, int d, int s, int count) +{ + const long addr = 0x1000; + u8 shadow[BUF_SIZE]; + u8 *buf; + int i, w, bytes; + + buf = map_sysmem(addr, BUF_SIZE); + + /* Fill with distinct bytes. */ + for (i = 0; i < BUF_SIZE; ++i) + buf[i] = shadow[i] = i; + + /* Parameter sanity checking. */ + w = cmd_get_data_size(suffix, 4); + ut_assert(w == 1 || w == 2 || w == 4 || (MEM_SUPPORT_64BIT_DATA && w == 8)); + + bytes = count * w; + ut_assert(d < BUF_SIZE); + ut_assert(d + bytes <= BUF_SIZE); + ut_assert(s < BUF_SIZE); + ut_assert(s + bytes <= BUF_SIZE); + + /* This is exactly what we expect to happen to "buf" */ + memmove(shadow + d, shadow + s, bytes); + + run_commandf("cp%s 0x%lx 0x%lx 0x%x", suffix, addr + s, addr + d, count); + + ut_asserteq(0, memcmp(buf, shadow, BUF_SIZE)); + + unmap_sysmem(buf); + + return 0; +} + +static int mem_test_cp_b(struct unit_test_state *uts) +{ + static const struct param tests[] = { + { 0, 128, 128 }, + { 128, 0, 128 }, + { 0, 16, 32 }, + { 16, 0, 32 }, + { 60, 100, 100 }, + { 100, 60, 100 }, + { 123, 54, 96 }, + { 54, 123, 96 }, + }; + const struct param *p; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + p = &tests[i]; + ret = do_test(uts, ".b", p->d, p->s, p->count); + if (ret) + return ret; + } + + return 0; +} +MEM_TEST(mem_test_cp_b); + +static int mem_test_cp_w(struct unit_test_state *uts) +{ + static const struct param tests[] = { + { 0, 128, 64 }, + { 128, 0, 64 }, + { 0, 16, 16 }, + { 16, 0, 16 }, + { 60, 100, 50 }, + { 100, 60, 50 }, + { 123, 54, 48 }, + { 54, 123, 48 }, + }; + const struct param *p; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + p = &tests[i]; + ret = do_test(uts, ".w", p->d, p->s, p->count); + if (ret) + return ret; + } + + return 0; +} +MEM_TEST(mem_test_cp_w); + +static int mem_test_cp_l(struct unit_test_state *uts) +{ + static const struct param tests[] = { + { 0, 128, 32 }, + { 128, 0, 32 }, + { 0, 16, 8 }, + { 16, 0, 8 }, + { 60, 100, 25 }, + { 100, 60, 25 }, + { 123, 54, 24 }, + { 54, 123, 24 }, + }; + const struct param *p; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + p = &tests[i]; + ret = do_test(uts, ".l", p->d, p->s, p->count); + if (ret) + return ret; + } + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + p = &tests[i]; + ret = do_test(uts, "", p->d, p->s, p->count); + if (ret) + return ret; + } + + return 0; +} +MEM_TEST(mem_test_cp_l); + +#if MEM_SUPPORT_64BIT_DATA +static int mem_test_cp_q(struct unit_test_state *uts) +{ + static const struct param tests[] = { + { 0, 128, 16 }, + { 128, 0, 16 }, + { 0, 16, 8 }, + { 16, 0, 8 }, + { 60, 100, 15 }, + { 100, 60, 15 }, + { 123, 54, 12 }, + { 54, 123, 12 }, + }; + const struct param *p; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + p = &tests[i]; + ret = do_test(uts, ".q", p->d, p->s, p->count); + if (ret) + return ret; + } + + return 0; +} +MEM_TEST(mem_test_cp_q); +#endif diff --git a/test/dm/spmi.c b/test/dm/spmi.c index 9cc284b98c..97bb0eb30f 100644 --- a/test/dm/spmi.c +++ b/test/dm/spmi.c @@ -81,7 +81,7 @@ static int dm_test_spmi_access_peripheral(struct unit_test_state *uts) int offset_count; /* Get second pin of PMIC GPIO */ - ut_assertok(gpio_lookup_name("spmi1", &dev, &offset, &gpio)); + ut_assertok(gpio_lookup_name("pmic1", &dev, &offset, &gpio)); /* Check if PMIC is parent */ ut_asserteq(device_get_uclass_id(dev->parent), UCLASS_PMIC); @@ -92,7 +92,7 @@ static int dm_test_spmi_access_peripheral(struct unit_test_state *uts) name = gpio_get_bank_info(dev, &offset_count); /* Check bank name */ - ut_asserteq_str("spmi", name); + ut_asserteq_str("pmic", name); /* Check pin count */ ut_asserteq(4, offset_count); diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh index dec2634de3..257b50fd06 100755 --- a/test/fs/fs-test.sh +++ b/test/fs/fs-test.sh @@ -23,7 +23,7 @@ # -------------------------------------------- # pre-requisite binaries list. -PREREQ_BINS="md5sum mkfs mount umount dd fallocate mkdir" +PREREQ_BINS="sha256sum mkfs mount umount dd fallocate mkdir" # All generated output files from this test will be in $OUT_DIR # Hence everything is sandboxed. @@ -44,9 +44,9 @@ SMALL_FILE="1MB.file" # $BIG_FILE is the name of the 2.5GB file in the file system image BIG_FILE="2.5GB.file" -# $MD5_FILE will have the expected md5s when we do the test +# $HASH_FILE will have the expected hashes when we do the test # They shall have a suffix which represents their file system (ext4/fat16/...) -MD5_FILE="${OUT_DIR}/md5s.list" +HASH_FILE="${OUT_DIR}/hash.list" # $OUT shall be the prefix of the test output. Their suffix will be .out OUT="${OUT_DIR}/fs-test" @@ -103,7 +103,7 @@ function compile_sandbox() { # Clean out all generated files other than the file system images # We save time by not deleting and recreating the file system images function prepare_env() { - rm -f ${MD5_FILE}.* ${OUT}.* + rm -f ${HASH_FILE}.* ${OUT}.* mkdir -p ${OUT_DIR} } @@ -254,14 +254,14 @@ setenv filesize ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL printenv filesize # Test Case 4b - Read full 1MB of small file -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # Test Case 5a - First 1MB of big file ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x0 printenv filesize # Test Case 5b - First 1MB of big file -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # fails for ext as no offset support @@ -269,7 +269,7 @@ setenv filesize ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x9C300000 printenv filesize # Test Case 6b - Last 1MB of big file -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # fails for ext as no offset support @@ -277,7 +277,7 @@ setenv filesize ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF00000 printenv filesize # Test Case 7b - One from the last 1MB chunk of 2GB -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # fails for ext as no offset support @@ -285,7 +285,7 @@ setenv filesize ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x80000000 printenv filesize # Test Case 8b - One from the start 1MB chunk from 2GB -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # fails for ext as no offset support @@ -293,7 +293,7 @@ setenv filesize ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_BIG $length 0x7FF80000 printenv filesize # Test Case 9b - One 1MB chunk crossing the 2GB boundary -md5sum $addr \$filesize +hash sha256 $addr \$filesize setenv filesize # Generic failure case @@ -309,8 +309,8 @@ ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL ${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}$FILE_WRITE \$filesize mw.b $addr 00 100 ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_WRITE -# Test Case 11b - Check md5 of written to is same as the one read from -md5sum $addr \$filesize +# Test Case 11b - Check hash of written to is same as the one read from +hash sha256 $addr \$filesize setenv filesize # @@ -327,13 +327,13 @@ ${PREFIX}load host${SUFFIX} $addr ${FPATH}$FILE_SMALL ${PREFIX}${WRITE} host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2 \$filesize mw.b $addr 00 100 ${PREFIX}load host${SUFFIX} $addr ${FPATH}./${FILE_WRITE}2 -# Test Case 13b - Check md5 of written to is same as the one read from -md5sum $addr \$filesize +# Test Case 13b - Check hash of written to is same as the one read from +hash sha256 $addr \$filesize setenv filesize mw.b $addr 00 100 ${PREFIX}load host${SUFFIX} $addr ${FPATH}${FILE_WRITE}2 -# Test Case 13c - Check md5 of written to is same as the one read from -md5sum $addr \$filesize +# Test Case 13c - Check hash of written to is same as the one read from + hasheshash sha256 $addr \$filesize setenv filesize # reset @@ -342,7 +342,7 @@ EOF } # 1st argument is the name of the image file. -# 2nd argument is the file where we generate the md5s of the files +# 2nd argument is the file where we generate the hashes of the files # generated with the appropriate start and length that we use to test. # It creates the necessary files in the image to test. # $GB2p5 is the path of the big file (2.5 GB) @@ -380,29 +380,29 @@ function create_files() { sudo rm -f "${MB1}.w" sudo rm -f "${MB1}.w2" - # Generate the md5sums of reads that we will test against small file - dd if="${MB1}" bs=1M skip=0 count=1 2> /dev/null | md5sum > "$2" + # Generate the hashes of reads that we will test against small file + dd if="${MB1}" bs=1M skip=0 count=1 2> /dev/null | sha256sum > "$2" - # Generate the md5sums of reads that we will test against big file + # Generate the hashes of reads that we will test against big file # One from beginning of file. dd if="${GB2p5}" bs=1M skip=0 count=1 \ - 2> /dev/null | md5sum >> "$2" + 2> /dev/null | sha256sum >> "$2" # One from end of file. dd if="${GB2p5}" bs=1M skip=2499 count=1 \ - 2> /dev/null | md5sum >> "$2" + 2> /dev/null | sha256sum >> "$2" # One from the last 1MB chunk of 2GB dd if="${GB2p5}" bs=1M skip=2047 count=1 \ - 2> /dev/null | md5sum >> "$2" + 2> /dev/null | sha256sum >> "$2" # One from the start 1MB chunk from 2GB dd if="${GB2p5}" bs=1M skip=2048 count=1 \ - 2> /dev/null | md5sum >> "$2" + 2> /dev/null | sha256sum >> "$2" # One 1MB chunk crossing the 2GB boundary dd if="${GB2p5}" bs=512K skip=4095 count=2 \ - 2> /dev/null | md5sum >> "$2" + 2> /dev/null | sha256sum >> "$2" sync sudo umount "$MOUNT_DIR" @@ -422,35 +422,35 @@ function pass_fail() { fi } -# 1st parameter is the string which leads to an md5 generation +# 1st parameter is the string which leads to an hash generation # 2nd parameter is the file we grep, for that string -# 3rd parameter is the name of the file which has md5s in it -# 4th parameter is the line # in the md5 file that we match it against -# This function checks if the md5 of the file in the sandbox matches +# 3rd parameter is the name of the file which has hashes in it +# 4th parameter is the line # in the hash file that we match against +# This function checks if the hash of the file in the sandbox matches # that calculated while generating the file # 5th parameter is the string to print with the result -check_md5() { - # md5sum in u-boot has output of form: - # md5 for 01000008 ... 01100007 ==> <md5> - # the 7th field is the actual md5 - md5_src=`grep -A2 "$1" "$2" | grep "md5 for" | tr -d '\r'` - md5_src=($md5_src) - md5_src=${md5_src[6]} - - # The md5 list, each line is of the form: - # - <md5> - # the 2nd field is the actual md5 - md5_dst=`sed -n $4p $3` - md5_dst=($md5_dst) - md5_dst=${md5_dst[0]} +check_hash() { + # hash cmd output in u-boot has output of form: + # sha256 for 01000008 ... 01100007 ==> <hash> + # the 7th field is the actual hash + hash_src=`grep -A2 "$1" "$2" | grep "sha256 for" | tr -d '\r'` + hash_src=($hash_src) + hash_src=${hash_src[6]} + + # The hash list, each line is of the form: + # - <hash> + # the 2nd field is the actual hash + hash_dst=`sed -n $4p $3` + hash_dst=($hash_dst) + hash_dst=${hash_dst[0]} # For a pass they should match. - [ "$md5_src" = "$md5_dst" ] + [ "$hash_src" = "$hash_dst" ] pass_fail "$5" } # 1st parameter is the name of the output file to check -# 2nd parameter is the name of the file containing the md5 expected +# 2nd parameter is the name of the file containing the expected hash # 3rd parameter is the name of the small file # 4th parameter is the name of the big file # 5th paramter is the name of the written file @@ -483,34 +483,34 @@ function check_results() { # Check read full mb of 1MB.file grep -A4 "Test Case 4a " "$1" | grep -q "filesize=100000" pass_fail "TC4: load of $3 size" - check_md5 "Test Case 4b " "$1" "$2" 1 "TC4: load from $3" + check_hash "Test Case 4b " "$1" "$2" 1 "TC4: load from $3" # Check first mb of 2.5GB.file grep -A4 "Test Case 5a " "$1" | grep -q "filesize=100000" pass_fail "TC5: load of 1st MB from $4 size" - check_md5 "Test Case 5b " "$1" "$2" 2 "TC5: load of 1st MB from $4" + check_hash "Test Case 5b " "$1" "$2" 2 "TC5: load of 1st MB from $4" # Check last mb of 2.5GB.file grep -A4 "Test Case 6a " "$1" | grep -q "filesize=100000" pass_fail "TC6: load of last MB from $4 size" - check_md5 "Test Case 6b " "$1" "$2" 3 "TC6: load of last MB from $4" + check_hash "Test Case 6b " "$1" "$2" 3 "TC6: load of last MB from $4" # Check last 1mb chunk of 2gb from 2.5GB file grep -A4 "Test Case 7a " "$1" | grep -q "filesize=100000" pass_fail "TC7: load of last 1mb chunk of 2GB from $4 size" - check_md5 "Test Case 7b " "$1" "$2" 4 \ + check_hash "Test Case 7b " "$1" "$2" 4 \ "TC7: load of last 1mb chunk of 2GB from $4" # Check first 1mb chunk after 2gb from 2.5GB file grep -A4 "Test Case 8a " "$1" | grep -q "filesize=100000" pass_fail "TC8: load 1st MB chunk after 2GB from $4 size" - check_md5 "Test Case 8b " "$1" "$2" 5 \ + check_hash "Test Case 8b " "$1" "$2" 5 \ "TC8: load 1st MB chunk after 2GB from $4" # Check 1mb chunk crossing the 2gb boundary from 2.5GB file grep -A4 "Test Case 9a " "$1" | grep -q "filesize=100000" pass_fail "TC9: load 1MB chunk crossing 2GB boundary from $4 size" - check_md5 "Test Case 9b " "$1" "$2" 6 \ + check_hash "Test Case 9b " "$1" "$2" 6 \ "TC9: load 1MB chunk crossing 2GB boundary from $4" # Check 2mb chunk from the last 1MB of 2.5GB file loads 1MB @@ -520,7 +520,7 @@ function check_results() { # Check 1mb chunk write grep -A2 "Test Case 11a " "$1" | grep -q '1048576 bytes written' pass_fail "TC11: 1MB write to $3.w - write succeeded" - check_md5 "Test Case 11b " "$1" "$2" 1 \ + check_hash "Test Case 11b " "$1" "$2" 1 \ "TC11: 1MB write to $3.w - content verified" # Check lookup of 'dot' directory @@ -530,9 +530,9 @@ function check_results() { # Check directory traversal grep -A2 "Test Case 13a " "$1" | grep -q '1048576 bytes written' pass_fail "TC13: 1MB write to ./$3.w2 - write succeeded" - check_md5 "Test Case 13b " "$1" "$2" 1 \ + check_hash "Test Case 13b " "$1" "$2" 1 \ "TC13: 1MB read from ./$3.w2 - content verified" - check_md5 "Test Case 13c " "$1" "$2" 1 \ + check_hash "Test Case 13c " "$1" "$2" 1 \ "TC13: 1MB read from $3.w2 - content verified" echo "** End $1" @@ -543,7 +543,7 @@ function check_results() { # be performed. function test_fs_nonfs() { echo "Creating files in $fs image if not already present." - create_files $IMAGE $MD5_FILE_FS + create_files $IMAGE $HASH_FILE_FS OUT_FILE="${OUT}.$1.${fs}.out" test_image $IMAGE $fs $SMALL_FILE $BIG_FILE $1 "" \ @@ -552,7 +552,7 @@ function test_fs_nonfs() { grep -v -e "File System is consistent\|update journal finished" \ -e "reading .*\.file\|writing .*\.file.w" \ < ${OUT_FILE} > ${OUT_FILE}_clean - check_results ${OUT_FILE}_clean $MD5_FILE_FS $SMALL_FILE \ + check_results ${OUT_FILE}_clean $HASH_FILE_FS $SMALL_FILE \ $BIG_FILE TOTAL_FAIL=$((TOTAL_FAIL + FAIL)) TOTAL_PASS=$((TOTAL_PASS + PASS)) @@ -580,12 +580,12 @@ for fs in ext4 fat16 fat32; do echo "Creating $fs image if not already present." IMAGE=${IMG}.${fs}.img - MD5_FILE_FS="${MD5_FILE}.${fs}" + HASH_FILE_FS="${HASH_FILE}.${fs}" create_image $IMAGE $fs # host commands test echo "Creating files in $fs image if not already present." - create_files $IMAGE $MD5_FILE_FS + create_files $IMAGE $HASH_FILE_FS # Lets mount the image and test host hostfs commands mkdir -p "$MOUNT_DIR" @@ -606,7 +606,7 @@ for fs in ext4 fat16 fat32; do sudo umount "$MOUNT_DIR" rmdir "$MOUNT_DIR" - check_results $OUT_FILE $MD5_FILE_FS $SMALL_FILE $BIG_FILE + check_results $OUT_FILE $HASH_FILE_FS $SMALL_FILE $BIG_FILE TOTAL_FAIL=$((TOTAL_FAIL + FAIL)) TOTAL_PASS=$((TOTAL_PASS + PASS)) echo "Summary: PASS: $PASS FAIL: $FAIL" diff --git a/test/hush/dollar.c b/test/hush/dollar.c index 4caa07c192..68d0874d90 100644 --- a/test/hush/dollar.c +++ b/test/hush/dollar.c @@ -53,29 +53,12 @@ static int hush_test_simple_dollar(struct unit_test_state *uts) ut_asserteq(1, run_command("dollar_foo='bar quux", 0)); /* Next line contains error message */ ut_assert_skipline(); - - if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) { - /* - * For some strange reasons, the console is not empty after - * running above command. - * So, we reset it to not have side effects for other tests. - */ - console_record_reset_enable(); - } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - ut_assert_console_end(); - } + ut_assert_console_end(); ut_asserteq(1, run_command("dollar_foo=bar quux\"", 0)); - /* Two next lines contain error message */ - ut_assert_skipline(); + /* Next line contains error message */ ut_assert_skipline(); - - if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) { - /* See above comments. */ - console_record_reset_enable(); - } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) { - ut_assert_console_end(); - } + ut_assert_console_end(); ut_assertok(run_command("dollar_foo='bar \"quux'", 0)); diff --git a/test/py/requirements.txt b/test/py/requirements.txt index f7e76bdb91..07348b6159 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -12,7 +12,7 @@ packaging==21.3 pbr==5.4.3 pluggy==0.13.0 py==1.10.0 -pycryptodomex==3.9.8 +pycryptodomex==3.19.1 pyelftools==0.27 pygit2==1.9.2 pyparsing==3.0.7 diff --git a/test/py/tests/test_i2c.py b/test/py/tests/test_i2c.py new file mode 100644 index 0000000000..825d0c2e6e --- /dev/null +++ b/test/py/tests/test_i2c.py @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import random +import re + +""" +Note: This test relies on boardenv_* containing configuration values to define +the i2c device info including the bus list and eeprom address/value. This test +will be automatically skipped without this. + +For example: + +# Setup env__i2c_device_test to set the i2c bus list and probe_all boolean +# parameter. For i2c_probe_all_buses case, if probe_all parameter is set to +# False then it probes all the buses listed in bus_list instead of probing all +# the buses available. +env__i2c_device_test = { + 'bus_list': [0, 2, 5, 12, 16, 18], + 'probe_all': False, +} + +# Setup env__i2c_eeprom_device_test to set the i2c bus number, eeprom address +# and configured value for i2c_eeprom test case. Test will be skipped if +# env__i2c_eeprom_device_test is not set +env__i2c_eeprom_device_test = { + 'bus': 3, + 'eeprom_addr': 0x54, + 'eeprom_val': '30 31', +} +""" + +def get_i2c_test_env(u_boot_console): + f = u_boot_console.config.env.get("env__i2c_device_test", None) + if not f: + pytest.skip("No I2C device to test!") + else: + bus_list = f.get("bus_list", None) + if not bus_list: + pytest.skip("I2C bus list is not provided!") + probe_all = f.get("probe_all", False) + return bus_list, probe_all + +@pytest.mark.buildconfigspec("cmd_i2c") +def test_i2c_bus(u_boot_console): + bus_list, probe = get_i2c_test_env(u_boot_console) + bus = random.choice(bus_list) + expected_response = f"Bus {bus}:" + response = u_boot_console.run_command("i2c bus") + assert expected_response in response + +@pytest.mark.buildconfigspec("cmd_i2c") +def test_i2c_dev(u_boot_console): + bus_list, probe = get_i2c_test_env(u_boot_console) + expected_response = "Current bus is" + response = u_boot_console.run_command("i2c dev") + assert expected_response in response + +@pytest.mark.buildconfigspec("cmd_i2c") +def test_i2c_probe(u_boot_console): + bus_list, probe = get_i2c_test_env(u_boot_console) + bus = random.choice(bus_list) + expected_response = f"Setting bus to {bus}" + response = u_boot_console.run_command(f"i2c dev {bus}") + assert expected_response in response + expected_response = "Valid chip addresses:" + response = u_boot_console.run_command("i2c probe") + assert expected_response in response + +@pytest.mark.buildconfigspec("cmd_i2c") +def test_i2c_eeprom(u_boot_console): + f = u_boot_console.config.env.get("env__i2c_eeprom_device_test", None) + if not f: + pytest.skip("No I2C eeprom to test!") + + bus = f.get("bus", 0) + if bus < 0: + pytest.fail("No bus specified via env__i2c_eeprom_device_test!") + + addr = f.get("eeprom_addr", -1) + if addr < 0: + pytest.fail("No eeprom address specified via env__i2c_eeprom_device_test!") + + value = f.get("eeprom_val") + if not value: + pytest.fail( + "No eeprom configured value provided via env__i2c_eeprom_device_test!" + ) + + # Enable i2c mux bridge + u_boot_console.run_command("i2c dev %x" % bus) + u_boot_console.run_command("i2c probe") + output = u_boot_console.run_command("i2c md %x 0 5" % addr) + assert value in output + +@pytest.mark.buildconfigspec("cmd_i2c") +def test_i2c_probe_all_buses(u_boot_console): + bus_list, probe = get_i2c_test_env(u_boot_console) + bus = random.choice(bus_list) + expected_response = f"Bus {bus}:" + response = u_boot_console.run_command("i2c bus") + assert expected_response in response + + # Get all the bus list + if probe: + buses = re.findall("Bus (.+?):", response) + bus_list = [int(x) for x in buses] + + for dev in bus_list: + expected_response = f"Setting bus to {dev}" + response = u_boot_console.run_command(f"i2c dev {dev}") + assert expected_response in response + expected_response = "Valid chip addresses:" + response = u_boot_console.run_command("i2c probe") + assert expected_response in response diff --git a/test/py/tests/test_mdio.py b/test/py/tests/test_mdio.py new file mode 100644 index 0000000000..89711e70b5 --- /dev/null +++ b/test/py/tests/test_mdio.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import re + +""" +Note: This test relies on boardenv_* containing configuration values to define +the PHY device info including the device name, address, register address/value +and write data value. This test will be automatically skipped without this. + +For example: + +# Setup env__mdio_util_test to set the PHY address, device names, register +# address, register address value, and write data value to test mdio commands. +# Test will be skipped if env_mdio_util_test is not set +env__mdio_util_test = { + "eth0": {"phy_addr": 0xc, "device_name": "TI DP83867", "reg": 0, + "reg_val": 0x1000, "write_val": 0x100}, + "eth1": {"phy_addr": 0xa0, "device_name": "TI DP83867", "reg": 1, + "reg_val": 0x2000, "write_val": 0x100}, +} +""" + +def get_mdio_test_env(u_boot_console): + f = u_boot_console.config.env.get("env__mdio_util_test", None) + if not f or len(f) == 0: + pytest.skip("No PHY device to test!") + else: + return f + +@pytest.mark.buildconfigspec("cmd_mii") +@pytest.mark.buildconfigspec("phylib") +def test_mdio_list(u_boot_console): + f = get_mdio_test_env(u_boot_console) + output = u_boot_console.run_command("mdio list") + for dev, val in f.items(): + phy_addr = val.get("phy_addr") + dev_name = val.get("device_name") + + assert f"{phy_addr:x} -" in output + assert dev_name in output + +@pytest.mark.buildconfigspec("cmd_mii") +@pytest.mark.buildconfigspec("phylib") +def test_mdio_read(u_boot_console): + f = get_mdio_test_env(u_boot_console) + output = u_boot_console.run_command("mdio list") + for dev, val in f.items(): + phy_addr = hex(val.get("phy_addr")) + dev_name = val.get("device_name") + reg = hex(val.get("reg")) + reg_val = hex(val.get("reg_val")) + + output = u_boot_console.run_command(f"mdio read {phy_addr} {reg}") + assert f"PHY at address {int(phy_addr, 16):x}:" in output + assert f"{int(reg, 16):x} - {reg_val}" in output + +@pytest.mark.buildconfigspec("cmd_mii") +@pytest.mark.buildconfigspec("phylib") +def test_mdio_write(u_boot_console): + f = get_mdio_test_env(u_boot_console) + output = u_boot_console.run_command("mdio list") + for dev, val in f.items(): + phy_addr = hex(val.get("phy_addr")) + dev_name = val.get("device_name") + reg = hex(val.get("reg")) + reg_val = hex(val.get("reg_val")) + wr_val = hex(val.get("write_val")) + + u_boot_console.run_command(f"mdio write {phy_addr} {reg} {wr_val}") + output = u_boot_console.run_command(f"mdio read {phy_addr} {reg}") + assert f"PHY at address {int(phy_addr, 16):x}:" in output + assert f"{int(reg, 16):x} - {wr_val}" in output + + u_boot_console.run_command(f"mdio write {phy_addr} {reg} {reg_val}") + output = u_boot_console.run_command(f"mdio read {phy_addr} {reg}") + assert f"PHY at address {int(phy_addr, 16):x}:" in output + assert f"{int(reg, 16):x} - {reg_val}" in output diff --git a/test/py/tests/test_memtest.py b/test/py/tests/test_memtest.py new file mode 100644 index 0000000000..0618d96f1b --- /dev/null +++ b/test/py/tests/test_memtest.py @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest + +""" +Note: This test relies on boardenv_* containing configuration values to define +the memory test parameters such as start address, memory size, pattern, +iterations and timeout. This test will be automatically skipped without this. + +For example: + +# Setup env__memtest to set the start address of the memory range, size of the +# memory range to test from starting address, pattern to be written to memory, +# number of test iterations, and expected time to complete the test of mtest +# command. start address, size, and pattern parameters value should be in hex +# and rest of the params value should be integer. +env__memtest = { + 'start_addr': 0x0, + 'size': 0x1000, + 'pattern': 0x0, + 'iteration': 16, + 'timeout': 50000, +} +""" + +def get_memtest_env(u_boot_console): + f = u_boot_console.config.env.get("env__memtest", None) + if not f: + pytest.skip("memtest is not enabled!") + else: + start = f.get("start_addr", 0x0) + size = f.get("size", 0x1000) + pattern = f.get("pattern", 0x0) + iteration = f.get("iteration", 2) + timeout = f.get("timeout", 50000) + end = hex(int(start) + int(size)) + return start, end, pattern, iteration, timeout + +@pytest.mark.buildconfigspec("cmd_memtest") +def test_memtest_negative(u_boot_console): + """Negative testcase where end address is smaller than starting address and + pattern is invalid.""" + start, end, pattern, iteration, timeout = get_memtest_env(u_boot_console) + expected_response = "Refusing to do empty test" + response = u_boot_console.run_command( + f"mtest 2000 1000 {pattern} {hex(iteration)}" + ) + assert expected_response in response + output = u_boot_console.run_command("echo $?") + assert not output.endswith("0") + u_boot_console.run_command(f"mtest {start} {end} 'xyz' {hex(iteration)}") + output = u_boot_console.run_command("echo $?") + assert not output.endswith("0") + +@pytest.mark.buildconfigspec("cmd_memtest") +def test_memtest_ddr(u_boot_console): + """Test that md reads memory as expected, and that memory can be modified + using the mw command.""" + start, end, pattern, iteration, timeout = get_memtest_env(u_boot_console) + expected_response = f"Tested {str(iteration)} iteration(s) with 0 errors." + with u_boot_console.temporary_timeout(timeout): + response = u_boot_console.run_command( + f"mtest {start} {end} {pattern} {hex(iteration)}" + ) + assert expected_response in response + output = u_boot_console.run_command("echo $?") + assert output.endswith("0") diff --git a/test/py/tests/test_mii.py b/test/py/tests/test_mii.py new file mode 100644 index 0000000000..7b6816d108 --- /dev/null +++ b/test/py/tests/test_mii.py @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import re + +""" +Note: This test doesn't rely on boardenv_* configuration value but they can +change test behavior. + +For example: + +# Setup env__mii_deive_test_skip to True if tests with ethernet PHY devices +# should be skipped. For example: Missing PHY device +env__mii_device_test_skip = True + +# Setup env__mii_device_test to set the MII device names. Test will be skipped +# if env_mii_device_test is not set +env__mii_device_test = { + 'device_list': ['eth0', 'eth1'], +} +""" + +@pytest.mark.buildconfigspec("cmd_mii") +def test_mii_info(u_boot_console): + if u_boot_console.config.env.get("env__mii_device_test_skip", False): + pytest.skip("MII device test is not enabled!") + expected_output = "PHY" + output = u_boot_console.run_command("mii info") + if not re.search(r"PHY (.+?):", output): + pytest.skip("PHY device does not exist!") + assert expected_output in output + +@pytest.mark.buildconfigspec("cmd_mii") +def test_mii_list(u_boot_console): + if u_boot_console.config.env.get("env__mii_device_test_skip", False): + pytest.skip("MII device test is not enabled!") + + f = u_boot_console.config.env.get("env__mii_device_test", None) + if not f: + pytest.skip("No MII device to test!") + + dev_list = f.get("device_list") + if not dev_list: + pytest.fail("No MII device list provided via env__mii_device_test!") + + expected_output = "Current device" + output = u_boot_console.run_command("mii device") + mii_devices = ( + re.search(r"MII devices: '(.+)'", output).groups()[0].replace("'", "").split() + ) + + assert len([x for x in dev_list if x in mii_devices]) == len(dev_list) + assert expected_output in output + +@pytest.mark.buildconfigspec("cmd_mii") +def test_mii_set_device(u_boot_console): + test_mii_list(u_boot_console) + f = u_boot_console.config.env.get("env__mii_device_test", None) + dev_list = f.get("device_list") + output = u_boot_console.run_command("mii device") + current_dev = re.search(r"Current device: '(.+?)'", output).groups()[0] + + for dev in dev_list: + u_boot_console.run_command(f"mii device {dev}") + output = u_boot_console.run_command("echo $?") + assert output.endswith("0") + + u_boot_console.run_command(f"mii device {current_dev}") + output = u_boot_console.run_command("mii device") + dev = re.search(r"Current device: '(.+?)'", output).groups()[0] + assert current_dev == dev + +@pytest.mark.buildconfigspec("cmd_mii") +def test_mii_read(u_boot_console): + test_mii_list(u_boot_console) + 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 read {eth_addr} 0") + output = u_boot_console.run_command("echo $?") + assert output.endswith("0") + +@pytest.mark.buildconfigspec("cmd_mii") +def test_mii_dump(u_boot_console): + test_mii_list(u_boot_console) + expected_response = "PHY control register" + output = u_boot_console.run_command("mii info") + eth_addr = hex(int(re.search(r"PHY (.+?):", output).groups()[0], 16)) + response = u_boot_console.run_command(f"mii dump {eth_addr} 0") + assert expected_response in response + output = u_boot_console.run_command("echo $?") + assert output.endswith("0") diff --git a/test/py/tests/test_net.py b/test/py/tests/test_net.py index 2495608786..cc2e53c698 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,11 @@ 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. +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. @@ -99,6 +105,8 @@ def test_net_pre_commands(u_boot_console): if init_pci: u_boot_console.run_command('pci enum') + u_boot_console.run_command('net list') + @pytest.mark.buildconfigspec('cmd_dhcp') def test_net_dhcp(u_boot_console): """Test the dhcp command. @@ -118,6 +126,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", False): + 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") + + # 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 + + # 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. |