From 900b6723e76897841888a18d20d710d7dfdbee7c Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Tue, 5 Apr 2022 11:42:31 -0600 Subject: [PATCH] ztest: Fix userspace ztests in new API Update the new API to use K_USER as the flags for both CONFIG_USERSPACE and CONFIG_TEST_USERSPACE. Also, fix the linker script to properly include the suites, tests, and rules. Fixes #44108 Signed-off-by: Yuval Peress --- cmake/modules/unittest.cmake | 2 +- include/zephyr/linker/common-ram.ld | 8 ---- subsys/testsuite/CMakeLists.txt | 4 ++ subsys/testsuite/include/ztest.ld | 41 ++++++++--------- subsys/testsuite/include/ztest_unittest.ld | 28 ++++++++++++ .../testsuite/ztest/include/ztest_test_new.h | 45 +++++++++++-------- subsys/testsuite/ztest/src/ztest_new.c | 4 +- 7 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 subsys/testsuite/include/ztest_unittest.ld diff --git a/cmake/modules/unittest.cmake b/cmake/modules/unittest.cmake index 607e418f25..8973abf939 100644 --- a/cmake/modules/unittest.cmake +++ b/cmake/modules/unittest.cmake @@ -62,7 +62,7 @@ target_compile_options(testbinary PRIVATE ) target_link_options(testbinary PRIVATE - -T "${ZEPHYR_BASE}/subsys/testsuite/include/ztest.ld" + -T "${ZEPHYR_BASE}/subsys/testsuite/include/ztest_unittest.ld" ) target_link_libraries(testbinary PRIVATE diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index f36c7d8021..eeee5289a3 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -145,11 +145,3 @@ #ifdef CONFIG_USERSPACE _static_kernel_objects_end = .; #endif - -#if defined(CONFIG_ZTEST) - ITERABLE_SECTION_RAM(ztest_suite_node, 4) -#if defined(CONFIG_ZTEST_NEW_API) - ITERABLE_SECTION_RAM(ztest_unit_test, 4) - ITERABLE_SECTION_RAM(ztest_test_rule, 4) -#endif /* CONFIG_ZTEST_NEW_API */ -#endif /* CONFIG_ZTEST */ diff --git a/subsys/testsuite/CMakeLists.txt b/subsys/testsuite/CMakeLists.txt index b7bed7047c..7fe6c2d0b4 100644 --- a/subsys/testsuite/CMakeLists.txt +++ b/subsys/testsuite/CMakeLists.txt @@ -8,3 +8,7 @@ zephyr_include_directories_ifdef(CONFIG_TEST add_subdirectory_ifdef(CONFIG_COVERAGE_GCOV coverage) zephyr_library_sources_ifdef(CONFIG_TEST_BUSY_SIM busy_sim/busy_sim.c) + +if(NOT BOARD STREQUAL unit_testing) + zephyr_linker_sources(RODATA include/ztest.ld) +endif() diff --git a/subsys/testsuite/include/ztest.ld b/subsys/testsuite/include/ztest.ld index 14de5a897f..222fb685ac 100644 --- a/subsys/testsuite/include/ztest.ld +++ b/subsys/testsuite/include/ztest.ld @@ -4,25 +4,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -SECTIONS -{ - .data.ztest_suite_node_area : ALIGN(4) - { - _ztest_suite_node_list_start = .; - KEEP(*(SORT_BY_NAME(._ztest_suite_node.static.*))) - _ztest_suite_node_list_end = .; - } - .data.ztest_unit_test_area : ALIGN(4) - { - _ztest_unit_test_list_start = .; - KEEP(*(SORT_BY_NAME(._ztest_unit_test.static.*))) - _ztest_unit_test_list_end = .; - } - .data.ztest_test_rule_area : ALIGN(4) - { - _ztest_test_rule_list_start = .; - KEEP(*(SORT_BY_NAME(._ztest_test_rule.static.*))) - _ztest_test_rule_list_end = .; - } -} -INSERT AFTER .data; +#if defined(CONFIG_ARM_MMU) +#define _ZTEST_ALIGN CONFIG_MMU_PAGE_SIZE +#elif defined(CONFIG_ARM_MPU) +#define _ZTEST_ALIGN CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE +#elif defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) +#define _ZTEST_ALIGN 16 +#else +#define _ZTEST_ALIGN 4 +#endif + +#if defined(CONFIG_ZTEST) +Z_LINK_ITERABLE_ALIGNED(ztest_suite_node, _ZTEST_ALIGN); + +#if defined(CONFIG_ZTEST_NEW_API) +Z_LINK_ITERABLE_ALIGNED(ztest_unit_test, _ZTEST_ALIGN); +Z_LINK_ITERABLE_ALIGNED(ztest_test_rule, _ZTEST_ALIGN); +#endif /* CONFIG_ZTEST_NEW_API */ + +#endif /* CONFIG_ZTEST */ diff --git a/subsys/testsuite/include/ztest_unittest.ld b/subsys/testsuite/include/ztest_unittest.ld new file mode 100644 index 0000000000..af73dfe7e7 --- /dev/null +++ b/subsys/testsuite/include/ztest_unittest.ld @@ -0,0 +1,28 @@ +/* + * Copyright 2022 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTIONS +{ + .data.ztest_suite_node_area : ALIGN(4) + { + _ztest_suite_node_list_start = .; + KEEP(*(SORT_BY_NAME(._ztest_suite_node.static.*))) + _ztest_suite_node_list_end = .; + } + .data.ztest_unit_test_area : ALIGN(4) + { + _ztest_unit_test_list_start = .; + KEEP(*(SORT_BY_NAME(._ztest_unit_test.static.*))) + _ztest_unit_test_list_end = .; + } + .data.ztest_test_rule_area : ALIGN(4) + { + _ztest_test_rule_list_start = .; + KEEP(*(SORT_BY_NAME(._ztest_test_rule.static.*))) + _ztest_test_rule_list_end = .; + } +} +INSERT AFTER .data; diff --git a/subsys/testsuite/ztest/include/ztest_test_new.h b/subsys/testsuite/ztest/include/ztest_test_new.h index c000f75a9f..6ae940a015 100644 --- a/subsys/testsuite/ztest/include/ztest_test_new.h +++ b/subsys/testsuite/ztest/include/ztest_test_new.h @@ -17,6 +17,12 @@ #include #include +#if defined(CONFIG_USERSPACE) || defined(CONFIG_TEST_USERSPACE) +#define __USERSPACE_FLAGS (K_USER) +#else +#define __USERSPACE_FLAGS (0) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -49,31 +55,31 @@ struct ztest_suite_stats { */ struct ztest_suite_node { /** The name of the test suite. */ - const char *name; + const char * const name; /** * Setup function to run before running this suite * * @return Pointer to the data structure that will be used throughout this test suite */ - void *(*setup)(void); + void *(*const setup)(void); /** * Function to run before each test in this suite * * @param data The test suite's data returned from setup() */ - void (*before)(void *data); + void (*const before)(void *data); /** * Function to run after each test in this suite * * @param data The test suite's data returned from setup() */ - void (*after)(void *data); + void (*const after)(void *data); /** * Teardown function to run after running this suite * * @param data The test suite's data returned from setup() */ - void (*teardown)(void *data); + void (*const teardown)(void *data); /** * An optional predicate function to determine if the test should run. If NULL, then the * test will only run once on the first attempt. @@ -81,9 +87,9 @@ struct ztest_suite_node { * @param state The current state of the test application. * @return True if the suite should be run; false to skip. */ - bool (*predicate)(const void *state); + bool (*const predicate)(const void *state); /** Stats */ - struct ztest_suite_stats stats; + struct ztest_suite_stats * const stats; }; extern struct ztest_suite_node _ztest_suite_node_list_start[]; @@ -103,17 +109,18 @@ extern struct ztest_suite_node _ztest_suite_node_list_end[]; * @param after_fn The function to call after each unit test in this suite * @param teardown_fn The function to call after running all the tests in this suite */ -#define ZTEST_SUITE(SUITE_NAME, PREDICATE, setup_fn, before_fn, after_fn, teardown_fn) \ - static STRUCT_SECTION_ITERABLE(ztest_suite_node, \ - UTIL_CAT(z_ztest_test_node_, SUITE_NAME)) = { \ - .name = STRINGIFY(SUITE_NAME), \ - .setup = (setup_fn), \ - .before = (before_fn), \ - .after = (after_fn), \ - .teardown = (teardown_fn), \ - .predicate = PREDICATE, \ +#define ZTEST_SUITE(SUITE_NAME, PREDICATE, setup_fn, before_fn, after_fn, teardown_fn) \ + static struct ztest_suite_stats UTIL_CAT(z_ztest_test_node_stats_, SUITE_NAME); \ + static const STRUCT_SECTION_ITERABLE(ztest_suite_node, \ + UTIL_CAT(z_ztest_test_node_, SUITE_NAME)) = { \ + .name = STRINGIFY(SUITE_NAME), \ + .setup = (setup_fn), \ + .before = (before_fn), \ + .after = (after_fn), \ + .teardown = (teardown_fn), \ + .predicate = PREDICATE, \ + .stats = &UTIL_CAT(z_ztest_test_node_stats_, SUITE_NAME), \ } - /** * Run the registered unit tests which return true from their pragma function. * @@ -240,7 +247,7 @@ static inline void unit_test_noop(void) * @param suite The name of the test suite to attach this test * @param fn The test function to call. */ -#define ZTEST_USER(suite, fn) Z_ZTEST(suite, fn, COND_CODE_1(CONFIG_USERSPACE, (K_USER), (0))) +#define ZTEST_USER(suite, fn) Z_ZTEST(suite, fn, __USERSPACE_FLAGS) /** * @brief Define a test function @@ -262,7 +269,7 @@ static inline void unit_test_noop(void) * @param suite The name of the test suite to attach this test * @param fn The test function to call. */ -#define ZTEST_USER_F(suite, fn) Z_ZTEST_F(suite, fn, COND_CODE_1(CONFIG_USERSPACE, (K_USER), (0))) +#define ZTEST_USER_F(suite, fn) Z_ZTEST_F(suite, fn, __USERSPACE_FLAGS) /** * @brief Test rule callback function signature diff --git a/subsys/testsuite/ztest/src/ztest_new.c b/subsys/testsuite/ztest/src/ztest_new.c index ecc0715816..2679015210 100644 --- a/subsys/testsuite/ztest/src/ztest_new.c +++ b/subsys/testsuite/ztest/src/ztest_new.c @@ -559,7 +559,7 @@ int ztest_run_test_suites(const void *state) int count = 0; for (ptr = _ztest_suite_node_list_start; ptr < _ztest_suite_node_list_end; ++ptr) { - struct ztest_suite_stats *stats = &ptr->stats; + struct ztest_suite_stats *stats = ptr->stats; bool should_run = true; if (ptr->predicate != NULL) { @@ -590,7 +590,7 @@ void ztest_verify_all_test_suites_ran(void) struct ztest_unit_test *test; for (suite = _ztest_suite_node_list_start; suite < _ztest_suite_node_list_end; ++suite) { - if (suite->stats.run_count < 1) { + if (suite->stats->run_count < 1) { PRINT("ERROR: Test suite '%s' did not run.\n", suite->name); all_tests_run = false; }