xref: /aosp_15_r20/external/kmod/testsuite/testsuite.h (revision cc4ad7da8cefe208cb129ac2aa9a357c7c72deb2)
1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker  * Copyright (C) 2012-2013  ProFUSION embedded systems
3*cc4ad7daSAndroid Build Coastguard Worker  *
4*cc4ad7daSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or
5*cc4ad7daSAndroid Build Coastguard Worker  * modify it under the terms of the GNU Lesser General Public
6*cc4ad7daSAndroid Build Coastguard Worker  * License as published by the Free Software Foundation; either
7*cc4ad7daSAndroid Build Coastguard Worker  * version 2.1 of the License, or (at your option) any later version.
8*cc4ad7daSAndroid Build Coastguard Worker  *
9*cc4ad7daSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
10*cc4ad7daSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*cc4ad7daSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*cc4ad7daSAndroid Build Coastguard Worker  * Lesser General Public License for more details.
13*cc4ad7daSAndroid Build Coastguard Worker  *
14*cc4ad7daSAndroid Build Coastguard Worker  * You should have received a copy of the GNU Lesser General Public
15*cc4ad7daSAndroid Build Coastguard Worker  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16*cc4ad7daSAndroid Build Coastguard Worker  */
17*cc4ad7daSAndroid Build Coastguard Worker 
18*cc4ad7daSAndroid Build Coastguard Worker #pragma once
19*cc4ad7daSAndroid Build Coastguard Worker 
20*cc4ad7daSAndroid Build Coastguard Worker #include <stdbool.h>
21*cc4ad7daSAndroid Build Coastguard Worker #include <stdarg.h>
22*cc4ad7daSAndroid Build Coastguard Worker #include <stdio.h>
23*cc4ad7daSAndroid Build Coastguard Worker 
24*cc4ad7daSAndroid Build Coastguard Worker #include <shared/macro.h>
25*cc4ad7daSAndroid Build Coastguard Worker 
26*cc4ad7daSAndroid Build Coastguard Worker struct test;
27*cc4ad7daSAndroid Build Coastguard Worker typedef int (*testfunc)(const struct test *t);
28*cc4ad7daSAndroid Build Coastguard Worker 
29*cc4ad7daSAndroid Build Coastguard Worker enum test_config {
30*cc4ad7daSAndroid Build Coastguard Worker 	/*
31*cc4ad7daSAndroid Build Coastguard Worker 	 * Where's the roots dir for this test. It will LD_PRELOAD path.so in
32*cc4ad7daSAndroid Build Coastguard Worker 	 * order to trap calls to functions using paths.
33*cc4ad7daSAndroid Build Coastguard Worker 	 */
34*cc4ad7daSAndroid Build Coastguard Worker 	TC_ROOTFS = 0,
35*cc4ad7daSAndroid Build Coastguard Worker 
36*cc4ad7daSAndroid Build Coastguard Worker 	/*
37*cc4ad7daSAndroid Build Coastguard Worker 	 * What's the desired string to be returned by `uname -r`. It will
38*cc4ad7daSAndroid Build Coastguard Worker 	 * trap calls to uname(3P) by LD_PRELOAD'ing uname.so and then filling
39*cc4ad7daSAndroid Build Coastguard Worker 	 * in the information in u.release.
40*cc4ad7daSAndroid Build Coastguard Worker 	 */
41*cc4ad7daSAndroid Build Coastguard Worker 	TC_UNAME_R,
42*cc4ad7daSAndroid Build Coastguard Worker 
43*cc4ad7daSAndroid Build Coastguard Worker 	/*
44*cc4ad7daSAndroid Build Coastguard Worker 	 * Fake calls to init_module(2), returning return-code and setting
45*cc4ad7daSAndroid Build Coastguard Worker 	 * errno to err-code. Set this variable with the following format:
46*cc4ad7daSAndroid Build Coastguard Worker 	 *
47*cc4ad7daSAndroid Build Coastguard Worker 	 *        modname:return-code:err-code
48*cc4ad7daSAndroid Build Coastguard Worker 	 *
49*cc4ad7daSAndroid Build Coastguard Worker 	 * When this variable is used, all calls to init_module() are trapped
50*cc4ad7daSAndroid Build Coastguard Worker 	 * and by default the return code is 0. In other words, they fake
51*cc4ad7daSAndroid Build Coastguard Worker 	 * "success" for all modules, except the ones in the list above, for
52*cc4ad7daSAndroid Build Coastguard Worker 	 * which the return codes are used.
53*cc4ad7daSAndroid Build Coastguard Worker 	 */
54*cc4ad7daSAndroid Build Coastguard Worker 	TC_INIT_MODULE_RETCODES,
55*cc4ad7daSAndroid Build Coastguard Worker 
56*cc4ad7daSAndroid Build Coastguard Worker 	/*
57*cc4ad7daSAndroid Build Coastguard Worker 	 * Fake calls to delete_module(2), returning return-code and setting
58*cc4ad7daSAndroid Build Coastguard Worker 	 * errno to err-code. Set this variable with the following format:
59*cc4ad7daSAndroid Build Coastguard Worker 	 *
60*cc4ad7daSAndroid Build Coastguard Worker 	 *        modname:return-code:err-code
61*cc4ad7daSAndroid Build Coastguard Worker 	 *
62*cc4ad7daSAndroid Build Coastguard Worker 	 * When this variable is used, all calls to init_module() are trapped
63*cc4ad7daSAndroid Build Coastguard Worker 	 * and by default the return code is 0. In other words, they fake
64*cc4ad7daSAndroid Build Coastguard Worker 	 * "success" for all modules, except the ones in the list above, for
65*cc4ad7daSAndroid Build Coastguard Worker 	 * which the return codes are used.
66*cc4ad7daSAndroid Build Coastguard Worker 	 */
67*cc4ad7daSAndroid Build Coastguard Worker 	TC_DELETE_MODULE_RETCODES,
68*cc4ad7daSAndroid Build Coastguard Worker 
69*cc4ad7daSAndroid Build Coastguard Worker 	_TC_LAST,
70*cc4ad7daSAndroid Build Coastguard Worker };
71*cc4ad7daSAndroid Build Coastguard Worker 
72*cc4ad7daSAndroid Build Coastguard Worker #define S_TC_ROOTFS "TESTSUITE_ROOTFS"
73*cc4ad7daSAndroid Build Coastguard Worker #define S_TC_UNAME_R "TESTSUITE_UNAME_R"
74*cc4ad7daSAndroid Build Coastguard Worker #define S_TC_INIT_MODULE_RETCODES "TESTSUITE_INIT_MODULE_RETCODES"
75*cc4ad7daSAndroid Build Coastguard Worker #define S_TC_DELETE_MODULE_RETCODES "TESTSUITE_DELETE_MODULE_RETCODES"
76*cc4ad7daSAndroid Build Coastguard Worker 
77*cc4ad7daSAndroid Build Coastguard Worker struct keyval {
78*cc4ad7daSAndroid Build Coastguard Worker 	const char *key;
79*cc4ad7daSAndroid Build Coastguard Worker 	const char *val;
80*cc4ad7daSAndroid Build Coastguard Worker };
81*cc4ad7daSAndroid Build Coastguard Worker 
82*cc4ad7daSAndroid Build Coastguard Worker struct test {
83*cc4ad7daSAndroid Build Coastguard Worker 	const char *name;
84*cc4ad7daSAndroid Build Coastguard Worker 	const char *description;
85*cc4ad7daSAndroid Build Coastguard Worker 	struct {
86*cc4ad7daSAndroid Build Coastguard Worker 		/* File with correct stdout */
87*cc4ad7daSAndroid Build Coastguard Worker 		const char *out;
88*cc4ad7daSAndroid Build Coastguard Worker 		/* File with correct stderr */
89*cc4ad7daSAndroid Build Coastguard Worker 		const char *err;
90*cc4ad7daSAndroid Build Coastguard Worker 
91*cc4ad7daSAndroid Build Coastguard Worker 		/*
92*cc4ad7daSAndroid Build Coastguard Worker 		 * whether to treat the correct files as regex to the real
93*cc4ad7daSAndroid Build Coastguard Worker 		 * output
94*cc4ad7daSAndroid Build Coastguard Worker 		 */
95*cc4ad7daSAndroid Build Coastguard Worker 		bool regex;
96*cc4ad7daSAndroid Build Coastguard Worker 
97*cc4ad7daSAndroid Build Coastguard Worker 		/*
98*cc4ad7daSAndroid Build Coastguard Worker 		 * Vector with pair of files
99*cc4ad7daSAndroid Build Coastguard Worker 		 * key = correct file
100*cc4ad7daSAndroid Build Coastguard Worker 		 * val = file to check
101*cc4ad7daSAndroid Build Coastguard Worker 		 */
102*cc4ad7daSAndroid Build Coastguard Worker 		const struct keyval *files;
103*cc4ad7daSAndroid Build Coastguard Worker 	} output;
104*cc4ad7daSAndroid Build Coastguard Worker 	/* comma-separated list of loaded modules at the end of the test */
105*cc4ad7daSAndroid Build Coastguard Worker 	const char *modules_loaded;
106*cc4ad7daSAndroid Build Coastguard Worker 	testfunc func;
107*cc4ad7daSAndroid Build Coastguard Worker 	const char *config[_TC_LAST];
108*cc4ad7daSAndroid Build Coastguard Worker 	const char *path;
109*cc4ad7daSAndroid Build Coastguard Worker 	const struct keyval *env_vars;
110*cc4ad7daSAndroid Build Coastguard Worker 	bool need_spawn;
111*cc4ad7daSAndroid Build Coastguard Worker 	bool expected_fail;
112*cc4ad7daSAndroid Build Coastguard Worker 	/* allow to skip tests that don't meet compile-time dependencies */
113*cc4ad7daSAndroid Build Coastguard Worker 	bool skip;
114*cc4ad7daSAndroid Build Coastguard Worker 	bool print_outputs;
115*cc4ad7daSAndroid Build Coastguard Worker } __attribute__((aligned(8)));
116*cc4ad7daSAndroid Build Coastguard Worker 
117*cc4ad7daSAndroid Build Coastguard Worker 
118*cc4ad7daSAndroid Build Coastguard Worker int test_init(const struct test *start, const struct test *stop,
119*cc4ad7daSAndroid Build Coastguard Worker 	      int argc, char *const argv[]);
120*cc4ad7daSAndroid Build Coastguard Worker const struct test *test_find(const struct test *start, const struct test *stop,
121*cc4ad7daSAndroid Build Coastguard Worker 			     const char *name);
122*cc4ad7daSAndroid Build Coastguard Worker int test_spawn_prog(const char *prog, const char *const args[]);
123*cc4ad7daSAndroid Build Coastguard Worker int test_run(const struct test *t);
124*cc4ad7daSAndroid Build Coastguard Worker 
125*cc4ad7daSAndroid Build Coastguard Worker #define TS_EXPORT __attribute__ ((visibility("default")))
126*cc4ad7daSAndroid Build Coastguard Worker 
127*cc4ad7daSAndroid Build Coastguard Worker #define _LOG(prefix, fmt, ...) printf("TESTSUITE: " prefix fmt, ## __VA_ARGS__)
128*cc4ad7daSAndroid Build Coastguard Worker #define LOG(fmt, ...) _LOG("", fmt, ## __VA_ARGS__)
129*cc4ad7daSAndroid Build Coastguard Worker #define WARN(fmt, ...) _LOG("WARN: ", fmt, ## __VA_ARGS__)
130*cc4ad7daSAndroid Build Coastguard Worker #define ERR(fmt, ...) _LOG("ERR: ", fmt, ## __VA_ARGS__)
131*cc4ad7daSAndroid Build Coastguard Worker 
132*cc4ad7daSAndroid Build Coastguard Worker #define assert_return(expr, r)						\
133*cc4ad7daSAndroid Build Coastguard Worker 	do {								\
134*cc4ad7daSAndroid Build Coastguard Worker 		if ((!(expr))) {					\
135*cc4ad7daSAndroid Build Coastguard Worker 			ERR("Failed assertion: " #expr " %s:%d %s\n",	\
136*cc4ad7daSAndroid Build Coastguard Worker 			    __FILE__, __LINE__, __PRETTY_FUNCTION__);	\
137*cc4ad7daSAndroid Build Coastguard Worker 			return (r);					\
138*cc4ad7daSAndroid Build Coastguard Worker 		}							\
139*cc4ad7daSAndroid Build Coastguard Worker 	} while (false)
140*cc4ad7daSAndroid Build Coastguard Worker 
141*cc4ad7daSAndroid Build Coastguard Worker 
142*cc4ad7daSAndroid Build Coastguard Worker /* Test definitions */
143*cc4ad7daSAndroid Build Coastguard Worker #define DEFINE_TEST_WITH_FUNC(_name, _func, ...) \
144*cc4ad7daSAndroid Build Coastguard Worker 	static const struct test UNIQ(s##_name) \
145*cc4ad7daSAndroid Build Coastguard Worker 	__attribute__((used, section("kmod_tests"), aligned(8))) = { \
146*cc4ad7daSAndroid Build Coastguard Worker 		.name = #_name, \
147*cc4ad7daSAndroid Build Coastguard Worker 		.func = _func, \
148*cc4ad7daSAndroid Build Coastguard Worker 		## __VA_ARGS__ \
149*cc4ad7daSAndroid Build Coastguard Worker 	};
150*cc4ad7daSAndroid Build Coastguard Worker 
151*cc4ad7daSAndroid Build Coastguard Worker #define DEFINE_TEST(_name, ...) DEFINE_TEST_WITH_FUNC(_name, _name, __VA_ARGS__)
152*cc4ad7daSAndroid Build Coastguard Worker 
153*cc4ad7daSAndroid Build Coastguard Worker #define TESTSUITE_MAIN() \
154*cc4ad7daSAndroid Build Coastguard Worker 	extern struct test __start_kmod_tests[] __attribute__((weak, visibility("hidden")));	\
155*cc4ad7daSAndroid Build Coastguard Worker 	extern struct test __stop_kmod_tests[] __attribute__((weak, visibility("hidden")));	\
156*cc4ad7daSAndroid Build Coastguard Worker 	int main(int argc, char *argv[])							\
157*cc4ad7daSAndroid Build Coastguard Worker 	{											\
158*cc4ad7daSAndroid Build Coastguard Worker 		const struct test *t;								\
159*cc4ad7daSAndroid Build Coastguard Worker 		int arg;									\
160*cc4ad7daSAndroid Build Coastguard Worker 												\
161*cc4ad7daSAndroid Build Coastguard Worker 		arg = test_init(__start_kmod_tests, __stop_kmod_tests, argc, argv);		\
162*cc4ad7daSAndroid Build Coastguard Worker 		if (arg == 0)									\
163*cc4ad7daSAndroid Build Coastguard Worker 			return 0;								\
164*cc4ad7daSAndroid Build Coastguard Worker 		if (arg < 0)									\
165*cc4ad7daSAndroid Build Coastguard Worker 			return EXIT_FAILURE;							\
166*cc4ad7daSAndroid Build Coastguard Worker 												\
167*cc4ad7daSAndroid Build Coastguard Worker 		if (arg < argc) {								\
168*cc4ad7daSAndroid Build Coastguard Worker 			t = test_find(__start_kmod_tests, __stop_kmod_tests, argv[arg]);	\
169*cc4ad7daSAndroid Build Coastguard Worker 			if (t == NULL) {							\
170*cc4ad7daSAndroid Build Coastguard Worker 				fprintf(stderr, "could not find test %s\n", argv[arg]);		\
171*cc4ad7daSAndroid Build Coastguard Worker 				exit(EXIT_FAILURE);						\
172*cc4ad7daSAndroid Build Coastguard Worker 			}									\
173*cc4ad7daSAndroid Build Coastguard Worker 												\
174*cc4ad7daSAndroid Build Coastguard Worker 			return test_run(t);							\
175*cc4ad7daSAndroid Build Coastguard Worker 		}										\
176*cc4ad7daSAndroid Build Coastguard Worker 												\
177*cc4ad7daSAndroid Build Coastguard Worker 		for (t = __start_kmod_tests; t < __stop_kmod_tests; t++) {			\
178*cc4ad7daSAndroid Build Coastguard Worker 			if (test_run(t) != 0)							\
179*cc4ad7daSAndroid Build Coastguard Worker 				exit(EXIT_FAILURE);						\
180*cc4ad7daSAndroid Build Coastguard Worker 		}										\
181*cc4ad7daSAndroid Build Coastguard Worker 												\
182*cc4ad7daSAndroid Build Coastguard Worker 		exit(EXIT_SUCCESS);								\
183*cc4ad7daSAndroid Build Coastguard Worker 	}											\
184*cc4ad7daSAndroid Build Coastguard Worker 
185*cc4ad7daSAndroid Build Coastguard Worker #ifdef noreturn
186*cc4ad7daSAndroid Build Coastguard Worker # define __noreturn noreturn
187*cc4ad7daSAndroid Build Coastguard Worker #elif __STDC_VERSION__ >= 201112L
188*cc4ad7daSAndroid Build Coastguard Worker # define __noreturn _Noreturn
189*cc4ad7daSAndroid Build Coastguard Worker #else
190*cc4ad7daSAndroid Build Coastguard Worker # define __noreturn __attribute__((noreturn))
191*cc4ad7daSAndroid Build Coastguard Worker #endif
192