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