Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _TEST_H_
6 : : #define _TEST_H_
7 : :
8 : : #include <errno.h>
9 : : #include <stdbool.h>
10 : : #include <stddef.h>
11 : : #include <stdint.h>
12 : : #include <stdio.h>
13 : : #include <stdlib.h>
14 : : #include <string.h>
15 : : #include <sys/queue.h>
16 : :
17 : : #include <rte_bitops.h>
18 : : #include <rte_common.h>
19 : : #include <rte_debug.h>
20 : : #include <rte_hexdump.h>
21 : : #include <rte_lcore.h>
22 : : #include <rte_os_shim.h>
23 : :
24 : : #define TEST_SUCCESS EXIT_SUCCESS
25 : : #define TEST_FAILED -1
26 : : #define TEST_SKIPPED 77
27 : :
28 : : /* Before including test.h file you can define
29 : : * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test
30 : : * failures. Mostly useful in test development phase. */
31 : : #ifndef TEST_TRACE_FAILURE
32 : : # define TEST_TRACE_FAILURE(_file, _line, _func)
33 : : #endif
34 : :
35 : : #include <rte_test.h>
36 : :
37 : : #define TEST_ASSERT RTE_TEST_ASSERT
38 : :
39 : : #define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL
40 : :
41 : : /*
42 : : * Helpers backing the TEST_ASSERT_BUFFERS_ARE_EQUAL* macros.
43 : : *
44 : : * Keeping the comparison logic in inline functions ensures each macro
45 : : * argument is evaluated exactly once and gives the compiler real types
46 : : * to check against, which the original all-macro implementation could
47 : : * not provide.
48 : : */
49 : : static inline bool
50 : : test_buffers_equal_offset(const void *a, const void *b,
51 : : size_t len, size_t off)
52 : : {
53 : : const uint8_t *pa = (const uint8_t *)a + off;
54 : : const uint8_t *pb = (const uint8_t *)b + off;
55 : :
56 : : return memcmp(pa, pb, len) == 0;
57 : : }
58 : :
59 : : static inline bool
60 : 2 : test_buffers_equal_bit(const void *a, const void *b, size_t len)
61 : : {
62 : : const uint8_t *pa = a;
63 : : const uint8_t *pb = b;
64 : 2 : size_t len_bytes = len >> 3;
65 : 2 : size_t len_bits = len & 7;
66 : :
67 [ + - ]: 2 : if (memcmp(pa, pb, len_bytes) != 0)
68 : : return false;
69 [ + + ]: 2 : if (len_bits != 0) {
70 : 1 : uint8_t mask = (uint8_t)RTE_GENMASK32(7, 8 - len_bits);
71 : :
72 [ - + ]: 1 : if ((pa[len_bytes] & mask) != (pb[len_bytes] & mask))
73 : 0 : return false;
74 : : }
75 : : return true;
76 : : }
77 : :
78 : : static inline bool
79 : 0 : test_buffers_equal_bit_offset(const void *a, const void *b,
80 : : size_t len, size_t off)
81 : : {
82 : : const uint8_t *pa = a;
83 : : const uint8_t *pb = b;
84 : 0 : size_t off_bits = off & 7;
85 : 0 : size_t off_bytes = off >> 3;
86 : :
87 [ # # ]: 0 : if (off_bits != 0) {
88 : 0 : uint8_t first_bits = 8 - off_bits;
89 : 0 : uint8_t mask = (uint8_t)RTE_GENMASK32(first_bits - 1, 0);
90 : :
91 [ # # ]: 0 : if ((pa[off_bytes] & mask) != (pb[off_bytes] & mask))
92 : : return false;
93 : : RTE_ASSERT(len >= first_bits);
94 : 0 : off_bytes++;
95 : 0 : len -= first_bits;
96 : : }
97 : 0 : return test_buffers_equal_bit(pa + off_bytes, pb + off_bytes, len);
98 : : }
99 : :
100 : : /* Compare two buffers (length in bytes) */
101 : : #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \
102 : : if (memcmp((a), (b), (len)) != 0) { \
103 : : printf("TestCase %s() line %d failed: " msg "\n", \
104 : : __func__, __LINE__, ##__VA_ARGS__); \
105 : : TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
106 : : return TEST_FAILED; \
107 : : } \
108 : : } while (0)
109 : :
110 : : /* Compare two buffers with offset (length and offset in bytes) */
111 : : #define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \
112 : : if (!test_buffers_equal_offset((a), (b), (len), (off))) { \
113 : : printf("TestCase %s() line %d failed: " msg "\n", \
114 : : __func__, __LINE__, ##__VA_ARGS__); \
115 : : TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
116 : : return TEST_FAILED; \
117 : : } \
118 : : } while (0)
119 : :
120 : : /* Compare two buffers (length in bits) */
121 : : #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do { \
122 : : if (!test_buffers_equal_bit((a), (b), (len))) { \
123 : : printf("TestCase %s() line %d failed: " msg "\n", \
124 : : __func__, __LINE__, ##__VA_ARGS__); \
125 : : TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
126 : : return TEST_FAILED; \
127 : : } \
128 : : } while (0)
129 : :
130 : : /* Compare two buffers with offset (length and offset in bits) */
131 : : #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) \
132 : : do { \
133 : : if (!test_buffers_equal_bit_offset((a), (b), (len), (off))) { \
134 : : printf("TestCase %s() line %d failed: " msg "\n", \
135 : : __func__, __LINE__, ##__VA_ARGS__); \
136 : : TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
137 : : return TEST_FAILED; \
138 : : } \
139 : : } while (0)
140 : :
141 : : #define TEST_ASSERT_NOT_EQUAL RTE_TEST_ASSERT_NOT_EQUAL
142 : :
143 : : #define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS
144 : :
145 : : #define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL
146 : :
147 : : #define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL
148 : :
149 : : #define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL
150 : :
151 : : struct unit_test_case {
152 : : int (*setup)(void);
153 : : void (*teardown)(void);
154 : : int (*testcase)(void);
155 : : int (*testcase_with_data)(const void *data);
156 : : const char *name;
157 : : unsigned enabled;
158 : : const void *data;
159 : : };
160 : :
161 : : #define TEST_CASE(fn) { NULL, NULL, fn, NULL, #fn, 1, NULL }
162 : :
163 : : #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, NULL, name, 1, NULL }
164 : :
165 : : #define TEST_CASE_ST(setup, teardown, testcase) \
166 : : { setup, teardown, testcase, NULL, #testcase, 1, NULL }
167 : :
168 : : #define TEST_CASE_WITH_DATA(setup, teardown, testcase, data) \
169 : : { setup, teardown, NULL, testcase, #testcase, 1, data }
170 : :
171 : : #define TEST_CASE_NAMED_ST(name, setup, teardown, testcase) \
172 : : { setup, teardown, testcase, NULL, name, 1, NULL }
173 : :
174 : : #define TEST_CASE_NAMED_WITH_DATA(name, setup, teardown, testcase, data) \
175 : : { setup, teardown, NULL, testcase, name, 1, data }
176 : :
177 : : #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, NULL, #fn, 0, NULL }
178 : :
179 : : #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \
180 : : { setup, teardown, testcase, NULL, #testcase, 0, NULL }
181 : :
182 : : #define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0, NULL }
183 : :
184 : : static inline void
185 : : debug_hexdump(FILE *file, const char *title, const void *buf, size_t len)
186 : : {
187 [ + - + - : 1044 : if (rte_log_get_global_level() == RTE_LOG_DEBUG)
+ - + - -
- + - + -
+ - + - +
- + - + -
+ - + - -
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - + - +
- + - + -
+ - + - +
- + - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- + - - -
+ - + - -
- - - ]
188 : 1044 : rte_hexdump(file, title, buf, len);
189 : : }
190 : :
191 : : struct unit_test_suite {
192 : : const char *suite_name;
193 : : int (*setup)(void);
194 : : void (*teardown)(void);
195 : : unsigned int total;
196 : : unsigned int executed;
197 : : unsigned int succeeded;
198 : : unsigned int skipped;
199 : : unsigned int failed;
200 : : unsigned int unsupported;
201 : : struct unit_test_suite **unit_test_suites;
202 : : struct unit_test_case unit_test_cases[];
203 : : };
204 : :
205 : : int unit_test_suite_runner(struct unit_test_suite *suite);
206 : : extern int last_test_result;
207 : :
208 : : #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
209 : :
210 : : #include <cmdline_parse.h>
211 : : #include <cmdline_parse_string.h>
212 : :
213 : : extern const char *prgname;
214 : :
215 : : int commands_init(void);
216 : : int command_valid(const char *cmd);
217 : :
218 : : int test_exit(void);
219 : : int test_mp_secondary(void);
220 : : int test_panic(void);
221 : : int test_timer_secondary(void);
222 : :
223 : : int test_set_rxtx_conf(cmdline_fixed_string_t mode);
224 : : int test_set_rxtx_anchor(cmdline_fixed_string_t type);
225 : : int test_set_rxtx_sc(cmdline_fixed_string_t type);
226 : :
227 : : typedef int (test_callback)(void);
228 : : TAILQ_HEAD(test_commands_list, test_command);
229 : : struct test_command {
230 : : TAILQ_ENTRY(test_command) next;
231 : : const char *command;
232 : : test_callback *callback;
233 : : };
234 : :
235 : : void add_test_command(struct test_command *t);
236 : :
237 : : /* Register a test function with its command string. Should not be used directly */
238 : : #define REGISTER_TEST_COMMAND(cmd, func) \
239 : : static struct test_command test_struct_##cmd = { \
240 : : .command = RTE_STR(cmd), \
241 : : .callback = func, \
242 : : }; \
243 : : RTE_INIT(test_register_##cmd) \
244 : : { \
245 : : add_test_command(&test_struct_##cmd); \
246 : : }
247 : :
248 : : /* Register a test function as a particular type.
249 : : * These can be used to build up test suites automatically
250 : : */
251 : : #define REGISTER_PERF_TEST REGISTER_TEST_COMMAND
252 : : #define REGISTER_DRIVER_TEST REGISTER_TEST_COMMAND
253 : : #define REGISTER_STRESS_TEST REGISTER_TEST_COMMAND
254 : :
255 : : /* fast tests are a bit special. They can be specified as supporting running without
256 : : * hugepages and/or under ASan.
257 : : * - The "no_huge" options should be passed as either "NOHUGE_OK" or "NOHUGE_SKIP"
258 : : * - The "ASan" options should be passed as either "ASAN_OK" or "ASAN_SKIP"
259 : : */
260 : : #define REGISTER_FAST_TEST(cmd, no_huge, ASan, func) REGISTER_TEST_COMMAND(cmd, func)
261 : :
262 : : /* For unstable or experimental tests cases which need work or which may be removed
263 : : * in the future.
264 : : */
265 : : #define REGISTER_ATTIC_TEST REGISTER_TEST_COMMAND
266 : :
267 : : /**
268 : : * Scale test iterations inversely with core count.
269 : : *
270 : : * On high core count systems, tests with per-core work can exceed
271 : : * timeout limits due to increased lock contention and scheduling
272 : : * overhead. This helper scales iterations to keep total test time
273 : : * roughly constant regardless of core count.
274 : : *
275 : : * @param base Base iteration count (used on single-core systems)
276 : : * @param min Minimum iterations (floor to ensure meaningful testing)
277 : : * @return Scaled iteration count
278 : : */
279 : : static inline unsigned int
280 : : test_scale_iterations(unsigned int base, unsigned int min)
281 : : {
282 : 4 : return RTE_MAX(base / rte_lcore_count(), min);
283 : : }
284 : :
285 : : #endif
|