xref: /dpdk/app/test/test.h (revision 06e2856620a70000b2a28f0ea715fc247b85fd8d)
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_os_shim.h>
16 
17 #define TEST_SUCCESS EXIT_SUCCESS
18 #define TEST_FAILED  -1
19 #define TEST_SKIPPED  77
20 
21 /* Before including test.h file you can define
22  * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test
23  * failures. Mostly useful in test development phase. */
24 #ifndef TEST_TRACE_FAILURE
25 # define TEST_TRACE_FAILURE(_file, _line, _func)
26 #endif
27 
28 #include <rte_test.h>
29 
30 #define TEST_ASSERT RTE_TEST_ASSERT
31 
32 #define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL
33 
34 /* Compare two buffers (length in bytes) */
35 #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len,  msg, ...) do {	\
36 	if (memcmp(a, b, len)) {                                        \
37 		printf("TestCase %s() line %d failed: "              \
38 			msg "\n", __func__, __LINE__, ##__VA_ARGS__);    \
39 		TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);    \
40 		return TEST_FAILED;                                  \
41 	}                                                        \
42 } while (0)
43 
44 /* Compare two buffers with offset (length and offset in bytes) */
45 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \
46 	const uint8_t *_a_with_off = (const uint8_t *)a + off;              \
47 	const uint8_t *_b_with_off = (const uint8_t *)b + off;              \
48 	TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len, msg);  \
49 } while (0)
50 
51 /* Compare two buffers (length in bits) */
52 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do {	\
53 	uint8_t _last_byte_a, _last_byte_b;                       \
54 	uint8_t _last_byte_mask, _last_byte_bits;                  \
55 	TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg);     \
56 	if (len % 8) {                                              \
57 		_last_byte_bits = len % 8;                   \
58 		_last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \
59 		_last_byte_a = ((const uint8_t *)a)[len >> 3];            \
60 		_last_byte_b = ((const uint8_t *)b)[len >> 3];            \
61 		_last_byte_a &= _last_byte_mask;                     \
62 		_last_byte_b &= _last_byte_mask;                    \
63 		if (_last_byte_a != _last_byte_b) {                  \
64 			printf("TestCase %s() line %d failed: "              \
65 				msg "\n", __func__, __LINE__, ##__VA_ARGS__);\
66 			TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);    \
67 			return TEST_FAILED;                                  \
68 		}                                                        \
69 	}                                                            \
70 } while (0)
71 
72 /* Compare two buffers with offset (length and offset in bits) */
73 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) do {	\
74 	uint8_t _first_byte_a, _first_byte_b;                                 \
75 	uint8_t _first_byte_mask, _first_byte_bits;                           \
76 	uint32_t _len_without_first_byte = (off % 8) ?                       \
77 				len - (8 - (off % 8)) :                       \
78 				len;                                          \
79 	uint32_t _off_in_bytes = (off % 8) ? (off >> 3) + 1 : (off >> 3);     \
80 	const uint8_t *_a_with_off = (const uint8_t *)a + _off_in_bytes;      \
81 	const uint8_t *_b_with_off = (const uint8_t *)b + _off_in_bytes;      \
82 	TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off,           \
83 				_len_without_first_byte, msg);                \
84 	if (off % 8) {                                                        \
85 		_first_byte_bits = 8 - (off % 8);                             \
86 		_first_byte_mask = (1 << _first_byte_bits) - 1;               \
87 		_first_byte_a = *(_a_with_off - 1);                           \
88 		_first_byte_b = *(_b_with_off - 1);                           \
89 		_first_byte_a &= _first_byte_mask;                            \
90 		_first_byte_b &= _first_byte_mask;                            \
91 		if (_first_byte_a != _first_byte_b) {                         \
92 			printf("TestCase %s() line %d failed: "               \
93 				msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
94 			TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);     \
95 			return TEST_FAILED;                                   \
96 		}                                                             \
97 	}                                                                     \
98 } while (0)
99 
100 #define TEST_ASSERT_NOT_EQUAL RTE_TEST_ASSERT_NOT_EQUAL
101 
102 #define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS
103 
104 #define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL
105 
106 #define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL
107 
108 #define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL
109 
110 struct unit_test_case {
111 	int (*setup)(void);
112 	void (*teardown)(void);
113 	int (*testcase)(void);
114 	int (*testcase_with_data)(const void *data);
115 	const char *name;
116 	unsigned enabled;
117 	const void *data;
118 };
119 
120 #define TEST_CASE(fn) { NULL, NULL, fn, NULL, #fn, 1, NULL }
121 
122 #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, NULL, name, 1, NULL }
123 
124 #define TEST_CASE_ST(setup, teardown, testcase) \
125 		{ setup, teardown, testcase, NULL, #testcase, 1, NULL }
126 
127 #define TEST_CASE_WITH_DATA(setup, teardown, testcase, data) \
128 		{ setup, teardown, NULL, testcase, #testcase, 1, data }
129 
130 #define TEST_CASE_NAMED_ST(name, setup, teardown, testcase) \
131 		{ setup, teardown, testcase, NULL, name, 1, NULL }
132 
133 #define TEST_CASE_NAMED_WITH_DATA(name, setup, teardown, testcase, data) \
134 		{ setup, teardown, NULL, testcase, name, 1, data }
135 
136 #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, NULL, #fn, 0, NULL }
137 
138 #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \
139 		{ setup, teardown, testcase, NULL, #testcase, 0, NULL }
140 
141 #define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0, NULL }
142 
143 static inline void
144 debug_hexdump(FILE *file, const char *title, const void *buf, size_t len)
145 {
146 	if (rte_log_get_global_level() == RTE_LOG_DEBUG)
147 		rte_hexdump(file, title, buf, len);
148 }
149 
150 struct unit_test_suite {
151 	const char *suite_name;
152 	int (*setup)(void);
153 	void (*teardown)(void);
154 	unsigned int total;
155 	unsigned int executed;
156 	unsigned int succeeded;
157 	unsigned int skipped;
158 	unsigned int failed;
159 	unsigned int unsupported;
160 	struct unit_test_suite **unit_test_suites;
161 	struct unit_test_case unit_test_cases[];
162 };
163 
164 int unit_test_suite_runner(struct unit_test_suite *suite);
165 extern int last_test_result;
166 
167 #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
168 
169 #include <cmdline_parse.h>
170 #include <cmdline_parse_string.h>
171 
172 extern const char *prgname;
173 
174 int commands_init(void);
175 int command_valid(const char *cmd);
176 
177 int test_mp_secondary(void);
178 int test_timer_secondary(void);
179 
180 int test_set_rxtx_conf(cmdline_fixed_string_t mode);
181 int test_set_rxtx_anchor(cmdline_fixed_string_t type);
182 int test_set_rxtx_sc(cmdline_fixed_string_t type);
183 
184 typedef int (test_callback)(void);
185 TAILQ_HEAD(test_commands_list, test_command);
186 struct test_command {
187 	TAILQ_ENTRY(test_command) next;
188 	const char *command;
189 	test_callback *callback;
190 };
191 
192 void add_test_command(struct test_command *t);
193 
194 /* Register a test function with its command string. Should not be used directly */
195 #define REGISTER_TEST_COMMAND(cmd, func) \
196 	static struct test_command test_struct_##cmd = { \
197 		.command = RTE_STR(cmd), \
198 		.callback = func, \
199 	}; \
200 	RTE_INIT(test_register_##cmd) \
201 	{ \
202 		add_test_command(&test_struct_##cmd); \
203 	}
204 
205 /* Register a test function as a particular type.
206  * These can be used to build up test suites automatically
207  */
208 #define REGISTER_FAST_TEST(cmd, no_huge, ASan, func)  REGISTER_TEST_COMMAND(cmd, func)
209 #define REGISTER_PERF_TEST REGISTER_TEST_COMMAND
210 #define REGISTER_DRIVER_TEST REGISTER_TEST_COMMAND
211 #define REGISTER_STRESS_TEST REGISTER_TEST_COMMAND
212 
213 #endif
214