From facd0f57db85163432bdca7767a05e3f1d742b9f Mon Sep 17 00:00:00 2001 From: Ying ming Date: Thu, 11 Mar 2021 11:17:03 +0800 Subject: [PATCH] test: schedule_api : test some negative test Add error test of api to improve branch and line coverage in sched.c. Signed-off-by: Ying ming --- tests/kernel/sched/schedule_api/prj.conf | 1 + tests/kernel/sched/schedule_api/prj_dumb.conf | 1 + .../kernel/sched/schedule_api/prj_multiq.conf | 1 + tests/kernel/sched/schedule_api/src/main.c | 10 +- .../sched/schedule_api/src/test_sched.h | 8 + .../kernel/sched/schedule_api/src/user_api.c | 284 +++++++++++++++++- tests/kernel/sched/schedule_api/testcase.yaml | 14 +- 7 files changed, 307 insertions(+), 12 deletions(-) diff --git a/tests/kernel/sched/schedule_api/prj.conf b/tests/kernel/sched/schedule_api/prj.conf index 6b5392c8e9b..9a2383c8584 100644 --- a/tests/kernel/sched/schedule_api/prj.conf +++ b/tests/kernel/sched/schedule_api/prj.conf @@ -6,3 +6,4 @@ CONFIG_NUM_COOP_PRIORITIES=30 CONFIG_MAX_THREAD_BYTES=5 CONFIG_TEST_USERSPACE=y CONFIG_MP_NUM_CPUS=1 +CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/sched/schedule_api/prj_dumb.conf b/tests/kernel/sched/schedule_api/prj_dumb.conf index 76a0c1ffe1a..5d226599542 100644 --- a/tests/kernel/sched/schedule_api/prj_dumb.conf +++ b/tests/kernel/sched/schedule_api/prj_dumb.conf @@ -4,3 +4,4 @@ CONFIG_TEST_USERSPACE=y CONFIG_SCHED_DUMB=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_NUM_CPUS=1 +CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/sched/schedule_api/prj_multiq.conf b/tests/kernel/sched/schedule_api/prj_multiq.conf index bf8c1d6a525..e373e7939e3 100644 --- a/tests/kernel/sched/schedule_api/prj_multiq.conf +++ b/tests/kernel/sched/schedule_api/prj_multiq.conf @@ -4,3 +4,4 @@ CONFIG_TEST_USERSPACE=y CONFIG_SCHED_MULTIQ=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_NUM_CPUS=1 +CONFIG_ZTEST_FATAL_HOOK=y diff --git a/tests/kernel/sched/schedule_api/src/main.c b/tests/kernel/sched/schedule_api/src/main.c index 054ee5d79b7..5c861aacf0e 100644 --- a/tests/kernel/sched/schedule_api/src/main.c +++ b/tests/kernel/sched/schedule_api/src/main.c @@ -52,6 +52,7 @@ void test_main(void) ztest_1cpu_unit_test(test_priority_preemptible_wait_prio), ztest_unit_test(test_yield_cooperative), ztest_unit_test(test_sleep_cooperative), + ztest_unit_test(test_busy_wait_cooperative), ztest_unit_test(test_sleep_wakeup_preemptible), ztest_unit_test(test_pending_thread_wakeup), ztest_unit_test(test_time_slicing_preemptible), @@ -65,7 +66,14 @@ void test_main(void) ztest_unit_test(test_priority_scheduling), ztest_unit_test(test_wakeup_expired_timer_thread), ztest_user_unit_test(test_user_k_wakeup), - ztest_user_unit_test(test_user_k_is_preempt) + ztest_user_unit_test(test_user_k_is_preempt), + ztest_user_unit_test(test_k_thread_suspend_init_null), + ztest_user_unit_test(test_k_thread_resume_init_null), + ztest_user_unit_test(test_k_thread_priority_get_init_null), + ztest_user_unit_test(test_k_thread_priority_set_init_null), + ztest_user_unit_test(test_k_thread_priority_set_overmax), + ztest_user_unit_test(test_k_thread_priority_set_upgrade), + ztest_user_unit_test(test_k_wakeup_init_null) ); ztest_run_test_suite(threads_scheduling); } diff --git a/tests/kernel/sched/schedule_api/src/test_sched.h b/tests/kernel/sched/schedule_api/src/test_sched.h index 9b9486dd12c..094865cb2c2 100644 --- a/tests/kernel/sched/schedule_api/src/test_sched.h +++ b/tests/kernel/sched/schedule_api/src/test_sched.h @@ -32,6 +32,7 @@ void test_priority_preemptible_wait_prio(void); void test_bad_priorities(void); void test_yield_cooperative(void); void test_sleep_cooperative(void); +void test_busy_wait_cooperative(void); void test_sleep_wakeup_preemptible(void); void test_pending_thread_wakeup(void); void test_time_slicing_preemptible(void); @@ -46,5 +47,12 @@ void test_priority_scheduling(void); void test_wakeup_expired_timer_thread(void); void test_user_k_wakeup(void); void test_user_k_is_preempt(void); +void test_k_thread_suspend_init_null(void); +void test_k_thread_resume_init_null(void); +void test_k_thread_priority_get_init_null(void); +void test_k_thread_priority_set_init_null(void); +void test_k_thread_priority_set_overmax(void); +void test_k_thread_priority_set_upgrade(void); +void test_k_wakeup_init_null(void); #endif /* __TEST_SCHED_H__ */ diff --git a/tests/kernel/sched/schedule_api/src/user_api.c b/tests/kernel/sched/schedule_api/src/user_api.c index 309bec2009b..fecfd8217e0 100644 --- a/tests/kernel/sched/schedule_api/src/user_api.c +++ b/tests/kernel/sched/schedule_api/src/user_api.c @@ -5,12 +5,18 @@ */ #include "test_sched.h" +#include +#include +#include +#include struct k_thread user_thread; K_SEM_DEFINE(user_sem, 0, 1); ZTEST_BMEM volatile int thread_was_preempt; +#define THREAD_TEST_PRIORITY 0 + K_THREAD_STACK_DEFINE(ustack, STACK_SIZE); static void sleepy_thread(void *p1, void *p2, void *p3) @@ -25,7 +31,7 @@ static void sleepy_thread(void *p1, void *p2, void *p3) void test_user_k_wakeup(void) { - k_thread_create(&user_thread, ustack, STACK_SIZE, sleepy_thread, + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, sleepy_thread, NULL, NULL, NULL, k_thread_priority_get(k_current_get()), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -33,6 +39,7 @@ void test_user_k_wakeup(void) k_yield(); /* Let thread run and start sleeping forever */ k_wakeup(&user_thread); k_sem_take(&user_sem, K_FOREVER); + k_thread_abort(tid); } static void preempt_test_thread(void *p1, void *p2, void *p3) @@ -59,8 +66,8 @@ void test_user_k_is_preempt(void) */ int twp; - k_thread_create(&user_thread, ustack, STACK_SIZE, preempt_test_thread, - NULL, NULL, NULL, + k_tid_t tid = k_thread_create(&user_thread, ustack, + STACK_SIZE, preempt_test_thread, NULL, NULL, NULL, k_thread_priority_get(k_current_get()), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -68,8 +75,9 @@ void test_user_k_is_preempt(void) twp = thread_was_preempt; zassert_false(twp, "unexpected return value"); + k_thread_abort(tid); - k_thread_create(&user_thread, ustack, STACK_SIZE, preempt_test_thread, + tid = k_thread_create(&user_thread, ustack, STACK_SIZE, preempt_test_thread, NULL, NULL, NULL, K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS, K_NO_WAIT); @@ -78,4 +86,272 @@ void test_user_k_is_preempt(void) twp = thread_was_preempt; zassert_true(twp, "unexpected return value"); + k_thread_abort(tid); } + +/** + * userspace negative test: take NULL as input param to verify + * the api will trigger a fatal exception + */ +#ifdef CONFIG_USERSPACE +static void thread_suspend_init_null(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + k_thread_suspend(NULL); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_suspend() API + * + * @details Create a thread and set k_thread_suspend() input param to NULL + * will trigger a fatal error. + * + * @ingroup kernel_sched_tests + * + * @see k_thread_suspend() + */ +void test_k_thread_suspend_init_null(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_suspend_init_null, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_suspend_init_null(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_resume_init_null(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + k_thread_resume(NULL); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_resume() API + * + * @details Create a thread and set k_thread_resume() input param to NULL + * will trigger a fatal error. + * + * @ingroup kernel_sched_tests + * + * @see k_thread_resume() + */ +void test_k_thread_resume_init_null(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_resume_init_null, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_resume_init_null(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_priority_get_init_null(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + k_thread_priority_get(NULL); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_priority_get() API + * + * @details Create a thread and set thread_k_thread_priority_get() param input to + * NULL will trigger a fatal error. + * + * @ingroup kernel_sched_tests + * + * @see thread_k_thread_priority_get() + */ +void test_k_thread_priority_get_init_null(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_priority_get_init_null, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_priority_get_init_null(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_priority_set_init_null(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + k_thread_priority_set(NULL, 0); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_priority_set() API + * + * @details Create a thread and set k_thread_priority_set() param input to + * NULL will trigger a fatal error. + * + * @ingroup kernel_sched_tests + * + * @see k_thread_priority_set() + */ +void test_k_thread_priority_set_init_null(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_priority_set_init_null, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_priority_set_init_null(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_priority_set_overmax(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + + /* set valid priority value outside the priority range will invoke fatal error */ + k_thread_priority_set(k_current_get(), K_LOWEST_APPLICATION_THREAD_PRIO + 1); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_priority_set() API + * + * @details Check input param range overmax in userspace test. + * + * @ingroup kernel_sched_tests + * + * @see k_thread_priority_set() + */ +void test_k_thread_priority_set_overmax(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_priority_set_overmax, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_priority_set_overmax(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_priority_set_upgrade(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + + /* at first, set an valid priority */ + k_thread_priority_set(k_current_get(), THREAD_TEST_PRIORITY); + /* it cannot upgraded thread priority in usermode */ + k_thread_priority_set(k_current_get(), THREAD_TEST_PRIORITY - 1); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_thread_priority_set() API + * + * @details Check input param range fail in userspace test. + * + * @ingroup kernel_sched_tests + * + * @see k_thread_priority_set() + */ +void test_k_thread_priority_set_upgrade(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_priority_set_upgrade, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_thread_priority_set_upgrade(void) +{ + ztest_test_skip(); +} +#endif + +#ifdef CONFIG_USERSPACE +static void thread_wakeup_init_null(void *p1, void *p2, void *p3) +{ + ztest_set_fault_valid(true); + k_wakeup(NULL); + + /* should not go here */ + ztest_test_fail(); +} + +/** + * @brief Test k_wakeup() API + * + * @details Create a thread and set k_wakeup() input param to NULL + * will trigger a fatal error + * + * @ingroup kernel_sched_tests + * + * @see k_wakeup() + */ +void test_k_wakeup_init_null(void) +{ + k_tid_t tid = k_thread_create(&user_thread, ustack, STACK_SIZE, + (k_thread_entry_t)thread_wakeup_init_null, + NULL, NULL, NULL, + K_PRIO_PREEMPT(THREAD_TEST_PRIORITY), + K_USER | K_INHERIT_PERMS, K_NO_WAIT); + + k_thread_join(tid, K_FOREVER); +} +#else +void test_k_wakeup_init_null(void) +{ + ztest_test_skip(); +} +#endif diff --git a/tests/kernel/sched/schedule_api/testcase.yaml b/tests/kernel/sched/schedule_api/testcase.yaml index 649815da13f..92eb4b210b4 100644 --- a/tests/kernel/sched/schedule_api/testcase.yaml +++ b/tests/kernel/sched/schedule_api/testcase.yaml @@ -5,29 +5,29 @@ tests: filter: not CONFIG_SCHED_MULTIQ extra_configs: - CONFIG_TIMESLICING=y - tags: kernel threads sched userspace + tags: kernel threads sched userspace ignore_faults kernel.scheduler.no_timeslicing: filter: not CONFIG_SCHED_MULTIQ extra_configs: - CONFIG_TIMESLICING=n - tags: kernel threads sched userspace + tags: kernel threads sched userspace ignore_faults kernel.scheduler.multiq: extra_args: CONF_FILE=prj_multiq.conf extra_configs: - CONFIG_TIMESLICING=y - tags: kernel threads sched userspace + tags: kernel threads sched userspace ignore_faults kernel.scheduler.multiq_no_timeslicing: extra_args: CONF_FILE=prj_multiq.conf extra_configs: - CONFIG_TIMESLICING=n - tags: kernel threads sched userspace - kernel.scheduler.dumb_timeslicing: + tags: kernel threads sched userspacei ignore_faults + kernel.scheduler.dumb_no_timeslicing: extra_args: CONF_FILE=prj_dumb.conf extra_configs: - CONFIG_TIMESLICING=y - tags: kernel threads sched userspace + tags: kernel threads sched userspace ignore_faults kernel.scheduler.dumb_no_timeslicing: extra_args: CONF_FILE=prj_dumb.conf extra_configs: - CONFIG_TIMESLICING=n - tags: kernel threads sched userspace + tags: kernel threads sched userspace ignore_faults