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