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