1 /*
2 * Copyright (c) 2016 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/irq_offload.h>
9 #include <zephyr/ztest_error_hook.h>
10
11 #define TIMEOUT K_MSEC(100)
12 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
13 #define STACK_LEN 2
14
15 static ZTEST_BMEM stack_data_t data[STACK_LEN];
16 extern struct k_stack stack;
17 K_THREAD_STACK_DEFINE(threadstack2, STACK_SIZE);
18 struct k_thread thread_data2;
19
stack_pop_fail(struct k_stack * rx_data_stack)20 static void stack_pop_fail(struct k_stack *rx_data_stack)
21 {
22 stack_data_t rx_data;
23
24 /**TESTPOINT: stack pop returns -EBUSY*/
25 zassert_equal(k_stack_pop(rx_data_stack, &rx_data, K_NO_WAIT), -EBUSY);
26 /**TESTPOINT: stack pop returns -EAGAIN*/
27 zassert_equal(k_stack_pop(rx_data_stack, &rx_data, TIMEOUT), -EAGAIN);
28 }
29
30 /**
31 * @addtogroup kernel_stack_tests
32 * @{
33 */
34
35 /* Sub-thread entry */
tStack_pop_entry(void * p1,void * p2,void * p3)36 void tStack_pop_entry(void *p1, void *p2, void *p3)
37 {
38 zassert_true(k_stack_pop(p1, p2, K_FOREVER), "stack pop failed\n");
39 }
40
41 /**
42 * @brief Verifies stack pop functionality
43 * @see k_stack_init(), k_stack_pop()
44 */
ZTEST(stack_fail,test_stack_pop_fail)45 ZTEST(stack_fail, test_stack_pop_fail)
46 {
47 k_stack_init(&stack, data, STACK_LEN);
48
49 stack_pop_fail(&stack);
50 }
51
52 /**
53 * @brief Verifies cleanup a stack that still be needed by another
54 * thread.
55 * @see k_stack_cleanup()
56 */
ZTEST(stack_fail,test_stack_cleanup_error)57 ZTEST(stack_fail, test_stack_cleanup_error)
58 {
59 stack_data_t rx_data[STACK_LEN - 1];
60
61 k_stack_init(&stack, data, STACK_LEN);
62 /* Creat a new thread */
63 k_tid_t tid = k_thread_create(&thread_data2, threadstack2, STACK_SIZE,
64 tStack_pop_entry, &stack,
65 rx_data, NULL, K_PRIO_PREEMPT(0), 0,
66 K_NO_WAIT);
67 /* Delay for finishing some actions of the new thread */
68 k_sleep(K_MSEC(500));
69 /* Try to clean up the stack, that still be waited by the thread */
70 zassert_true(k_stack_cleanup(&stack) == -EAGAIN, "The stack is cleanuped successful");
71 /* clear the spawn thread to avoid side effect */
72 k_thread_abort(tid);
73 }
74
75 /**
76 * @brief Verifies push a data in the full stack.
77 * @see k_stack_push()
78 */
ZTEST(stack_fail,test_stack_push_full)79 ZTEST(stack_fail, test_stack_push_full)
80 {
81 stack_data_t tx_data[STACK_LEN] = {0};
82 stack_data_t data_tmp = 0;
83
84 k_stack_init(&stack, data, STACK_LEN);
85 for (int i = 0; i < STACK_LEN; i++) {
86 zassert_true(k_stack_push(&stack, tx_data[i]) == 0, "push data into stack failed");
87 }
88 /* Verify that push a data in the full stack, a negative value will be met */
89 zassert_true(k_stack_push(&stack, data_tmp) == -ENOMEM, "push data successful");
90 }
91
92 #ifdef CONFIG_USERSPACE
93 /**
94 * @brief Verifies stack pop from a user thread
95 * @see k_stack_init(), k_stack_pop()
96 */
ZTEST_USER(stack_fail,test_stack_user_pop_fail)97 ZTEST_USER(stack_fail, test_stack_user_pop_fail)
98 {
99 struct k_stack *alloc_stack = k_object_alloc(K_OBJ_STACK);
100
101 zassert_not_null(alloc_stack, "couldn't allocate stack object");
102 zassert_false(k_stack_alloc_init(alloc_stack, STACK_LEN),
103 "stack init failed");
104
105 stack_pop_fail(alloc_stack);
106 }
107
108 /**
109 * @brief Verifies stack alloc and initialize a null pointer.
110 * @see k_stack_alloc_init()
111 */
ZTEST_USER(stack_fail,test_stack_user_init_null)112 ZTEST_USER(stack_fail, test_stack_user_init_null)
113 {
114 ztest_set_fault_valid(true);
115 k_stack_alloc_init(NULL, STACK_LEN);
116 }
117
118 /**
119 * @brief Verify that alloc and initialize a stack with
120 * 0 memory.
121 * @see k_stack_alloc_init()
122 */
ZTEST_USER(stack_fail,test_stack_user_init_invalid_value)123 ZTEST_USER(stack_fail, test_stack_user_init_invalid_value)
124 {
125 ztest_set_fault_valid(true);
126 struct k_stack *alloc_stack = k_object_alloc(K_OBJ_STACK);
127
128 zassert_not_null(alloc_stack, "couldn't allocate stack object");
129 k_stack_alloc_init(alloc_stack, 0);
130 }
131
132 /**
133 * @brief Verify that push some data into a NULL
134 * pointer.
135 * @see k_stack_push()
136 */
ZTEST_USER(stack_fail,test_stack_user_push_null)137 ZTEST_USER(stack_fail, test_stack_user_push_null)
138 {
139 ztest_set_fault_valid(true);
140 k_stack_push(NULL, 0);
141 }
142
143 /**
144 * @brief Verifies pop data from a NULL pointer.
145 * @see k_stack_pop()
146 */
ZTEST_USER(stack_fail,test_stack_user_pop_null)147 ZTEST_USER(stack_fail, test_stack_user_pop_null)
148 {
149 ztest_set_fault_valid(true);
150 k_stack_pop(NULL, 0, K_NO_WAIT);
151 }
152
153 /**
154 * @brief Verifies cleanup a stack that its data still be waited by
155 * another thread.
156 * @see k_stack_pop()
157 */
ZTEST_USER(stack_fail,test_stack_user_pop_permission)158 ZTEST_USER(stack_fail, test_stack_user_pop_permission)
159 {
160 ztest_set_fault_valid(true);
161 struct k_stack *alloc_stack = k_object_alloc(K_OBJ_STACK);
162
163 zassert_not_null(alloc_stack, "couldn't allocate stack object");
164 zassert_false(k_stack_alloc_init(alloc_stack, STACK_LEN),
165 "stack init failed");
166 /* Try to access and to write data at invalid address */
167 k_stack_pop(alloc_stack, (stack_data_t *)alloc_stack, K_NO_WAIT);
168 }
169 #endif
170 /**
171 * @}
172 */
173