Loading...
Note: File does not exist in v4.10.11.
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4 * Copyright (c) 2023 Tejun Heo <tj@kernel.org>
5 * Copyright (c) 2023 David Vernet <dvernet@meta.com>
6 */
7
8#ifndef __SCX_TEST_H__
9#define __SCX_TEST_H__
10
11#include <errno.h>
12#include <scx/common.h>
13#include <scx/compat.h>
14
15enum scx_test_status {
16 SCX_TEST_PASS = 0,
17 SCX_TEST_SKIP,
18 SCX_TEST_FAIL,
19};
20
21#define EXIT_KIND(__ent) __COMPAT_ENUM_OR_ZERO("scx_exit_kind", #__ent)
22
23struct scx_test {
24 /**
25 * name - The name of the testcase.
26 */
27 const char *name;
28
29 /**
30 * description - A description of your testcase: what it tests and is
31 * meant to validate.
32 */
33 const char *description;
34
35 /*
36 * setup - Setup the test.
37 * @ctx: A pointer to a context object that will be passed to run and
38 * cleanup.
39 *
40 * An optional callback that allows a testcase to perform setup for its
41 * run. A test may return SCX_TEST_SKIP to skip the run.
42 */
43 enum scx_test_status (*setup)(void **ctx);
44
45 /*
46 * run - Run the test.
47 * @ctx: Context set in the setup() callback. If @ctx was not set in
48 * setup(), it is NULL.
49 *
50 * The main test. Callers should return one of:
51 *
52 * - SCX_TEST_PASS: Test passed
53 * - SCX_TEST_SKIP: Test should be skipped
54 * - SCX_TEST_FAIL: Test failed
55 *
56 * This callback must be defined.
57 */
58 enum scx_test_status (*run)(void *ctx);
59
60 /*
61 * cleanup - Perform cleanup following the test
62 * @ctx: Context set in the setup() callback. If @ctx was not set in
63 * setup(), it is NULL.
64 *
65 * An optional callback that allows a test to perform cleanup after
66 * being run. This callback is run even if the run() callback returns
67 * SCX_TEST_SKIP or SCX_TEST_FAIL. It is not run if setup() returns
68 * SCX_TEST_SKIP or SCX_TEST_FAIL.
69 */
70 void (*cleanup)(void *ctx);
71};
72
73void scx_test_register(struct scx_test *test);
74
75#define REGISTER_SCX_TEST(__test) \
76 __attribute__((constructor)) \
77 static void ___scxregister##__LINE__(void) \
78 { \
79 scx_test_register(__test); \
80 }
81
82#define SCX_ERR(__fmt, ...) \
83 do { \
84 fprintf(stderr, "ERR: %s:%d\n", __FILE__, __LINE__); \
85 fprintf(stderr, __fmt"\n", ##__VA_ARGS__); \
86 } while (0)
87
88#define SCX_FAIL(__fmt, ...) \
89 do { \
90 SCX_ERR(__fmt, ##__VA_ARGS__); \
91 return SCX_TEST_FAIL; \
92 } while (0)
93
94#define SCX_FAIL_IF(__cond, __fmt, ...) \
95 do { \
96 if (__cond) \
97 SCX_FAIL(__fmt, ##__VA_ARGS__); \
98 } while (0)
99
100#define SCX_GT(_x, _y) SCX_FAIL_IF((_x) <= (_y), "Expected %s > %s (%lu > %lu)", \
101 #_x, #_y, (u64)(_x), (u64)(_y))
102#define SCX_GE(_x, _y) SCX_FAIL_IF((_x) < (_y), "Expected %s >= %s (%lu >= %lu)", \
103 #_x, #_y, (u64)(_x), (u64)(_y))
104#define SCX_LT(_x, _y) SCX_FAIL_IF((_x) >= (_y), "Expected %s < %s (%lu < %lu)", \
105 #_x, #_y, (u64)(_x), (u64)(_y))
106#define SCX_LE(_x, _y) SCX_FAIL_IF((_x) > (_y), "Expected %s <= %s (%lu <= %lu)", \
107 #_x, #_y, (u64)(_x), (u64)(_y))
108#define SCX_EQ(_x, _y) SCX_FAIL_IF((_x) != (_y), "Expected %s == %s (%lu == %lu)", \
109 #_x, #_y, (u64)(_x), (u64)(_y))
110#define SCX_ASSERT(_x) SCX_FAIL_IF(!(_x), "Expected %s to be true (%lu)", \
111 #_x, (u64)(_x))
112
113#define SCX_ECODE_VAL(__ecode) ({ \
114 u64 __val = 0; \
115 bool __found = false; \
116 \
117 __found = __COMPAT_read_enum("scx_exit_code", #__ecode, &__val); \
118 SCX_ASSERT(__found); \
119 (s64)__val; \
120})
121
122#define SCX_KIND_VAL(__kind) ({ \
123 u64 __val = 0; \
124 bool __found = false; \
125 \
126 __found = __COMPAT_read_enum("scx_exit_kind", #__kind, &__val); \
127 SCX_ASSERT(__found); \
128 __val; \
129})
130
131#endif // # __SCX_TEST_H__