xref: /aosp_15_r20/external/ltp/include/tst_test_macros.h (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2015-2024 Cyril Hrubis <[email protected]>
4  * Copyright (c) Linux Test Project, 2021-2022
5  */
6 
7 #ifndef TST_TEST_MACROS_H__
8 #define TST_TEST_MACROS_H__
9 
10 #include <stdbool.h>
11 
12 #define TEST(SCALL) \
13 	do { \
14 		errno = 0; \
15 		TST_RET = SCALL; \
16 		TST_ERR = errno; \
17 	} while (0)
18 
19 #define TEST_VOID(SCALL) \
20 	do { \
21 		errno = 0; \
22 		SCALL; \
23 		TST_ERR = errno; \
24 	} while (0)
25 
26 extern long TST_RET;
27 extern int TST_ERR;
28 extern int TST_PASS;
29 
30 extern void *TST_RET_PTR;
31 
32 #define TESTPTR(SCALL) \
33 	do { \
34 		errno = 0; \
35 		TST_RET_PTR = (void*)SCALL; \
36 		TST_ERR = errno; \
37 	} while (0)
38 
39 
40 #define TST_2_(_1, _2, ...) _2
41 
42 #define TST_FMT_(FMT, _1, ...) FMT, ##__VA_ARGS__
43 
44 #define TST_MSG_(RES, FMT, SCALL, ...) \
45 	tst_res_(__FILE__, __LINE__, RES, \
46 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__))
47 
48 #define TST_MSGP_(RES, FMT, PAR, SCALL, ...) \
49 	tst_res_(__FILE__, __LINE__, RES, \
50 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__), PAR)
51 
52 #define TST_MSGP2_(RES, FMT, PAR, PAR2, SCALL, ...) \
53 	tst_res_(__FILE__, __LINE__, RES, \
54 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__), PAR, PAR2)
55 
56 #define TST_EXP_POSITIVE__(SCALL, SSCALL, ...)                                 \
57 	do {                                                                   \
58 		TEST(SCALL);                                                   \
59 		                                                               \
60 		TST_PASS = 0;                                                  \
61 		                                                               \
62 		if (TST_RET == -1) {                                           \
63 			TST_MSG_(TFAIL | TTERRNO, " failed",                   \
64 			         SSCALL, ##__VA_ARGS__);                       \
65 			break;                                                 \
66 		}                                                              \
67 		                                                               \
68 		if (TST_RET < 0) {                                             \
69 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
70 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
71 			break;                                                 \
72 		}                                                              \
73                                                                                \
74 		TST_PASS = 1;                                                  \
75                                                                                \
76 	} while (0)
77 
78 #define TST_EXP_POSITIVE_(SCALL, SSCALL, ...)                                  \
79 	({                                                                     \
80 		TST_EXP_POSITIVE__(SCALL, SSCALL, ##__VA_ARGS__);              \
81 		TST_RET;                                                       \
82 	})
83 
84 #define TST_EXP_POSITIVE(SCALL, ...)                                           \
85 	({                                                                     \
86 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
87 		                                                               \
88 		if (TST_PASS) {                                                \
89 			TST_MSGP_(TPASS, " returned %ld",                      \
90 			          TST_RET, #SCALL, ##__VA_ARGS__);             \
91 		}                                                              \
92 		                                                               \
93 		TST_RET;                                                       \
94 	})
95 
96 #define TST_EXP_FD_SILENT(SCALL, ...)	TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
97 
98 #define TST_EXP_FD(SCALL, ...)                                                 \
99 	({                                                                     \
100 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
101 		                                                               \
102 		if (TST_PASS)                                                  \
103 			TST_MSGP_(TPASS, " returned fd %ld", TST_RET,          \
104 				#SCALL, ##__VA_ARGS__);                        \
105 		                                                               \
106 		TST_RET;                                                       \
107 	})
108 
109 #define TST_EXP_FD_OR_FAIL(SCALL, ERRNO, ...)                                  \
110 	({                                                                     \
111 		if (ERRNO)                                                     \
112 			TST_EXP_FAIL(SCALL, ERRNO, ##__VA_ARGS__);             \
113 		else                                                           \
114 			TST_EXP_FD(SCALL, ##__VA_ARGS__);                      \
115 		                                                               \
116 		TST_RET;                                                       \
117 	})
118 
119 #define TST_EXP_PID_SILENT(SCALL, ...)	TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
120 
121 #define TST_EXP_PID(SCALL, ...)                                                \
122 	({                                                                     \
123 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
124 									       \
125 		if (TST_PASS)                                                  \
126 			TST_MSGP_(TPASS, " returned pid %ld", TST_RET,         \
127 				#SCALL, ##__VA_ARGS__);                        \
128 		                                                               \
129 		TST_RET;                                                       \
130 	})
131 
132 #define TST_EXP_VAL_SILENT_(SCALL, VAL, SSCALL, ...)                           \
133 	do {                                                                   \
134 		TEST(SCALL);                                                   \
135 		                                                               \
136 		TST_PASS = 0;                                                  \
137 		                                                               \
138 		if (TST_RET != VAL) {                                          \
139 			TST_MSGP2_(TFAIL | TTERRNO, " retval %ld != %ld",      \
140 			          TST_RET, (long)VAL, SSCALL, ##__VA_ARGS__);  \
141 			break;                                                 \
142 		}                                                              \
143 		                                                               \
144 		TST_PASS = 1;                                                  \
145 		                                                               \
146 	} while (0)
147 
148 #define TST_EXP_VAL_SILENT(SCALL, VAL, ...) TST_EXP_VAL_SILENT_(SCALL, VAL, #SCALL, ##__VA_ARGS__)
149 
150 #define TST_EXP_VAL(SCALL, VAL, ...)                                           \
151 	do {                                                                   \
152 		TST_EXP_VAL_SILENT_(SCALL, VAL, #SCALL, ##__VA_ARGS__);        \
153 		                                                               \
154 		if (TST_PASS)                                                  \
155 			TST_MSG_(TPASS, " passed", #SCALL, ##__VA_ARGS__);     \
156 			                                                       \
157 	} while(0)
158 
159 #define TST_EXP_PASS_SILENT_(SCALL, SSCALL, ...)                               \
160 	do {                                                                   \
161 		TEST(SCALL);                                                   \
162 		                                                               \
163 		TST_PASS = 0;                                                  \
164 		                                                               \
165 		if (TST_RET == -1) {                                           \
166 			TST_MSG_(TFAIL | TTERRNO, " failed",                   \
167 			         SSCALL, ##__VA_ARGS__);                       \
168 		        break;                                                 \
169 		}                                                              \
170 		                                                               \
171 		if (TST_RET != 0) {                                            \
172 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
173 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
174 			break;                                                 \
175 		}                                                              \
176                                                                                \
177 		TST_PASS = 1;                                                  \
178                                                                                \
179 	} while (0)
180 
181 #define TST_EXP_PASS_SILENT(SCALL, ...) TST_EXP_PASS_SILENT_(SCALL, #SCALL, ##__VA_ARGS__)
182 
183 #define TST_EXP_PASS(SCALL, ...)                                               \
184 	do {                                                                   \
185 		TST_EXP_PASS_SILENT_(SCALL, #SCALL, ##__VA_ARGS__);            \
186 		                                                               \
187 		if (TST_PASS)                                                  \
188 			TST_MSG_(TPASS, " passed", #SCALL, ##__VA_ARGS__);     \
189 	} while (0)                                                            \
190 
191 /*
192  * Returns true if err is in the exp_err array.
193  */
194 bool tst_errno_in_set(int err, const int *exp_errs, int exp_errs_cnt);
195 
196 /*
197  * Fills in the buf with the errno names in the exp_err set. The buf must be at
198  * least 20 * exp_errs_cnt bytes long.
199  */
200 const char *tst_errno_names(char *buf, const int *exp_errs, int exp_errs_cnt);
201 
202 #define TST_EXP_FAIL_SILENT_(PASS_COND, SCALL, SSCALL, ERRNOS, ERRNOS_CNT, ...)\
203 	do {                                                                   \
204 		TEST(SCALL);                                                   \
205 		                                                               \
206 		TST_PASS = 0;                                                  \
207 		                                                               \
208 		if (PASS_COND) {                                               \
209 			TST_MSG_(TFAIL, " succeeded", SSCALL, ##__VA_ARGS__);  \
210 		        break;                                                 \
211 		}                                                              \
212 		                                                               \
213 		if (TST_RET != -1) {                                           \
214 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
215 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
216 			break;                                                 \
217 		}                                                              \
218 		                                                               \
219 		if (tst_errno_in_set(TST_ERR, ERRNOS, ERRNOS_CNT)) {           \
220 			TST_PASS = 1;                                          \
221 		} else {                                                       \
222 			char tst_str_buf__[ERRNOS_CNT * 20];                   \
223 			TST_MSGP_(TFAIL | TTERRNO, " expected %s",             \
224 				  tst_errno_names(tst_str_buf__,               \
225 						  ERRNOS, ERRNOS_CNT),         \
226 				  SSCALL, ##__VA_ARGS__);                      \
227 		}                                                              \
228 	} while (0)
229 
230 #define TST_EXP_FAIL_SILENT_PTR_(SCALL, SSCALL, FAIL_PTR_VAL,                  \
231 	ERRNOS, ERRNOS_CNT, ...)                                               \
232 	do {                                                                   \
233 		TESTPTR(SCALL);                                                \
234 		                                                               \
235 		TST_PASS = 0;                                                  \
236 		                                                               \
237 		if (TST_RET_PTR != FAIL_PTR_VAL) {                             \
238 			TST_MSG_(TFAIL, " succeeded", SSCALL, ##__VA_ARGS__);  \
239 		        break;                                                 \
240 		}                                                              \
241 		                                                               \
242 		if (!tst_errno_in_set(TST_ERR, ERRNOS, ERRNOS_CNT)) {          \
243 			char tst_str_buf__[ERRNOS_CNT * 20];                   \
244 			TST_MSGP_(TFAIL | TTERRNO, " expected %s",             \
245 				  tst_errno_names(tst_str_buf__,               \
246 						  ERRNOS, ERRNOS_CNT),         \
247 				  SSCALL, ##__VA_ARGS__);                      \
248 			break;                                                 \
249 		}                                                              \
250                                                                                \
251 		TST_PASS = 1;                                                  \
252                                                                                \
253 	} while (0)
254 
255 #define TST_EXP_FAIL_PTR_(SCALL, SSCALL, FAIL_PTR_VAL,                         \
256 	ERRNOS, ERRNOS_CNT, ...)                                               \
257 	do {                                                                   \
258 		TST_EXP_FAIL_SILENT_PTR_(SCALL, SSCALL, FAIL_PTR_VAL,          \
259 	        ERRNOS, ERRNOS_CNT, ##__VA_ARGS__);                            \
260 		if (TST_PASS)                                                  \
261 			TST_MSG_(TPASS | TTERRNO, " ", SSCALL, ##__VA_ARGS__); \
262 	} while (0)
263 
264 
265 #define TST_EXP_FAIL_ARR_(SCALL, SSCALL, EXP_ERRS, EXP_ERRS_CNT, ...)          \
266 	do {                                                                   \
267 		TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, SSCALL,              \
268 			EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__);                \
269 		if (TST_PASS)                                                  \
270 			TST_MSG_(TPASS | TTERRNO, " ", SSCALL, ##__VA_ARGS__); \
271 	} while (0)
272 
273 #define TST_EXP_FAIL(SCALL, EXP_ERR, ...)                                      \
274 	do {                                                                   \
275 		int tst_exp_err__ = EXP_ERR;                                   \
276 		TST_EXP_FAIL_ARR_(SCALL, #SCALL, &tst_exp_err__, 1,            \
277                                   ##__VA_ARGS__);                              \
278 	} while (0)
279 
280 #define TST_EXP_FAIL_ARR(SCALL, EXP_ERRS, EXP_ERRS_CNT, ...)                   \
281 		TST_EXP_FAIL_ARR_(SCALL, #SCALL, EXP_ERRS,                     \
282 				  EXP_ERRS_CNT, ##__VA_ARGS__);
283 
284 #define TST_EXP_FAIL2_ARR_(SCALL, SSCALL, EXP_ERRS, EXP_ERRS_CNT, ...)         \
285 	do {                                                                   \
286 		TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, SSCALL,              \
287 			EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__);                \
288 		if (TST_PASS)                                                  \
289 			TST_MSG_(TPASS | TTERRNO, " ", SSCALL, ##__VA_ARGS__); \
290 	} while (0)
291 
292 #define TST_EXP_FAIL2_ARR(SCALL, EXP_ERRS, EXP_ERRS_CNT, ...)                \
293 		TST_EXP_FAIL2_ARR_(SCALL, #SCALL, EXP_ERRS,                    \
294 		                  EXP_ERRS_CNT, ##__VA_ARGS__);
295 
296 #define TST_EXP_FAIL_PTR_NULL(SCALL, EXP_ERR, ...)                          \
297 	do {                                                                   \
298 		int tst_exp_err__ = EXP_ERR;                                   \
299 		TST_EXP_FAIL_PTR_(SCALL, #SCALL, NULL,                         \
300 			&tst_exp_err__, 1, ##__VA_ARGS__);                     \
301 	} while (0)
302 
303 #define TST_EXP_FAIL_PTR_NULL_ARR(SCALL, EXP_ERRS, EXP_ERRS_CNT, ...)      \
304 	do {                                                                   \
305 		TST_EXP_FAIL_PTR_(SCALL, #SCALL, NULL,                         \
306 			EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__);        \
307 	} while (0)
308 
309 #define TST_EXP_FAIL_PTR_VOID(SCALL, EXP_ERR, ...)                         \
310 	do {                                                                   \
311 		int tst_exp_err__ = EXP_ERR;                                   \
312 		TST_EXP_FAIL_PTR_(SCALL, #SCALL, (void *)-1,                   \
313 			&tst_exp_err__, 1, ##__VA_ARGS__);                     \
314 	} while (0)
315 
316 #define TST_EXP_FAIL_PTR_VOID_ARR(SCALL, EXP_ERRS, EXP_ERRS_CNT, ...)      \
317 	do {                                                                   \
318 		TST_EXP_FAIL_PTR_(SCALL, #SCALL, (void *)-1,                   \
319 			EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__);        \
320 	} while (0)
321 
322 #define TST_EXP_FAIL2(SCALL, EXP_ERR, ...)                                     \
323 	do {                                                                   \
324 		int tst_exp_err__ = EXP_ERR;                                   \
325 		TST_EXP_FAIL2_ARR_(SCALL, #SCALL, &tst_exp_err__, 1,           \
326                                   ##__VA_ARGS__);                              \
327 	} while (0)
328 
329 #define TST_EXP_FAIL_SILENT(SCALL, EXP_ERR, ...)                               \
330 	do {                                                                   \
331 		int tst_exp_err__ = EXP_ERR;                                   \
332 		TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, #SCALL,              \
333 			&tst_exp_err__, 1, ##__VA_ARGS__);                     \
334 	} while (0)
335 
336 #define TST_EXP_FAIL2_SILENT(SCALL, EXP_ERR, ...)                              \
337 	do {                                                                   \
338 		int tst_exp_err__ = EXP_ERR;                                   \
339 		TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, #SCALL,              \
340 			&tst_exp_err__, 1, ##__VA_ARGS__);                     \
341 	} while (0)
342 
343 #define TST_EXP_EXPR(EXPR, FMT, ...)						\
344 	tst_res_(__FILE__, __LINE__, (EXPR) ? TPASS : TFAIL, "Expect: " FMT, ##__VA_ARGS__);
345 
346 #define TST_EXP_EQ_(VAL_A, SVAL_A, VAL_B, SVAL_B, TYPE, PFS) do {\
347 	TYPE tst_tmp_a__ = VAL_A; \
348 	TYPE tst_tmp_b__ = VAL_B; \
349 	if (tst_tmp_a__ == tst_tmp_b__) { \
350 		tst_res_(__FILE__, __LINE__, TPASS, \
351 			SVAL_A " == " SVAL_B " (" PFS ")", tst_tmp_a__); \
352 	} else { \
353 		tst_res_(__FILE__, __LINE__, TFAIL, \
354 			SVAL_A " (" PFS ") != " SVAL_B " (" PFS ")", \
355 			tst_tmp_a__, tst_tmp_b__); \
356 	} \
357 } while (0)
358 
359 #define TST_EXP_EQ_LI(VAL_A, VAL_B) \
360 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, long long, "%lli")
361 
362 #define TST_EXP_EQ_LU(VAL_A, VAL_B) \
363 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, unsigned long long, "%llu")
364 
365 #define TST_EXP_EQ_SZ(VAL_A, VAL_B) \
366 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, size_t, "%zu")
367 
368 #define TST_EXP_EQ_SSZ(VAL_A, VAL_B) \
369 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, ssize_t, "%zi")
370 
371 #endif	/* TST_TEST_MACROS_H__ */
372