From 1c7217511cd9a050183402b56c0371e4f9720bea Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:34:47 -0700 Subject: test: Add an overall test runner Add a new test runner that will eventually be able to run any test. For now, have it run the 'command' unit tests, so that the functionality in cmd_ut_category() moves into it. Signed-off-by: Simon Glass --- include/test/ut.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 17400c73ea..88e75ab791 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -356,4 +356,46 @@ void ut_silence_console(struct unit_test_state *uts); */ void ut_unsilence_console(struct unit_test_state *uts); +/** + * ut_run_tests() - Run a set of tests + * + * This runs the tests, handling any preparation and clean-up needed. It prints + * the name of each test before running it. + * + * @uts: Test state to update. The caller should ensure that this is zeroed for + * the first call to this function. On exit, @uts->fail_count is + * incremented by the number of failures (0, one hopes) + * @prefix: String prefix for the tests. Any tests that have this prefix will be + * printed without the prefix, so that it is easier to see the unique part + * of the test name. If NULL, no prefix processing is done + * @tests: List of tests to run + * @count: Number of tests to run + * @select_name: Name of a single test to run (from the list provided). If NULL + * then all tests are run + * @return 0 if all tests passed, -ENOENT if test @select_name was not found, + * -EBADF if any failed + */ +int ut_run_tests(struct unit_test_state *uts, const char *prefix, + struct unit_test *tests, int count, const char *select_name); + +/** + * ut_run_tests() - Run a set of tests + * + * This runs the test, handling any preparation and clean-up needed. It prints + * the name of each test before running it. + * + * @category: Category of these tests. This is a string printed at the start to + * announce the the number of tests + * @prefix: String prefix for the tests. Any tests that have this prefix will be + * printed without the prefix, so that it is easier to see the unique part + * of the test name. If NULL, no prefix processing is done + * @tests: List of tests to run + * @count: Number of tests to run + * @select_name: Name of a single test to run (from the list provided). If NULL + * then all tests are run + * @return 0 if all tests passed, -1 if any failed + */ +int ut_run_list(const char *name, const char *prefix, struct unit_test *tests, + int count, const char *select_name); + #endif -- cgit v1.2.3 From d002a2764418fa8f054d94789e7814f60294318f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:34:48 -0700 Subject: test: Create pre/post-run functions Split out the test preparation into a separation function before expanding it. Add a post-run function as well, currently empty. Signed-off-by: Simon Glass --- include/test/ut.h | 20 ++++++++++++++++++++ test/test-main.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 10 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 88e75ab791..7cb5e10f3a 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -356,6 +356,26 @@ void ut_silence_console(struct unit_test_state *uts); */ void ut_unsilence_console(struct unit_test_state *uts); +/** + * test_pre_run() - Handle any preparation needed to run a test + * + * @uts: Test state + * @test: Test to prepare for + * @return 0 if OK, -EAGAIN to skip this test since some required feature is not + * available, other -ve on error (meaning that testing cannot likely + * continue) + */ +int test_pre_run(struct unit_test_state *uts, struct unit_test *test); + +/** + * test_post_run() - Handle cleaning up after a test + * + * @uts: Test state + * @test: Test to clean up after + * @return 0 if OK, -ve on error (meaning that testing cannot likely continue) + */ +int test_post_run(struct unit_test_state *uts, struct unit_test *test); + /** * ut_run_tests() - Run a set of tests * diff --git a/test/test-main.c b/test/test-main.c index 376e7ebd3d..7961fd8aa3 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -8,6 +8,27 @@ #include #include +int test_pre_run(struct unit_test_state *uts, struct unit_test *test) +{ + uts->start = mallinfo(); + + if (test->flags & UT_TESTF_CONSOLE_REC) { + int ret = console_record_reset_enable(); + + if (ret) { + printf("Skipping: Console recording disabled\n"); + return -EAGAIN; + } + } + + return 0; +} + +int test_post_run(struct unit_test_state *uts, struct unit_test *test) +{ + return 0; +} + int ut_run_tests(struct unit_test_state *uts, const char *prefix, struct unit_test *tests, int count, const char *select_name) { @@ -17,6 +38,7 @@ int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (test = tests; test < tests + count; test++) { const char *test_name = test->name; + int ret; /* Remove the prefix */ if (prefix && !strncmp(test_name, prefix, prefix_len)) @@ -27,18 +49,17 @@ int ut_run_tests(struct unit_test_state *uts, const char *prefix, printf("Test: %s\n", test_name); found++; - if (test->flags & UT_TESTF_CONSOLE_REC) { - int ret = console_record_reset_enable(); - - if (ret) { - printf("Skipping: Console recording disabled\n"); - continue; - } - } - - uts->start = mallinfo(); + ret = test_pre_run(uts, test); + if (ret == -EAGAIN) + continue; + if (ret) + return ret; test->func(uts); + + ret = test_post_run(uts, test); + if (ret) + return ret; } if (select_name && !found) return -ENOENT; -- cgit v1.2.3 From 47ec3ede4efe214b4debdaf845d6eb622154f405 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:34:55 -0700 Subject: test: Move delay skipping to test_pre_run() This allows delays to be skipped in sandbox tests. Move it to the common pre-init function. Signed-off-by: Simon Glass --- include/test/ut.h | 11 +++++++++++ test/dm/test-dm.c | 2 -- test/test-main.c | 2 ++ test/ut.c | 7 +++++++ 4 files changed, 20 insertions(+), 2 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 7cb5e10f3a..e5ec18e60b 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -356,6 +356,17 @@ void ut_silence_console(struct unit_test_state *uts); */ void ut_unsilence_console(struct unit_test_state *uts); +/** + * ut_set_skip_delays() - Sets whether delays should be skipped + * + * Normally functions like mdelay() cause U-Boot to wait for a while. This + * allows all such delays to be skipped on sandbox, to speed up tests + * + * @uts: Test state (in case in future we want to keep state here) + * @skip_delays: true to skip delays, false to process them normally + */ +void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays); + /** * test_pre_run() - Handle any preparation needed to run a test * diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index fdd35f663e..569ffbbad9 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -78,8 +78,6 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test, ut_assertok(test_post_run(uts, test)); - state_set_skip_delays(false); - ut_assertok(dm_test_destroy(uts)); return 0; diff --git a/test/test-main.c b/test/test-main.c index e273777b6e..6f0d32f7e2 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -30,6 +30,8 @@ static int do_autoprobe(struct unit_test_state *uts) int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { + ut_set_skip_delays(uts, false); + uts->start = mallinfo(); if (test->flags & UT_TESTF_SCAN_PDATA) diff --git a/test/ut.c b/test/ut.c index 7328338731..ea0af153e4 100644 --- a/test/ut.c +++ b/test/ut.c @@ -133,3 +133,10 @@ void ut_unsilence_console(struct unit_test_state *uts) { gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); } + +void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays) +{ +#ifdef CONFIG_SANDBOX + state_set_skip_delays(skip_delays); +#endif +} -- cgit v1.2.3 From 72b524cf426697e764c9c63611d0f6743f50f0f5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:34:56 -0700 Subject: test: Handle driver model reinit in test_pre_run() For driver model tests we want to reinit the data structures so that everything is in a known state before the test runs. This avoids one test changing something that breaks a subsequent tests. Move the call for this into test_pre_run(). Signed-off-by: Simon Glass --- include/test/test.h | 2 ++ include/test/ut.h | 10 ++++++++++ test/dm/test-dm.c | 6 +++--- test/test-main.c | 3 +++ 4 files changed, 18 insertions(+), 3 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/test.h b/include/test/test.h index d282cb2362..6997568cc0 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -15,6 +15,7 @@ * @fail_count: Number of tests that failed * @start: Store the starting mallinfo when doing leak test * @priv: A pointer to some other info some suites want to track + * @of_live: true to use livetree if available, false to use flattree * @of_root: Record of the livetree root node (used for setting up tests) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value @@ -24,6 +25,7 @@ struct unit_test_state { struct mallinfo start; void *priv; struct device_node *of_root; + bool of_live; char expect_str[256]; char actual_str[256]; }; diff --git a/include/test/ut.h b/include/test/ut.h index e5ec18e60b..6e56ca99c3 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -387,6 +387,16 @@ int test_pre_run(struct unit_test_state *uts, struct unit_test *test); */ int test_post_run(struct unit_test_state *uts, struct unit_test *test); +/** + * dm_test_init() - Get ready to run a driver model test + * + * This clears out the driver model data structures. For sandbox it resets the + * state structure. + * + * @uts: Test state + */ +int dm_test_init(struct unit_test_state *uts); + /** * ut_run_tests() - Run a set of tests * diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index 569ffbbad9..ceeac3fd36 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -24,10 +24,10 @@ DECLARE_GLOBAL_DATA_PTR; struct unit_test_state global_dm_test_state; static struct dm_test_state _global_priv_dm_test_state; -/* Get ready for testing */ -static int dm_test_init(struct unit_test_state *uts, bool of_live) +int dm_test_init(struct unit_test_state *uts) { struct dm_test_state *dms = uts->priv; + bool of_live = uts->of_live; memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; @@ -70,7 +70,7 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test, printf("Test: %s: %s%s\n", test->name, fname, !of_live ? " (flat tree)" : ""); - ut_assertok(dm_test_init(uts, of_live)); + uts->of_live = of_live; ut_assertok(test_pre_run(uts, test)); diff --git a/test/test-main.c b/test/test-main.c index 6f0d32f7e2..f14b7b09f7 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -30,6 +30,9 @@ static int do_autoprobe(struct unit_test_state *uts) int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { + if (test->flags & UT_TESTF_DM) + ut_assertok(dm_test_init(uts)); + ut_set_skip_delays(uts, false); uts->start = mallinfo(); -- cgit v1.2.3 From c79705ea938e40e204ad90e083a0654f0598a772 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:34:58 -0700 Subject: test: Move dm_test_init() into test-main.c Move this function into test-main so that all the init is in one place. Rename it so that its purpose is clearer. Signed-off-by: Simon Glass --- include/test/ut.h | 9 --------- test/dm/test-dm.c | 22 ---------------------- test/test-main.c | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 32 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 6e56ca99c3..4e0aba9f70 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -387,15 +387,6 @@ int test_pre_run(struct unit_test_state *uts, struct unit_test *test); */ int test_post_run(struct unit_test_state *uts, struct unit_test *test); -/** - * dm_test_init() - Get ready to run a driver model test - * - * This clears out the driver model data structures. For sandbox it resets the - * state structure. - * - * @uts: Test state - */ -int dm_test_init(struct unit_test_state *uts); /** * ut_run_tests() - Run a set of tests diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index 15adc53f53..d601e49752 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -23,27 +22,6 @@ DECLARE_GLOBAL_DATA_PTR; struct unit_test_state global_dm_test_state; -int dm_test_init(struct unit_test_state *uts) -{ - bool of_live = uts->of_live; - - uts->root = NULL; - uts->testdev = NULL; - uts->force_fail_alloc = false; - uts->skip_post_probe = false; - gd->dm_root = NULL; - if (!CONFIG_IS_ENABLED(OF_PLATDATA)) - memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); - state_reset_for_test(state_get_current()); - - /* Determine whether to make the live tree available */ - gd_set_of_root(of_live ? uts->of_root : NULL); - ut_assertok(dm_init(of_live)); - uts->root = dm_root(); - - return 0; -} - static int dm_test_destroy(struct unit_test_state *uts) { int id; diff --git a/test/test-main.c b/test/test-main.c index f14b7b09f7..8b0121bdce 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -7,12 +7,43 @@ #include #include #include +#include #include +#include #include #include DECLARE_GLOBAL_DATA_PTR; +/** + * dm_test_pre_run() - Get ready to run a driver model test + * + * This clears out the driver model data structures. For sandbox it resets the + * state structure + * + * @uts: Test state + */ +static int dm_test_pre_run(struct unit_test_state *uts) +{ + bool of_live = uts->of_live; + + uts->root = NULL; + uts->testdev = NULL; + uts->force_fail_alloc = false; + uts->skip_post_probe = false; + gd->dm_root = NULL; + if (!CONFIG_IS_ENABLED(OF_PLATDATA)) + memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); + state_reset_for_test(state_get_current()); + + /* Determine whether to make the live tree available */ + gd_set_of_root(of_live ? uts->of_root : NULL); + ut_assertok(dm_init(of_live)); + uts->root = dm_root(); + + return 0; +} + /* Ensure all the test devices are probed */ static int do_autoprobe(struct unit_test_state *uts) { @@ -31,7 +62,7 @@ static int do_autoprobe(struct unit_test_state *uts) int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { if (test->flags & UT_TESTF_DM) - ut_assertok(dm_test_init(uts)); + ut_assertok(dm_test_pre_run(uts)); ut_set_skip_delays(uts, false); -- cgit v1.2.3 From 99a88fe1bd98ad800ec0460e3174c2a846a991fe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:35:00 -0700 Subject: test: Move test running into a separate function Add a function to handle the preparation for running a test and the post-test clean-up. Signed-off-by: Simon Glass --- include/test/ut.h | 16 ++++++++++++++++ test/test-main.c | 32 +++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 9 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 4e0aba9f70..98f699cbba 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -387,6 +387,22 @@ int test_pre_run(struct unit_test_state *uts, struct unit_test *test); */ int test_post_run(struct unit_test_state *uts, struct unit_test *test); +/** + * ut_run_test() - Run a single test + * + * This runs the test, handling any preparation and clean-up needed. It prints + * the name of each test before running it. + * + * @uts: Test state to update. The caller should ensure that this is zeroed for + * the first call to this function. On exit, @uts->fail_count is + * incremented by the number of failures (0, one hopes) + * @test: Test to run + * @name: Name of test, possibly skipping a prefix that should not be displayed + * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if + * any failed + */ +int ut_run_test(struct unit_test_state *uts, struct unit_test *test, + const char *name); /** * ut_run_tests() - Run a set of tests diff --git a/test/test-main.c b/test/test-main.c index 3806c2ad89..dee28d35d8 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -121,6 +121,28 @@ int test_post_run(struct unit_test_state *uts, struct unit_test *test) return 0; } +int ut_run_test(struct unit_test_state *uts, struct unit_test *test, + const char *test_name) +{ + int ret; + + printf("Test: %s\n", test_name); + + ret = test_pre_run(uts, test); + if (ret == -EAGAIN) + return -EAGAIN; + if (ret) + return ret; + + test->func(uts); + + ret = test_post_run(uts, test); + if (ret) + return ret; + + return 0; +} + int ut_run_tests(struct unit_test_state *uts, const char *prefix, struct unit_test *tests, int count, const char *select_name) { @@ -138,20 +160,12 @@ int ut_run_tests(struct unit_test_state *uts, const char *prefix, if (select_name && strcmp(select_name, test_name)) continue; - printf("Test: %s\n", test_name); + ret = ut_run_test(uts, test, test_name); found++; - - ret = test_pre_run(uts, test); if (ret == -EAGAIN) continue; if (ret) return ret; - - test->func(uts); - - ret = test_post_run(uts, test); - if (ret) - return ret; } if (select_name && !found) return -ENOENT; -- cgit v1.2.3 From ca44ca0556a29934de6356cd70a1b10f9a13c15c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:35:01 -0700 Subject: test: Use ut_run_test() to run driver model tests Instead of having a separate function for running driver model tests, use the common one. Make the pre/post-run functions private since we don't need these outside of test-main.c Signed-off-by: Simon Glass --- include/test/ut.h | 20 -------------------- test/dm/test-dm.c | 11 +---------- test/test-main.c | 26 +++++++++++++++++++++++--- 3 files changed, 24 insertions(+), 33 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index 98f699cbba..adef0b7e1c 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -367,26 +367,6 @@ void ut_unsilence_console(struct unit_test_state *uts); */ void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays); -/** - * test_pre_run() - Handle any preparation needed to run a test - * - * @uts: Test state - * @test: Test to prepare for - * @return 0 if OK, -EAGAIN to skip this test since some required feature is not - * available, other -ve on error (meaning that testing cannot likely - * continue) - */ -int test_pre_run(struct unit_test_state *uts, struct unit_test *test); - -/** - * test_post_run() - Handle cleaning up after a test - * - * @uts: Test state - * @test: Test to clean up after - * @return 0 if OK, -ve on error (meaning that testing cannot likely continue) - */ -int test_post_run(struct unit_test_state *uts, struct unit_test *test); - /** * ut_run_test() - Run a single test * diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index df938395bb..b01123c740 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -25,17 +25,8 @@ struct unit_test_state global_dm_test_state; static int dm_do_test(struct unit_test_state *uts, struct unit_test *test, bool of_live) { - const char *fname = strrchr(test->file, '/') + 1; - - printf("Test: %s: %s%s\n", test->name, fname, - !of_live ? " (flat tree)" : ""); uts->of_live = of_live; - - ut_assertok(test_pre_run(uts, test)); - - test->func(uts); - - ut_assertok(test_post_run(uts, test)); + ut_assertok(ut_run_test(uts, test, test->name)); return 0; } diff --git a/test/test-main.c b/test/test-main.c index dee28d35d8..32c4d4b199 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -80,7 +80,16 @@ static int do_autoprobe(struct unit_test_state *uts) return ret; } -int test_pre_run(struct unit_test_state *uts, struct unit_test *test) +/** + * test_pre_run() - Handle any preparation needed to run a test + * + * @uts: Test state + * @test: Test to prepare for + * @return 0 if OK, -EAGAIN to skip this test since some required feature is not + * available, other -ve on error (meaning that testing cannot likely + * continue) + */ +static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { if (test->flags & UT_TESTF_DM) ut_assertok(dm_test_pre_run(uts)); @@ -112,7 +121,14 @@ int test_pre_run(struct unit_test_state *uts, struct unit_test *test) return 0; } -int test_post_run(struct unit_test_state *uts, struct unit_test *test) +/** + * test_post_run() - Handle cleaning up after a test + * + * @uts: Test state + * @test: Test to clean up after + * @return 0 if OK, -ve on error (meaning that testing cannot likely continue) + */ +static int test_post_run(struct unit_test_state *uts, struct unit_test *test) { ut_unsilence_console(uts); if (test->flags & UT_TESTF_DM) @@ -124,9 +140,13 @@ int test_post_run(struct unit_test_state *uts, struct unit_test *test) int ut_run_test(struct unit_test_state *uts, struct unit_test *test, const char *test_name) { + const char *fname = strrchr(test->file, '/') + 1; + const char *note = ""; int ret; - printf("Test: %s\n", test_name); + if ((test->flags & UT_TESTF_DM) && !uts->of_live) + note = " (flat tree)"; + printf("Test: %s: %s%s\n", test_name, fname, note); ret = test_pre_run(uts, test); if (ret == -EAGAIN) -- cgit v1.2.3 From d2281bb09b0ebf580f8efe23c84c240a2f3ea9bb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:35:03 -0700 Subject: test: Add ut_run_test_live_flat() to run tests twice Driver model tests are generally run twice, once with livetree enable and again with it disabled. Add a function to handle this and call it from the driver model test runner. Make ut_run_test() private since it is not used outside test-main.c now. Signed-off-by: Simon Glass --- include/test/ut.h | 13 ++++++----- test/dm/test-dm.c | 37 +----------------------------- test/test-main.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 44 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index adef0b7e1c..d06bc5089b 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -368,10 +368,13 @@ void ut_unsilence_console(struct unit_test_state *uts); void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays); /** - * ut_run_test() - Run a single test + * ut_run_test_live_flat() - Run a test with both live and flat tree * - * This runs the test, handling any preparation and clean-up needed. It prints - * the name of each test before running it. + * This calls ut_run_test() with livetree enabled, which is the standard setup + * for runnig tests. Then, for driver model test, it calls it again with + * livetree disabled. This allows checking of flattree being used when OF_LIVE + * is enabled, as is the case in U-Boot proper before relocation, as well as in + * SPL. * * @uts: Test state to update. The caller should ensure that this is zeroed for * the first call to this function. On exit, @uts->fail_count is @@ -381,8 +384,8 @@ void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays); * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if * any failed */ -int ut_run_test(struct unit_test_state *uts, struct unit_test *test, - const char *name); +int ut_run_test_live_flat(struct unit_test_state *uts, struct unit_test *test, + const char *name); /** * ut_run_tests() - Run a set of tests diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index de41fc09db..826b64565e 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -22,21 +22,6 @@ DECLARE_GLOBAL_DATA_PTR; struct unit_test_state global_dm_test_state; -/** - * dm_test_run_on_flattree() - Check if we should run a test with flat DT - * - * This skips long/slow tests where there is not much value in running a flat - * DT test in addition to a live DT test. - * - * @return true to run the given test on the flat device tree - */ -static bool dm_test_run_on_flattree(struct unit_test *test) -{ - const char *fname = strrchr(test->file, '/') + 1; - - return !strstr(fname, "video") || strstr(test->name, "video_base"); -} - static bool test_matches(const char *test_name, const char *find_name) { if (!find_name) @@ -85,31 +70,11 @@ int dm_test_run(const char *test_name) uts->of_root = gd_of_root(); for (test = tests; test < tests + n_ents; test++) { const char *name = test->name; - int runs; if (!test_matches(name, test_name)) continue; - /* Run with the live tree if possible */ - runs = 0; - if (CONFIG_IS_ENABLED(OF_LIVE)) { - if (!(test->flags & UT_TESTF_FLAT_TREE)) { - uts->of_live = true; - ut_assertok(ut_run_test(uts, test, test->name)); - runs++; - } - } - - /* - * Run with the flat tree if we couldn't run it with live tree, - * or it is a core test. - */ - if (!(test->flags & UT_TESTF_LIVE_TREE) && - (!runs || dm_test_run_on_flattree(test))) { - uts->of_live = false; - ut_assertok(ut_run_test(uts, test, test->name)); - runs++; - } + ut_assertok(ut_run_test_live_flat(uts, test, test->name)); found++; } diff --git a/test/test-main.c b/test/test-main.c index 32c4d4b199..4e17c9edb2 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -80,6 +80,24 @@ static int do_autoprobe(struct unit_test_state *uts) return ret; } +/* + * ut_test_run_on_flattree() - Check if we should run a test with flat DT + * + * This skips long/slow tests where there is not much value in running a flat + * DT test in addition to a live DT test. + * + * @return true to run the given test on the flat device tree + */ +static bool ut_test_run_on_flattree(struct unit_test *test) +{ + const char *fname = strrchr(test->file, '/') + 1; + + if (!(test->flags & UT_TESTF_DM)) + return false; + + return !strstr(fname, "video") || strstr(test->name, "video_base"); +} + /** * test_pre_run() - Handle any preparation needed to run a test * @@ -137,8 +155,22 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) return 0; } -int ut_run_test(struct unit_test_state *uts, struct unit_test *test, - const char *test_name) +/** + * ut_run_test() - Run a single test + * + * This runs the test, handling any preparation and clean-up needed. It prints + * the name of each test before running it. + * + * @uts: Test state to update. The caller should ensure that this is zeroed for + * the first call to this function. On exit, @uts->fail_count is + * incremented by the number of failures (0, one hopes) + * @test_name: Test to run + * @name: Name of test, possibly skipping a prefix that should not be displayed + * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if + * any failed + */ +static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, + const char *test_name) { const char *fname = strrchr(test->file, '/') + 1; const char *note = ""; @@ -163,6 +195,35 @@ int ut_run_test(struct unit_test_state *uts, struct unit_test *test, return 0; } +int ut_run_test_live_flat(struct unit_test_state *uts, struct unit_test *test, + const char *name) +{ + int runs; + + /* Run with the live tree if possible */ + runs = 0; + if (CONFIG_IS_ENABLED(OF_LIVE)) { + if (!(test->flags & UT_TESTF_FLAT_TREE)) { + uts->of_live = true; + ut_assertok(ut_run_test(uts, test, test->name)); + runs++; + } + } + + /* + * Run with the flat tree if we couldn't run it with live tree, + * or it is a core test. + */ + if (!(test->flags & UT_TESTF_LIVE_TREE) && + (!runs || ut_test_run_on_flattree(test))) { + uts->of_live = false; + ut_assertok(ut_run_test(uts, test, test->name)); + runs++; + } + + return 0; +} + int ut_run_tests(struct unit_test_state *uts, const char *prefix, struct unit_test *tests, int count, const char *select_name) { @@ -180,7 +241,7 @@ int ut_run_tests(struct unit_test_state *uts, const char *prefix, if (select_name && strcmp(select_name, test_name)) continue; - ret = ut_run_test(uts, test, test_name); + ret = ut_run_test_live_flat(uts, test, test_name); found++; if (ret == -EAGAIN) continue; -- cgit v1.2.3 From fe806861a98b4ad524d070c6d7b9d20fd475ec6f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:35:04 -0700 Subject: test: Use a local variable for test state At present we use a global test state for all driver-model tests. Make use of a local struct like we do with the other tests. To make this work, add functions to get and set this state. When a test starts, the state is set (so it can be used in the test). When a test finishes, the state is unset, so it cannot be used by mistake. Signed-off-by: Simon Glass --- include/test/ut.h | 14 ++++++++++++++ test/dm/test-dm.c | 4 +--- test/dm/test-driver.c | 10 +++++++++- test/dm/test-uclass.c | 7 +++++-- test/test-main.c | 18 ++++++++++++++++++ 5 files changed, 47 insertions(+), 6 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index d06bc5089b..bed0e6eb5f 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -367,6 +367,20 @@ void ut_unsilence_console(struct unit_test_state *uts); */ void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays); +/** + * test_get_state() - Get the active test state + * + * @return the currently active test state, or NULL if none + */ +struct unit_test_state *test_get_state(void); + +/** + * test_set_state() - Set the active test state + * + * @uts: Test state to use as currently active test state, or NULL if none + */ +void test_set_state(struct unit_test_state *uts); + /** * ut_run_test_live_flat() - Run a test with both live and flat tree * diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index 826b64565e..cdaf27bf98 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -20,8 +20,6 @@ DECLARE_GLOBAL_DATA_PTR; -struct unit_test_state global_dm_test_state; - static bool test_matches(const char *test_name, const char *find_name) { if (!find_name) @@ -44,7 +42,7 @@ int dm_test_run(const char *test_name) { struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); const int n_ents = ll_entry_count(struct unit_test, dm_test); - struct unit_test_state *uts = &global_dm_test_state; + struct unit_test_state uts_s = { .fail_count = 0 }, *uts = &uts_s; struct unit_test *test; int found; diff --git a/test/dm/test-driver.c b/test/dm/test-driver.c index 63dc9d335a..02cb974b0f 100644 --- a/test/dm/test-driver.c +++ b/test/dm/test-driver.c @@ -18,7 +18,6 @@ #include int dm_testdrv_op_count[DM_TEST_OP_COUNT]; -static struct unit_test_state *uts = &global_dm_test_state; static int testdrv_ping(struct udevice *dev, int pingval, int *pingret) { @@ -37,6 +36,8 @@ static const struct test_ops test_ops = { static int test_bind(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); + /* Private data should not be allocated */ ut_assert(!dev_get_priv(dev)); @@ -46,6 +47,7 @@ static int test_bind(struct udevice *dev) static int test_probe(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); struct dm_test_priv *priv = dev_get_priv(dev); /* Private data should be allocated */ @@ -58,6 +60,8 @@ static int test_probe(struct udevice *dev) static int test_remove(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); + /* Private data should still be allocated */ ut_assert(dev_get_priv(dev)); @@ -67,6 +71,8 @@ static int test_remove(struct udevice *dev) static int test_unbind(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); + /* Private data should not be allocated */ ut_assert(!dev_get_priv(dev)); @@ -116,6 +122,8 @@ static int test_manual_bind(struct udevice *dev) static int test_manual_probe(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); + dm_testdrv_op_count[DM_TEST_OP_PROBE]++; if (!uts->force_fail_alloc) dev_set_priv(dev, calloc(1, sizeof(struct dm_test_priv))); diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c index f4b540c927..067701734a 100644 --- a/test/dm/test-uclass.c +++ b/test/dm/test-uclass.c @@ -17,8 +17,6 @@ #include #include -static struct unit_test_state *uts = &global_dm_test_state; - int test_ping(struct udevice *dev, int pingval, int *pingret) { const struct test_ops *ops = device_get_ops(dev); @@ -31,6 +29,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret) static int test_post_bind(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); struct dm_test_perdev_uc_pdata *uc_pdata; dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++; @@ -56,6 +55,7 @@ static int test_pre_unbind(struct udevice *dev) static int test_pre_probe(struct udevice *dev) { struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); + struct unit_test_state *uts = test_get_state(); dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++; ut_assert(priv); @@ -66,6 +66,7 @@ static int test_pre_probe(struct udevice *dev) static int test_post_probe(struct udevice *dev) { + struct unit_test_state *uts = test_get_state(); struct udevice *prev = list_entry(dev->uclass_node.prev, struct udevice, uclass_node); @@ -100,6 +101,8 @@ static int test_pre_remove(struct udevice *dev) static int test_init(struct uclass *uc) { + struct unit_test_state *uts = test_get_state(); + dm_testdrv_op_count[DM_TEST_OP_INIT]++; ut_assert(uclass_get_priv(uc)); diff --git a/test/test-main.c b/test/test-main.c index 4e17c9edb2..139fc1f6f1 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -16,6 +16,19 @@ DECLARE_GLOBAL_DATA_PTR; +/* This is valid when a test is running, NULL otherwise */ +static struct unit_test_state *cur_test_state; + +struct unit_test_state *test_get_state(void) +{ + return cur_test_state; +} + +void test_set_state(struct unit_test_state *uts) +{ + cur_test_state = uts; +} + /** * dm_test_pre_run() - Get ready to run a driver model test * @@ -180,6 +193,9 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, note = " (flat tree)"; printf("Test: %s: %s%s\n", test_name, fname, note); + /* Allow access to test state from drivers */ + test_set_state(uts); + ret = test_pre_run(uts, test); if (ret == -EAGAIN) return -EAGAIN; @@ -192,6 +208,8 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, if (ret) return ret; + test_set_state( NULL); + return 0; } -- cgit v1.2.3 From f97f85e6618667c877b90e938d6bf36d56e69270 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Mar 2021 17:35:05 -0700 Subject: test: Run driver-model tests using ut_run_list() Use this function instead of implementing it separately for driver model. Make ut_run_tests() private since it is only used in test-main.c Signed-off-by: Simon Glass --- include/test/ut.h | 42 --------------------------- test/dm/test-dm.c | 45 ++++------------------------ test/test-main.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 81 insertions(+), 93 deletions(-) (limited to 'include/test/ut.h') diff --git a/include/test/ut.h b/include/test/ut.h index bed0e6eb5f..fbbba286ee 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -381,48 +381,6 @@ struct unit_test_state *test_get_state(void); */ void test_set_state(struct unit_test_state *uts); -/** - * ut_run_test_live_flat() - Run a test with both live and flat tree - * - * This calls ut_run_test() with livetree enabled, which is the standard setup - * for runnig tests. Then, for driver model test, it calls it again with - * livetree disabled. This allows checking of flattree being used when OF_LIVE - * is enabled, as is the case in U-Boot proper before relocation, as well as in - * SPL. - * - * @uts: Test state to update. The caller should ensure that this is zeroed for - * the first call to this function. On exit, @uts->fail_count is - * incremented by the number of failures (0, one hopes) - * @test: Test to run - * @name: Name of test, possibly skipping a prefix that should not be displayed - * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if - * any failed - */ -int ut_run_test_live_flat(struct unit_test_state *uts, struct unit_test *test, - const char *name); - -/** - * ut_run_tests() - Run a set of tests - * - * This runs the tests, handling any preparation and clean-up needed. It prints - * the name of each test before running it. - * - * @uts: Test state to update. The caller should ensure that this is zeroed for - * the first call to this function. On exit, @uts->fail_count is - * incremented by the number of failures (0, one hopes) - * @prefix: String prefix for the tests. Any tests that have this prefix will be - * printed without the prefix, so that it is easier to see the unique part - * of the test name. If NULL, no prefix processing is done - * @tests: List of tests to run - * @count: Number of tests to run - * @select_name: Name of a single test to run (from the list provided). If NULL - * then all tests are run - * @return 0 if all tests passed, -ENOENT if test @select_name was not found, - * -EBADF if any failed - */ -int ut_run_tests(struct unit_test_state *uts, const char *prefix, - struct unit_test *tests, int count, const char *select_name); - /** * ut_run_tests() - Run a set of tests * diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index cdaf27bf98..20af1c13b3 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -20,31 +20,14 @@ DECLARE_GLOBAL_DATA_PTR; -static bool test_matches(const char *test_name, const char *find_name) -{ - if (!find_name) - return true; - - if (!strcmp(test_name, find_name)) - return true; - - /* All tests have this prefix */ - if (!strncmp(test_name, "dm_test_", 8)) - test_name += 8; - - if (!strcmp(test_name, find_name)) - return true; - - return false; -} +struct unit_test_state global_dm_test_state; int dm_test_run(const char *test_name) { struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); const int n_ents = ll_entry_count(struct unit_test, dm_test); struct unit_test_state uts_s = { .fail_count = 0 }, *uts = &uts_s; - struct unit_test *test; - int found; + struct device_node *of_root; uts->fail_count = 0; @@ -60,29 +43,11 @@ int dm_test_run(const char *test_name) } } - if (!test_name) - printf("Running %d driver model tests\n", n_ents); - else - - found = 0; - uts->of_root = gd_of_root(); - for (test = tests; test < tests + n_ents; test++) { - const char *name = test->name; - - if (!test_matches(name, test_name)) - continue; - - ut_assertok(ut_run_test_live_flat(uts, test, test->name)); - found++; - } - - if (test_name && !found) - printf("Test '%s' not found\n", test_name); - else - printf("Failures: %d\n", uts->fail_count); + of_root = gd_of_root(); + ut_run_list("driver model", "dm_test_", tests, n_ents, test_name); /* Put everything back to normal so that sandbox works as expected */ - gd_set_of_root(uts->of_root); + gd_set_of_root(of_root); gd->dm_root = NULL; ut_assertok(dm_init(CONFIG_IS_ENABLED(OF_LIVE))); dm_scan_plat(false); diff --git a/test/test-main.c b/test/test-main.c index 139fc1f6f1..16c0d13ea5 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -111,6 +111,38 @@ static bool ut_test_run_on_flattree(struct unit_test *test) return !strstr(fname, "video") || strstr(test->name, "video_base"); } +/** + * test_matches() - Check if a test should be run + * + * This checks if the a test should be run. In the normal case of running all + * tests, @select_name is NULL. + * + * @prefix: String prefix for the tests. Any tests that have this prefix will be + * printed without the prefix, so that it is easier to see the unique part + * of the test name. If NULL, no prefix processing is done + * @test_name: Name of current test + * @select_name: Name of test to run (or NULL for all) + * @return true to run this test, false to skip it + */ +static bool test_matches(const char *prefix, const char *test_name, + const char *select_name) +{ + if (!select_name) + return true; + + if (!strcmp(test_name, select_name)) + return true; + + /* All tests have this prefix */ + if (prefix && !strncmp(test_name, prefix, strlen(prefix))) + test_name += strlen(prefix); + + if (!strcmp(test_name, select_name)) + return true; + + return false; +} + /** * test_pre_run() - Handle any preparation needed to run a test * @@ -213,8 +245,25 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, return 0; } -int ut_run_test_live_flat(struct unit_test_state *uts, struct unit_test *test, - const char *name) +/** + * ut_run_test_live_flat() - Run a test with both live and flat tree + * + * This calls ut_run_test() with livetree enabled, which is the standard setup + * for runnig tests. Then, for driver model test, it calls it again with + * livetree disabled. This allows checking of flattree being used when OF_LIVE + * is enabled, as is the case in U-Boot proper before relocation, as well as in + * SPL. + * + * @uts: Test state to update. The caller should ensure that this is zeroed for + * the first call to this function. On exit, @uts->fail_count is + * incremented by the number of failures (0, one hopes) + * @test: Test to run + * @name: Name of test, possibly skipping a prefix that should not be displayed + * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if + * any failed + */ +static int ut_run_test_live_flat(struct unit_test_state *uts, + struct unit_test *test, const char *name) { int runs; @@ -242,24 +291,39 @@ int ut_run_test_live_flat(struct unit_test_state *uts, struct unit_test *test, return 0; } -int ut_run_tests(struct unit_test_state *uts, const char *prefix, - struct unit_test *tests, int count, const char *select_name) +/** + * ut_run_tests() - Run a set of tests + * + * This runs the tests, handling any preparation and clean-up needed. It prints + * the name of each test before running it. + * + * @uts: Test state to update. The caller should ensure that this is zeroed for + * the first call to this function. On exit, @uts->fail_count is + * incremented by the number of failures (0, one hopes) + * @prefix: String prefix for the tests. Any tests that have this prefix will be + * printed without the prefix, so that it is easier to see the unique part + * of the test name. If NULL, no prefix processing is done + * @tests: List of tests to run + * @count: Number of tests to run + * @select_name: Name of a single test to run (from the list provided). If NULL + * then all tests are run + * @return 0 if all tests passed, -ENOENT if test @select_name was not found, + * -EBADF if any failed + */ +static int ut_run_tests(struct unit_test_state *uts, const char *prefix, + struct unit_test *tests, int count, + const char *select_name) { struct unit_test *test; - int prefix_len = prefix ? strlen(prefix) : 0; int found = 0; for (test = tests; test < tests + count; test++) { const char *test_name = test->name; int ret; - /* Remove the prefix */ - if (prefix && !strncmp(test_name, prefix, prefix_len)) - test_name += prefix_len; - - if (select_name && strcmp(select_name, test_name)) + if (!test_matches(prefix, test_name, select_name)) continue; - ret = ut_run_test_live_flat(uts, test, test_name); + ret = ut_run_test_live_flat(uts, test, select_name); found++; if (ret == -EAGAIN) continue; @@ -281,6 +345,7 @@ int ut_run_list(const char *category, const char *prefix, if (!select_name) printf("Running %d %s tests\n", count, category); + uts.of_root = gd_of_root(); ret = ut_run_tests(&uts, prefix, tests, count, select_name); if (ret == -ENOENT) -- cgit v1.2.3