From e23b0ab49f97affaff005155677a71bb121e0204 Mon Sep 17 00:00:00 2001 From: jing wang Date: Tue, 20 Dec 2016 16:41:43 +0800 Subject: [PATCH] tests: add zephyr thread lifecycle test case with unified kernel this commit cover zephyr thread lifecycle relavant apis testing k_thread_spawn k_current_get k_thread_abort k_thread_cancel k_thread_suspend k_thread_resume Change-Id: I99bff0dd803f6e68e165f3388a3be09425c0596c Signed-off-by: jing wang Signed-off-by: Anas Nashif --- .../threads_lifecycle/lifecycle_api/Makefile | 4 + .../threads_lifecycle/lifecycle_api/prj.conf | 1 + .../lifecycle_api/src/Makefile | 3 + .../lifecycle_api/src/main.c | 53 +++++++ .../src/test_threads_cancel_abort.c | 136 ++++++++++++++++++ .../lifecycle_api/src/test_threads_spawn.c | 91 ++++++++++++ .../src/test_threads_suspend_resume.c | 73 ++++++++++ .../lifecycle_api/testcase.ini | 4 + 8 files changed, 365 insertions(+) create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/Makefile create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/prj.conf create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/src/Makefile create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/src/main.c create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_cancel_abort.c create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_spawn.c create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_suspend_resume.c create mode 100644 tests/kernel/threads_lifecycle/lifecycle_api/testcase.ini diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/Makefile b/tests/kernel/threads_lifecycle/lifecycle_api/Makefile new file mode 100644 index 00000000000..4de50f93d4d --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/Makefile @@ -0,0 +1,4 @@ +BOARD ?= qemu_x86 +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.inc diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/prj.conf b/tests/kernel/threads_lifecycle/lifecycle_api/prj.conf new file mode 100644 index 00000000000..9467c292689 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/src/Makefile b/tests/kernel/threads_lifecycle/lifecycle_api/src/Makefile new file mode 100644 index 00000000000..5f78a7a2145 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/src/Makefile @@ -0,0 +1,3 @@ +include $(ZEPHYR_BASE)/tests/Makefile.test + +obj-y = main.o test_threads_spawn.o test_threads_suspend_resume.o test_threads_cancel_abort.o diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/src/main.c b/tests/kernel/threads_lifecycle/lifecycle_api/src/main.c new file mode 100644 index 00000000000..29beff21ed3 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/src/main.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup t_threads_lifecycle + * @{ + * @defgroup t_threads_lifecycle_api test_threads_lifecycle_api + * @brief TestPurpose: verify zephyr basic threads lifecycle apis + * @} + */ + +#include +extern void test_threads_spawn_params(void); +extern void test_threads_spawn_priority(void); +extern void test_threads_spawn_delay(void); +extern void test_threads_suspend_resume_cooperative(void); +extern void test_threads_suspend_resume_preemptible(void); +extern void test_threads_cancel_undelayed(void); +extern void test_threads_cancel_delayed(void); +extern void test_threads_cancel_started(void); +extern void test_threads_abort_self(void); +extern void test_threads_abort_others(void); + +/*test case main entry*/ +void test_main(void *p1, void *p2, void *p3) +{ + ztest_test_suite(test_threads_lifecycle, + ztest_unit_test(test_threads_spawn_params), + ztest_unit_test(test_threads_spawn_priority), + ztest_unit_test(test_threads_spawn_delay), + ztest_unit_test(test_threads_suspend_resume_cooperative), + ztest_unit_test(test_threads_suspend_resume_preemptible), + ztest_unit_test(test_threads_cancel_undelayed), + ztest_unit_test(test_threads_cancel_delayed), + ztest_unit_test(test_threads_cancel_started), + ztest_unit_test(test_threads_abort_self), + ztest_unit_test(test_threads_abort_others) + ); + ztest_run_test_suite(test_threads_lifecycle); +} diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_cancel_abort.c b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_cancel_abort.c new file mode 100644 index 00000000000..2dd86bc2975 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_cancel_abort.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup t_threads_lifecycle + * @{ + * @defgroup t_threads_cancel_abort test_threads_cancel_abort + * @} + */ +#include + +#define STACK_SIZE 256 +static char __noinit __stack tstack[STACK_SIZE]; +static int execute_flag; + +static void thread_entry(void *p1, void *p2, void *p3) +{ + execute_flag = 1; + k_sleep(100); + execute_flag = 2; +} + +static void thread_entry_abort(void *p1, void *p2, void *p3) +{ + /**TESTPOINT: abort current thread*/ + execute_flag = 1; + k_thread_abort(k_current_get()); + /*unreachable*/ + execute_flag = 2; + assert_true(1 == 0, NULL); +} + +/*test cases*/ +void test_threads_cancel_undelayed(void) +{ + int cur_prio = k_thread_priority_get(k_current_get()); + + /* spawn thread with lower priority */ + int spawn_prio = cur_prio + 1; + + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + spawn_prio, 0, 0); + + /**TESTPOINT: check cancel retcode when thread is not delayed*/ + int cancel_ret = k_thread_cancel(tid); + + assert_equal(cancel_ret, -EINVAL, NULL); + k_thread_abort(tid); +} + +void test_threads_cancel_started(void) +{ + int cur_prio = k_thread_priority_get(k_current_get()); + + /* spawn thread with lower priority */ + int spawn_prio = cur_prio + 1; + + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + spawn_prio, 0, 0); + + k_sleep(50); + /**TESTPOINT: check cancel retcode when thread is started*/ + int cancel_ret = k_thread_cancel(tid); + + assert_equal(cancel_ret, -EINVAL, NULL); + k_thread_abort(tid); +} + +void test_threads_cancel_delayed(void) +{ + int cur_prio = k_thread_priority_get(k_current_get()); + + /* spawn thread with lower priority */ + int spawn_prio = cur_prio + 1; + + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + spawn_prio, 0, 100); + + k_sleep(50); + /**TESTPOINT: check cancel retcode when thread is started*/ + int cancel_ret = k_thread_cancel(tid); + + assert_equal(cancel_ret, 0, NULL); + k_thread_abort(tid); +} + +void test_threads_abort_self(void) +{ + execute_flag = 0; + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry_abort, NULL, NULL, NULL, + 0, 0, 0); + k_sleep(100); + /**TESTPOINT: spawned thread executed but abort itself*/ + assert_true(execute_flag == 1, NULL); + k_thread_abort(tid); +} + +void test_threads_abort_others(void) +{ + execute_flag = 0; + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + 0, 0, 0); + + k_thread_abort(tid); + k_sleep(100); + /**TESTPOINT: check not-started thread is aborted*/ + assert_true(execute_flag == 0, NULL); + + tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + 0, 0, 0); + k_sleep(50); + k_thread_abort(tid); + /**TESTPOINT: check running thread is aborted*/ + assert_true(execute_flag == 1, NULL); + k_sleep(1000); + assert_true(execute_flag == 1, NULL); +} diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_spawn.c b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_spawn.c new file mode 100644 index 00000000000..b87ee485c7c --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_spawn.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup t_threads_lifecycle + * @{ + * @defgroup t_threads_spawn test_thread_spawn + * @brief TestPurpose: verify basic thread spawn relevant apis + * @} + */ + +#include + +#define STACK_SIZE 256 +static char __noinit __stack tstack[STACK_SIZE]; + +static char tp1[8]; +static int tp2 = 100; +static struct k_sema *tp3; +static int spawn_prio; + +static void thread_entry_params(void *p1, void *p2, void *p3) +{ + /* checkpoint: check parameter 1, 2, 3 */ + assert_equal((char *)p1, tp1, NULL); + assert_equal((int)p2, tp2, NULL); + assert_equal((struct k_sema *)p3, tp3, NULL); +} + +static void thread_entry_priority(void *p1, void *p2, void *p3) +{ + /* checkpoint: check priority */ + assert_equal(k_thread_priority_get(k_current_get()), spawn_prio, NULL); +} + +static void thread_entry_delay(void *p1, void *p2, void *p3) +{ + tp2 = 100; +} + +/*test cases*/ +void test_threads_spawn_params(void) +{ + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry_params, (void *)tp1, (void *)tp2, (void *)tp3, + 0, 0, 0); + + k_sleep(100); + k_thread_abort(tid); +} + +void test_threads_spawn_priority(void) +{ + /* spawn thread with higher priority */ + spawn_prio = k_thread_priority_get(k_current_get()) - 1; + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry_priority, NULL, NULL, NULL, + spawn_prio, 0, 0); + k_sleep(100); + k_thread_abort(tid); +} + +void test_threads_spawn_delay(void) +{ + /* spawn thread with higher priority */ + tp2 = 10; + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry_delay, NULL, NULL, NULL, + 0, 0, 120); + /* 100 < 120 ensure spawn thread not start */ + k_sleep(100); + /* checkpoint: check spawn thread not execute */ + assert_true(tp2 == 10, NULL); + /* checkpoint: check spawn thread executed */ + k_sleep(100); + assert_true(tp2 == 100, NULL); + k_thread_abort(tid); +} diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_suspend_resume.c b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_suspend_resume.c new file mode 100644 index 00000000000..3a91d51e2e3 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/src/test_threads_suspend_resume.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup t_threads_lifecycle + * @{ + * @defgroup t_threads_suspend_resume test_threads_suspend_resume + * @} + */ +#include + +#define STACK_SIZE 256 +static char __noinit __stack tstack[STACK_SIZE]; +static int last_prio; + +static void thread_entry(void *p1, void *p2, void *p3) +{ + last_prio = k_thread_priority_get(k_current_get()); +} + +static void threads_suspend_resume(int prio) +{ + int old_prio = k_thread_priority_get(k_current_get()); + + /* set current thread */ + last_prio = prio; + k_thread_priority_set(k_current_get(), last_prio); + + /* spawn thread with lower priority */ + int spawn_prio = last_prio + 1; + + k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, + thread_entry, NULL, NULL, NULL, + spawn_prio, 0, 0); + /* checkpoint: suspend current thread */ + k_thread_suspend(tid); + k_sleep(100); + /* checkpoint: spawned thread shouldn't be executed after suspend */ + assert_false(last_prio == spawn_prio, NULL); + k_thread_resume(tid); + k_sleep(100); + /* checkpoint: spawned thread should be executed after resume */ + assert_true(last_prio == spawn_prio, NULL); + + k_thread_abort(tid); + + /* restore environment */ + k_thread_priority_set(k_current_get(), old_prio); +} + +/*test cases*/ +void test_threads_suspend_resume_cooperative(void) +{ + threads_suspend_resume(-2); +} + +void test_threads_suspend_resume_preemptible(void) +{ + threads_suspend_resume(1); +} diff --git a/tests/kernel/threads_lifecycle/lifecycle_api/testcase.ini b/tests/kernel/threads_lifecycle/lifecycle_api/testcase.ini new file mode 100644 index 00000000000..effdb40b936 --- /dev/null +++ b/tests/kernel/threads_lifecycle/lifecycle_api/testcase.ini @@ -0,0 +1,4 @@ +[test] +tags = kernel +# tickless is not supported on nios2 +arch_exclude = nios2