]>
Commit | Line | Data |
---|---|---|
7c466b97 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
7fb2c3ea SK |
2 | /* |
3 | * kselftest.h: kselftest framework return codes to include from | |
4 | * selftests. | |
5 | * | |
6 | * Copyright (c) 2014 Shuah Khan <shuahkh@osg.samsung.com> | |
7 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | |
8 | * | |
245dd604 KC |
9 | * Using this API consists of first counting how many tests your code |
10 | * has to run, and then starting up the reporting: | |
11 | * | |
12 | * ksft_print_header(); | |
13 | * ksft_set_plan(total_number_of_tests); | |
14 | * | |
15 | * For each test, report any progress, debugging, etc with: | |
16 | * | |
17 | * ksft_print_msg(fmt, ...); | |
18 | * | |
19 | * and finally report the pass/fail/skip/xfail state of the test with one of: | |
20 | * | |
21 | * ksft_test_result(condition, fmt, ...); | |
22 | * ksft_test_result_pass(fmt, ...); | |
23 | * ksft_test_result_fail(fmt, ...); | |
24 | * ksft_test_result_skip(fmt, ...); | |
25 | * ksft_test_result_xfail(fmt, ...); | |
26 | * ksft_test_result_error(fmt, ...); | |
27 | * | |
28 | * When all tests are finished, clean up and exit the program with one of: | |
29 | * | |
30 | * ksft_exit(condition); | |
31 | * ksft_exit_pass(); | |
32 | * ksft_exit_fail(); | |
33 | * | |
34 | * If the program wants to report details on why the entire program has | |
35 | * failed, it can instead exit with a message (this is usually done when | |
36 | * the program is aborting before finishing all tests): | |
37 | * | |
38 | * ksft_exit_fail_msg(fmt, ...); | |
39 | * | |
7fb2c3ea SK |
40 | */ |
41 | #ifndef __KSELFTEST_H | |
42 | #define __KSELFTEST_H | |
43 | ||
fc2e634e | 44 | #include <errno.h> |
7fb2c3ea SK |
45 | #include <stdlib.h> |
46 | #include <unistd.h> | |
151b2732 | 47 | #include <stdarg.h> |
a18261d7 | 48 | #include <stdio.h> |
7fb2c3ea | 49 | |
4100e675 DH |
50 | /* define kselftest exit codes */ |
51 | #define KSFT_PASS 0 | |
52 | #define KSFT_FAIL 1 | |
53 | #define KSFT_XFAIL 2 | |
54 | #define KSFT_XPASS 3 | |
3c07aaef | 55 | #define KSFT_SKIP 4 |
4100e675 | 56 | |
7fb2c3ea SK |
57 | /* counters */ |
58 | struct ksft_count { | |
59 | unsigned int ksft_pass; | |
60 | unsigned int ksft_fail; | |
61 | unsigned int ksft_xfail; | |
62 | unsigned int ksft_xpass; | |
63 | unsigned int ksft_xskip; | |
c0bb2cf4 | 64 | unsigned int ksft_error; |
7fb2c3ea SK |
65 | }; |
66 | ||
67 | static struct ksft_count ksft_cnt; | |
5821ba96 | 68 | static unsigned int ksft_plan; |
7fb2c3ea | 69 | |
b6a4b66d PE |
70 | static inline int ksft_test_num(void) |
71 | { | |
72 | return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail + | |
73 | ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass + | |
c0bb2cf4 | 74 | ksft_cnt.ksft_xskip + ksft_cnt.ksft_error; |
b6a4b66d PE |
75 | } |
76 | ||
7fb2c3ea SK |
77 | static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; } |
78 | static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; } | |
79 | static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; } | |
80 | static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; } | |
81 | static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; } | |
c0bb2cf4 | 82 | static inline void ksft_inc_error_cnt(void) { ksft_cnt.ksft_error++; } |
7fb2c3ea | 83 | |
1d3ee8be SK |
84 | static inline int ksft_get_pass_cnt(void) { return ksft_cnt.ksft_pass; } |
85 | static inline int ksft_get_fail_cnt(void) { return ksft_cnt.ksft_fail; } | |
86 | static inline int ksft_get_xfail_cnt(void) { return ksft_cnt.ksft_xfail; } | |
87 | static inline int ksft_get_xpass_cnt(void) { return ksft_cnt.ksft_xpass; } | |
88 | static inline int ksft_get_xskip_cnt(void) { return ksft_cnt.ksft_xskip; } | |
c0bb2cf4 | 89 | static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; } |
1d3ee8be | 90 | |
b6a4b66d PE |
91 | static inline void ksft_print_header(void) |
92 | { | |
10f531f6 SK |
93 | if (!(getenv("KSFT_TAP_LEVEL"))) |
94 | printf("TAP version 13\n"); | |
b6a4b66d PE |
95 | } |
96 | ||
5821ba96 KC |
97 | static inline void ksft_set_plan(unsigned int plan) |
98 | { | |
99 | ksft_plan = plan; | |
100 | printf("1..%d\n", ksft_plan); | |
101 | } | |
102 | ||
7fb2c3ea SK |
103 | static inline void ksft_print_cnts(void) |
104 | { | |
5821ba96 KC |
105 | if (ksft_plan != ksft_test_num()) |
106 | printf("# Planned tests != run tests (%u != %u)\n", | |
107 | ksft_plan, ksft_test_num()); | |
245dd604 | 108 | printf("# Totals: pass:%d fail:%d xfail:%d xpass:%d skip:%d error:%d\n", |
1d3ee8be SK |
109 | ksft_cnt.ksft_pass, ksft_cnt.ksft_fail, |
110 | ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass, | |
c0bb2cf4 | 111 | ksft_cnt.ksft_xskip, ksft_cnt.ksft_error); |
b6a4b66d PE |
112 | } |
113 | ||
ab52a484 PE |
114 | static inline void ksft_print_msg(const char *msg, ...) |
115 | { | |
fc2e634e | 116 | int saved_errno = errno; |
ab52a484 PE |
117 | va_list args; |
118 | ||
119 | va_start(args, msg); | |
120 | printf("# "); | |
fc2e634e | 121 | errno = saved_errno; |
ab52a484 PE |
122 | vprintf(msg, args); |
123 | va_end(args); | |
124 | } | |
125 | ||
151b2732 | 126 | static inline void ksft_test_result_pass(const char *msg, ...) |
b6a4b66d | 127 | { |
fc2e634e | 128 | int saved_errno = errno; |
151b2732 PE |
129 | va_list args; |
130 | ||
b6a4b66d | 131 | ksft_cnt.ksft_pass++; |
151b2732 PE |
132 | |
133 | va_start(args, msg); | |
134 | printf("ok %d ", ksft_test_num()); | |
fc2e634e | 135 | errno = saved_errno; |
151b2732 PE |
136 | vprintf(msg, args); |
137 | va_end(args); | |
b6a4b66d PE |
138 | } |
139 | ||
151b2732 | 140 | static inline void ksft_test_result_fail(const char *msg, ...) |
b6a4b66d | 141 | { |
fc2e634e | 142 | int saved_errno = errno; |
151b2732 PE |
143 | va_list args; |
144 | ||
b6a4b66d | 145 | ksft_cnt.ksft_fail++; |
151b2732 PE |
146 | |
147 | va_start(args, msg); | |
148 | printf("not ok %d ", ksft_test_num()); | |
fc2e634e | 149 | errno = saved_errno; |
151b2732 PE |
150 | vprintf(msg, args); |
151 | va_end(args); | |
b6a4b66d PE |
152 | } |
153 | ||
245dd604 KC |
154 | /** |
155 | * ksft_test_result() - Report test success based on truth of condition | |
156 | * | |
157 | * @condition: if true, report test success, otherwise failure. | |
158 | */ | |
159 | #define ksft_test_result(condition, fmt, ...) do { \ | |
160 | if (!!(condition)) \ | |
161 | ksft_test_result_pass(fmt, ##__VA_ARGS__);\ | |
162 | else \ | |
163 | ksft_test_result_fail(fmt, ##__VA_ARGS__);\ | |
164 | } while (0) | |
165 | ||
166 | static inline void ksft_test_result_xfail(const char *msg, ...) | |
167 | { | |
168 | int saved_errno = errno; | |
169 | va_list args; | |
170 | ||
171 | ksft_cnt.ksft_xfail++; | |
172 | ||
173 | va_start(args, msg); | |
174 | printf("ok %d # XFAIL ", ksft_test_num()); | |
175 | errno = saved_errno; | |
176 | vprintf(msg, args); | |
177 | va_end(args); | |
178 | } | |
179 | ||
151b2732 | 180 | static inline void ksft_test_result_skip(const char *msg, ...) |
b6a4b66d | 181 | { |
fc2e634e | 182 | int saved_errno = errno; |
151b2732 PE |
183 | va_list args; |
184 | ||
b6a4b66d | 185 | ksft_cnt.ksft_xskip++; |
151b2732 PE |
186 | |
187 | va_start(args, msg); | |
b85d387c | 188 | printf("ok %d # SKIP ", ksft_test_num()); |
fc2e634e | 189 | errno = saved_errno; |
151b2732 PE |
190 | vprintf(msg, args); |
191 | va_end(args); | |
7fb2c3ea SK |
192 | } |
193 | ||
245dd604 | 194 | /* TODO: how does "error" differ from "fail" or "skip"? */ |
c0bb2cf4 SK |
195 | static inline void ksft_test_result_error(const char *msg, ...) |
196 | { | |
fc2e634e | 197 | int saved_errno = errno; |
c0bb2cf4 SK |
198 | va_list args; |
199 | ||
200 | ksft_cnt.ksft_error++; | |
201 | ||
202 | va_start(args, msg); | |
203 | printf("not ok %d # error ", ksft_test_num()); | |
fc2e634e | 204 | errno = saved_errno; |
c0bb2cf4 SK |
205 | vprintf(msg, args); |
206 | va_end(args); | |
207 | } | |
208 | ||
7fb2c3ea SK |
209 | static inline int ksft_exit_pass(void) |
210 | { | |
b6a4b66d | 211 | ksft_print_cnts(); |
4100e675 | 212 | exit(KSFT_PASS); |
7fb2c3ea | 213 | } |
b6a4b66d | 214 | |
7fb2c3ea SK |
215 | static inline int ksft_exit_fail(void) |
216 | { | |
b6a4b66d | 217 | ksft_print_cnts(); |
4100e675 | 218 | exit(KSFT_FAIL); |
7fb2c3ea | 219 | } |
b6a4b66d | 220 | |
245dd604 KC |
221 | /** |
222 | * ksft_exit() - Exit selftest based on truth of condition | |
223 | * | |
224 | * @condition: if true, exit self test with success, otherwise fail. | |
225 | */ | |
226 | #define ksft_exit(condition) do { \ | |
227 | if (!!(condition)) \ | |
228 | ksft_exit_pass(); \ | |
229 | else \ | |
230 | ksft_exit_fail(); \ | |
231 | } while (0) | |
232 | ||
151b2732 | 233 | static inline int ksft_exit_fail_msg(const char *msg, ...) |
b6a4b66d | 234 | { |
fc2e634e | 235 | int saved_errno = errno; |
151b2732 PE |
236 | va_list args; |
237 | ||
238 | va_start(args, msg); | |
239 | printf("Bail out! "); | |
fc2e634e | 240 | errno = saved_errno; |
151b2732 PE |
241 | vprintf(msg, args); |
242 | va_end(args); | |
243 | ||
b6a4b66d PE |
244 | ksft_print_cnts(); |
245 | exit(KSFT_FAIL); | |
246 | } | |
247 | ||
7fb2c3ea SK |
248 | static inline int ksft_exit_xfail(void) |
249 | { | |
b6a4b66d | 250 | ksft_print_cnts(); |
4100e675 | 251 | exit(KSFT_XFAIL); |
7fb2c3ea | 252 | } |
b6a4b66d | 253 | |
7fb2c3ea SK |
254 | static inline int ksft_exit_xpass(void) |
255 | { | |
b6a4b66d | 256 | ksft_print_cnts(); |
4100e675 | 257 | exit(KSFT_XPASS); |
7fb2c3ea | 258 | } |
b6a4b66d | 259 | |
151b2732 | 260 | static inline int ksft_exit_skip(const char *msg, ...) |
7fb2c3ea | 261 | { |
b85d387c PB |
262 | int saved_errno = errno; |
263 | va_list args; | |
151b2732 | 264 | |
b85d387c PB |
265 | va_start(args, msg); |
266 | ||
267 | /* | |
268 | * FIXME: several tests misuse ksft_exit_skip so produce | |
269 | * something sensible if some tests have already been run | |
270 | * or a plan has been printed. Those tests should use | |
271 | * ksft_test_result_skip or ksft_exit_fail_msg instead. | |
272 | */ | |
273 | if (ksft_plan || ksft_test_num()) { | |
274 | ksft_cnt.ksft_xskip++; | |
275 | printf("ok %d # SKIP ", 1 + ksft_test_num()); | |
276 | } else { | |
277 | printf("1..0 # SKIP "); | |
278 | } | |
279 | if (msg) { | |
fc2e634e | 280 | errno = saved_errno; |
151b2732 PE |
281 | vprintf(msg, args); |
282 | va_end(args); | |
151b2732 | 283 | } |
b85d387c PB |
284 | if (ksft_test_num()) |
285 | ksft_print_cnts(); | |
4100e675 | 286 | exit(KSFT_SKIP); |
7fb2c3ea SK |
287 | } |
288 | ||
289 | #endif /* __KSELFTEST_H */ |