1e701e381faac8977f472b881d426335b869998dcLucas De Marchi/*
2e6b0e49b4ea7937a98b16f23d621244ee1a3e588Lucas De Marchi * Copyright (C) 2012-2013  ProFUSION embedded systems
3e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
4e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * This program is free software; you can redistribute it and/or
5e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * modify it under the terms of the GNU Lesser General Public
6e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * License as published by the Free Software Foundation; either
7e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * version 2.1 of the License, or (at your option) any later version.
8e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
9e701e381faac8977f472b881d426335b869998dcLucas De Marchi * This program is distributed in the hope that it will be useful,
10e701e381faac8977f472b881d426335b869998dcLucas De Marchi * but WITHOUT ANY WARRANTY; without even the implied warranty of
11e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * Lesser General Public License for more details.
13e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
14e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * You should have received a copy of the GNU Lesser General Public
15dea2dfee9b301da84dbb09cf510b8ebf2ef28fffLucas De Marchi * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16e701e381faac8977f472b881d426335b869998dcLucas De Marchi */
17e701e381faac8977f472b881d426335b869998dcLucas De Marchi
18e8fd8fec236062e94e9486c64e482b780988f9bfLucas De Marchi#pragma once
1980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
2080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <stdbool.h>
2180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <stdarg.h>
22a6421a04e02746af273fed873ff038d81a828f7fLucas De Marchi#include <stdio.h>
2380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
24576dd4393d0deb2f4e050c5d1b96eaafb03bcb2cLucas De Marchi#include <shared/macro.h>
25d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi
2680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistruct test;
2780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchitypedef int (*testfunc)(const struct test *t);
2880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
2980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchienum test_config {
3023e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	/*
3123e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * Where's the roots dir for this test. It will LD_PRELOAD path.so in
3223e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * order to trap calls to functions using paths.
3323e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 */
3480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	TC_ROOTFS = 0,
3523e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi
3623e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	/*
3723e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * What's the desired string to be returned by `uname -r`. It will
3823e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * trap calls to uname(3P) by LD_PRELOAD'ing uname.so and then filling
3923e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * in the information in u.release.
4023e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 */
4180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	TC_UNAME_R,
4223e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi
4323e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	/*
4423e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * Fake calls to init_module(2), returning return-code and setting
4523e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * errno to err-code. Set this variable with the following format:
4623e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *
4723e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *        modname:return-code:err-code
4823e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *
4923e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * When this variable is used, all calls to init_module() are trapped
5023e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * and by default the return code is 0. In other words, they fake
5123e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * "success" for all modules, except the ones in the list above, for
5223e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * which the return codes are used.
5323e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 */
5453646fc56f32b7e3e7a2a8cd1e24aeb6b3422dbcLucas De Marchi	TC_INIT_MODULE_RETCODES,
5523e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi
5623e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	/*
5723e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * Fake calls to delete_module(2), returning return-code and setting
5823e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * errno to err-code. Set this variable with the following format:
5923e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *
6023e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *        modname:return-code:err-code
6123e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 *
6223e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * When this variable is used, all calls to init_module() are trapped
6323e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * and by default the return code is 0. In other words, they fake
6423e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * "success" for all modules, except the ones in the list above, for
6523e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 * which the return codes are used.
6623e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi	 */
67f6ef5d6b5fa47ab5fa9c9275eaa38916b92ca5a4Lucas De Marchi	TC_DELETE_MODULE_RETCODES,
6823e354bfdfc3e44e90cf1b578a9a29883cf06c4bLucas De Marchi
6980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	_TC_LAST,
7080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi};
7180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
726afc9cd616f792deafc9d5d1ee3cd7edd5d90ce2Lucas De Marchi#define S_TC_ROOTFS "TESTSUITE_ROOTFS"
7368cc44937653da88e8d5b72ad3d5eb86b5c7a424Lucas De Marchi#define S_TC_UNAME_R "TESTSUITE_UNAME_R"
7453646fc56f32b7e3e7a2a8cd1e24aeb6b3422dbcLucas De Marchi#define S_TC_INIT_MODULE_RETCODES "TESTSUITE_INIT_MODULE_RETCODES"
75f6ef5d6b5fa47ab5fa9c9275eaa38916b92ca5a4Lucas De Marchi#define S_TC_DELETE_MODULE_RETCODES "TESTSUITE_DELETE_MODULE_RETCODES"
7668cc44937653da88e8d5b72ad3d5eb86b5c7a424Lucas De Marchi
7734db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchistruct keyval {
7834db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi	const char *key;
7934db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi	const char *val;
8034db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi};
8168cc44937653da88e8d5b72ad3d5eb86b5c7a424Lucas De Marchi
8280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistruct test {
8380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const char *name;
8480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const char *description;
853dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	struct {
863e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		/* File with correct stdout */
87bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer		const char *out;
883e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		/* File with correct stderr */
89bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer		const char *err;
903e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
913e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		/*
923e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		 * Vector with pair of files
933e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		 * key = correct file
943e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		 * val = file to check
953e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		 */
963e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		const struct keyval *files;
973dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	} output;
9888ac40840f0d13aaca844bb7198c252178968878Michal Marek	/* comma-separated list of loaded modules at the end of the test */
9988ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char *modules_loaded;
10080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	testfunc func;
10180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const char *config[_TC_LAST];
102f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	const char *path;
10334db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi	const struct keyval *env_vars;
104ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi	bool need_spawn;
105fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner	bool expected_fail;
106f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi	bool print_outputs;
107c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi} __attribute__((aligned(8)));
10880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
10980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
110c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchiint test_init(const struct test *start, const struct test *stop,
111c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	      int argc, char *const argv[]);
112c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchiconst struct test *test_find(const struct test *start, const struct test *stop,
113c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			     const char *name);
11495daea07f44f6907859850e37d3468376759f66fLucas De Marchiint test_spawn_prog(const char *prog, const char *const args[]);
11580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchiint test_run(const struct test *t);
11680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
11780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#define TS_EXPORT __attribute__ ((visibility("default")))
11880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
11980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#define _LOG(prefix, fmt, ...) printf("TESTSUITE: " prefix fmt, ## __VA_ARGS__)
12080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#define LOG(fmt, ...) _LOG("", fmt, ## __VA_ARGS__)
12180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#define WARN(fmt, ...) _LOG("WARN: ", fmt, ## __VA_ARGS__)
12280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#define ERR(fmt, ...) _LOG("ERR: ", fmt, ## __VA_ARGS__)
12380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
12430471c80a48fc6888b9359056226438e5d2482caLucas De Marchi#define assert_return(expr, r)						\
12530471c80a48fc6888b9359056226438e5d2482caLucas De Marchi	do {								\
12630471c80a48fc6888b9359056226438e5d2482caLucas De Marchi		if ((!(expr))) {					\
1272d1f8bdec03780438d2571ec6dd80bb6dbd2cc91Lucas De Marchi			ERR("Failed assertion: " #expr " %s:%d %s\n",	\
12830471c80a48fc6888b9359056226438e5d2482caLucas De Marchi			    __FILE__, __LINE__, __PRETTY_FUNCTION__);	\
12930471c80a48fc6888b9359056226438e5d2482caLucas De Marchi			return (r);					\
13030471c80a48fc6888b9359056226438e5d2482caLucas De Marchi		}							\
13130471c80a48fc6888b9359056226438e5d2482caLucas De Marchi	} while (false)
13230471c80a48fc6888b9359056226438e5d2482caLucas De Marchi
13330471c80a48fc6888b9359056226438e5d2482caLucas De Marchi
13480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi/* Test definitions */
135c5d81989bc09cf735e3d7bd4e74381b4fe65ffadLucas De Marchi#define DEFINE_TEST(_name, ...) \
1364328982058bd6840518ff552a0405bf8f9d73909Lucas De Marchi	static const struct test s##_name##UNIQ \
137c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	__attribute__((used, section("kmod_tests"), aligned(8))) = { \
13880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		.name = #_name, \
13980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		.func = _name, \
140c5d81989bc09cf735e3d7bd4e74381b4fe65ffadLucas De Marchi		## __VA_ARGS__ \
141c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	};
14280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
1434328982058bd6840518ff552a0405bf8f9d73909Lucas De Marchi#define TESTSUITE_MAIN() \
144c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	extern struct test __start_kmod_tests[] __attribute__((weak, visibility("hidden")));	\
145c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	extern struct test __stop_kmod_tests[] __attribute__((weak, visibility("hidden")));	\
146c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	int main(int argc, char *argv[])							\
147c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	{											\
148c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		const struct test *t;								\
149c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		int arg;									\
150c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi												\
151c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		arg = test_init(__start_kmod_tests, __stop_kmod_tests, argc, argv);		\
152c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		if (arg == 0)									\
153c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			return 0;								\
154c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi												\
155c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		if (arg < argc) {								\
156c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			t = test_find(__start_kmod_tests, __stop_kmod_tests, argv[arg]);	\
157c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			if (t == NULL) {							\
158c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi				fprintf(stderr, "could not find test %s\n", argv[arg]);		\
159c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi				exit(EXIT_FAILURE);						\
160c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			}									\
161c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi												\
162c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			return test_run(t);							\
163c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		}										\
164c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi												\
165c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		for (t = __start_kmod_tests; t < __stop_kmod_tests; t++) {			\
166c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			if (test_run(t) != 0)							\
167c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi				exit(EXIT_FAILURE);						\
168c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		}										\
169c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi												\
170c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		exit(EXIT_SUCCESS);								\
171c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	}											\
172e9fa9de3c9fa60f85baddee6fc07229b2c48b2f9Lucas De Marchi
173d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi#ifdef noreturn
174d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi# define __noreturn noreturn
175d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi#elif __STDC_VERSION__ >= 201112L
176d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi# define __noreturn _Noreturn
177d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi#else
178d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi# define __noreturn __attribute__((noreturn))
179d96ca9c42930a2a0942b807b9afb3053f38ec9b9Lucas De Marchi#endif
180