• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2015-2020 Cyril Hrubis <chrubis@suse.cz>
4  * Copyright (c) Linux Test Project, 2021-2022
5  */
6 
7 #ifndef TST_TEST_MACROS_H__
8 #define TST_TEST_MACROS_H__
9 
10 #define TEST(SCALL) \
11 	do { \
12 		errno = 0; \
13 		TST_RET = SCALL; \
14 		TST_ERR = errno; \
15 	} while (0)
16 
17 #define TEST_VOID(SCALL) \
18 	do { \
19 		errno = 0; \
20 		SCALL; \
21 		TST_ERR = errno; \
22 	} while (0)
23 
24 extern long TST_RET;
25 extern int TST_ERR;
26 extern int TST_PASS;
27 
28 extern void *TST_RET_PTR;
29 
30 #define TESTPTR(SCALL) \
31 	do { \
32 		errno = 0; \
33 		TST_RET_PTR = (void*)SCALL; \
34 		TST_ERR = errno; \
35 	} while (0)
36 
37 
38 #define TST_2_(_1, _2, ...) _2
39 
40 #define TST_FMT_(FMT, _1, ...) FMT, ##__VA_ARGS__
41 
42 #define TST_MSG_(RES, FMT, SCALL, ...) \
43 	tst_res_(__FILE__, __LINE__, RES, \
44 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__))
45 
46 #define TST_MSGP_(RES, FMT, PAR, SCALL, ...) \
47 	tst_res_(__FILE__, __LINE__, RES, \
48 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__), PAR)
49 
50 #define TST_MSGP2_(RES, FMT, PAR, PAR2, SCALL, ...) \
51 	tst_res_(__FILE__, __LINE__, RES, \
52 		TST_FMT_(TST_2_(dummy, ##__VA_ARGS__, SCALL) FMT, __VA_ARGS__), PAR, PAR2)
53 
54 #define TST_EXP_POSITIVE__(SCALL, SSCALL, ...)                                 \
55 	do {                                                                   \
56 		TEST(SCALL);                                                   \
57 		                                                               \
58 		TST_PASS = 0;                                                  \
59 		                                                               \
60 		if (TST_RET == -1) {                                           \
61 			TST_MSG_(TFAIL | TTERRNO, " failed",                   \
62 			         SSCALL, ##__VA_ARGS__);                       \
63 			break;                                                 \
64 		}                                                              \
65 		                                                               \
66 		if (TST_RET < 0) {                                             \
67 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
68 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
69 			break;                                                 \
70 		}                                                              \
71                                                                                \
72 		TST_PASS = 1;                                                  \
73                                                                                \
74 	} while (0)
75 
76 #define TST_EXP_POSITIVE_(SCALL, ...)                                          \
77 	({                                                                     \
78 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
79 		TST_RET;                                                       \
80 	})
81 
82 #define TST_EXP_POSITIVE(SCALL, ...)                                           \
83 	({                                                                     \
84 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
85 		                                                               \
86 		if (TST_PASS) {                                                \
87 			TST_MSGP_(TPASS, " returned %ld",                      \
88 			          TST_RET, #SCALL, ##__VA_ARGS__);             \
89 		}                                                              \
90 		                                                               \
91 		TST_RET;                                                       \
92 	})
93 
94 #define TST_EXP_FD_SILENT(SCALL, ...)	TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
95 
96 #define TST_EXP_FD(SCALL, ...)                                                 \
97 	({                                                                     \
98 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
99 		                                                               \
100 		if (TST_PASS)                                                  \
101 			TST_MSGP_(TPASS, " returned fd %ld", TST_RET,          \
102 				#SCALL, ##__VA_ARGS__);                        \
103 		                                                               \
104 		TST_RET;                                                       \
105 	})
106 
107 #define TST_EXP_FD_OR_FAIL(SCALL, ERRNO, ...)                                  \
108 	({                                                                     \
109 		if (ERRNO)                                                     \
110 			TST_EXP_FAIL(SCALL, ERRNO, ##__VA_ARGS__);             \
111 		else                                                           \
112 			TST_EXP_FD(SCALL, ##__VA_ARGS__);                      \
113 		                                                               \
114 		TST_RET;                                                       \
115 	})
116 
117 #define TST_EXP_PID_SILENT(SCALL, ...)	TST_EXP_POSITIVE_(SCALL, #SCALL, ##__VA_ARGS__)
118 
119 #define TST_EXP_PID(SCALL, ...)                                                \
120 	({                                                                     \
121 		TST_EXP_POSITIVE__(SCALL, #SCALL, ##__VA_ARGS__);              \
122 									       \
123 		if (TST_PASS)                                                  \
124 			TST_MSGP_(TPASS, " returned pid %ld", TST_RET,         \
125 				#SCALL, ##__VA_ARGS__);                        \
126 		                                                               \
127 		TST_RET;                                                       \
128 	})
129 
130 #define TST_EXP_VAL_SILENT_(SCALL, VAL, SSCALL, ...)                           \
131 	do {                                                                   \
132 		TEST(SCALL);                                                   \
133 		                                                               \
134 		TST_PASS = 0;                                                  \
135 		                                                               \
136 		if (TST_RET != VAL) {                                          \
137 			TST_MSGP2_(TFAIL | TTERRNO, " retval %ld != %ld",      \
138 			          TST_RET, (long)VAL, SSCALL, ##__VA_ARGS__);  \
139 			break;                                                 \
140 		}                                                              \
141 		                                                               \
142 		TST_PASS = 1;                                                  \
143 		                                                               \
144 	} while (0)
145 
146 #define TST_EXP_VAL_SILENT(SCALL, VAL, ...) TST_EXP_VAL_SILENT_(SCALL, VAL, #SCALL, ##__VA_ARGS__)
147 
148 #define TST_EXP_VAL(SCALL, VAL, ...)                                           \
149 	do {                                                                   \
150 		TST_EXP_VAL_SILENT_(SCALL, VAL, #SCALL, ##__VA_ARGS__);        \
151 		                                                               \
152 		if (TST_PASS)                                                  \
153 			TST_MSG_(TPASS, " passed", #SCALL, ##__VA_ARGS__);     \
154 			                                                       \
155 	} while(0)
156 
157 #define TST_EXP_PASS_SILENT_(SCALL, SSCALL, ...)                               \
158 	do {                                                                   \
159 		TEST(SCALL);                                                   \
160 		                                                               \
161 		TST_PASS = 0;                                                  \
162 		                                                               \
163 		if (TST_RET == -1) {                                           \
164 			TST_MSG_(TFAIL | TTERRNO, " failed",                   \
165 			         SSCALL, ##__VA_ARGS__);                       \
166 		        break;                                                 \
167 		}                                                              \
168 		                                                               \
169 		if (TST_RET != 0) {                                            \
170 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
171 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
172 			break;                                                 \
173 		}                                                              \
174                                                                                \
175 		TST_PASS = 1;                                                  \
176                                                                                \
177 	} while (0)
178 
179 #define TST_EXP_PASS_SILENT(SCALL, ...) TST_EXP_PASS_SILENT_(SCALL, #SCALL, ##__VA_ARGS__)
180 
181 #define TST_EXP_PASS(SCALL, ...)                                               \
182 	do {                                                                   \
183 		TST_EXP_PASS_SILENT_(SCALL, #SCALL, ##__VA_ARGS__);            \
184 		                                                               \
185 		if (TST_PASS)                                                  \
186 			TST_MSG_(TPASS, " passed", #SCALL, ##__VA_ARGS__);     \
187 	} while (0)                                                            \
188 
189 #define TST_EXP_FAIL_SILENT_(PASS_COND, SCALL, SSCALL, ERRNO, ...)             \
190 	do {                                                                   \
191 		TEST(SCALL);                                                   \
192 		                                                               \
193 		TST_PASS = 0;                                                  \
194 		                                                               \
195 		if (PASS_COND) {                                               \
196 			TST_MSG_(TFAIL, " succeeded", SSCALL, ##__VA_ARGS__);  \
197 		        break;                                                 \
198 		}                                                              \
199 		                                                               \
200 		if (TST_RET != -1) {                                           \
201 			TST_MSGP_(TFAIL | TTERRNO, " invalid retval %ld",      \
202 			          TST_RET, SSCALL, ##__VA_ARGS__);             \
203 			break;                                                 \
204 		}                                                              \
205 		                                                               \
206 		if (TST_ERR == (ERRNO)) {                                      \
207 			TST_PASS = 1;                                          \
208 		} else {                                                       \
209 			TST_MSGP_(TFAIL | TTERRNO, " expected %s",             \
210 				  tst_strerrno(ERRNO),                         \
211 				  SSCALL, ##__VA_ARGS__);                      \
212 		}                                                              \
213 	} while (0)
214 
215 #define TST_EXP_FAIL(SCALL, ERRNO, ...)                                        \
216 	do {                                                                   \
217 		TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, #SCALL,              \
218 			ERRNO, ##__VA_ARGS__);                                 \
219 		if (TST_PASS)                                                  \
220 			TST_MSG_(TPASS | TTERRNO, " ", #SCALL, ##__VA_ARGS__); \
221 	} while (0)
222 
223 #define TST_EXP_FAIL2(SCALL, ERRNO, ...)                                       \
224 	do {                                                                   \
225 		TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, #SCALL,              \
226 			ERRNO, ##__VA_ARGS__);                                 \
227 		if (TST_PASS)                                                  \
228 			TST_MSG_(TPASS | TTERRNO, " ", #SCALL, ##__VA_ARGS__); \
229 	} while (0)
230 
231 #define TST_EXP_FAIL_SILENT(SCALL, ERRNO, ...) \
232 	TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, #SCALL, ERRNO, ##__VA_ARGS__)
233 
234 #define TST_EXP_FAIL2_SILENT(SCALL, ERRNO, ...) \
235 	TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, #SCALL, ERRNO, ##__VA_ARGS__)
236 
237 #define TST_EXP_EXPR(EXPR, FMT, ...)						\
238 	tst_res_(__FILE__, __LINE__, (EXPR) ? TPASS : TFAIL, "Expect: " FMT, ##__VA_ARGS__);
239 
240 #define TST_EXP_EQ_(VAL_A, SVAL_A, VAL_B, SVAL_B, TYPE, PFS) do {\
241 	TYPE tst_tmp_a__ = VAL_A; \
242 	TYPE tst_tmp_b__ = VAL_B; \
243 	if (tst_tmp_a__ == tst_tmp_b__) { \
244 		tst_res_(__FILE__, __LINE__, TPASS, \
245 			SVAL_A " == " SVAL_B " (" PFS ")", tst_tmp_a__); \
246 	} else { \
247 		tst_res_(__FILE__, __LINE__, TFAIL, \
248 			SVAL_A " (" PFS ") != " SVAL_B " (" PFS ")", \
249 			tst_tmp_a__, tst_tmp_b__); \
250 	} \
251 } while (0)
252 
253 #define TST_EXP_EQ_LI(VAL_A, VAL_B) \
254 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, long long, "%lli")
255 
256 #define TST_EXP_EQ_LU(VAL_A, VAL_B) \
257 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, unsigned long long, "%llu")
258 
259 #define TST_EXP_EQ_SZ(VAL_A, VAL_B) \
260 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, size_t, "%zu")
261 
262 #define TST_EXP_EQ_SSZ(VAL_A, VAL_B) \
263 		TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, ssize_t, "%zi")
264 
265 #endif	/* TST_TEST_MACROS_H__ */
266