1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
11 #include <rte_hexdump.h>
12 #include <rte_common.h>
15 #define TEST_SUCCESS EXIT_SUCCESS
16 #define TEST_FAILED -1
17 #define TEST_SKIPPED 77
19 /* Before including test.h file you can define
20 * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test
21 * failures. Mostly useful in test development phase. */
22 #ifndef TEST_TRACE_FAILURE
23 # define TEST_TRACE_FAILURE(_file, _line, _func)
26 #define TEST_ASSERT(cond, msg, ...) do { \
28 printf("TestCase %s() line %d failed: " \
29 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
30 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
35 #define TEST_ASSERT_EQUAL(a, b, msg, ...) do { \
37 printf("TestCase %s() line %d failed: " \
38 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
39 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
44 /* Compare two buffers (length in bytes) */
45 #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \
46 if (memcmp(a, b, len)) { \
47 printf("TestCase %s() line %d failed: " \
48 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
49 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
54 /* Compare two buffers with offset (length and offset in bytes) */
55 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \
56 const uint8_t *_a_with_off = (const uint8_t *)a + off; \
57 const uint8_t *_b_with_off = (const uint8_t *)b + off; \
58 TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len, msg); \
61 /* Compare two buffers (length in bits) */
62 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do { \
63 uint8_t _last_byte_a, _last_byte_b; \
64 uint8_t _last_byte_mask, _last_byte_bits; \
65 TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg); \
67 _last_byte_bits = len % 8; \
68 _last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \
69 _last_byte_a = ((const uint8_t *)a)[len >> 3]; \
70 _last_byte_b = ((const uint8_t *)b)[len >> 3]; \
71 _last_byte_a &= _last_byte_mask; \
72 _last_byte_b &= _last_byte_mask; \
73 if (_last_byte_a != _last_byte_b) { \
74 printf("TestCase %s() line %d failed: " \
75 msg "\n", __func__, __LINE__, ##__VA_ARGS__);\
76 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
82 /* Compare two buffers with offset (length and offset in bits) */
83 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) do { \
84 uint8_t _first_byte_a, _first_byte_b; \
85 uint8_t _first_byte_mask, _first_byte_bits; \
86 uint32_t _len_without_first_byte = (off % 8) ? \
87 len - (8 - (off % 8)) : \
89 uint32_t _off_in_bytes = (off % 8) ? (off >> 3) + 1 : (off >> 3); \
90 const uint8_t *_a_with_off = (const uint8_t *)a + _off_in_bytes; \
91 const uint8_t *_b_with_off = (const uint8_t *)b + _off_in_bytes; \
92 TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off, \
93 _len_without_first_byte, msg); \
95 _first_byte_bits = 8 - (off % 8); \
96 _first_byte_mask = (1 << _first_byte_bits) - 1; \
97 _first_byte_a = *(_a_with_off - 1); \
98 _first_byte_b = *(_b_with_off - 1); \
99 _first_byte_a &= _first_byte_mask; \
100 _first_byte_b &= _first_byte_mask; \
101 if (_first_byte_a != _first_byte_b) { \
102 printf("TestCase %s() line %d failed: " \
103 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
104 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
105 return TEST_FAILED; \
110 #define TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do { \
112 printf("TestCase %s() line %d failed: " \
113 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
114 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
115 return TEST_FAILED; \
119 #define TEST_ASSERT_SUCCESS(val, msg, ...) do { \
120 typeof(val) _val = (val); \
121 if (!(_val == 0)) { \
122 printf("TestCase %s() line %d failed (err %d): " \
123 msg "\n", __func__, __LINE__, _val, \
125 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
126 return TEST_FAILED; \
130 #define TEST_ASSERT_FAIL(val, msg, ...) do { \
132 printf("TestCase %s() line %d failed: " \
133 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
134 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
135 return TEST_FAILED; \
139 #define TEST_ASSERT_NULL(val, msg, ...) do { \
140 if (!(val == NULL)) { \
141 printf("TestCase %s() line %d failed: " \
142 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
143 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
144 return TEST_FAILED; \
148 #define TEST_ASSERT_NOT_NULL(val, msg, ...) do { \
149 if (!(val != NULL)) { \
150 printf("TestCase %s() line %d failed: " \
151 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
152 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \
153 return TEST_FAILED; \
157 struct unit_test_case {
159 void (*teardown)(void);
160 int (*testcase)(void);
165 #define TEST_CASE(fn) { NULL, NULL, fn, #fn, 1 }
167 #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name, 1 }
169 #define TEST_CASE_ST(setup, teardown, testcase) \
170 { setup, teardown, testcase, #testcase, 1 }
173 #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn, 0 }
175 #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \
176 { setup, teardown, testcase, #testcase, 0 }
178 #define TEST_CASES_END() { NULL, NULL, NULL, NULL, 0 }
181 debug_hexdump(FILE *file, const char *title, const void *buf, size_t len)
183 if (rte_log_get_global_level() == RTE_LOG_DEBUG)
184 rte_hexdump(file, title, buf, len);
187 struct unit_test_suite {
188 const char *suite_name;
190 void (*teardown)(void);
191 struct unit_test_case unit_test_cases[];
194 int unit_test_suite_runner(struct unit_test_suite *suite);
195 extern int last_test_result;
197 #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
199 #include <cmdline_parse.h>
200 #include <cmdline_parse_string.h>
202 extern const char *prgname;
204 int commands_init(void);
206 int test_mp_secondary(void);
208 int test_set_rxtx_conf(cmdline_fixed_string_t mode);
209 int test_set_rxtx_anchor(cmdline_fixed_string_t type);
210 int test_set_rxtx_sc(cmdline_fixed_string_t type);
212 typedef int (test_callback)(void);
213 TAILQ_HEAD(test_commands_list, test_command);
214 struct test_command {
215 TAILQ_ENTRY(test_command) next;
217 test_callback *callback;
220 void add_test_command(struct test_command *t);
222 /* Register a test function with its command string */
223 #define REGISTER_TEST_COMMAND(cmd, func) \
224 static struct test_command test_struct_##cmd = { \
225 .command = RTE_STR(cmd), \
228 static void __attribute__((constructor, used)) \
229 test_register_##cmd(void) \
231 add_test_command(&test_struct_##cmd); \