1 /* tc_utilities.h - testcase utilities header file */
2
3 /*
4 * Copyright (c) 2012-2015 Wind River Systems, Inc.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #ifndef ZEPHYR_TESTSUITE_INCLUDE_TC_UTIL_H_
10 #define ZEPHYR_TESTSUITE_INCLUDE_TC_UTIL_H_
11
12 #include <zephyr/kernel.h>
13
14 #include <string.h>
15 #ifdef CONFIG_SHELL
16 #include <zephyr/shell/shell.h>
17 #endif
18 #include <zephyr/sys/printk.h>
19
20 #if defined CONFIG_ZTEST_TC_UTIL_USER_OVERRIDE
21 #include <tc_util_user_override.h>
22 #endif
23
24 #ifndef PRINT_DATA
25 #define PRINT_DATA(fmt, ...) printk(fmt, ##__VA_ARGS__)
26 #endif
27
28 #if defined CONFIG_ARCH_POSIX
29 #include "posix_board_if.h"
30 #endif
31
32 /**
33 * @def TC_PRINT_RUNID
34 * @brief Report a Run ID
35 *
36 * When the CPP symbol \c TC_RUNID is defined (for example, from the
37 * compile environment), print the defined string ``RunID:
38 * <TC_RUNID>`` when called (TC_END_REPORT() will also call it).
39 *
40 * This is used mainly when automating the execution and running of
41 * multiple test cases, to verify that the expected image is being
42 * executed (as sometimes the targets fail to flash or reset
43 * properly).
44 *
45 * TC_RUNID is any string, that will be converted to a string literal.
46 */
47 #define TC_STR_HELPER(x) #x
48 #define TC_STR(x) TC_STR_HELPER(x)
49 #ifdef TC_RUNID
50 #define TC_PRINT_RUNID PRINT_DATA("RunID: " TC_STR(TC_RUNID) "\n")
51 #else
52 #define TC_PRINT_RUNID do {} while (false)
53 #endif
54
55 #ifndef PRINT_LINE
56 #define PRINT_LINE \
57 PRINT_DATA( \
58 "============================================================" \
59 "=======\n")
60 #endif
61
62 /* stack size and priority for test suite task */
63 #define TASK_STACK_SIZE (1024 * 2)
64
65 #define FMT_ERROR "%s - %s@%d. "
66
67 #define TC_PASS 0
68 #define TC_FAIL 1
69 #define TC_SKIP 2
70 #define TC_FLAKY 3
71
72 #ifndef TC_PASS_STR
73 #define TC_PASS_STR "PASS"
74 #endif
75 #ifndef TC_FAIL_STR
76 #define TC_FAIL_STR "FAIL"
77 #endif
78 #ifndef TC_SKIP_STR
79 #define TC_SKIP_STR "SKIP"
80 #endif
81 #ifndef TC_FLAKY_STR
82 #define TC_FLAKY_STR "FLAKY"
83 #endif
84
TC_RESULT_TO_STR(int result)85 static inline const char *TC_RESULT_TO_STR(int result)
86 {
87 switch (result) {
88 case TC_PASS:
89 return TC_PASS_STR;
90 case TC_FAIL:
91 return TC_FAIL_STR;
92 case TC_SKIP:
93 return TC_SKIP_STR;
94 case TC_FLAKY:
95 return TC_FLAKY_STR;
96 default:
97 return "?";
98 }
99 }
100
101 static uint32_t tc_start_time;
102 static uint32_t tc_spend_time;
103
get_start_time_cyc(void)104 static inline void get_start_time_cyc(void)
105 {
106 tc_start_time = k_cycle_get_32();
107 }
108
get_test_duration_ms(void)109 static inline void get_test_duration_ms(void)
110 {
111 uint32_t spend_cycle = k_cycle_get_32() - tc_start_time;
112
113 tc_spend_time = k_cyc_to_ms_ceil32(spend_cycle);
114 }
115
116 #ifndef TC_ERROR
117 #define TC_ERROR(fmt, ...) \
118 do { \
119 PRINT_DATA(FMT_ERROR, "FAIL", __func__, __LINE__); \
120 PRINT_DATA(fmt, ##__VA_ARGS__); \
121 } while (false)
122 #endif
123
print_nothing(const char * fmt,...)124 static inline void print_nothing(const char *fmt, ...)
125 {
126 ARG_UNUSED(fmt);
127 }
128
129 #ifndef TC_PRINT
130 #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT)
131 #define TC_PRINT(fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__)
132 #else
133 #define TC_PRINT(fmt, ...) print_nothing(fmt, ##__VA_ARGS__)
134 #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */
135 #endif /* TC_PRINT */
136
137 #ifndef TC_SUMMARY_PRINT
138 #define TC_SUMMARY_PRINT(fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__)
139 #endif
140
141 #ifndef TC_START_PRINT
142 #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT)
143 #define TC_START_PRINT(name) PRINT_DATA("START - %s\n", name);
144 #else
145 #define TC_START_PRINT(name) print_nothing(name)
146 #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */
147 #endif /* TC_START_PRINT */
148
149 #ifndef TC_START
150 #define TC_START(name) \
151 do { \
152 TC_START_PRINT(name); \
153 } while (0)
154 #endif
155
156 #ifndef TC_END
157 #define TC_END(result, fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__)
158 #endif
159
160 #ifndef TC_END_PRINT
161 #if defined(CONFIG_ZTEST_VERBOSE_OUTPUT)
162 #define TC_END_PRINT(result, fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__); PRINT_LINE
163 #else
164 #define TC_END_PRINT(result, fmt, ...) print_nothing(fmt)
165 #endif /* CONFIG_ZTEST_VERBOSE_OUTPUT */
166 #endif /* TC_END_PRINT */
167
168 /* prints result and the function name */
169 #ifndef Z_TC_END_RESULT
170 #define Z_TC_END_RESULT(result, func) \
171 do { \
172 TC_END_PRINT(result, " %s - %s in %u.%03u seconds\n", \
173 TC_RESULT_TO_STR(result), func, tc_spend_time/1000, \
174 tc_spend_time%1000); \
175 } while (0)
176 #endif
177
178 #ifndef TC_END_RESULT
179 #define TC_END_RESULT(result) \
180 Z_TC_END_RESULT((result), __func__)
181 #endif
182
183 #ifndef TC_END_RESULT_CUSTOM
184 #define TC_END_RESULT_CUSTOM(result, func) \
185 Z_TC_END_RESULT((result), func)
186 #endif
187
188 #ifndef TC_SUITE_PRINT
189 #define TC_SUITE_PRINT(fmt, ...) PRINT_DATA(fmt, ##__VA_ARGS__)
190 #endif
191
192 #ifndef TC_SUITE_START
193 #define TC_SUITE_START(name) \
194 do { \
195 TC_SUITE_PRINT("Running TESTSUITE %s\n", name); \
196 PRINT_LINE; \
197 } while (false)
198 #endif
199
200 #ifndef TC_SUITE_END
201 #define TC_SUITE_END(name, result) \
202 do { \
203 if (result != TC_FAIL) { \
204 TC_SUITE_PRINT("TESTSUITE %s succeeded\n", name); \
205 } else { \
206 TC_SUITE_PRINT("TESTSUITE %s failed.\n", name); \
207 } \
208 } while (false)
209 #endif
210
211 #if defined(CONFIG_ARCH_POSIX)
212 #include <zephyr/logging/log_ctrl.h>
213 #define TC_END_POST(result) do { \
214 LOG_PANIC(); \
215 posix_exit(result); \
216 } while (0)
217 #else
218 #define TC_END_POST(result)
219 #endif /* CONFIG_ARCH_POSIX */
220
221 #ifndef TC_END_REPORT
222 #define TC_END_REPORT(result) \
223 do { \
224 PRINT_LINE; \
225 TC_PRINT_RUNID; \
226 TC_END(result, \
227 "PROJECT EXECUTION %s\n", \
228 (result) == TC_PASS ? "SUCCESSFUL" : "FAILED"); \
229 TC_END_POST(result); \
230 } while (false)
231 #endif
232
233 #if defined(CONFIG_SHELL)
234 #define TC_CMD_DEFINE(name) \
235 static int cmd_##name(const struct shell *sh, size_t argc, \
236 char **argv) \
237 { \
238 TC_START(__func__); \
239 name(); \
240 TC_END_RESULT(TC_PASS); \
241 return 0; \
242 }
243 #define TC_CMD_ITEM(name) cmd_##name
244 #else
245 #define TC_CMD_DEFINE(name) \
246 int cmd_##name(int argc, char *argv[]) \
247 { \
248 TC_START(__func__); \
249 name(); \
250 TC_END_RESULT(TC_PASS); \
251 return 0; \
252 }
253 #define TC_CMD_ITEM(name) {STRINGIFY(name), cmd_##name, "none"}
254 #endif
255
256 #endif /* ZEPHYR_TESTSUITE_INCLUDE_TC_UTIL_H_ */
257