blob: bb0eb507ac2f29bee6b091ff6bd108fe627c2af9 [file] [log] [blame]
Lucas De Marchie701e382012-01-26 17:01:41 -02001/*
Lucas De Marchie6b0e492013-01-16 11:27:21 -02002 * Copyright (C) 2012-2013 ProFUSION embedded systems
Lucas De Marchie701e382012-01-26 17:01:41 -02003 *
Lucas De Marchie1b1ab22012-07-10 09:42:24 -03004 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
Lucas De Marchie701e382012-01-26 17:01:41 -02008 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Lucas De Marchie1b1ab22012-07-10 09:42:24 -030011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
Lucas De Marchie701e382012-01-26 17:01:41 -020013 *
Lucas De Marchie1b1ab22012-07-10 09:42:24 -030014 * You should have received a copy of the GNU Lesser General Public
Lucas De Marchidea2dfe2014-12-25 23:32:03 -020015 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Lucas De Marchie701e382012-01-26 17:01:41 -020016 */
17
Lucas De Marchie8fd8fe2012-07-18 10:19:48 -030018#pragma once
Lucas De Marchi80f9e022012-01-24 20:59:54 -020019
20#include <stdbool.h>
21#include <stdarg.h>
Lucas De Marchia6421a02016-08-10 14:51:57 -030022#include <stdio.h>
Lucas De Marchi80f9e022012-01-24 20:59:54 -020023
Lucas De Marchi576dd432014-10-02 22:03:19 -030024#include <shared/macro.h>
Lucas De Marchid96ca9c2013-12-17 19:10:16 -020025
Lucas De Marchi80f9e022012-01-24 20:59:54 -020026struct test;
27typedef int (*testfunc)(const struct test *t);
28
29enum test_config {
Lucas De Marchi23e354b2012-02-06 16:50:54 -020030 /*
31 * Where's the roots dir for this test. It will LD_PRELOAD path.so in
32 * order to trap calls to functions using paths.
33 */
Lucas De Marchi80f9e022012-01-24 20:59:54 -020034 TC_ROOTFS = 0,
Lucas De Marchi23e354b2012-02-06 16:50:54 -020035
36 /*
37 * What's the desired string to be returned by `uname -r`. It will
38 * trap calls to uname(3P) by LD_PRELOAD'ing uname.so and then filling
39 * in the information in u.release.
40 */
Lucas De Marchi80f9e022012-01-24 20:59:54 -020041 TC_UNAME_R,
Lucas De Marchi23e354b2012-02-06 16:50:54 -020042
43 /*
44 * Fake calls to init_module(2), returning return-code and setting
45 * errno to err-code. Set this variable with the following format:
46 *
47 * modname:return-code:err-code
48 *
49 * When this variable is used, all calls to init_module() are trapped
50 * and by default the return code is 0. In other words, they fake
51 * "success" for all modules, except the ones in the list above, for
52 * which the return codes are used.
53 */
Lucas De Marchi53646fc2012-01-26 02:09:28 -020054 TC_INIT_MODULE_RETCODES,
Lucas De Marchi23e354b2012-02-06 16:50:54 -020055
56 /*
57 * Fake calls to delete_module(2), returning return-code and setting
58 * errno to err-code. Set this variable with the following format:
59 *
60 * modname:return-code:err-code
61 *
62 * When this variable is used, all calls to init_module() are trapped
63 * and by default the return code is 0. In other words, they fake
64 * "success" for all modules, except the ones in the list above, for
65 * which the return codes are used.
66 */
Lucas De Marchif6ef5d62012-01-26 16:10:41 -020067 TC_DELETE_MODULE_RETCODES,
Lucas De Marchi23e354b2012-02-06 16:50:54 -020068
Lucas De Marchi80f9e022012-01-24 20:59:54 -020069 _TC_LAST,
70};
71
Lucas De Marchi6afc9cd2012-01-25 02:44:45 -020072#define S_TC_ROOTFS "TESTSUITE_ROOTFS"
Lucas De Marchi68cc4492012-01-24 22:04:46 -020073#define S_TC_UNAME_R "TESTSUITE_UNAME_R"
Lucas De Marchi53646fc2012-01-26 02:09:28 -020074#define S_TC_INIT_MODULE_RETCODES "TESTSUITE_INIT_MODULE_RETCODES"
Lucas De Marchif6ef5d62012-01-26 16:10:41 -020075#define S_TC_DELETE_MODULE_RETCODES "TESTSUITE_DELETE_MODULE_RETCODES"
Lucas De Marchi68cc4492012-01-24 22:04:46 -020076
Lucas De Marchi34db3f22012-06-06 01:42:30 -030077struct keyval {
78 const char *key;
79 const char *val;
80};
Lucas De Marchi68cc4492012-01-24 22:04:46 -020081
Lucas De Marchi80f9e022012-01-24 20:59:54 -020082struct test {
83 const char *name;
84 const char *description;
Lucas De Marchi3dbb8de2012-01-25 17:46:52 -020085 struct {
Lucas De Marchi3e451bf2012-10-04 00:21:52 -030086 /* File with correct stdout */
John Spencerbd4e7342013-08-27 01:38:11 +020087 const char *out;
Lucas De Marchi3e451bf2012-10-04 00:21:52 -030088 /* File with correct stderr */
John Spencerbd4e7342013-08-27 01:38:11 +020089 const char *err;
Lucas De Marchi3e451bf2012-10-04 00:21:52 -030090
91 /*
92 * Vector with pair of files
93 * key = correct file
94 * val = file to check
95 */
96 const struct keyval *files;
Lucas De Marchi3dbb8de2012-01-25 17:46:52 -020097 } output;
Michal Marek88ac4082014-02-28 13:05:28 +010098 /* comma-separated list of loaded modules at the end of the test */
99 const char *modules_loaded;
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200100 testfunc func;
101 const char *config[_TC_LAST];
Dave Reisnerf31d49c2012-02-14 21:49:26 -0500102 const char *path;
Lucas De Marchi34db3f22012-06-06 01:42:30 -0300103 const struct keyval *env_vars;
Lucas De Marchied2df4e2012-01-24 23:28:39 -0200104 bool need_spawn;
Dave Reisnerfa0046b2012-01-30 17:52:25 -0500105 bool expected_fail;
Lucas De Marchif6dc2392015-02-21 13:39:36 -0200106 bool print_outputs;
Lucas De Marchic5798fe2014-10-09 14:14:58 -0300107} __attribute__((aligned(8)));
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200108
109
Lucas De Marchic5798fe2014-10-09 14:14:58 -0300110int test_init(const struct test *start, const struct test *stop,
111 int argc, char *const argv[]);
112const struct test *test_find(const struct test *start, const struct test *stop,
113 const char *name);
Lucas De Marchi95daea02012-01-25 20:32:48 -0200114int test_spawn_prog(const char *prog, const char *const args[]);
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200115int test_run(const struct test *t);
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200116
117#define TS_EXPORT __attribute__ ((visibility("default")))
118
119#define _LOG(prefix, fmt, ...) printf("TESTSUITE: " prefix fmt, ## __VA_ARGS__)
120#define LOG(fmt, ...) _LOG("", fmt, ## __VA_ARGS__)
121#define WARN(fmt, ...) _LOG("WARN: ", fmt, ## __VA_ARGS__)
122#define ERR(fmt, ...) _LOG("ERR: ", fmt, ## __VA_ARGS__)
123
Lucas De Marchi30471c82014-06-06 02:19:01 -0300124#define assert_return(expr, r) \
125 do { \
126 if ((!(expr))) { \
Lucas De Marchi2d1f8bd2015-01-14 16:28:16 -0200127 ERR("Failed assertion: " #expr " %s:%d %s\n", \
Lucas De Marchi30471c82014-06-06 02:19:01 -0300128 __FILE__, __LINE__, __PRETTY_FUNCTION__); \
129 return (r); \
130 } \
131 } while (false)
132
133
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200134/* Test definitions */
Lucas De Marchic5d81982012-02-07 10:46:46 -0200135#define DEFINE_TEST(_name, ...) \
Lucas De Marchi43289822014-10-09 14:29:04 -0300136 static const struct test s##_name##UNIQ \
Lucas De Marchic5798fe2014-10-09 14:14:58 -0300137 __attribute__((used, section("kmod_tests"), aligned(8))) = { \
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200138 .name = #_name, \
139 .func = _name, \
Lucas De Marchic5d81982012-02-07 10:46:46 -0200140 ## __VA_ARGS__ \
Lucas De Marchic5798fe2014-10-09 14:14:58 -0300141 };
Lucas De Marchi80f9e022012-01-24 20:59:54 -0200142
Lucas De Marchi43289822014-10-09 14:29:04 -0300143#define TESTSUITE_MAIN() \
Lucas De Marchic5798fe2014-10-09 14:14:58 -0300144 extern struct test __start_kmod_tests[] __attribute__((weak, visibility("hidden"))); \
145 extern struct test __stop_kmod_tests[] __attribute__((weak, visibility("hidden"))); \
146 int main(int argc, char *argv[]) \
147 { \
148 const struct test *t; \
149 int arg; \
150 \
151 arg = test_init(__start_kmod_tests, __stop_kmod_tests, argc, argv); \
152 if (arg == 0) \
153 return 0; \
154 \
155 if (arg < argc) { \
156 t = test_find(__start_kmod_tests, __stop_kmod_tests, argv[arg]); \
157 if (t == NULL) { \
158 fprintf(stderr, "could not find test %s\n", argv[arg]); \
159 exit(EXIT_FAILURE); \
160 } \
161 \
162 return test_run(t); \
163 } \
164 \
165 for (t = __start_kmod_tests; t < __stop_kmod_tests; t++) { \
166 if (test_run(t) != 0) \
167 exit(EXIT_FAILURE); \
168 } \
169 \
170 exit(EXIT_SUCCESS); \
171 } \
Lucas De Marchie9fa9de2012-02-07 10:09:20 -0200172
Lucas De Marchid96ca9c2013-12-17 19:10:16 -0200173#ifdef noreturn
174# define __noreturn noreturn
175#elif __STDC_VERSION__ >= 201112L
176# define __noreturn _Noreturn
177#else
178# define __noreturn __attribute__((noreturn))
179#endif