xref: /linux/tools/testing/selftests/sched_ext/scx_test.h (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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 
15 enum 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 
23 struct 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 
73 void 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__
132