From a8c07ac4970d92dce76d93e61fdddb7f3bea65e4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:41 -0600 Subject: [PATCH 01/30] alist: Mention the error condition in alist_add_placeholder() Update the function comment to note that this function can return NULL if it runs out of memory. Signed-off-by: Simon Glass --- include/alist.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/alist.h b/include/alist.h index 68d268f01af..0343946bc4a 100644 --- a/include/alist.h +++ b/include/alist.h @@ -151,8 +151,9 @@ void *alist_ensure_ptr(struct alist *lst, uint index); * alist_add_placeholder() - Add a new item to the end of the list * * @lst: alist to add to - * Return: Pointer to the newly added position. Note that this is not inited so - * the caller must copy the requested struct to the returned pointer + * Return: Pointer to the newly added position, or NULL if out of memory. Note + * that this is not inited so the caller must copy the requested struct to the + * returned pointer */ void *alist_add_placeholder(struct alist *lst); From 13bd29849953c7d5294b64ba22495a928dd70d80 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:42 -0600 Subject: [PATCH 02/30] alist: Add a comment for alist_init_struct() Comment this macro so that it is clear how to use it. Signed-off-by: Simon Glass --- include/alist.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/alist.h b/include/alist.h index 0343946bc4a..a727f1c7dfa 100644 --- a/include/alist.h +++ b/include/alist.h @@ -198,6 +198,12 @@ bool alist_expand_by(struct alist *lst, uint inc_by); */ bool alist_init(struct alist *lst, uint obj_size, uint alloc_size); +/** + * alist_init_struct() - Typed version of alist_init() + * + * Use as: + * alist_init(&lst, struct my_struct); + */ #define alist_init_struct(_lst, _struct) \ alist_init(_lst, sizeof(_struct), 0) From 6668d860f78035969db301f2c43266094d455191 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:43 -0600 Subject: [PATCH 03/30] alist: Expand the comment for alist_get() Add a better description for this macro. Signed-off-by: Simon Glass --- include/alist.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/alist.h b/include/alist.h index a727f1c7dfa..2c78ede201e 100644 --- a/include/alist.h +++ b/include/alist.h @@ -116,7 +116,12 @@ static inline const void *alist_getd(struct alist *lst, uint index) return lst->data + index * lst->obj_size; } -/** get an entry as a constant */ +/** + * alist_get() - get an entry as a constant + * + * Use as (to obtain element 2 of the list): + * const struct my_struct *ptr = alist_get(lst, 2, struct my_struct) + */ #define alist_get(_lst, _index, _struct) \ ((const _struct *)alist_get_ptr(_lst, _index)) From 2ce146a3de7beeaa89ef4f8677fe71a38546156b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:44 -0600 Subject: [PATCH 04/30] alist: Add a way to get the next element Add a new function which returns the next element after the one provided, if it exists in the list. Signed-off-by: Simon Glass --- include/alist.h | 34 +++++++++++++++++++++++++++++++ lib/alist.c | 21 +++++++++++++++++++ test/lib/alist.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/include/alist.h b/include/alist.h index 2c78ede201e..97523af37a6 100644 --- a/include/alist.h +++ b/include/alist.h @@ -71,6 +71,21 @@ static inline bool alist_has(struct alist *lst, uint index) return index < lst->count; } +/** + * alist_calc_index() - Calculate the index of an item in the list + * + * The returned element number will be -1 if the list is empty or the pointer + * pointers to before the list starts. + * + * If the pointer points to after the last item, the calculated element-number + * will be returned, even though it is greater than lst->count + * + * @lst: alist to check + * @ptr: pointer to check + * Return: element number of the pointer + */ +int alist_calc_index(const struct alist *lst, const void *ptr); + /** * alist_err() - Check if the alist is still valid * @@ -190,6 +205,25 @@ bool alist_expand_by(struct alist *lst, uint inc_by); #define alist_add(_lst, _obj) \ ((typeof(_obj) *)alist_add_ptr(_lst, &(_obj))) +/** get next entry as a constant */ +#define alist_next(_lst, _objp) \ + ((const typeof(_objp))alist_next_ptrd(_lst, _objp)) + +/** get next entry, which can be written to */ +#define alist_nextw(_lst, _objp) \ + ((typeof(_objp))alist_next_ptrd(_lst, _objp)) + +/** + * alist_next_ptrd() - Get a pointer to the next list element + * + * This returns NULL if the requested element is beyond lst->count + * + * @lst: List to check + * @ptr: Pointer to current element (must be valid) + * Return: Pointer to next element, or NULL if @ptr is the last + */ +const void *alist_next_ptrd(const struct alist *lst, const void *ptr); + /** * alist_init() - Set up a new object list * diff --git a/lib/alist.c b/lib/alist.c index b7928cad520..7730fe0d473 100644 --- a/lib/alist.c +++ b/lib/alist.c @@ -106,6 +106,27 @@ const void *alist_get_ptr(const struct alist *lst, uint index) return lst->data + index * lst->obj_size; } +int alist_calc_index(const struct alist *lst, const void *ptr) +{ + uint index; + + if (!lst->count || ptr < lst->data) + return -1; + + index = (ptr - lst->data) / lst->obj_size; + + return index; +} + +const void *alist_next_ptrd(const struct alist *lst, const void *ptr) +{ + int index = alist_calc_index(lst, ptr); + + assert(index != -1); + + return alist_get_ptr(lst, index + 1); +} + void *alist_ensure_ptr(struct alist *lst, uint index) { uint minsize = index + 1; diff --git a/test/lib/alist.c b/test/lib/alist.c index d41845c7e6c..96092affec9 100644 --- a/test/lib/alist.c +++ b/test/lib/alist.c @@ -240,3 +240,55 @@ static int lib_test_alist_add(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_alist_add, 0); + +/* Test alist_next() */ +static int lib_test_alist_next(struct unit_test_state *uts) +{ + const struct my_struct *ptr; + struct my_struct data, *ptr2; + struct alist lst; + ulong start; + + start = ut_check_free(); + + ut_assert(alist_init_struct(&lst, struct my_struct)); + data.val = 123; + data.other_val = 0; + alist_add(&lst, data); + + data.val = 321; + alist_add(&lst, data); + + data.val = 789; + alist_add(&lst, data); + + ptr = alist_get(&lst, 0, struct my_struct); + ut_assertnonnull(ptr); + ut_asserteq(123, ptr->val); + + ptr = alist_next(&lst, ptr); + ut_assertnonnull(ptr); + ut_asserteq(321, ptr->val); + + ptr2 = (struct my_struct *)ptr; + ptr2 = alist_nextw(&lst, ptr2); + ut_assertnonnull(ptr2); + + ptr = alist_next(&lst, ptr); + ut_assertnonnull(ptr); + ut_asserteq(789, ptr->val); + ut_asserteq_ptr(ptr, ptr2); + ptr2->val = 89; + ut_asserteq(89, ptr->val); + + ptr = alist_next(&lst, ptr); + ut_assertnull(ptr); + + alist_uninit(&lst); + + /* Check for memory leaks */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_alist_next, 0); From 83bc5989fc5f71e2c40d75ea786ccbf937b9fbab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:45 -0600 Subject: [PATCH 05/30] alist: Add for-loop helpers Add some macros which permit easy iteration through an alist, similar to those provided by the 'list' implementation. Signed-off-by: Simon Glass --- include/alist.h | 50 ++++++++++++++++++++++++++++++++ lib/alist.c | 7 +++++ test/lib/alist.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/include/alist.h b/include/alist.h index 97523af37a6..0090b9c0eb1 100644 --- a/include/alist.h +++ b/include/alist.h @@ -224,6 +224,56 @@ bool alist_expand_by(struct alist *lst, uint inc_by); */ const void *alist_next_ptrd(const struct alist *lst, const void *ptr); +/** + * alist_chk_ptr() - Check whether a pointer is within a list + * + * Checks if the pointer points to an existing element of the list. The pointer + * must point to the start of an element, either in the list, or just outside of + * it. This function is only useful for handling for() loops + * + * Return: true if @ptr is within the list (0..count-1), else false + */ +bool alist_chk_ptr(const struct alist *lst, const void *ptr); + +/** + * alist_start() - Get the start of the list (first element) + * + * Note that this will always return ->data even if it is not NULL + * + * Usage: + * const struct my_struct *obj; # 'const' is optional + * + * alist_start(&lst, struct my_struct) + */ +#define alist_start(_lst, _struct) \ + ((_struct *)(_lst)->data) + +/** + * alist_end() - Get the end of the list (just after last element) + * + * Usage: + * const struct my_struct *obj; # 'const' is optional + * + * alist_end(&lst, struct my_struct) + */ +#define alist_end(_lst, _struct) \ + ((_struct *)(_lst)->data + (_lst)->count) + +/** + * alist_for_each() - Iterate over an alist (with constant pointer) + * + * Use as: + * const struct my_struct *obj; # 'const' is optional + * + * alist_for_each(obj, &lst) { + * obj->... + * } + */ +#define alist_for_each(_pos, _lst) \ + for (_pos = alist_start(_lst, typeof(*(_pos))); \ + _pos < alist_end(_lst, typeof(*(_pos))); \ + _pos++) + /** * alist_init() - Set up a new object list * diff --git a/lib/alist.c b/lib/alist.c index 7730fe0d473..1a4b4fb9c40 100644 --- a/lib/alist.c +++ b/lib/alist.c @@ -118,6 +118,13 @@ int alist_calc_index(const struct alist *lst, const void *ptr) return index; } +bool alist_chk_ptr(const struct alist *lst, const void *ptr) +{ + int index = alist_calc_index(lst, ptr); + + return index >= 0 && index < lst->count; +} + const void *alist_next_ptrd(const struct alist *lst, const void *ptr) { int index = alist_calc_index(lst, ptr); diff --git a/test/lib/alist.c b/test/lib/alist.c index 96092affec9..1715a22584c 100644 --- a/test/lib/alist.c +++ b/test/lib/alist.c @@ -292,3 +292,77 @@ static int lib_test_alist_next(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_alist_next, 0); + +/* Test alist_for_each() */ +static int lib_test_alist_for_each(struct unit_test_state *uts) +{ + const struct my_struct *ptr; + struct my_struct data, *ptr2; + struct alist lst; + ulong start; + int sum; + + start = ut_check_free(); + + ut_assert(alist_init_struct(&lst, struct my_struct)); + ut_asserteq_ptr(NULL, alist_end(&lst, struct my_struct)); + + sum = 0; + alist_for_each(ptr, &lst) + sum++; + ut_asserteq(0, sum); + + alist_for_each(ptr, &lst) + sum++; + ut_asserteq(0, sum); + + /* add three items */ + data.val = 1; + data.other_val = 0; + alist_add(&lst, data); + + ptr = lst.data; + ut_asserteq_ptr(ptr + 1, alist_end(&lst, struct my_struct)); + + data.val = 2; + alist_add(&lst, data); + ut_asserteq_ptr(ptr + 2, alist_end(&lst, struct my_struct)); + + data.val = 3; + alist_add(&lst, data); + ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct)); + + /* check alist_chk_ptr() */ + ut_asserteq(true, alist_chk_ptr(&lst, ptr + 2)); + ut_asserteq(false, alist_chk_ptr(&lst, ptr + 3)); + ut_asserteq(false, alist_chk_ptr(&lst, ptr + 4)); + ut_asserteq(true, alist_chk_ptr(&lst, ptr)); + ut_asserteq(false, alist_chk_ptr(&lst, ptr - 1)); + + /* sum all items */ + sum = 0; + alist_for_each(ptr, &lst) + sum += ptr->val; + ut_asserteq(6, sum); + + /* increment all items */ + alist_for_each(ptr2, &lst) + ptr2->val += 1; + + /* sum all items again */ + sum = 0; + alist_for_each(ptr, &lst) + sum += ptr->val; + ut_asserteq(9, sum); + + ptr = lst.data; + ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct)); + + alist_uninit(&lst); + + /* Check for memory leaks */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_alist_for_each, 0); From 70f5f17415a257ce8d5f32df5b40194b89a27960 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:46 -0600 Subject: [PATCH 06/30] alist: Add a function to empty the list Sometimes it is useful to empty the list without de-allocating any of the memory used, e.g. when the list will be re-populated immediately afterwards. Add a new function for this. Signed-off-by: Simon Glass --- include/alist.h | 7 +++++++ lib/alist.c | 5 +++++ test/lib/alist.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/include/alist.h b/include/alist.h index 0090b9c0eb1..c639e42ab7d 100644 --- a/include/alist.h +++ b/include/alist.h @@ -274,6 +274,13 @@ bool alist_chk_ptr(const struct alist *lst, const void *ptr); _pos < alist_end(_lst, typeof(*(_pos))); \ _pos++) +/** + * alist_empty() - Empty an alist + * + * This removes all entries from the list, without changing the allocated size + */ +void alist_empty(struct alist *lst); + /** * alist_init() - Set up a new object list * diff --git a/lib/alist.c b/lib/alist.c index 1a4b4fb9c40..32cd45b0b01 100644 --- a/lib/alist.c +++ b/lib/alist.c @@ -41,6 +41,11 @@ void alist_uninit(struct alist *lst) memset(lst, '\0', sizeof(struct alist)); } +void alist_empty(struct alist *lst) +{ + lst->count = 0; +} + /** * alist_expand_to() - Expand a list to the given size * diff --git a/test/lib/alist.c b/test/lib/alist.c index 1715a22584c..87135bb3a51 100644 --- a/test/lib/alist.c +++ b/test/lib/alist.c @@ -358,6 +358,16 @@ static int lib_test_alist_for_each(struct unit_test_state *uts) ptr = lst.data; ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct)); + /* empty the list and try again */ + alist_empty(&lst); + ut_asserteq_ptr(ptr, alist_end(&lst, struct my_struct)); + ut_assertnull(alist_get(&lst, 0, struct my_struct)); + + sum = 0; + alist_for_each(ptr, &lst) + sum += ptr->val; + ut_asserteq(0, sum); + alist_uninit(&lst); /* Check for memory leaks */ @@ -366,3 +376,35 @@ static int lib_test_alist_for_each(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_alist_for_each, 0); + +/* Test alist_empty() */ +static int lib_test_alist_empty(struct unit_test_state *uts) +{ + struct my_struct data; + struct alist lst; + ulong start; + + start = ut_check_free(); + + ut_assert(alist_init_struct(&lst, struct my_struct)); + ut_asserteq(0, lst.count); + data.val = 1; + data.other_val = 0; + alist_add(&lst, data); + ut_asserteq(1, lst.count); + ut_asserteq(4, lst.alloc); + + alist_empty(&lst); + ut_asserteq(0, lst.count); + ut_asserteq(4, lst.alloc); + ut_assertnonnull(lst.data); + ut_asserteq(sizeof(data), lst.obj_size); + + alist_uninit(&lst); + + /* Check for memory leaks */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_alist_empty, 0); From d01c58acb71874721c05684472412ce169bb7df8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:47 -0600 Subject: [PATCH 07/30] alist: Add a way to efficiently filter an alist Unlike linked lists, it is inefficient to remove items from an alist, particularly if it is large. If most items need to be removed, then the time-complexity approaches O(n2). Provide a way to do this efficiently, by working through the alist once and copying elements down. Signed-off-by: Simon Glass --- include/alist.h | 30 +++++++++++++++++ lib/alist.c | 8 +++++ test/lib/alist.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/include/alist.h b/include/alist.h index c639e42ab7d..b00d9ea97d6 100644 --- a/include/alist.h +++ b/include/alist.h @@ -274,6 +274,36 @@ bool alist_chk_ptr(const struct alist *lst, const void *ptr); _pos < alist_end(_lst, typeof(*(_pos))); \ _pos++) +/** + * alist_for_each_filter() - version which sets up a 'from' pointer too + * + * This is used for filtering out information in the list. It works by iterating + * through the list, copying elements down over the top of elements to be + * deleted. + * + * In this example, 'from' iterates through the list from start to end,, 'to' + * also begins at the start, but only increments if the element at 'from' should + * be kept. This provides an O(n) filtering operation. Note that + * alist_update_end() must be called after the loop, to update the count. + * + * alist_for_each_filter(from, to, &lst) { + * if (from->val != 2) + * *to++ = *from; + * } + * alist_update_end(&lst, to); + */ +#define alist_for_each_filter(_pos, _from, _lst) \ + for (_pos = _from = alist_start(_lst, typeof(*(_pos))); \ + _pos < alist_end(_lst, typeof(*(_pos))); \ + _pos++) + +/** + * alist_update_end() - Set the element count based on a given pointer + * + * Set the given element as the final one + */ +void alist_update_end(struct alist *lst, const void *end); + /** * alist_empty() - Empty an alist * diff --git a/lib/alist.c b/lib/alist.c index 32cd45b0b01..4ce651f5c45 100644 --- a/lib/alist.c +++ b/lib/alist.c @@ -123,6 +123,14 @@ int alist_calc_index(const struct alist *lst, const void *ptr) return index; } +void alist_update_end(struct alist *lst, const void *ptr) +{ + int index; + + index = alist_calc_index(lst, ptr); + lst->count = index == -1 ? 0 : index; +} + bool alist_chk_ptr(const struct alist *lst, const void *ptr) { int index = alist_calc_index(lst, ptr); diff --git a/test/lib/alist.c b/test/lib/alist.c index 87135bb3a51..0bf24578d2e 100644 --- a/test/lib/alist.c +++ b/test/lib/alist.c @@ -408,3 +408,88 @@ static int lib_test_alist_empty(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_alist_empty, 0); + +static int lib_test_alist_filter(struct unit_test_state *uts) +{ + struct my_struct *from, *to, *ptr; + struct my_struct data; + struct alist lst; + ulong start; + int count; + + start = ut_check_free(); + + ut_assert(alist_init_struct(&lst, struct my_struct)); + data.val = 1; + data.other_val = 0; + alist_add(&lst, data); + + data.val = 2; + alist_add(&lst, data); + + data.val = 3; + alist_add(&lst, data); + ptr = lst.data; + + /* filter out all values except 2 */ + alist_for_each_filter(from, to, &lst) { + if (from->val != 2) + *to++ = *from; + } + alist_update_end(&lst, to); + + ut_asserteq(2, lst.count); + ut_assertnonnull(lst.data); + + ut_asserteq(1, alist_get(&lst, 0, struct my_struct)->val); + ut_asserteq(3, alist_get(&lst, 1, struct my_struct)->val); + ut_asserteq_ptr(ptr + 3, from); + ut_asserteq_ptr(ptr + 2, to); + + /* filter out nothing */ + alist_for_each_filter(from, to, &lst) { + if (from->val != 2) + *to++ = *from; + } + alist_update_end(&lst, to); + ut_asserteq_ptr(ptr + 2, from); + ut_asserteq_ptr(ptr + 2, to); + + ut_asserteq(2, lst.count); + ut_assertnonnull(lst.data); + + ut_asserteq(1, alist_get(&lst, 0, struct my_struct)->val); + ut_asserteq(3, alist_get(&lst, 1, struct my_struct)->val); + + /* filter out everything */ + alist_for_each_filter(from, to, &lst) { + if (from->val == 2) + *to++ = *from; + } + alist_update_end(&lst, to); + ut_asserteq_ptr(ptr + 2, from); + ut_asserteq_ptr(ptr, to); + + /* filter out everything (nop) */ + count = 0; + alist_for_each_filter(from, to, &lst) { + if (from->val == 2) + *to++ = *from; + count++; + } + alist_update_end(&lst, to); + ut_asserteq_ptr(ptr, from); + ut_asserteq_ptr(ptr, to); + ut_asserteq(0, count); + + ut_asserteq(0, lst.count); + ut_assertnonnull(lst.data); + + alist_uninit(&lst); + + /* Check for memory leaks */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_alist_filter, 0); From b84c13f37d19a3605bb6e34d26c2396cc0fffd86 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:48 -0600 Subject: [PATCH 08/30] alist: Add maintainer Add myself as maintainer of alist Signed-off-by: Simon Glass --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index df046192ea0..0399ed1dbf6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -58,6 +58,13 @@ F: cmd/acpi.c F: include/acpi/ F: lib/acpi/ +ALIST: +M: Simon Glass +S: Maintained +F: include/alist.h +F: lib/alist.c +F: test/lib/alist.c + ANDROID AB M: Igor Opaniuk M: Mattijs Korpershoek From cedf9ccaa27828876bc29b1dfc721cea2e5e6dfc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:49 -0600 Subject: [PATCH 09/30] dm: core: Add a function to see if a device exists All the uclass functions for finding a device end up creating a uclass if it doesn't exist. Add a function which instead returns NULL in this case. This is useful when in the 'unbind' path, since we don't want to undo any unbinding which has already happened. Signed-off-by: Simon Glass --- drivers/core/uclass.c | 11 +++++++++++ include/dm/uclass.h | 11 +++++++++++ test/dm/core.c | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 7ae0884a75e..f846a35d6b2 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -304,6 +304,17 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name, return uclass_find_device_by_namelen(id, name, strlen(name), devp); } +struct udevice *uclass_try_first_device(enum uclass_id id) +{ + struct uclass *uc; + + uc = uclass_find(id); + if (!uc || list_empty(&uc->dev_head)) + return NULL; + + return list_first_entry(&uc->dev_head, struct udevice, uclass_node); +} + int uclass_find_next_free_seq(struct uclass *uc) { struct udevice *dev; diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 456eef7f2f3..c2793040923 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -435,6 +435,17 @@ int uclass_next_device_check(struct udevice **devp); int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, struct udevice **devp); +/** + * uclass_try_first_device()- See if there is a device for a uclass + * + * If the uclass exists, this returns the first device on that uclass, without + * probing it. If the uclass does not exist, it gives up + * + * @id: Uclass ID to check + * Return: Pointer to device, if found, else NULL + */ +struct udevice *uclass_try_first_device(enum uclass_id id); + /** * uclass_probe_all() - Probe all devices based on an uclass ID * diff --git a/test/dm/core.c b/test/dm/core.c index e0c5b9e0017..7371d3ff426 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -1351,3 +1351,25 @@ static int dm_test_dev_get_mem(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_dev_get_mem, UTF_SCAN_FDT); + +/* Test uclass_try_first_device() */ +static int dm_test_try_first_device(struct unit_test_state *uts) +{ + struct udevice *dev; + + /* Check that it doesn't create a device or uclass */ + ut_assertnull(uclass_find(UCLASS_TEST)); + ut_assertnull(uclass_try_first_device(UCLASS_TEST)); + ut_assertnull(uclass_try_first_device(UCLASS_TEST)); + ut_assertnull(uclass_find(UCLASS_TEST)); + + /* Create a test device */ + ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual, + &dev)); + dev = uclass_try_first_device(UCLASS_TEST); + ut_assertnonnull(dev); + ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev)); + + return 0; +} +DM_TEST(dm_test_try_first_device, 0); From 6e625484f59472663199d1eec4d2e3f226af32b7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:50 -0600 Subject: [PATCH 10/30] test: boot: Use a consistent name for the script bootmeth In the bootflow tests the script bootmeth is bound with the name bootmeth_script whereas the others have a name without the bootmeth_ prefix. Adjust it to be the same. Signed-off-by: Simon Glass Reviewed-by: Mattijs Korpershoek --- test/boot/bootflow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 0d4e966892e..8762d21ef3c 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -542,7 +542,7 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev, /* Enable the script bootmeth too */ ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_2script), - "bootmeth_script", 0, ofnode_null(), &dev)); + "script", 0, ofnode_null(), &dev)); /* Enable the cros bootmeth if needed */ if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros_android) { From 82e6d79d9e044660b2a1310527292d48171c2463 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:46 -0600 Subject: [PATCH 11/30] bloblist: test: Move test into common This test doesn't belong at the top level. Move it into the common/ directory, to match its implementation. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/common/Makefile | 3 +++ test/{ => common}/bloblist.c | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename test/{ => common}/bloblist.c (100%) diff --git a/test/Makefile b/test/Makefile index 145c952d2c3..5d62b5c3357 100644 --- a/test/Makefile +++ b/test/Makefile @@ -5,7 +5,6 @@ obj-y += test-main.o ifneq ($(CONFIG_$(XPL_)BLOBLIST),) -obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o endif obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/ diff --git a/test/common/Makefile b/test/common/Makefile index 12c65f8c951..b6bff9201ec 100644 --- a/test/common/Makefile +++ b/test/common/Makefile @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += cmd_ut_common.o obj-$(CONFIG_AUTOBOOT) += test_autoboot.o +ifneq ($(CONFIG_$(XPL_)BLOBLIST),) +obj-$(CONFIG_$(XPL_)CMDLINE) += bloblist.o +endif obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_EVENT_DYNAMIC) += event.o obj-y += cread.o diff --git a/test/bloblist.c b/test/common/bloblist.c similarity index 100% rename from test/bloblist.c rename to test/common/bloblist.c From 692ed744ba0cd85b6f186a902d4a8b2017880dd9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:47 -0600 Subject: [PATCH 12/30] bloblist: test: Drop global_data declarations This pointer is not used any more, so drop the declarations. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/common/bloblist.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/common/bloblist.c b/test/common/bloblist.c index fd85c7ab79e..7b90fa7f352 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -6,13 +6,10 @@ #include #include #include -#include #include #include #include -DECLARE_GLOBAL_DATA_PTR; - /* Declare a new bloblist test */ #define BLOBLIST_TEST(_name, _flags) \ UNIT_TEST(_name, _flags, bloblist_test) From a5896b8a3e69aa73914bb5811555c89e22a127b5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:48 -0600 Subject: [PATCH 13/30] test: Drop test-trace.sh and common.sh The trace feature is now tested in CI so there is no need for these old script. Also they don't work. Drop them. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/common.sh | 20 ------------- test/trace/test-trace.sh | 64 ---------------------------------------- 2 files changed, 84 deletions(-) delete mode 100644 test/common.sh delete mode 100755 test/trace/test-trace.sh diff --git a/test/common.sh b/test/common.sh deleted file mode 100644 index 904d579b7bf..00000000000 --- a/test/common.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -OUTPUT_DIR=sandbox - -fail() { - echo "Test failed: $1" - if [ -n ${tmp} ]; then - rm ${tmp} - fi - exit 1 -} - -build_uboot() { - echo "Build sandbox" - OPTS="O=${OUTPUT_DIR} $1" - NUM_CPUS=$(nproc) - echo ${OPTS} - make ${OPTS} sandbox_config - make ${OPTS} -s -j${NUM_CPUS} -} diff --git a/test/trace/test-trace.sh b/test/trace/test-trace.sh deleted file mode 100755 index 5130b2bf017..00000000000 --- a/test/trace/test-trace.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0+ -# Copyright (c) 2013 The Chromium OS Authors. -# - -# Simple test script for tracing with sandbox - -TRACE_OPT="FTRACE=1" - -BASE="$(dirname $0)/.." -. $BASE/common.sh - -run_trace() { - echo "Run trace" - ./${OUTPUT_DIR}/u-boot < 0 ? 1 : 0)}')" - - if [ "${counts}" != "1 1 0 1 " ]; then - fail "trace collection error: ${counts}" - fi -} - -echo "Simple trace test / sanity check using sandbox" -echo -tmp="$(tempfile)" -build_uboot "${TRACE_OPT}" -run_trace >${tmp} -check_results ${tmp} -rm ${tmp} -echo "Test passed" From e67cc4ba1f45c2c7ab0ca1e3cf8da1c5893f7cb5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:49 -0600 Subject: [PATCH 14/30] compression: test: Move test into lib This test doesn't belong at the top level. Move it into the lib/ directory, since that is where compression is implemented. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/lib/Makefile | 3 +++ test/{ => lib}/compression.c | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename test/{ => lib}/compression.c (100%) diff --git a/test/Makefile b/test/Makefile index 5d62b5c3357..ff621344a03 100644 --- a/test/Makefile +++ b/test/Makefile @@ -10,7 +10,6 @@ endif obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/ obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o obj-$(CONFIG_$(XPL_)CMDLINE) += command_ut.o -obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o obj-y += dm/ obj-$(CONFIG_FUZZ) += fuzz/ ifndef CONFIG_SANDBOX_VPL diff --git a/test/lib/Makefile b/test/lib/Makefile index a54387a058e..ce22780eed8 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -2,6 +2,9 @@ # # (C) Copyright 2018 # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + +obj-$(CONFIG_$(XPL_)UT_COMPRESSION) += compression.o + ifeq ($(CONFIG_XPL_BUILD),) obj-y += cmd_ut_lib.o obj-y += abuf.o diff --git a/test/compression.c b/test/lib/compression.c similarity index 100% rename from test/compression.c rename to test/lib/compression.c From 5cf39254e3dc1424248e72e428446df251587bbf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:50 -0600 Subject: [PATCH 15/30] compression: test: Move into the lib suite There is no particular need for compression to have its own test suite. Move it into the lib suite instead. Add the missing help for 'common' and update the docs. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- include/test/compression.h | 16 ---------------- test/cmd_ut.c | 5 ----- test/lib/compression.c | 39 ++++++++++++++------------------------ 3 files changed, 14 insertions(+), 46 deletions(-) delete mode 100644 include/test/compression.h diff --git a/include/test/compression.h b/include/test/compression.h deleted file mode 100644 index 02fcfa49f65..00000000000 --- a/include/test/compression.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2017 Google, Inc - * Written by Simon Glass - */ - -#ifndef __TEST_COMPRESSION_H__ -#define __TEST_COMPRESSION_H__ - -#include - -/* Declare a new compression test */ -#define COMPRESSION_TEST(_name, _flags) \ - UNIT_TEST(_name, _flags, compression_test) - -#endif /* __TEST_ENV_H__ */ diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 53fddebd49d..32403b48ca4 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -111,8 +111,6 @@ static struct cmd_tbl cmd_ut_sub[] = { "", ""), #endif #ifdef CONFIG_SANDBOX - U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression, - "", ""), U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist, "", ""), U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""), @@ -207,9 +205,6 @@ U_BOOT_LONGHELP(ut, #ifdef CONFIG_CMDLINE "\ncmd - test various commands" #endif -#ifdef CONFIG_SANDBOX - "\ncompression - compressors and bootm decompression" -#endif #ifdef CONFIG_UT_DM "\ndm - driver model" #endif diff --git a/test/lib/compression.c b/test/lib/compression.c index 618a1936955..31b6e5b1eb4 100644 --- a/test/lib/compression.c +++ b/test/lib/compression.c @@ -23,8 +23,7 @@ #include #include -#include -#include +#include #include static const char plain[] = @@ -471,40 +470,40 @@ static int compression_test_gzip(struct unit_test_state *uts) return run_test(uts, "gzip", compress_using_gzip, uncompress_using_gzip); } -COMPRESSION_TEST(compression_test_gzip, 0); +LIB_TEST(compression_test_gzip, 0); static int compression_test_bzip2(struct unit_test_state *uts) { return run_test(uts, "bzip2", compress_using_bzip2, uncompress_using_bzip2); } -COMPRESSION_TEST(compression_test_bzip2, 0); +LIB_TEST(compression_test_bzip2, 0); static int compression_test_lzma(struct unit_test_state *uts) { return run_test(uts, "lzma", compress_using_lzma, uncompress_using_lzma); } -COMPRESSION_TEST(compression_test_lzma, 0); +LIB_TEST(compression_test_lzma, 0); static int compression_test_lzo(struct unit_test_state *uts) { return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo); } -COMPRESSION_TEST(compression_test_lzo, 0); +LIB_TEST(compression_test_lzo, 0); static int compression_test_lz4(struct unit_test_state *uts) { return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4); } -COMPRESSION_TEST(compression_test_lz4, 0); +LIB_TEST(compression_test_lz4, 0); static int compression_test_zstd(struct unit_test_state *uts) { return run_test(uts, "zstd", compress_using_zstd, uncompress_using_zstd); } -COMPRESSION_TEST(compression_test_zstd, 0); +LIB_TEST(compression_test_zstd, 0); static int compress_using_none(struct unit_test_state *uts, void *in, unsigned long in_size, @@ -570,50 +569,40 @@ static int compression_test_bootm_gzip(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip); } -COMPRESSION_TEST(compression_test_bootm_gzip, 0); +LIB_TEST(compression_test_bootm_gzip, 0); static int compression_test_bootm_bzip2(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2); } -COMPRESSION_TEST(compression_test_bootm_bzip2, 0); +LIB_TEST(compression_test_bootm_bzip2, 0); static int compression_test_bootm_lzma(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma); } -COMPRESSION_TEST(compression_test_bootm_lzma, 0); +LIB_TEST(compression_test_bootm_lzma, 0); static int compression_test_bootm_lzo(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo); } -COMPRESSION_TEST(compression_test_bootm_lzo, 0); +LIB_TEST(compression_test_bootm_lzo, 0); static int compression_test_bootm_lz4(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4); } -COMPRESSION_TEST(compression_test_bootm_lz4, 0); +LIB_TEST(compression_test_bootm_lz4, 0); static int compression_test_bootm_zstd(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_ZSTD, compress_using_zstd); } -COMPRESSION_TEST(compression_test_bootm_zstd, 0); +LIB_TEST(compression_test_bootm_zstd, 0); static int compression_test_bootm_none(struct unit_test_state *uts) { return run_bootm_test(uts, IH_COMP_NONE, compress_using_none); } -COMPRESSION_TEST(compression_test_bootm_none, 0); - -int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(compression_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(compression_test); - - return cmd_ut_category("compression", "compression_test_", - tests, n_ents, argc, argv); -} +LIB_TEST(compression_test_bootm_none, 0); From a6165509f24288f04a486609af26a040fb9c247d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:51 -0600 Subject: [PATCH 16/30] command_ut: test: Move test into lib This test doesn't belong at the top level. Move it into the lib/ directory, since that is where compression is implemented. Rename it to just 'command', since it is obviously a unit test and the _ut suffix does not add much except to make it different from the names of other test files. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/cmd/Makefile | 1 + test/{command_ut.c => cmd/command.c} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename test/{command_ut.c => cmd/command.c} (100%) diff --git a/test/Makefile b/test/Makefile index ff621344a03..48d8bc91ae6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o endif obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/ obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o -obj-$(CONFIG_$(XPL_)CMDLINE) += command_ut.o obj-y += dm/ obj-$(CONFIG_FUZZ) += fuzz/ ifndef CONFIG_SANDBOX_VPL diff --git a/test/cmd/Makefile b/test/cmd/Makefile index fe7a2165af2..6231a08186d 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -5,6 +5,7 @@ obj-y += cmd_ut_cmd.o +obj-$(CONFIG_$(XPL_)CMDLINE) += command.o ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o endif diff --git a/test/command_ut.c b/test/cmd/command.c similarity index 100% rename from test/command_ut.c rename to test/cmd/command.c From c25b35b6c6da208621e0ac61e46a4fad4337c092 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:52 -0600 Subject: [PATCH 17/30] command: test: Move into the cmd suite The command test was the very first test written in U-Boot, some 12 years ago. It predates the unit-test subsystem and was never converted over. There is no particular need for the command test to have its own command. It is also confusing to have it separate from the normal test suites. At present this test is not run in CI. Move it into the cmd suite instead, updating it to become a unit test. One of the checks is dropped to avoid an error. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd/command.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/cmd/command.c b/test/cmd/command.c index 2b8d28d7ae3..77800687ec3 100644 --- a/test/cmd/command.c +++ b/test/cmd/command.c @@ -10,13 +10,14 @@ #include #include #include +#include +#include static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; " "setenv list ${list}3\0" "setenv list ${list}4"; -static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int command_test(struct unit_test_state *uts) { char long_str[CONFIG_SYS_CBSIZE + 42]; @@ -72,8 +73,12 @@ static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, assert(run_commandf("'") == 1); assert(run_commandf("env %s %s", "delete -f", "list") == 0); - /* Expected: "Error: "list" not defined" */ - assert(run_commandf("printenv list") == 1); + /* + * Expected: "## Error: "list" not defined" + * (disabled to avoid pytest bailing out) + * + * assert(run_commandf("printenv list") == 1); + */ memset(long_str, 'x', sizeof(long_str)); assert(run_commandf("Truncation case: %s", long_str) == -ENOSPC); @@ -93,12 +98,10 @@ static int do_ut_cmd(struct cmd_tbl *cmdtp, int flag, int argc, /* Clean up before exit */ run_command("env default -f -a", 0); + /* put back the FDT environment */ + ut_assertok(env_set("from_fdt", "yes")); + printf("%s: Everything went swimmingly\n", __func__); return 0; } - -U_BOOT_CMD( - ut_cmd, 5, 1, do_ut_cmd, - "Very basic test of command parsers", - "" -); +CMD_TEST(command_test, 0); From ee3c8698e0908d881ce85fd82a26f2ac96978c71 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:53 -0600 Subject: [PATCH 18/30] test: Update command test to use unit-test functions Rather than enabled DEBUG and using assert(), use the unit-test functions now provided. Drop a check that causes pytest to fail. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd/command.c | 63 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/test/cmd/command.c b/test/cmd/command.c index 77800687ec3..5ec93d490ba 100644 --- a/test/cmd/command.c +++ b/test/cmd/command.c @@ -26,16 +26,16 @@ static int command_test(struct unit_test_state *uts) /* commands separated by \n */ run_command_list("setenv list 1\n setenv list ${list}1", -1, 0); - assert(!strcmp("11", env_get("list"))); + ut_assert(!strcmp("11", env_get("list"))); /* command followed by \n and nothing else */ run_command_list("setenv list 1${list}\n", -1, 0); - assert(!strcmp("111", env_get("list"))); + ut_assert(!strcmp("111", env_get("list"))); /* a command string with \0 in it. Stuff after \0 should be ignored */ run_command("setenv list", 0); run_command_list(test_cmd, sizeof(test_cmd), 0); - assert(!strcmp("123", env_get("list"))); + ut_assert(!strcmp("123", env_get("list"))); /* * a command list where we limit execution to only the first command @@ -43,60 +43,61 @@ static int command_test(struct unit_test_state *uts) */ run_command_list("setenv list 1\n setenv list ${list}2; " "setenv list ${list}3", strlen("setenv list 1"), 0); - assert(!strcmp("1", env_get("list"))); + ut_assert(!strcmp("1", env_get("list"))); - assert(run_command("false", 0) == 1); - assert(run_command("echo", 0) == 0); - assert(run_command_list("false", -1, 0) == 1); - assert(run_command_list("echo", -1, 0) == 0); + ut_asserteq(1, run_command("false", 0)); + ut_assertok(run_command("echo", 0)); + ut_asserteq(1, run_command_list("false", -1, 0)); + ut_assertok(run_command_list("echo", -1, 0)); #ifdef CONFIG_HUSH_PARSER run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0); run_command("run foo", 0); - assert(env_get("black") != NULL); - assert(!strcmp("1", env_get("black"))); - assert(env_get("adder") != NULL); - assert(!strcmp("2", env_get("adder"))); + ut_assertnonnull(env_get("black")); + ut_asserteq(0, strcmp("1", env_get("black"))); + ut_assertnonnull(env_get("adder")); + ut_asserteq(0, strcmp("2", env_get("adder"))); #endif - assert(run_command("", 0) == 0); - assert(run_command(" ", 0) == 0); + ut_assertok(run_command("", 0)); + ut_assertok(run_command(" ", 0)); - assert(run_command("'", 0) == 1); + ut_asserteq(1, run_command("'", 0)); /* Variadic function test-cases */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-zero-length" - assert(run_commandf("") == 0); + ut_assertok(run_commandf("")); #pragma GCC diagnostic pop - assert(run_commandf(" ") == 0); - assert(run_commandf("'") == 1); + ut_assertok(run_commandf(" ")); + ut_asserteq(1, run_commandf("'")); - assert(run_commandf("env %s %s", "delete -f", "list") == 0); + ut_assertok(run_commandf("env %s %s", "delete -f", "list")); /* * Expected: "## Error: "list" not defined" * (disabled to avoid pytest bailing out) * - * assert(run_commandf("printenv list") == 1); + * ut_asserteq(1, run_commandf("printenv list")); */ memset(long_str, 'x', sizeof(long_str)); - assert(run_commandf("Truncation case: %s", long_str) == -ENOSPC); + ut_asserteq(-ENOSPC, run_commandf("Truncation case: %s", long_str)); if (IS_ENABLED(CONFIG_HUSH_PARSER)) { - assert(run_commandf("env %s %s %s %s", "delete -f", "adder", - "black", "foo") == 0); - assert(run_commandf("setenv foo 'setenv %s 1\nsetenv %s 2'", - "black", "adder") == 0); - run_command("run foo", 0); - assert(env_get("black")); - assert(!strcmp("1", env_get("black"))); - assert(env_get("adder")); - assert(!strcmp("2", env_get("adder"))); + ut_assertok(run_commandf("env %s %s %s %s", "delete -f", + "adder", "black", "foo")); + ut_assertok(run_commandf( + "setenv foo 'setenv %s 1\nsetenv %s 2'", + "black", "adder")); + ut_assertok(run_command("run foo", 0)); + ut_assertnonnull(env_get("black")); + ut_asserteq(0, strcmp("1", env_get("black"))); + ut_assertnonnull(env_get("adder")); + ut_asserteq(0, strcmp("2", env_get("adder"))); } /* Clean up before exit */ - run_command("env default -f -a", 0); + ut_assertok(run_command("env default -f -a", 0)); /* put back the FDT environment */ ut_assertok(env_set("from_fdt", "yes")); From 7f8b8c5abc28704e794c4bf05903afc88c808581 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:54 -0600 Subject: [PATCH 19/30] bootm: test: Move test into boot This test doesn't belong at the top level. Move it into the boot/ directory, to match its implementation. This test is currently dependent on bloblist, but the real dependency is on sandbox, so update that. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 3 --- test/boot/Makefile | 3 +++ test/{ => boot}/bootm.c | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename test/{ => boot}/bootm.c (100%) diff --git a/test/Makefile b/test/Makefile index 48d8bc91ae6..4366e495a15 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,9 +4,6 @@ obj-y += test-main.o -ifneq ($(CONFIG_$(XPL_)BLOBLIST),) -obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o -endif obj-$(CONFIG_$(XPL_)CMDLINE) += cmd/ obj-$(CONFIG_$(XPL_)CMDLINE) += cmd_ut.o obj-y += dm/ diff --git a/test/boot/Makefile b/test/boot/Makefile index d8eded20d4f..63487e8d29e 100644 --- a/test/boot/Makefile +++ b/test/boot/Makefile @@ -10,6 +10,9 @@ obj-$(CONFIG_EXPO) += expo.o obj-$(CONFIG_CEDIT) += cedit.o endif +ifdef CONFIG_SANDBOX +obj-$(CONFIG_$(XPL_)CMDLINE) += bootm.o +endif obj-$(CONFIG_MEASURED_BOOT) += measurement.o ifdef CONFIG_OF_LIVE diff --git a/test/bootm.c b/test/boot/bootm.c similarity index 100% rename from test/bootm.c rename to test/boot/bootm.c From 479b389c3def872da79a03a7d08e2da6cb4391ee Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:55 -0600 Subject: [PATCH 20/30] test: Move print_ut test into common This test doesn't belong at the top level. Move it into the common/ directory, to match its implementation. Rename it to drop the unnecessary _ut suffix. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/common/Makefile | 1 + test/{print_ut.c => common/print.c} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename test/{print_ut.c => common/print.c} (100%) diff --git a/test/Makefile b/test/Makefile index 4366e495a15..9f19bfa472b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -14,7 +14,6 @@ endif ifneq ($(CONFIG_HUSH_PARSER),) obj-$(CONFIG_$(XPL_)CMDLINE) += hush/ endif -obj-$(CONFIG_$(XPL_)CMDLINE) += print_ut.o obj-$(CONFIG_$(XPL_)CMDLINE) += str_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o obj-y += ut.o diff --git a/test/common/Makefile b/test/common/Makefile index b6bff9201ec..53c4f16164d 100644 --- a/test/common/Makefile +++ b/test/common/Makefile @@ -7,3 +7,4 @@ endif obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_EVENT_DYNAMIC) += event.o obj-y += cread.o +obj-$(CONFIG_$(XPL_)CMDLINE) += print.o diff --git a/test/print_ut.c b/test/common/print.c similarity index 100% rename from test/print_ut.c rename to test/common/print.c From 33ca12b233288366e1e77c861e74883e6804dc23 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:56 -0600 Subject: [PATCH 21/30] test: Move print_ut into the common suite There is no particular need for bloblist to have its own test suite. Move it into the common suite instead. Add the missing help for 'common'. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd_ut.c | 3 +-- test/common/print.c | 27 ++++++++------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 32403b48ca4..9b47a2c1a93 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -99,7 +99,6 @@ static struct cmd_tbl cmd_ut_sub[] = { U_BOOT_CMD_MKENT(setexpr, CONFIG_SYS_MAXARGS, 1, do_ut_setexpr, "", ""), #endif - U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_ut_print, "", ""), #ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""), #endif @@ -205,6 +204,7 @@ U_BOOT_LONGHELP(ut, #ifdef CONFIG_CMDLINE "\ncmd - test various commands" #endif + "\ncommon - tests for common/ directory" #ifdef CONFIG_UT_DM "\ndm - driver model" #endif @@ -239,7 +239,6 @@ U_BOOT_LONGHELP(ut, #ifdef CONFIG_CMD_PCI_MPS "\npci_mps - PCI Express Maximum Payload Size" #endif - "\nprint - printing things to the console" "\nsetexpr - setexpr command" #ifdef CONFIG_SANDBOX "\nstr - basic test of string functions" diff --git a/test/common/print.c b/test/common/print.c index f5e607b21a3..f1eb9072d97 100644 --- a/test/common/print.c +++ b/test/common/print.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -20,9 +20,6 @@ #define FAKE_BUILD_TAG "jenkins-u-boot-denx_uboot_dm-master-build-aarch64" \ "and a lot more text to come" -/* Declare a new print test */ -#define PRINT_TEST(_name, _flags) UNIT_TEST(_name, _flags, print_test) - #if CONFIG_IS_ENABLED(LIB_UUID) /* Test printing GUIDs */ static int print_guid(struct unit_test_state *uts) @@ -59,7 +56,7 @@ static int print_guid(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_guid, 0); +COMMON_TEST(print_guid, 0); #endif #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) @@ -95,7 +92,7 @@ static int print_efi_ut(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_efi_ut, 0); +COMMON_TEST(print_efi_ut, 0); #endif static int print_printf(struct unit_test_state *uts) @@ -163,7 +160,7 @@ static int print_printf(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_printf, 0); +COMMON_TEST(print_printf, 0); static int print_display_buffer(struct unit_test_state *uts) { @@ -238,7 +235,7 @@ static int print_display_buffer(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_display_buffer, UTF_CONSOLE); +COMMON_TEST(print_display_buffer, UTF_CONSOLE); static int print_hexdump_line(struct unit_test_state *uts) { @@ -264,7 +261,7 @@ static int print_hexdump_line(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_hexdump_line, UTF_CONSOLE); +COMMON_TEST(print_hexdump_line, UTF_CONSOLE); static int print_do_hex_dump(struct unit_test_state *uts) { @@ -350,7 +347,7 @@ static int print_do_hex_dump(struct unit_test_state *uts) return 0; } -PRINT_TEST(print_do_hex_dump, UTF_CONSOLE); +COMMON_TEST(print_do_hex_dump, UTF_CONSOLE); static int snprint(struct unit_test_state *uts) { @@ -376,12 +373,4 @@ static int snprint(struct unit_test_state *uts) ut_asserteq(8, ret); return 0; } -PRINT_TEST(snprint, 0); - -int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(print_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(print_test); - - return cmd_ut_category("print", "print_", tests, n_ents, argc, argv); -} +COMMON_TEST(snprint, 0); From 2352526362500052eda11fcb6eac6e95418345d2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:57 -0600 Subject: [PATCH 22/30] test: Move str_ut test into lib This test doesn't belong at the top level. Move it into the lib/ directory, to match (most of) its implementation. Rename it to drop the unnecessary _ut suffix. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/lib/Makefile | 1 + test/{str_ut.c => lib/str.c} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename test/{str_ut.c => lib/str.c} (100%) diff --git a/test/Makefile b/test/Makefile index 9f19bfa472b..220a249c397 100644 --- a/test/Makefile +++ b/test/Makefile @@ -14,7 +14,6 @@ endif ifneq ($(CONFIG_HUSH_PARSER),) obj-$(CONFIG_$(XPL_)CMDLINE) += hush/ endif -obj-$(CONFIG_$(XPL_)CMDLINE) += str_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o obj-y += ut.o diff --git a/test/lib/Makefile b/test/lib/Makefile index ce22780eed8..be20bbc047f 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -17,6 +17,7 @@ obj-y += lmb.o obj-y += longjmp.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o +obj-$(CONFIG_$(XPL_)CMDLINE) += str.o obj-y += string.o obj-y += strlcat.o obj-$(CONFIG_ERRNO_STR) += test_errno_str.o diff --git a/test/str_ut.c b/test/lib/str.c similarity index 100% rename from test/str_ut.c rename to test/lib/str.c From 4563fb42f85810ac5af9fe33763056f6fd913905 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:58 -0600 Subject: [PATCH 23/30] str: test: Move into the lib suite There is no particular need for the str tests to have their own test suite. Move them into the lib suite instead. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd_ut.c | 4 ---- test/lib/str.c | 31 ++++++++++--------------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 9b47a2c1a93..96bea4747fd 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -114,7 +114,6 @@ static struct cmd_tbl cmd_ut_sub[] = { "", ""), U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""), #endif - U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""), #ifdef CONFIG_CMD_ADDRMAP U_BOOT_CMD_MKENT(addrmap, CONFIG_SYS_MAXARGS, 1, do_ut_addrmap, "", ""), #endif @@ -240,9 +239,6 @@ U_BOOT_LONGHELP(ut, "\npci_mps - PCI Express Maximum Payload Size" #endif "\nsetexpr - setexpr command" -#ifdef CONFIG_SANDBOX - "\nstr - basic test of string functions" -#endif #ifdef CONFIG_CMD_SEAMA "\nseama - seama command parameters loading and decoding" #endif diff --git a/test/lib/str.c b/test/lib/str.c index 96e048975d8..3cc9dfea6aa 100644 --- a/test/lib/str.c +++ b/test/lib/str.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include @@ -19,9 +19,6 @@ static const char str5[] = "0x9876543210the last time I was deloused"; static const char str6[] = "0778octal is seldom used"; static const char str7[] = "707it is a piece of computing history"; -/* Declare a new str test */ -#define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test) - static int str_upper(struct unit_test_state *uts) { char out[TEST_STR_SIZE]; @@ -58,7 +55,7 @@ static int str_upper(struct unit_test_state *uts) return 0; } -STR_TEST(str_upper, 0); +LIB_TEST(str_upper, 0); static int run_strtoul(struct unit_test_state *uts, const char *str, int base, ulong expect_val, int expect_endp_offset, bool upper) @@ -112,7 +109,7 @@ static int str_simple_strtoul(struct unit_test_state *uts) return 0; } -STR_TEST(str_simple_strtoul, 0); +LIB_TEST(str_simple_strtoul, 0); static int run_strtoull(struct unit_test_state *uts, const char *str, int base, unsigned long long expect_val, int expect_endp_offset, @@ -175,7 +172,7 @@ static int str_simple_strtoull(struct unit_test_state *uts) return 0; } -STR_TEST(str_simple_strtoull, 0); +LIB_TEST(str_simple_strtoull, 0); static int str_hextoul(struct unit_test_state *uts) { @@ -187,7 +184,7 @@ static int str_hextoul(struct unit_test_state *uts) return 0; } -STR_TEST(str_hextoul, 0); +LIB_TEST(str_hextoul, 0); static int str_dectoul(struct unit_test_state *uts) { @@ -199,7 +196,7 @@ static int str_dectoul(struct unit_test_state *uts) return 0; } -STR_TEST(str_dectoul, 0); +LIB_TEST(str_dectoul, 0); static int str_itoa(struct unit_test_state *uts) { @@ -219,7 +216,7 @@ static int str_itoa(struct unit_test_state *uts) return 0; } -STR_TEST(str_itoa, 0); +LIB_TEST(str_itoa, 0); static int str_xtoa(struct unit_test_state *uts) { @@ -239,7 +236,7 @@ static int str_xtoa(struct unit_test_state *uts) return 0; } -STR_TEST(str_xtoa, 0); +LIB_TEST(str_xtoa, 0); static int str_trailing(struct unit_test_state *uts) { @@ -271,7 +268,7 @@ static int str_trailing(struct unit_test_state *uts) return 0; } -STR_TEST(str_trailing, 0); +LIB_TEST(str_trailing, 0); static int test_str_to_list(struct unit_test_state *uts) { @@ -351,12 +348,4 @@ static int test_str_to_list(struct unit_test_state *uts) return 0; } -STR_TEST(test_str_to_list, 0); - -int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(str_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(str_test); - - return cmd_ut_category("str", "str_", tests, n_ents, argc, argv); -} +LIB_TEST(test_str_to_list, 0); From 7a27d4187a30ccd77b6bed49af63b8eb792fe9e4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:36:59 -0600 Subject: [PATCH 24/30] test: Move unicode_ut test into lib This test doesn't belong at the top level. Move it into the lib/ directory, to match its implementation. Rename it to drop the unnecessary _ut suffix. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/lib/Makefile | 1 + test/{unicode_ut.c => lib/unicode.c} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename test/{unicode_ut.c => lib/unicode.c} (100%) diff --git a/test/Makefile b/test/Makefile index 220a249c397..0b1affcf445 100644 --- a/test/Makefile +++ b/test/Makefile @@ -21,7 +21,6 @@ ifeq ($(CONFIG_XPL_BUILD),) obj-y += boot/ obj-$(CONFIG_UNIT_TEST) += common/ obj-y += log/ -obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode_ut.o else obj-$(CONFIG_SPL_UT_LOAD) += image/ endif diff --git a/test/lib/Makefile b/test/lib/Makefile index be20bbc047f..c36c8b0917d 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o +obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode.o obj-$(CONFIG_LIB_UUID) += uuid.o else obj-$(CONFIG_SANDBOX) += kconfig_spl.o diff --git a/test/unicode_ut.c b/test/lib/unicode.c similarity index 100% rename from test/unicode_ut.c rename to test/lib/unicode.c From 5912a9ea1ad25c9278148950f8653a3c1a03043b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:00 -0600 Subject: [PATCH 25/30] test: Move unicode tests into the lib suite There is no particular need for the unicode tests to have their own test suite. Move them into the lib suite instead. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd_ut.c | 7 ----- test/lib/unicode.c | 70 +++++++++++++++++++--------------------------- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 96bea4747fd..f86757361db 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -102,9 +102,6 @@ static struct cmd_tbl cmd_ut_sub[] = { #ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""), #endif -#if CONFIG_IS_ENABLED(UT_UNICODE) && !defined(API_BUILD) - U_BOOT_CMD_MKENT(unicode, CONFIG_SYS_MAXARGS, 1, do_ut_unicode, "", ""), -#endif #ifdef CONFIG_MEASURED_BOOT U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement, "", ""), @@ -244,10 +241,6 @@ U_BOOT_LONGHELP(ut, #endif #ifdef CONFIG_UT_TIME "\ntime - very basic test of time functions" -#endif -#if defined(CONFIG_UT_UNICODE) && \ - !defined(CONFIG_XPL_BUILD) && !defined(API_BUILD) - "\nunicode - Unicode functions" #endif ); diff --git a/test/lib/unicode.c b/test/lib/unicode.c index 13e29c9b9e3..673470c8d2c 100644 --- a/test/lib/unicode.c +++ b/test/lib/unicode.c @@ -11,13 +11,10 @@ #include #include #include +#include #include -#include #include -/* Linker list entry for a Unicode test */ -#define UNICODE_TEST(_name) UNIT_TEST(_name, 0, unicode_test) - /* Constants c1-c4 and d1-d4 encode the same letters */ /* Six characters translating to one utf-8 byte each. */ @@ -64,7 +61,7 @@ static int unicode_test_u16_strlen(struct unit_test_state *uts) ut_asserteq(6, u16_strlen(c4)); return 0; } -UNICODE_TEST(unicode_test_u16_strlen); +LIB_TEST(unicode_test_u16_strlen, 0); static int unicode_test_u16_strnlen(struct unit_test_state *uts) { @@ -75,7 +72,7 @@ static int unicode_test_u16_strnlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_u16_strnlen); +LIB_TEST(unicode_test_u16_strnlen, 0); static int unicode_test_u16_strdup(struct unit_test_state *uts) { @@ -87,7 +84,7 @@ static int unicode_test_u16_strdup(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_u16_strdup); +LIB_TEST(unicode_test_u16_strdup, 0); static int unicode_test_u16_strcpy(struct unit_test_state *uts) { @@ -100,7 +97,7 @@ static int unicode_test_u16_strcpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_u16_strcpy); +LIB_TEST(unicode_test_u16_strcpy, 0); /* U-Boot uses UTF-16 strings in the EFI context only. */ #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) @@ -173,7 +170,7 @@ static int unicode_test_string16(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_string16); +LIB_TEST(unicode_test_string16, 0); #endif static int unicode_test_utf8_get(struct unit_test_state *uts) @@ -218,7 +215,7 @@ static int unicode_test_utf8_get(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_get); +LIB_TEST(unicode_test_utf8_get, 0); static int unicode_test_utf8_put(struct unit_test_state *uts) { @@ -256,7 +253,7 @@ static int unicode_test_utf8_put(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_put); +LIB_TEST(unicode_test_utf8_put, 0); static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts) { @@ -272,7 +269,7 @@ static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_utf16_strlen); +LIB_TEST(unicode_test_utf8_utf16_strlen, 0); static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts) { @@ -290,7 +287,7 @@ static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_utf16_strnlen); +LIB_TEST(unicode_test_utf8_utf16_strnlen, 0); /** * ut_u16_strcmp() - Compare to u16 strings. @@ -354,7 +351,7 @@ static int unicode_test_utf8_utf16_strcpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_utf16_strcpy); +LIB_TEST(unicode_test_utf8_utf16_strcpy, 0); static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts) { @@ -398,7 +395,7 @@ static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_utf16_strncpy); +LIB_TEST(unicode_test_utf8_utf16_strncpy, 0); static int unicode_test_utf16_get(struct unit_test_state *uts) { @@ -424,7 +421,7 @@ static int unicode_test_utf16_get(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_get); +LIB_TEST(unicode_test_utf16_get, 0); static int unicode_test_utf16_put(struct unit_test_state *uts) { @@ -452,7 +449,7 @@ static int unicode_test_utf16_put(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_put); +LIB_TEST(unicode_test_utf16_put, 0); static int unicode_test_utf16_strnlen(struct unit_test_state *uts) { @@ -470,7 +467,7 @@ static int unicode_test_utf16_strnlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_strnlen); +LIB_TEST(unicode_test_utf16_strnlen, 0); static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts) { @@ -486,7 +483,7 @@ static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_utf8_strlen); +LIB_TEST(unicode_test_utf16_utf8_strlen, 0); static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts) { @@ -498,7 +495,7 @@ static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts) ut_asserteq(12, utf16_utf8_strnlen(c4, 3)); return 0; } -UNICODE_TEST(unicode_test_utf16_utf8_strnlen); +LIB_TEST(unicode_test_utf16_utf8_strnlen, 0); static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts) { @@ -543,7 +540,7 @@ static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_utf8_strcpy); +LIB_TEST(unicode_test_utf16_utf8_strcpy, 0); static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts) { @@ -587,7 +584,7 @@ static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf16_utf8_strncpy); +LIB_TEST(unicode_test_utf16_utf8_strncpy, 0); static int unicode_test_utf_to_lower(struct unit_test_state *uts) { @@ -604,7 +601,7 @@ static int unicode_test_utf_to_lower(struct unit_test_state *uts) #endif return 0; } -UNICODE_TEST(unicode_test_utf_to_lower); +LIB_TEST(unicode_test_utf_to_lower, 0); static int unicode_test_utf_to_upper(struct unit_test_state *uts) { @@ -621,7 +618,7 @@ static int unicode_test_utf_to_upper(struct unit_test_state *uts) #endif return 0; } -UNICODE_TEST(unicode_test_utf_to_upper); +LIB_TEST(unicode_test_utf_to_upper, 0); static int unicode_test_u16_strcasecmp(struct unit_test_state *uts) { @@ -646,7 +643,7 @@ static int unicode_test_u16_strcasecmp(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_u16_strcasecmp); +LIB_TEST(unicode_test_u16_strcasecmp, 0); static int unicode_test_u16_strncmp(struct unit_test_state *uts) { @@ -659,7 +656,7 @@ static int unicode_test_u16_strncmp(struct unit_test_state *uts) ut_assert(u16_strcmp(u"deghi", u"abcdef") > 0); return 0; } -UNICODE_TEST(unicode_test_u16_strncmp); +LIB_TEST(unicode_test_u16_strncmp, 0); static int unicode_test_u16_strsize(struct unit_test_state *uts) { @@ -669,7 +666,7 @@ static int unicode_test_u16_strsize(struct unit_test_state *uts) ut_asserteq_64(u16_strsize(c4), 14); return 0; } -UNICODE_TEST(unicode_test_u16_strsize); +LIB_TEST(unicode_test_u16_strsize, 0); static int unicode_test_utf_to_cp(struct unit_test_state *uts) { @@ -698,7 +695,7 @@ static int unicode_test_utf_to_cp(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf_to_cp); +LIB_TEST(unicode_test_utf_to_cp, 0); static void utf8_to_cp437_stream_helper(const char *in, char *out) { @@ -729,7 +726,7 @@ static int unicode_test_utf8_to_cp437_stream(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_to_cp437_stream); +LIB_TEST(unicode_test_utf8_to_cp437_stream, 0); static void utf8_to_utf32_stream_helper(const char *in, s32 *out) { @@ -778,7 +775,7 @@ static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_utf8_to_utf32_stream); +LIB_TEST(unicode_test_utf8_to_utf32_stream, 0); #ifdef CONFIG_EFI_LOADER static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts) @@ -795,7 +792,7 @@ static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_efi_create_indexed_name); +LIB_TEST(unicode_test_efi_create_indexed_name, 0); #endif static int unicode_test_u16_strlcat(struct unit_test_state *uts) @@ -846,13 +843,4 @@ static int unicode_test_u16_strlcat(struct unit_test_state *uts) return 0; } -UNICODE_TEST(unicode_test_u16_strlcat); - -int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test); - const int n_ents = UNIT_TEST_SUITE_COUNT(unicode_test); - - return cmd_ut_category("Unicode", "unicode_test_", - tests, n_ents, argc, argv); -} +LIB_TEST(unicode_test_u16_strlcat, 0); From 890d91ff3584fcdcf9dc5ff0b516dcd3a5e55108 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:01 -0600 Subject: [PATCH 26/30] test: Move time_ut test into lib This test doesn't belong at the top level. Move it into the lib/ directory, to match its implementation. Rename it to drop the unnecessary _ut suffix. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/Makefile | 1 - test/lib/Makefile | 1 + test/{time_ut.c => lib/time.c} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename test/{time_ut.c => lib/time.c} (100%) diff --git a/test/Makefile b/test/Makefile index 0b1affcf445..47a07d653a9 100644 --- a/test/Makefile +++ b/test/Makefile @@ -14,7 +14,6 @@ endif ifneq ($(CONFIG_HUSH_PARSER),) obj-$(CONFIG_$(XPL_)CMDLINE) += hush/ endif -obj-$(CONFIG_UT_TIME) += time_ut.o obj-y += ut.o ifeq ($(CONFIG_XPL_BUILD),) diff --git a/test/lib/Makefile b/test/lib/Makefile index c36c8b0917d..217c3baf881 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o +obj-$(CONFIG_UT_TIME) += time.o obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode.o obj-$(CONFIG_LIB_UUID) += uuid.o else diff --git a/test/time_ut.c b/test/lib/time.c similarity index 100% rename from test/time_ut.c rename to test/lib/time.c From dd0057dacb2e8bced192ca7c8698b1704b247908 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:02 -0600 Subject: [PATCH 27/30] test: Move time tests into the lib suite There is no particular need for the time tests to have their own test command. Move them into the lib suite instead. Update the test functions to match the normal unit-test signature. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/cmd_ut.c | 6 ------ test/lib/time.c | 29 ++++++++++------------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/test/cmd_ut.c b/test/cmd_ut.c index f86757361db..195b7ea50ac 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -99,9 +99,6 @@ static struct cmd_tbl cmd_ut_sub[] = { U_BOOT_CMD_MKENT(setexpr, CONFIG_SYS_MAXARGS, 1, do_ut_setexpr, "", ""), #endif -#ifdef CONFIG_UT_TIME - U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""), -#endif #ifdef CONFIG_MEASURED_BOOT U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement, "", ""), @@ -238,9 +235,6 @@ U_BOOT_LONGHELP(ut, "\nsetexpr - setexpr command" #ifdef CONFIG_CMD_SEAMA "\nseama - seama command parameters loading and decoding" -#endif -#ifdef CONFIG_UT_TIME - "\ntime - very basic test of time functions" #endif ); diff --git a/test/lib/time.c b/test/lib/time.c index 149c4b58f4a..2095bef7589 100644 --- a/test/lib/time.c +++ b/test/lib/time.c @@ -4,12 +4,13 @@ * Written by Simon Glass */ -#include #include #include #include +#include +#include -static int test_get_timer(void) +static int test_get_timer(struct unit_test_state *uts) { ulong base, start, next, diff; int iter; @@ -42,8 +43,9 @@ static int test_get_timer(void) return 0; } +LIB_TEST(test_get_timer, 0); -static int test_timer_get_us(void) +static int test_timer_get_us(struct unit_test_state *uts) { ulong prev, next, min = 1000000; long delta; @@ -76,8 +78,9 @@ static int test_timer_get_us(void) return 0; } +LIB_TEST(test_timer_get_us, 0); -static int test_time_comparison(void) +static int test_time_comparison(struct unit_test_state *uts) { ulong start_us, end_us, delta_us; long error; @@ -97,8 +100,9 @@ static int test_time_comparison(void) return 0; } +LIB_TEST(test_time_comparison, 0); -static int test_udelay(void) +static int test_udelay(struct unit_test_state *uts) { long error; ulong start, delta; @@ -116,17 +120,4 @@ static int test_udelay(void) return 0; } - -int do_ut_time(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - int ret = 0; - - ret |= test_get_timer(); - ret |= test_timer_get_us(); - ret |= test_time_comparison(); - ret |= test_udelay(); - - printf("Test %s\n", ret ? "failed" : "passed"); - - return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS; -} +LIB_TEST(test_udelay, 0); From 88db4fc5fec20429881896740df61d402b4b1f66 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:03 -0600 Subject: [PATCH 28/30] test: Update time tests to use unit-test asserts Rather than returning various error codes, use assertions to check that the test passes. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/lib/time.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/test/lib/time.c b/test/lib/time.c index 2095bef7589..b99e738c500 100644 --- a/test/lib/time.c +++ b/test/lib/time.c @@ -22,11 +22,7 @@ static int test_get_timer(struct unit_test_state *uts) next = get_timer(0); } while (start == next); - if (start + 1 != next) { - printf("%s: iter=%d, start=%lu, next=%lu, expected a difference of 1\n", - __func__, iter, start, next); - return -EINVAL; - } + ut_asserteq(start + 1, next); start++; } @@ -35,11 +31,7 @@ static int test_get_timer(struct unit_test_state *uts) * an extra millisecond may have passed. */ diff = get_timer(base); - if (diff != iter && diff != iter + 1) { - printf("%s: expected get_timer(base) to match elapsed time: diff=%lu, expected=%d\n", - __func__, diff, iter); - return -EINVAL; - } + ut_assert(diff == iter || diff == iter + 1); return 0; } @@ -57,11 +49,8 @@ static int test_timer_get_us(struct unit_test_state *uts) next = timer_get_us(); if (next != prev) { delta = next - prev; - if (delta < 0) { - printf("%s: timer_get_us() went backwards from %lu to %lu\n", - __func__, prev, next); - return -EINVAL; - } else if (delta != 0) { + ut_assert(delta >= 0); + if (delta) { if (delta < min) min = delta; prev = next; @@ -70,11 +59,7 @@ static int test_timer_get_us(struct unit_test_state *uts) } } - if (min != 1) { - printf("%s: Minimum microsecond delta should be 1 but is %lu\n", - __func__, min); - return -EINVAL; - } + ut_asserteq(1, min); return 0; } @@ -95,8 +80,7 @@ static int test_time_comparison(struct unit_test_state *uts) error = delta_us - 1000000; printf("%s: Microsecond time for 1 second: %lu, error = %ld\n", __func__, delta_us, error); - if (abs(error) > 1000) - return -EINVAL; + ut_assert(abs(error) <= 1000); return 0; } @@ -115,8 +99,7 @@ static int test_udelay(struct unit_test_state *uts) error = delta - 1000; printf("%s: Delay time for 1000 udelay(1000): %lu ms, error = %ld\n", __func__, delta, error); - if (abs(error) > 100) - return -EINVAL; + ut_assert(abs(error) <= 100); return 0; } From 4f570b36aa00fe094af9107b50fa60083cf765ab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:04 -0600 Subject: [PATCH 29/30] test: Correct display of failing test This should show the test name, not the selected name, since the user may be running all tests, in which case 'select_name' is NULL Fix it. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/test-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-main.c b/test/test-main.c index da5b07ce00b..e4f42689da4 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -622,7 +622,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (i = 0; i < uts->runs_per_test; i++) ret = ut_run_test_live_flat(uts, test); if (uts->fail_count != old_fail_count) { - printf("Test %s failed %d times\n", select_name, + printf("Test %s failed %d times\n", test_name, uts->fail_count - old_fail_count); } found++; From c63f4e40f112dd72bffd837b5f599173740214fc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 13:37:05 -0600 Subject: [PATCH 30/30] test: Quote test names When mentioning a test name, add single quotes to make it easier to see. Signed-off-by: Simon Glass Tested-by: Tom Rini # rpi_3, rpi_4, rpi_arm64, am64x_evm_a53, am64-sk --- test/test-main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test-main.c b/test/test-main.c index e4f42689da4..c825f9c7797 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -594,14 +594,14 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, */ len = strlen(test_name); if (len < 6 || strcmp(test_name + len - 6, "_norun")) { - printf("Test %s is manual so must have a name ending in _norun\n", + printf("Test '%s' is manual so must have a name ending in _norun\n", test_name); uts->fail_count++; return -EBADF; } if (!uts->force_run) { if (select_name) { - printf("Test %s skipped as it is manual (use -f to run it)\n", + printf("Test '%s' skipped as it is manual (use -f to run it)\n", test_name); } continue; @@ -612,7 +612,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, if (one && upto == pos) { ret = ut_run_test_live_flat(uts, one); if (uts->fail_count != old_fail_count) { - printf("Test %s failed %d times (position %d)\n", + printf("Test '%s' failed %d times (position %d)\n", one->name, uts->fail_count - old_fail_count, pos); } @@ -622,7 +622,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (i = 0; i < uts->runs_per_test; i++) ret = ut_run_test_live_flat(uts, test); if (uts->fail_count != old_fail_count) { - printf("Test %s failed %d times\n", test_name, + printf("Test '%s' failed %d times\n", test_name, uts->fail_count - old_fail_count); } found++;