1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * kselftest.h: low-level kselftest framework to include from 4 * selftest programs. When possible, please use 5 * kselftest_harness.h instead. 6 * 7 * Copyright (c) 2014 Shuah Khan <shuahkh@osg.samsung.com> 8 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 9 * 10 * Using this API consists of first counting how many tests your code 11 * has to run, and then starting up the reporting: 12 * 13 * ksft_print_header(); 14 * ksft_set_plan(total_number_of_tests); 15 * 16 * For each test, report any progress, debugging, etc with: 17 * 18 * ksft_print_msg(fmt, ...); 19 * 20 * and finally report the pass/fail/skip/xfail state of the test with one of: 21 * 22 * ksft_test_result(condition, fmt, ...); 23 * ksft_test_result_pass(fmt, ...); 24 * ksft_test_result_fail(fmt, ...); 25 * ksft_test_result_skip(fmt, ...); 26 * ksft_test_result_xfail(fmt, ...); 27 * ksft_test_result_error(fmt, ...); 28 * ksft_test_result_code(exit_code, test_name, fmt, ...); 29 * 30 * When all tests are finished, clean up and exit the program with one of: 31 * 32 * ksft_finished(); 33 * ksft_exit(condition); 34 * ksft_exit_pass(); 35 * ksft_exit_fail(); 36 * 37 * If the program wants to report details on why the entire program has 38 * failed, it can instead exit with a message (this is usually done when 39 * the program is aborting before finishing all tests): 40 * 41 * ksft_exit_fail_msg(fmt, ...); 42 * 43 */ 44 #ifndef __KSELFTEST_H 45 #define __KSELFTEST_H 46 47 #ifndef NOLIBC 48 #include <errno.h> 49 #include <stdlib.h> 50 #include <unistd.h> 51 #include <stdarg.h> 52 #include <string.h> 53 #include <stdio.h> 54 #endif 55 56 #ifndef ARRAY_SIZE 57 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 58 #endif 59 60 /* 61 * gcc cpuid.h provides __cpuid_count() since v4.4. 62 * Clang/LLVM cpuid.h provides __cpuid_count() since v3.4.0. 63 * 64 * Provide local define for tests needing __cpuid_count() because 65 * selftests need to work in older environments that do not yet 66 * have __cpuid_count(). 67 */ 68 #ifndef __cpuid_count 69 #define __cpuid_count(level, count, a, b, c, d) \ 70 __asm__ __volatile__ ("cpuid\n\t" \ 71 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 72 : "0" (level), "2" (count)) 73 #endif 74 75 /* define kselftest exit codes */ 76 #define KSFT_PASS 0 77 #define KSFT_FAIL 1 78 #define KSFT_XFAIL 2 79 #define KSFT_XPASS 3 80 #define KSFT_SKIP 4 81 82 #define __printf(a, b) __attribute__((format(printf, a, b))) 83 84 /* counters */ 85 struct ksft_count { 86 unsigned int ksft_pass; 87 unsigned int ksft_fail; 88 unsigned int ksft_xfail; 89 unsigned int ksft_xpass; 90 unsigned int ksft_xskip; 91 unsigned int ksft_error; 92 }; 93 94 static struct ksft_count ksft_cnt; 95 static unsigned int ksft_plan; 96 97 static inline unsigned int ksft_test_num(void) 98 { 99 return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail + 100 ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass + 101 ksft_cnt.ksft_xskip + ksft_cnt.ksft_error; 102 } 103 104 static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; } 105 static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; } 106 static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; } 107 static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; } 108 static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; } 109 static inline void ksft_inc_error_cnt(void) { ksft_cnt.ksft_error++; } 110 111 static inline int ksft_get_pass_cnt(void) { return ksft_cnt.ksft_pass; } 112 static inline int ksft_get_fail_cnt(void) { return ksft_cnt.ksft_fail; } 113 static inline int ksft_get_xfail_cnt(void) { return ksft_cnt.ksft_xfail; } 114 static inline int ksft_get_xpass_cnt(void) { return ksft_cnt.ksft_xpass; } 115 static inline int ksft_get_xskip_cnt(void) { return ksft_cnt.ksft_xskip; } 116 static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; } 117 118 static inline void ksft_print_header(void) 119 { 120 /* 121 * Force line buffering; If stdout is not connected to a terminal, it 122 * will otherwise default to fully buffered, which can cause output 123 * duplication if there is content in the buffer when fork()ing. If 124 * there is a crash, line buffering also means the most recent output 125 * line will be visible. 126 */ 127 setvbuf(stdout, NULL, _IOLBF, 0); 128 129 if (!(getenv("KSFT_TAP_LEVEL"))) 130 printf("TAP version 13\n"); 131 } 132 133 static inline void ksft_set_plan(unsigned int plan) 134 { 135 ksft_plan = plan; 136 printf("1..%u\n", ksft_plan); 137 } 138 139 static inline void ksft_print_cnts(void) 140 { 141 if (ksft_plan != ksft_test_num()) 142 printf("# Planned tests != run tests (%u != %u)\n", 143 ksft_plan, ksft_test_num()); 144 printf("# Totals: pass:%u fail:%u xfail:%u xpass:%u skip:%u error:%u\n", 145 ksft_cnt.ksft_pass, ksft_cnt.ksft_fail, 146 ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass, 147 ksft_cnt.ksft_xskip, ksft_cnt.ksft_error); 148 } 149 150 static inline __printf(1, 2) void ksft_print_msg(const char *msg, ...) 151 { 152 int saved_errno = errno; 153 va_list args; 154 155 va_start(args, msg); 156 printf("# "); 157 errno = saved_errno; 158 vprintf(msg, args); 159 va_end(args); 160 } 161 162 static inline void ksft_perror(const char *msg) 163 { 164 #ifndef NOLIBC 165 ksft_print_msg("%s: %s (%d)\n", msg, strerror(errno), errno); 166 #else 167 /* 168 * nolibc doesn't provide strerror() and it seems 169 * inappropriate to add one, just print the errno. 170 */ 171 ksft_print_msg("%s: %d)\n", msg, errno); 172 #endif 173 } 174 175 static inline __printf(1, 2) void ksft_test_result_pass(const char *msg, ...) 176 { 177 int saved_errno = errno; 178 va_list args; 179 180 ksft_cnt.ksft_pass++; 181 182 va_start(args, msg); 183 printf("ok %u ", ksft_test_num()); 184 errno = saved_errno; 185 vprintf(msg, args); 186 va_end(args); 187 } 188 189 static inline __printf(1, 2) void ksft_test_result_fail(const char *msg, ...) 190 { 191 int saved_errno = errno; 192 va_list args; 193 194 ksft_cnt.ksft_fail++; 195 196 va_start(args, msg); 197 printf("not ok %u ", ksft_test_num()); 198 errno = saved_errno; 199 vprintf(msg, args); 200 va_end(args); 201 } 202 203 /** 204 * ksft_test_result() - Report test success based on truth of condition 205 * 206 * @condition: if true, report test success, otherwise failure. 207 */ 208 #define ksft_test_result(condition, fmt, ...) do { \ 209 if (!!(condition)) \ 210 ksft_test_result_pass(fmt, ##__VA_ARGS__);\ 211 else \ 212 ksft_test_result_fail(fmt, ##__VA_ARGS__);\ 213 } while (0) 214 215 static inline __printf(1, 2) void ksft_test_result_xfail(const char *msg, ...) 216 { 217 int saved_errno = errno; 218 va_list args; 219 220 ksft_cnt.ksft_xfail++; 221 222 va_start(args, msg); 223 printf("ok %u # XFAIL ", ksft_test_num()); 224 errno = saved_errno; 225 vprintf(msg, args); 226 va_end(args); 227 } 228 229 static inline __printf(1, 2) void ksft_test_result_skip(const char *msg, ...) 230 { 231 int saved_errno = errno; 232 va_list args; 233 234 ksft_cnt.ksft_xskip++; 235 236 va_start(args, msg); 237 printf("ok %u # SKIP ", ksft_test_num()); 238 errno = saved_errno; 239 vprintf(msg, args); 240 va_end(args); 241 } 242 243 /* TODO: how does "error" differ from "fail" or "skip"? */ 244 static inline __printf(1, 2) void ksft_test_result_error(const char *msg, ...) 245 { 246 int saved_errno = errno; 247 va_list args; 248 249 ksft_cnt.ksft_error++; 250 251 va_start(args, msg); 252 printf("not ok %u # error ", ksft_test_num()); 253 errno = saved_errno; 254 vprintf(msg, args); 255 va_end(args); 256 } 257 258 static inline __printf(3, 4) 259 void ksft_test_result_code(int exit_code, const char *test_name, 260 const char *msg, ...) 261 { 262 const char *tap_code = "ok"; 263 const char *directive = ""; 264 int saved_errno = errno; 265 va_list args; 266 267 switch (exit_code) { 268 case KSFT_PASS: 269 ksft_cnt.ksft_pass++; 270 break; 271 case KSFT_XFAIL: 272 directive = " # XFAIL "; 273 ksft_cnt.ksft_xfail++; 274 break; 275 case KSFT_XPASS: 276 directive = " # XPASS "; 277 ksft_cnt.ksft_xpass++; 278 break; 279 case KSFT_SKIP: 280 directive = " # SKIP "; 281 ksft_cnt.ksft_xskip++; 282 break; 283 case KSFT_FAIL: 284 default: 285 tap_code = "not ok"; 286 ksft_cnt.ksft_fail++; 287 break; 288 } 289 290 /* Docs seem to call for double space if directive is absent */ 291 if (!directive[0] && msg[0]) 292 directive = " # "; 293 294 va_start(args, msg); 295 printf("%s %u %s%s", tap_code, ksft_test_num(), test_name, directive); 296 errno = saved_errno; 297 vprintf(msg, args); 298 printf("\n"); 299 va_end(args); 300 } 301 302 static inline int ksft_exit_pass(void) 303 { 304 ksft_print_cnts(); 305 exit(KSFT_PASS); 306 } 307 308 static inline int ksft_exit_fail(void) 309 { 310 ksft_print_cnts(); 311 exit(KSFT_FAIL); 312 } 313 314 /** 315 * ksft_exit() - Exit selftest based on truth of condition 316 * 317 * @condition: if true, exit self test with success, otherwise fail. 318 */ 319 #define ksft_exit(condition) do { \ 320 if (!!(condition)) \ 321 ksft_exit_pass(); \ 322 else \ 323 ksft_exit_fail(); \ 324 } while (0) 325 326 /** 327 * ksft_finished() - Exit selftest with success if all tests passed 328 */ 329 #define ksft_finished() \ 330 ksft_exit(ksft_plan == \ 331 ksft_cnt.ksft_pass + \ 332 ksft_cnt.ksft_xfail + \ 333 ksft_cnt.ksft_xskip) 334 335 static inline __printf(1, 2) int ksft_exit_fail_msg(const char *msg, ...) 336 { 337 int saved_errno = errno; 338 va_list args; 339 340 va_start(args, msg); 341 printf("Bail out! "); 342 errno = saved_errno; 343 vprintf(msg, args); 344 va_end(args); 345 346 ksft_print_cnts(); 347 exit(KSFT_FAIL); 348 } 349 350 static inline int ksft_exit_xfail(void) 351 { 352 ksft_print_cnts(); 353 exit(KSFT_XFAIL); 354 } 355 356 static inline int ksft_exit_xpass(void) 357 { 358 ksft_print_cnts(); 359 exit(KSFT_XPASS); 360 } 361 362 static inline __printf(1, 2) int ksft_exit_skip(const char *msg, ...) 363 { 364 int saved_errno = errno; 365 va_list args; 366 367 va_start(args, msg); 368 369 /* 370 * FIXME: several tests misuse ksft_exit_skip so produce 371 * something sensible if some tests have already been run 372 * or a plan has been printed. Those tests should use 373 * ksft_test_result_skip or ksft_exit_fail_msg instead. 374 */ 375 if (ksft_plan || ksft_test_num()) { 376 ksft_cnt.ksft_xskip++; 377 printf("ok %d # SKIP ", 1 + ksft_test_num()); 378 } else { 379 printf("1..0 # SKIP "); 380 } 381 if (msg) { 382 errno = saved_errno; 383 vprintf(msg, args); 384 va_end(args); 385 } 386 if (ksft_test_num()) 387 ksft_print_cnts(); 388 exit(KSFT_SKIP); 389 } 390 391 #endif /* __KSELFTEST_H */ 392