]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - tools/testing/selftests/kselftest.h
selftests: Add header documentation and helpers
[mirror_ubuntu-jammy-kernel.git] / tools / testing / selftests / kselftest.h
CommitLineData
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 */
58struct 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
67static struct ksft_count ksft_cnt;
5821ba96 68static unsigned int ksft_plan;
7fb2c3ea 69
b6a4b66d
PE
70static 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
77static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; }
78static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; }
79static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; }
80static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; }
81static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; }
c0bb2cf4 82static inline void ksft_inc_error_cnt(void) { ksft_cnt.ksft_error++; }
7fb2c3ea 83
1d3ee8be
SK
84static inline int ksft_get_pass_cnt(void) { return ksft_cnt.ksft_pass; }
85static inline int ksft_get_fail_cnt(void) { return ksft_cnt.ksft_fail; }
86static inline int ksft_get_xfail_cnt(void) { return ksft_cnt.ksft_xfail; }
87static inline int ksft_get_xpass_cnt(void) { return ksft_cnt.ksft_xpass; }
88static inline int ksft_get_xskip_cnt(void) { return ksft_cnt.ksft_xskip; }
c0bb2cf4 89static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; }
1d3ee8be 90
b6a4b66d
PE
91static 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
97static inline void ksft_set_plan(unsigned int plan)
98{
99 ksft_plan = plan;
100 printf("1..%d\n", ksft_plan);
101}
102
7fb2c3ea
SK
103static 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
114static 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 126static 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 140static 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
166static 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 180static 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
195static 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
209static inline int ksft_exit_pass(void)
210{
b6a4b66d 211 ksft_print_cnts();
4100e675 212 exit(KSFT_PASS);
7fb2c3ea 213}
b6a4b66d 214
7fb2c3ea
SK
215static 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 233static 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
248static inline int ksft_exit_xfail(void)
249{
b6a4b66d 250 ksft_print_cnts();
4100e675 251 exit(KSFT_XFAIL);
7fb2c3ea 252}
b6a4b66d 253
7fb2c3ea
SK
254static inline int ksft_exit_xpass(void)
255{
b6a4b66d 256 ksft_print_cnts();
4100e675 257 exit(KSFT_XPASS);
7fb2c3ea 258}
b6a4b66d 259
151b2732 260static 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 */