1 /*
2 * Copyright (c) 2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/ztest.h>
7 #include <zephyr/ztest_error_hook.h>
8
9 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
10 #define THREAD_TEST_PRIORITY 5
11
12 /* use to pass case type to threads */
13 static ZTEST_DMEM int case_type;
14
15 static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
16 static K_THREAD_STACK_DEFINE(test_stack, STACK_SIZE);
17 static struct k_thread tdata;
18 static struct k_thread test_tdata;
19
20 /* enumerate our negative case scenario */
21 enum {
22 THREAD_START,
23 FLOAT_DISABLE,
24 TIMEOUT_REMAINING_TICKS,
25 TIMEOUT_EXPIRES_TICKS,
26 THREAD_CREATE_NEWTHREAD_NULL,
27 THREAD_CREATE_STACK_NULL,
28 THREAD_CTEATE_STACK_SIZE_OVERFLOW
29 } neg_case;
30
test_thread(void * p1,void * p2,void * p3)31 static void test_thread(void *p1, void *p2, void *p3)
32 {
33 /* do nothing here */
34 }
35
tThread_entry_negative(void * p1,void * p2,void * p3)36 static void tThread_entry_negative(void *p1, void *p2, void *p3)
37 {
38 ARG_UNUSED(p2);
39 ARG_UNUSED(p3);
40
41 int choice = *((int *)p1);
42 uint32_t perm = K_INHERIT_PERMS;
43
44 TC_PRINT("current case is %d\n", choice);
45
46 /* Set up the fault or assert are expected before we call
47 * the target tested function.
48 */
49 switch (choice) {
50 case THREAD_START:
51 ztest_set_fault_valid(true);
52 k_thread_start(NULL);
53 break;
54 case FLOAT_DISABLE:
55 ztest_set_fault_valid(true);
56 k_float_disable(NULL);
57 break;
58 case TIMEOUT_REMAINING_TICKS:
59 ztest_set_fault_valid(true);
60 k_thread_timeout_remaining_ticks(NULL);
61 break;
62 case TIMEOUT_EXPIRES_TICKS:
63 ztest_set_fault_valid(true);
64 k_thread_timeout_expires_ticks(NULL);
65 break;
66 case THREAD_CREATE_NEWTHREAD_NULL:
67 ztest_set_fault_valid(true);
68 if (k_is_user_context()) {
69 perm = perm | K_USER;
70 }
71
72 k_thread_create((struct k_thread *)NULL, test_stack, STACK_SIZE,
73 test_thread, NULL, NULL, NULL,
74 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
75 perm, K_NO_WAIT);
76 break;
77 case THREAD_CREATE_STACK_NULL:
78 ztest_set_fault_valid(true);
79 if (k_is_user_context()) {
80 perm = perm | K_USER;
81 }
82
83 k_thread_create(&test_tdata, NULL, STACK_SIZE,
84 test_thread, NULL, NULL, NULL,
85 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
86 perm, K_NO_WAIT);
87 break;
88 case THREAD_CTEATE_STACK_SIZE_OVERFLOW:
89 ztest_set_fault_valid(true);
90 if (k_is_user_context()) {
91 perm = perm | K_USER;
92 }
93 k_thread_create(&test_tdata, test_stack, -1,
94 test_thread, NULL, NULL, NULL,
95 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
96 perm, K_NO_WAIT);
97 break;
98 default:
99 TC_PRINT("should not be here!\n");
100 break;
101 }
102
103 /* If negative comes here, it means error condition not been
104 * detected.
105 */
106 ztest_test_fail();
107 }
108
create_negative_test_thread(int choice)109 static void create_negative_test_thread(int choice)
110 {
111 uint32_t perm = K_INHERIT_PERMS;
112
113 if (k_is_user_context()) {
114 perm = perm | K_USER;
115 }
116
117 case_type = choice;
118
119 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
120 tThread_entry_negative,
121 (void *)&case_type, NULL, NULL,
122 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
123 perm, K_NO_WAIT);
124
125 (void)k_thread_join(tid, K_FOREVER);
126 }
127
128 /* TESTPOINT: Pass a null pointer into the API k_thread_start() */
ZTEST_USER(thread_error_case,test_thread_start)129 ZTEST_USER(thread_error_case, test_thread_start)
130 {
131 create_negative_test_thread(THREAD_START);
132 }
133
134 /* TESTPOINT: Pass a null pointer into the API k_float_disable() */
ZTEST_USER(thread_error_case,test_float_disable)135 ZTEST_USER(thread_error_case, test_float_disable)
136 {
137 create_negative_test_thread(FLOAT_DISABLE);
138 }
139
140 /* TESTPOINT: Pass a null pointer into the API */
ZTEST_USER(thread_error_case,test_timeout_remaining_ticks)141 ZTEST_USER(thread_error_case, test_timeout_remaining_ticks)
142 {
143 create_negative_test_thread(TIMEOUT_REMAINING_TICKS);
144 }
145
146 /* TESTPOINT: Pass a null pointer into the API */
ZTEST_USER(thread_error_case,test_timeout_expires_ticks)147 ZTEST_USER(thread_error_case, test_timeout_expires_ticks)
148 {
149 create_negative_test_thread(TIMEOUT_EXPIRES_TICKS);
150 }
151
152 /* TESTPOINT: Pass new thread with NULL into API */
ZTEST_USER(thread_error_case,test_thread_create_uninit)153 ZTEST_USER(thread_error_case, test_thread_create_uninit)
154 {
155 create_negative_test_thread(THREAD_CREATE_NEWTHREAD_NULL);
156 }
157
158 /* TESTPOINT: Pass a NULL stack into API */
ZTEST_USER(thread_error_case,test_thread_create_stack_null)159 ZTEST_USER(thread_error_case, test_thread_create_stack_null)
160 {
161 create_negative_test_thread(THREAD_CREATE_STACK_NULL);
162 }
163
164 /* TESTPOINT: Pass a overflow stack into API */
ZTEST_USER(thread_error_case,test_thread_create_stack_overflow)165 ZTEST_USER(thread_error_case, test_thread_create_stack_overflow)
166 {
167 create_negative_test_thread(THREAD_CTEATE_STACK_SIZE_OVERFLOW);
168 }
169
170 /*test case main entry*/
thread_grant_setup(void)171 void *thread_grant_setup(void)
172 {
173 k_thread_access_grant(k_current_get(), &tdata, &tstack, &test_tdata, &test_stack);
174
175 return NULL;
176 }
177
178 ZTEST_SUITE(thread_error_case, NULL, thread_grant_setup, NULL, NULL, NULL);
179