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