1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2015-2024 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 #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_ARR_(SCALL, SSCALL, EXP_ERRS, EXP_ERRS_CNT, ...) \ 231 do { \ 232 TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, SSCALL, \ 233 EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__); \ 234 if (TST_PASS) \ 235 TST_MSG_(TPASS | TTERRNO, " ", SSCALL, ##__VA_ARGS__); \ 236 } while (0) 237 238 #define TST_EXP_FAIL(SCALL, EXP_ERR, ...) \ 239 do { \ 240 int tst_exp_err__ = EXP_ERR; \ 241 TST_EXP_FAIL_ARR_(SCALL, #SCALL, &tst_exp_err__, 1, \ 242 ##__VA_ARGS__); \ 243 } while (0) 244 245 #define TST_EXP_FAIL_ARR(SCALL, EXP_ERRS, ...) \ 246 TST_EXP_FAIL_ARR_(SCALL, #SCALL, EXP_ERRS, \ 247 ARRAY_SIZE(EXP_ERRS), ##__VA_ARGS__); 248 249 #define TST_EXP_FAIL2_ARR_(SCALL, SSCALL, EXP_ERRS, EXP_ERRS_CNT, ...) \ 250 do { \ 251 TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, SSCALL, \ 252 EXP_ERRS, EXP_ERRS_CNT, ##__VA_ARGS__); \ 253 if (TST_PASS) \ 254 TST_MSG_(TPASS | TTERRNO, " ", SSCALL, ##__VA_ARGS__); \ 255 } while (0) 256 257 #define TST_EXP_FAIL2_ARR(SCALL, EXP_ERRS, ...) \ 258 TST_EXP_FAIL2_ARR_(SCALL, #SCALL, EXP_ERRS, \ 259 ARRAY_SIZE(EXP_ERRS), ##__VA_ARGS__); 260 261 #define TST_EXP_FAIL2(SCALL, EXP_ERR, ...) \ 262 do { \ 263 int tst_exp_err__ = EXP_ERR; \ 264 TST_EXP_FAIL2_ARR_(SCALL, #SCALL, &tst_exp_err__, 1, \ 265 ##__VA_ARGS__); \ 266 } while (0) 267 268 #define TST_EXP_FAIL_SILENT(SCALL, EXP_ERR, ...) \ 269 do { \ 270 int tst_exp_err__ = EXP_ERR; \ 271 TST_EXP_FAIL_SILENT_(TST_RET == 0, SCALL, #SCALL, \ 272 &tst_exp_err__, 1, ##__VA_ARGS__); \ 273 } while (0) 274 275 #define TST_EXP_FAIL2_SILENT(SCALL, EXP_ERR, ...) \ 276 do { \ 277 int tst_exp_err__ = EXP_ERR; \ 278 TST_EXP_FAIL_SILENT_(TST_RET >= 0, SCALL, #SCALL, \ 279 &tst_exp_err__, 1, ##__VA_ARGS__); \ 280 } while (0) 281 282 #define TST_EXP_EXPR(EXPR, FMT, ...) \ 283 tst_res_(__FILE__, __LINE__, (EXPR) ? TPASS : TFAIL, "Expect: " FMT, ##__VA_ARGS__); 284 285 #define TST_EXP_EQ_(VAL_A, SVAL_A, VAL_B, SVAL_B, TYPE, PFS) do {\ 286 TYPE tst_tmp_a__ = VAL_A; \ 287 TYPE tst_tmp_b__ = VAL_B; \ 288 if (tst_tmp_a__ == tst_tmp_b__) { \ 289 tst_res_(__FILE__, __LINE__, TPASS, \ 290 SVAL_A " == " SVAL_B " (" PFS ")", tst_tmp_a__); \ 291 } else { \ 292 tst_res_(__FILE__, __LINE__, TFAIL, \ 293 SVAL_A " (" PFS ") != " SVAL_B " (" PFS ")", \ 294 tst_tmp_a__, tst_tmp_b__); \ 295 } \ 296 } while (0) 297 298 #define TST_EXP_EQ_LI(VAL_A, VAL_B) \ 299 TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, long long, "%lli") 300 301 #define TST_EXP_EQ_LU(VAL_A, VAL_B) \ 302 TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, unsigned long long, "%llu") 303 304 #define TST_EXP_EQ_SZ(VAL_A, VAL_B) \ 305 TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, size_t, "%zu") 306 307 #define TST_EXP_EQ_SSZ(VAL_A, VAL_B) \ 308 TST_EXP_EQ_(VAL_A, #VAL_A, VAL_B, #VAL_B, ssize_t, "%zi") 309 310 #endif /* TST_TEST_MACROS_H__ */ 311