test/memzone: fix freeing test
[dpdk.git] / test / test / test.h
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 <stddef.h>
9 #include <sys/queue.h>
10
11 #include <rte_hexdump.h>
12 #include <rte_common.h>
13 #include <rte_log.h>
14
15 #define TEST_SUCCESS EXIT_SUCCESS
16 #define TEST_FAILED  -1
17 #define TEST_SKIPPED  77
18
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)
24 #endif
25
26 #define TEST_ASSERT(cond, msg, ...) do {                         \
27                 if (!(cond)) {                                           \
28                         printf("TestCase %s() line %d failed: "              \
29                                 msg "\n", __func__, __LINE__, ##__VA_ARGS__);    \
30                         TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);    \
31                         return TEST_FAILED;                                  \
32                 }                                                        \
33 } while (0)
34
35 #define TEST_ASSERT_EQUAL(a, b, msg, ...) do {                   \
36                 if (!(a == b)) {                                         \
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 (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__);    \
50                 return TEST_FAILED;                                  \
51         }                                                        \
52 } while (0)
53
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);  \
59 } while (0)
60
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);     \
66         if (len % 8) {                                              \
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__);    \
77                         return TEST_FAILED;                                  \
78                 }                                                        \
79         }                                                            \
80 } while (0)
81
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)) :                       \
88                                 len;                                          \
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);                \
94         if (off % 8) {                                                        \
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;                                   \
106                 }                                                             \
107         }                                                                     \
108 } while (0)
109
110 #define TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do {               \
111                 if (!(a != b)) {                                         \
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;                                  \
116                 }                                                        \
117 } while (0)
118
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,              \
124                                 ##__VA_ARGS__);                                  \
125                         TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);    \
126                         return TEST_FAILED;                                  \
127                 }                                                        \
128 } while (0)
129
130 #define TEST_ASSERT_FAIL(val, msg, ...) do {                     \
131                 if (!(val != 0)) {                                       \
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;                                  \
136                 }                                                        \
137 } while (0)
138
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;                                  \
145                 }                                                        \
146 } while (0)
147
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;                                  \
154                 }                                                        \
155 } while (0)
156
157 struct unit_test_case {
158         int (*setup)(void);
159         void (*teardown)(void);
160         int (*testcase)(void);
161         const char *name;
162         unsigned enabled;
163 };
164
165 #define TEST_CASE(fn) { NULL, NULL, fn, #fn, 1 }
166
167 #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name, 1 }
168
169 #define TEST_CASE_ST(setup, teardown, testcase) \
170                 { setup, teardown, testcase, #testcase, 1 }
171
172
173 #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn, 0 }
174
175 #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \
176                 { setup, teardown, testcase, #testcase, 0 }
177
178 #define TEST_CASES_END() { NULL, NULL, NULL, NULL, 0 }
179
180 static inline void
181 debug_hexdump(FILE *file, const char *title, const void *buf, size_t len)
182 {
183         if (rte_log_get_global_level() == RTE_LOG_DEBUG)
184                 rte_hexdump(file, title, buf, len);
185 }
186
187 struct unit_test_suite {
188         const char *suite_name;
189         int (*setup)(void);
190         void (*teardown)(void);
191         struct unit_test_case unit_test_cases[];
192 };
193
194 int unit_test_suite_runner(struct unit_test_suite *suite);
195 extern int last_test_result;
196
197 #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
198
199 #include <cmdline_parse.h>
200 #include <cmdline_parse_string.h>
201
202 extern const char *prgname;
203
204 int commands_init(void);
205
206 int test_mp_secondary(void);
207
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);
211
212 typedef int (test_callback)(void);
213 TAILQ_HEAD(test_commands_list, test_command);
214 struct test_command {
215         TAILQ_ENTRY(test_command) next;
216         const char *command;
217         test_callback *callback;
218 };
219
220 void add_test_command(struct test_command *t);
221
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), \
226                 .callback = func, \
227         }; \
228         static void __attribute__((constructor, used)) \
229         test_register_##cmd(void) \
230         { \
231                 add_test_command(&test_struct_##cmd); \
232         }
233
234 #endif