From b2bce215723c6ee3baacf5a562c6297db39744ab Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Wed, 4 Oct 2017 14:29:51 -0700 Subject: [PATCH] ztest: add user thread support We add macros to define test cases that should be run with the CPU in user mode, if the CPU supports it. ztest_test_suite() declarations are now static as they can't go on the main thread stack; the data gets shared between multiple threads. It's better here anyway as a large test suite could fill up the main stack, which is by default reduced to 512 bytes. Signed-off-by: Andrew Boie --- tests/ztest/include/ztest_test.h | 34 ++++++++++++++++++++++++++++++-- tests/ztest/src/ztest.c | 9 +++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/tests/ztest/include/ztest_test.h b/tests/ztest/include/ztest_test.h index 81f0cd7157..dd999889e7 100644 --- a/tests/ztest/include/ztest_test.h +++ b/tests/ztest/include/ztest_test.h @@ -18,6 +18,7 @@ struct unit_test { void (*test)(void); void (*setup)(void); void (*teardown)(void); + u32_t thread_options; }; void _ztest_run_test_suite(const char *name, struct unit_test *suite); @@ -73,9 +74,25 @@ static inline void unit_test_noop(void) */ #define ztest_unit_test_setup_teardown(fn, setup, teardown) { \ - STRINGIFY(fn), fn, setup, teardown \ + STRINGIFY(fn), fn, setup, teardown, 0 \ } +/** + * @brief Define a user mode test with setup and teardown functions + * + * This should be called as an argument to ztest_test_suite. The test will + * be run in the following order: @a setup, @a fn, @a teardown. ALL + * test functions will be run in user mode, and only if CONFIG_USERSPACE + * is enabled, otherwise this is the same as ztest_unit_test_setup_teardown(). + * + * @param fn Main test function + * @param setup Setup function + * @param teardown Teardown function + */ + +#define ztest_user_unit_test_setup_teardown(fn, setup, teardown) { \ + STRINGIFY(fn), fn, setup, teardown, K_USER \ +} /** * @brief Define a test function @@ -88,6 +105,19 @@ static inline void unit_test_noop(void) #define ztest_unit_test(fn) \ ztest_unit_test_setup_teardown(fn, unit_test_noop, unit_test_noop) +/** + * @brief Define a test function that should run as a user thread + * + * This should be called as an argument to ztest_test_suite. + * If CONFIG_USERSPACE is not enabled, this is functionally identical to + * ztest_unit_test(). + * + * @param fn Test function + */ + +#define ztest_user_unit_test(fn) \ + ztest_user_unit_test_setup_teardown(fn, unit_test_noop, unit_test_noop) + /** * @brief Define a test suite * @@ -104,7 +134,7 @@ static inline void unit_test_noop(void) * @param name Name of the testing suite */ #define ztest_test_suite(name, ...) \ - struct unit_test _##name[] = { \ + static struct unit_test _##name[] = { \ __VA_ARGS__, { 0 } \ } /** diff --git a/tests/ztest/src/ztest.c b/tests/ztest/src/ztest.c index 0fe678e59f..af821fdea6 100644 --- a/tests/ztest/src/ztest.c +++ b/tests/ztest/src/ztest.c @@ -139,12 +139,12 @@ out: #if CONFIG_ZTEST_STACKSIZE & (STACK_ALIGN - 1) #error "CONFIG_ZTEST_STACKSIZE must be a multiple of the stack alignment" #endif -static struct k_thread ztest_thread; +__kernel static struct k_thread ztest_thread; static K_THREAD_STACK_DEFINE(thread_stack, CONFIG_ZTEST_STACKSIZE + CONFIG_TEST_EXTRA_STACKSIZE); static int test_result; -static struct k_sem test_end_signal; +__kernel static struct k_sem test_end_signal; void ztest_test_fail(void) { @@ -163,6 +163,7 @@ void ztest_test_pass(void) static void init_testing(void) { k_sem_init(&test_end_signal, 0, 1); + k_object_access_all_grant(&test_end_signal); } static void test_cb(void *a, void *dummy2, void *dummy) @@ -187,8 +188,8 @@ static int run_test(struct unit_test *test) k_thread_create(&ztest_thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack), (k_thread_entry_t) test_cb, (struct unit_test *)test, - NULL, NULL, -1, 0, 0); - + NULL, NULL, -1, test->thread_options | K_INHERIT_PERMS, + 0); /* * There is an implicit expectation here that the thread that was * spawned is still higher priority than the current thread.