blob: c9f03ef93338ba5e849ee5324ce1f342aefd47c6 [file] [log] [blame]
Thomas Gleixnere500db32019-06-04 10:11:14 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kees Cookc99ee512015-06-16 10:54:14 -07002/*
3 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Kees Cookc99ee512015-06-16 10:54:14 -07004 *
Mickaël Salaündfa47d32017-05-26 20:43:57 +02005 * kselftest_harness.h: simple C unit test helper.
Kees Cookc99ee512015-06-16 10:54:14 -07006 *
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +02007 * See documentation in Documentation/dev-tools/kselftest.rst
Kees Cookc99ee512015-06-16 10:54:14 -07008 *
9 * API inspired by code.google.com/p/googletest
10 */
Mickaël Salaündfa47d32017-05-26 20:43:57 +020011
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +020012/**
13 * DOC: example
14 *
15 * .. code-block:: c
16 *
17 * #include "../kselftest_harness.h"
18 *
19 * TEST(standalone_test) {
20 * do_some_stuff;
21 * EXPECT_GT(10, stuff) {
22 * stuff_state_t state;
23 * enumerate_stuff_state(&state);
24 * TH_LOG("expectation failed with state: %s", state.msg);
25 * }
26 * more_stuff;
27 * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!");
28 * last_stuff;
29 * EXPECT_EQ(0, last_stuff);
30 * }
31 *
32 * FIXTURE(my_fixture) {
33 * mytype_t *data;
34 * int awesomeness_level;
35 * };
36 * FIXTURE_SETUP(my_fixture) {
37 * self->data = mytype_new();
38 * ASSERT_NE(NULL, self->data);
39 * }
40 * FIXTURE_TEARDOWN(my_fixture) {
41 * mytype_free(self->data);
42 * }
43 * TEST_F(my_fixture, data_is_good) {
44 * EXPECT_EQ(1, is_my_data_good(self->data));
45 * }
46 *
47 * TEST_HARNESS_MAIN
48 */
49
Mickaël Salaündfa47d32017-05-26 20:43:57 +020050#ifndef __KSELFTEST_HARNESS_H
51#define __KSELFTEST_HARNESS_H
Kees Cookc99ee512015-06-16 10:54:14 -070052
53#define _GNU_SOURCE
Mickaël Salaün369130b2017-08-07 01:23:37 +020054#include <asm/types.h>
55#include <errno.h>
56#include <stdbool.h>
Kees Cookb5bb6d32015-12-10 14:50:25 -080057#include <stdint.h>
Kees Cookc99ee512015-06-16 10:54:14 -070058#include <stdio.h>
59#include <stdlib.h>
60#include <string.h>
61#include <sys/types.h>
62#include <sys/wait.h>
63#include <unistd.h>
64
Alexandre Bellonid51f1f12019-05-24 00:42:22 +020065#define TEST_TIMEOUT_DEFAULT 30
Kees Cookc99ee512015-06-16 10:54:14 -070066
67/* Utilities exposed to the test definitions */
68#ifndef TH_LOG_STREAM
69# define TH_LOG_STREAM stderr
70#endif
71
72#ifndef TH_LOG_ENABLED
73# define TH_LOG_ENABLED 1
74#endif
75
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +020076/**
77 * TH_LOG(fmt, ...)
78 *
79 * @fmt: format string
80 * @...: optional arguments
81 *
82 * .. code-block:: c
83 *
84 * TH_LOG(format, ...)
85 *
Mickaël Salaün1256a522017-05-26 20:44:01 +020086 * Optional debug logging function available for use in tests.
87 * Logging may be enabled or disabled by defining TH_LOG_ENABLED.
88 * E.g., #define TH_LOG_ENABLED 1
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +020089 *
Mickaël Salaün1256a522017-05-26 20:44:01 +020090 * If no definition is provided, logging is enabled by default.
Mickaël Salaün369130b2017-08-07 01:23:37 +020091 *
92 * If there is no way to print an error message for the process running the
93 * test (e.g. not allowed to write to stderr), it is still possible to get the
94 * ASSERT_* number for which the test failed. This behavior can be enabled by
95 * writing `_metadata->no_print = true;` before the check sequence that is
96 * unable to print. When an error occur, instead of printing an error message
97 * and calling `abort(3)`, the test process call `_exit(2)` with the assert
98 * number as argument, which is then printed by the parent process.
Mickaël Salaün1256a522017-05-26 20:44:01 +020099 */
100#define TH_LOG(fmt, ...) do { \
Kees Cookc99ee512015-06-16 10:54:14 -0700101 if (TH_LOG_ENABLED) \
102 __TH_LOG(fmt, ##__VA_ARGS__); \
103} while (0)
104
105/* Unconditional logger for internal use. */
106#define __TH_LOG(fmt, ...) \
107 fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \
108 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
109
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200110/**
Kees Cook6c3b6d52018-03-15 09:59:16 -0700111 * XFAIL(statement, fmt, ...)
112 *
113 * @statement: statement to run after reporting XFAIL
114 * @fmt: format string
115 * @...: optional arguments
116 *
117 * This forces a "pass" after reporting a failure with an XFAIL prefix,
118 * and runs "statement", which is usually "return" or "goto skip".
119 */
120#define XFAIL(statement, fmt, ...) do { \
121 if (TH_LOG_ENABLED) { \
122 fprintf(TH_LOG_STREAM, "[ XFAIL! ] " fmt "\n", \
123 ##__VA_ARGS__); \
124 } \
125 /* TODO: find a way to pass xfail to test runner process. */ \
126 _metadata->passed = 1; \
127 _metadata->trigger = 0; \
128 statement; \
129} while (0)
130
131/**
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200132 * TEST(test_name) - Defines the test function and creates the registration
133 * stub
134 *
135 * @test_name: test name
136 *
137 * .. code-block:: c
138 *
139 * TEST(name) { implementation }
140 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200141 * Defines a test by name.
142 * Names must be unique and tests must not be run in parallel. The
143 * implementation containing block is a function and scoping should be treated
144 * as such. Returning early may be performed with a bare "return;" statement.
145 *
146 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
147 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200148#define TEST(test_name) __TEST_IMPL(test_name, -1)
Kees Cookc99ee512015-06-16 10:54:14 -0700149
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200150/**
151 * TEST_SIGNAL(test_name, signal)
152 *
153 * @test_name: test name
154 * @signal: signal number
155 *
156 * .. code-block:: c
157 *
158 * TEST_SIGNAL(name, signal) { implementation }
159 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200160 * Defines a test by name and the expected term signal.
161 * Names must be unique and tests must not be run in parallel. The
162 * implementation containing block is a function and scoping should be treated
163 * as such. Returning early may be performed with a bare "return;" statement.
164 *
165 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
166 */
167#define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
Kees Cookc99ee512015-06-16 10:54:14 -0700168
169#define __TEST_IMPL(test_name, _signal) \
170 static void test_name(struct __test_metadata *_metadata); \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700171 static inline void wrapper_##test_name( \
172 struct __test_metadata *_metadata, \
173 struct __fixture_variant_metadata *variant) \
174 { \
175 test_name(_metadata); \
176 } \
Kees Cookc99ee512015-06-16 10:54:14 -0700177 static struct __test_metadata _##test_name##_object = \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700178 { .name = #test_name, \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700179 .fn = &wrapper_##test_name, \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700180 .fixture = &_fixture_global, \
181 .termsig = _signal, \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200182 .timeout = TEST_TIMEOUT_DEFAULT, }; \
Kees Cookc99ee512015-06-16 10:54:14 -0700183 static void __attribute__((constructor)) _register_##test_name(void) \
184 { \
185 __register_test(&_##test_name##_object); \
186 } \
187 static void test_name( \
188 struct __test_metadata __attribute__((unused)) *_metadata)
189
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200190/**
191 * FIXTURE_DATA(datatype_name) - Wraps the struct name so we have one less
192 * argument to pass around
193 *
194 * @datatype_name: datatype name
195 *
196 * .. code-block:: c
197 *
198 * FIXTURE_DATA(datatype name)
199 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200200 * This call may be used when the type of the fixture data
201 * is needed. In general, this should not be needed unless
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200202 * the *self* is being passed to a helper directly.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200203 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200204#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
Kees Cookc99ee512015-06-16 10:54:14 -0700205
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200206/**
207 * FIXTURE(fixture_name) - Called once per fixture to setup the data and
208 * register
209 *
210 * @fixture_name: fixture name
211 *
212 * .. code-block:: c
213 *
214 * FIXTURE(datatype name) {
215 * type property1;
216 * ...
217 * };
218 *
219 * Defines the data provided to TEST_F()-defined tests as *self*. It should be
220 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().
Mickaël Salaün1256a522017-05-26 20:44:01 +0200221 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200222#define FIXTURE(fixture_name) \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700223 FIXTURE_VARIANT(fixture_name); \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700224 static struct __fixture_metadata _##fixture_name##_fixture_object = \
225 { .name = #fixture_name, }; \
Kees Cookc99ee512015-06-16 10:54:14 -0700226 static void __attribute__((constructor)) \
227 _register_##fixture_name##_data(void) \
228 { \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700229 __register_fixture(&_##fixture_name##_fixture_object); \
Kees Cookc99ee512015-06-16 10:54:14 -0700230 } \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200231 FIXTURE_DATA(fixture_name)
Kees Cookc99ee512015-06-16 10:54:14 -0700232
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200233/**
234 * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture.
Kees Cook6c3b6d52018-03-15 09:59:16 -0700235 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200236 *
237 * @fixture_name: fixture name
238 *
239 * .. code-block:: c
240 *
241 * FIXTURE_SETUP(fixture name) { implementation }
242 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200243 * Populates the required "setup" function for a fixture. An instance of the
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200244 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
Mickaël Salaün1256a522017-05-26 20:44:01 +0200245 * implementation.
246 *
247 * ASSERT_* are valid for use in this context and will prempt the execution
248 * of any dependent fixture tests.
249 *
250 * A bare "return;" statement may be used to return early.
251 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200252#define FIXTURE_SETUP(fixture_name) \
Kees Cookc99ee512015-06-16 10:54:14 -0700253 void fixture_name##_setup( \
254 struct __test_metadata __attribute__((unused)) *_metadata, \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700255 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
256 const FIXTURE_VARIANT(fixture_name) \
257 __attribute__((unused)) *variant)
258
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200259/**
260 * FIXTURE_TEARDOWN(fixture_name)
Kees Cook6c3b6d52018-03-15 09:59:16 -0700261 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200262 *
263 * @fixture_name: fixture name
264 *
265 * .. code-block:: c
266 *
267 * FIXTURE_TEARDOWN(fixture name) { implementation }
268 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200269 * Populates the required "teardown" function for a fixture. An instance of the
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200270 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
Mickaël Salaün1256a522017-05-26 20:44:01 +0200271 * implementation to clean up.
272 *
273 * A bare "return;" statement may be used to return early.
274 */
275#define FIXTURE_TEARDOWN(fixture_name) \
Kees Cookc99ee512015-06-16 10:54:14 -0700276 void fixture_name##_teardown( \
277 struct __test_metadata __attribute__((unused)) *_metadata, \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200278 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
Kees Cookc99ee512015-06-16 10:54:14 -0700279
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200280/**
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700281 * FIXTURE_VARIANT(fixture_name) - Optionally called once per fixture
282 * to declare fixture variant
283 *
284 * @fixture_name: fixture name
285 *
286 * .. code-block:: c
287 *
288 * FIXTURE_VARIANT(datatype name) {
289 * type property1;
290 * ...
291 * };
292 *
293 * Defines type of constant parameters provided to FIXTURE_SETUP() and TEST_F()
294 * as *variant*. Variants allow the same tests to be run with different
295 * arguments.
296 */
297#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
298
299/**
300 * FIXTURE_VARIANT_ADD(fixture_name, variant_name) - Called once per fixture
301 * variant to setup and register the data
302 *
303 * @fixture_name: fixture name
304 * @variant_name: name of the parameter set
305 *
306 * .. code-block:: c
307 *
308 * FIXTURE_ADD(datatype name) {
309 * .property1 = val1;
310 * ...
311 * };
312 *
313 * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and
314 * TEST_F() as *variant*. Tests of each fixture will be run once for each
315 * variant.
316 */
317#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
318 extern FIXTURE_VARIANT(fixture_name) \
319 _##fixture_name##_##variant_name##_variant; \
320 static struct __fixture_variant_metadata \
321 _##fixture_name##_##variant_name##_object = \
322 { .name = #variant_name, \
323 .data = &_##fixture_name##_##variant_name##_variant}; \
324 static void __attribute__((constructor)) \
325 _register_##fixture_name##_##variant_name(void) \
326 { \
327 __register_fixture_variant(&_##fixture_name##_fixture_object, \
328 &_##fixture_name##_##variant_name##_object); \
329 } \
330 FIXTURE_VARIANT(fixture_name) \
331 _##fixture_name##_##variant_name##_variant =
332
333/**
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200334 * TEST_F(fixture_name, test_name) - Emits test registration and helpers for
335 * fixture-based test cases
336 *
337 * @fixture_name: fixture name
338 * @test_name: test name
339 *
340 * .. code-block:: c
341 *
342 * TEST_F(fixture, name) { implementation }
343 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200344 * Defines a test that depends on a fixture (e.g., is part of a test case).
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200345 * Very similar to TEST() except that *self* is the setup instance of fixture's
Mickaël Salaün1256a522017-05-26 20:44:01 +0200346 * datatype exposed for use by the implementation.
Kees Cook6c3b6d52018-03-15 09:59:16 -0700347 *
348 * Warning: use of ASSERT_* here will skip TEARDOWN.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200349 */
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200350/* TODO(wad) register fixtures on dedicated test lists. */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200351#define TEST_F(fixture_name, test_name) \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200352 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
Kees Cookc99ee512015-06-16 10:54:14 -0700353
Mickaël Salaün1256a522017-05-26 20:44:01 +0200354#define TEST_F_SIGNAL(fixture_name, test_name, signal) \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200355 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
Kees Cookc99ee512015-06-16 10:54:14 -0700356
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200357#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
358 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
359
360#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
Kees Cookc99ee512015-06-16 10:54:14 -0700361 static void fixture_name##_##test_name( \
362 struct __test_metadata *_metadata, \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700363 FIXTURE_DATA(fixture_name) *self, \
364 const FIXTURE_VARIANT(fixture_name) *variant); \
Kees Cookc99ee512015-06-16 10:54:14 -0700365 static inline void wrapper_##fixture_name##_##test_name( \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700366 struct __test_metadata *_metadata, \
367 struct __fixture_variant_metadata *variant) \
Kees Cookc99ee512015-06-16 10:54:14 -0700368 { \
369 /* fixture data is alloced, setup, and torn down per call. */ \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200370 FIXTURE_DATA(fixture_name) self; \
371 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700372 fixture_name##_setup(_metadata, &self, variant->data); \
Kees Cookc99ee512015-06-16 10:54:14 -0700373 /* Let setup failure terminate early. */ \
374 if (!_metadata->passed) \
375 return; \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700376 fixture_name##_##test_name(_metadata, &self, variant->data); \
Kees Cookc99ee512015-06-16 10:54:14 -0700377 fixture_name##_teardown(_metadata, &self); \
378 } \
379 static struct __test_metadata \
380 _##fixture_name##_##test_name##_object = { \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700381 .name = #test_name, \
Kees Cook121e3572019-01-27 01:42:51 -0800382 .fn = &wrapper_##fixture_name##_##test_name, \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700383 .fixture = &_##fixture_name##_fixture_object, \
Kees Cook121e3572019-01-27 01:42:51 -0800384 .termsig = signal, \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200385 .timeout = tmout, \
Kees Cookc99ee512015-06-16 10:54:14 -0700386 }; \
387 static void __attribute__((constructor)) \
388 _register_##fixture_name##_##test_name(void) \
389 { \
390 __register_test(&_##fixture_name##_##test_name##_object); \
391 } \
392 static void fixture_name##_##test_name( \
393 struct __test_metadata __attribute__((unused)) *_metadata, \
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700394 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
395 const FIXTURE_VARIANT(fixture_name) \
396 __attribute__((unused)) *variant)
Kees Cookc99ee512015-06-16 10:54:14 -0700397
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200398/**
399 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness
400 *
401 * .. code-block:: c
402 *
403 * TEST_HARNESS_MAIN
404 *
405 * Use once to append a main() to the test file.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200406 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200407#define TEST_HARNESS_MAIN \
Kees Cookc99ee512015-06-16 10:54:14 -0700408 static void __attribute__((constructor)) \
409 __constructor_order_last(void) \
410 { \
411 if (!__constructor_order) \
412 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
413 } \
414 int main(int argc, char **argv) { \
415 return test_harness_run(argc, argv); \
416 }
417
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200418/**
419 * DOC: operators
420 *
421 * Operators for use in TEST() and TEST_F().
Mickaël Salaün1256a522017-05-26 20:44:01 +0200422 * ASSERT_* calls will stop test execution immediately.
423 * EXPECT_* calls will emit a failure warning, note it, and continue.
424 */
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200425
426/**
427 * ASSERT_EQ(expected, seen)
428 *
429 * @expected: expected value
430 * @seen: measured value
431 *
432 * ASSERT_EQ(expected, measured): expected == measured
433 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200434#define ASSERT_EQ(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300435 __EXPECT(expected, #expected, seen, #seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200436
437/**
438 * ASSERT_NE(expected, seen)
439 *
440 * @expected: expected value
441 * @seen: measured value
442 *
443 * ASSERT_NE(expected, measured): expected != measured
444 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200445#define ASSERT_NE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300446 __EXPECT(expected, #expected, seen, #seen, !=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200447
448/**
449 * ASSERT_LT(expected, seen)
450 *
451 * @expected: expected value
452 * @seen: measured value
453 *
454 * ASSERT_LT(expected, measured): expected < measured
455 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200456#define ASSERT_LT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300457 __EXPECT(expected, #expected, seen, #seen, <, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200458
459/**
460 * ASSERT_LE(expected, seen)
461 *
462 * @expected: expected value
463 * @seen: measured value
464 *
465 * ASSERT_LE(expected, measured): expected <= measured
466 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200467#define ASSERT_LE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300468 __EXPECT(expected, #expected, seen, #seen, <=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200469
470/**
471 * ASSERT_GT(expected, seen)
472 *
473 * @expected: expected value
474 * @seen: measured value
475 *
476 * ASSERT_GT(expected, measured): expected > measured
477 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200478#define ASSERT_GT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300479 __EXPECT(expected, #expected, seen, #seen, >, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200480
481/**
482 * ASSERT_GE(expected, seen)
483 *
484 * @expected: expected value
485 * @seen: measured value
486 *
487 * ASSERT_GE(expected, measured): expected >= measured
488 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200489#define ASSERT_GE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300490 __EXPECT(expected, #expected, seen, #seen, >=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200491
492/**
493 * ASSERT_NULL(seen)
494 *
495 * @seen: measured value
496 *
497 * ASSERT_NULL(measured): NULL == measured
498 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200499#define ASSERT_NULL(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300500 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
Kees Cookc99ee512015-06-16 10:54:14 -0700501
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200502/**
503 * ASSERT_TRUE(seen)
504 *
505 * @seen: measured value
506 *
507 * ASSERT_TRUE(measured): measured != 0
508 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200509#define ASSERT_TRUE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300510 __EXPECT(0, "0", seen, #seen, !=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200511
512/**
513 * ASSERT_FALSE(seen)
514 *
515 * @seen: measured value
516 *
517 * ASSERT_FALSE(measured): measured == 0
518 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200519#define ASSERT_FALSE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300520 __EXPECT(0, "0", seen, #seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200521
522/**
523 * ASSERT_STREQ(expected, seen)
524 *
525 * @expected: expected value
526 * @seen: measured value
527 *
528 * ASSERT_STREQ(expected, measured): !strcmp(expected, measured)
529 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200530#define ASSERT_STREQ(expected, seen) \
531 __EXPECT_STR(expected, seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200532
533/**
534 * ASSERT_STRNE(expected, seen)
535 *
536 * @expected: expected value
537 * @seen: measured value
538 *
539 * ASSERT_STRNE(expected, measured): strcmp(expected, measured)
540 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200541#define ASSERT_STRNE(expected, seen) \
542 __EXPECT_STR(expected, seen, !=, 1)
Kees Cookc99ee512015-06-16 10:54:14 -0700543
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200544/**
545 * EXPECT_EQ(expected, seen)
546 *
547 * @expected: expected value
548 * @seen: measured value
549 *
550 * EXPECT_EQ(expected, measured): expected == measured
551 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200552#define EXPECT_EQ(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300553 __EXPECT(expected, #expected, seen, #seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200554
555/**
556 * EXPECT_NE(expected, seen)
557 *
558 * @expected: expected value
559 * @seen: measured value
560 *
561 * EXPECT_NE(expected, measured): expected != measured
562 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200563#define EXPECT_NE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300564 __EXPECT(expected, #expected, seen, #seen, !=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200565
566/**
567 * EXPECT_LT(expected, seen)
568 *
569 * @expected: expected value
570 * @seen: measured value
571 *
572 * EXPECT_LT(expected, measured): expected < measured
573 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200574#define EXPECT_LT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300575 __EXPECT(expected, #expected, seen, #seen, <, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200576
577/**
578 * EXPECT_LE(expected, seen)
579 *
580 * @expected: expected value
581 * @seen: measured value
582 *
583 * EXPECT_LE(expected, measured): expected <= measured
584 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200585#define EXPECT_LE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300586 __EXPECT(expected, #expected, seen, #seen, <=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200587
588/**
589 * EXPECT_GT(expected, seen)
590 *
591 * @expected: expected value
592 * @seen: measured value
593 *
594 * EXPECT_GT(expected, measured): expected > measured
595 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200596#define EXPECT_GT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300597 __EXPECT(expected, #expected, seen, #seen, >, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200598
599/**
600 * EXPECT_GE(expected, seen)
601 *
602 * @expected: expected value
603 * @seen: measured value
604 *
605 * EXPECT_GE(expected, measured): expected >= measured
606 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200607#define EXPECT_GE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300608 __EXPECT(expected, #expected, seen, #seen, >=, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700609
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200610/**
611 * EXPECT_NULL(seen)
612 *
613 * @seen: measured value
614 *
615 * EXPECT_NULL(measured): NULL == measured
616 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200617#define EXPECT_NULL(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300618 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200619
620/**
621 * EXPECT_TRUE(seen)
622 *
623 * @seen: measured value
624 *
625 * EXPECT_TRUE(measured): 0 != measured
626 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200627#define EXPECT_TRUE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300628 __EXPECT(0, "0", seen, #seen, !=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200629
630/**
631 * EXPECT_FALSE(seen)
632 *
633 * @seen: measured value
634 *
635 * EXPECT_FALSE(measured): 0 == measured
636 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200637#define EXPECT_FALSE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300638 __EXPECT(0, "0", seen, #seen, ==, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700639
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200640/**
641 * EXPECT_STREQ(expected, seen)
642 *
643 * @expected: expected value
644 * @seen: measured value
645 *
646 * EXPECT_STREQ(expected, measured): !strcmp(expected, measured)
647 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200648#define EXPECT_STREQ(expected, seen) \
649 __EXPECT_STR(expected, seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200650
651/**
652 * EXPECT_STRNE(expected, seen)
653 *
654 * @expected: expected value
655 * @seen: measured value
656 *
657 * EXPECT_STRNE(expected, measured): strcmp(expected, measured)
658 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200659#define EXPECT_STRNE(expected, seen) \
660 __EXPECT_STR(expected, seen, !=, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700661
662#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
663
664/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is
665 * not thread-safe, but it should be fine in most sane test scenarios.
666 *
667 * Using __bail(), which optionally abort()s, is the easiest way to early
668 * return while still providing an optional block to the API consumer.
669 */
670#define OPTIONAL_HANDLER(_assert) \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200671 for (; _metadata->trigger; _metadata->trigger = \
672 __bail(_assert, _metadata->no_print, _metadata->step))
673
674#define __INC_STEP(_metadata) \
675 if (_metadata->passed && _metadata->step < 255) \
676 _metadata->step++;
Kees Cookc99ee512015-06-16 10:54:14 -0700677
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300678#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
Kees Cookc99ee512015-06-16 10:54:14 -0700679 /* Avoid multiple evaluation of the cases */ \
680 __typeof__(_expected) __exp = (_expected); \
681 __typeof__(_seen) __seen = (_seen); \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200682 if (_assert) __INC_STEP(_metadata); \
Kees Cookc99ee512015-06-16 10:54:14 -0700683 if (!(__exp _t __seen)) { \
Kees Cookb5bb6d32015-12-10 14:50:25 -0800684 unsigned long long __exp_print = (uintptr_t)__exp; \
685 unsigned long long __seen_print = (uintptr_t)__seen; \
Kees Cookc99ee512015-06-16 10:54:14 -0700686 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300687 _expected_str, __exp_print, #_t, \
688 _seen_str, __seen_print); \
Kees Cookc99ee512015-06-16 10:54:14 -0700689 _metadata->passed = 0; \
690 /* Ensure the optional handler is triggered */ \
691 _metadata->trigger = 1; \
692 } \
693} while (0); OPTIONAL_HANDLER(_assert)
694
695#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
696 const char *__exp = (_expected); \
697 const char *__seen = (_seen); \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200698 if (_assert) __INC_STEP(_metadata); \
Kees Cookc99ee512015-06-16 10:54:14 -0700699 if (!(strcmp(__exp, __seen) _t 0)) { \
700 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
701 _metadata->passed = 0; \
702 _metadata->trigger = 1; \
703 } \
704} while (0); OPTIONAL_HANDLER(_assert)
705
Jakub Kicinski1a895952020-04-27 18:03:47 -0700706/* List helpers */
707#define __LIST_APPEND(head, item) \
708{ \
709 /* Circular linked list where only prev is circular. */ \
710 if (head == NULL) { \
711 head = item; \
712 item->next = NULL; \
713 item->prev = item; \
714 return; \
715 } \
716 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
717 item->next = NULL; \
718 item->prev = head->prev; \
719 item->prev->next = item; \
720 head->prev = item; \
721 } else { \
722 item->next = head; \
723 item->next->prev = item; \
724 item->prev = item; \
725 head = item; \
726 } \
727}
728
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700729struct __test_metadata;
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700730struct __fixture_variant_metadata;
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700731
Jakub Kicinski142aca62020-04-27 18:03:48 -0700732/* Contains all the information about a fixture. */
733struct __fixture_metadata {
734 const char *name;
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700735 struct __test_metadata *tests;
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700736 struct __fixture_variant_metadata *variant;
Jakub Kicinski142aca62020-04-27 18:03:48 -0700737 struct __fixture_metadata *prev, *next;
738} _fixture_global __attribute__((unused)) = {
739 .name = "global",
740 .prev = &_fixture_global,
741};
742
743static struct __fixture_metadata *__fixture_list = &_fixture_global;
Jakub Kicinski142aca62020-04-27 18:03:48 -0700744static int __constructor_order;
745
746#define _CONSTRUCTOR_ORDER_FORWARD 1
747#define _CONSTRUCTOR_ORDER_BACKWARD -1
748
749static inline void __register_fixture(struct __fixture_metadata *f)
750{
Jakub Kicinski142aca62020-04-27 18:03:48 -0700751 __LIST_APPEND(__fixture_list, f);
752}
753
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700754struct __fixture_variant_metadata {
755 const char *name;
756 const void *data;
757 struct __fixture_variant_metadata *prev, *next;
758};
759
760static inline void
761__register_fixture_variant(struct __fixture_metadata *f,
762 struct __fixture_variant_metadata *variant)
763{
764 __LIST_APPEND(f->variant, variant);
765}
766
Kees Cookc99ee512015-06-16 10:54:14 -0700767/* Contains all the information for test execution and status checking. */
768struct __test_metadata {
769 const char *name;
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700770 void (*fn)(struct __test_metadata *,
771 struct __fixture_variant_metadata *);
Kees Cookf46f5762020-03-13 16:12:51 -0700772 pid_t pid; /* pid of test when being run */
Jakub Kicinski142aca62020-04-27 18:03:48 -0700773 struct __fixture_metadata *fixture;
Kees Cookc99ee512015-06-16 10:54:14 -0700774 int termsig;
775 int passed;
776 int trigger; /* extra handler after the evaluation */
Kees Cookc31801d2020-03-13 16:12:52 -0700777 int timeout; /* seconds to wait for test timeout */
778 bool timed_out; /* did this test timeout instead of exiting? */
Mickaël Salaün369130b2017-08-07 01:23:37 +0200779 __u8 step;
780 bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
Kees Cookc99ee512015-06-16 10:54:14 -0700781 struct __test_metadata *prev, *next;
782};
783
Kees Cookc99ee512015-06-16 10:54:14 -0700784/*
785 * Since constructors are called in reverse order, reverse the test
786 * list so tests are run in source declaration order.
787 * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
788 * However, it seems not all toolchains do this correctly, so use
789 * __constructor_order to detect which direction is called first
790 * and adjust list building logic to get things running in the right
791 * direction.
792 */
793static inline void __register_test(struct __test_metadata *t)
794{
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700795 __LIST_APPEND(t->fixture->tests, t);
Kees Cookc99ee512015-06-16 10:54:14 -0700796}
797
Mickaël Salaün369130b2017-08-07 01:23:37 +0200798static inline int __bail(int for_realz, bool no_print, __u8 step)
Kees Cookc99ee512015-06-16 10:54:14 -0700799{
Mickaël Salaün369130b2017-08-07 01:23:37 +0200800 if (for_realz) {
801 if (no_print)
802 _exit(step);
Kees Cookc99ee512015-06-16 10:54:14 -0700803 abort();
Mickaël Salaün369130b2017-08-07 01:23:37 +0200804 }
Kees Cookc99ee512015-06-16 10:54:14 -0700805 return 0;
806}
807
Kees Cookc31801d2020-03-13 16:12:52 -0700808struct __test_metadata *__active_test;
809static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
810{
811 struct __test_metadata *t = __active_test;
812
813 /* Sanity check handler execution environment. */
814 if (!t) {
815 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000816 "no active test in SIGALRM handler!?\n");
Kees Cookc31801d2020-03-13 16:12:52 -0700817 abort();
818 }
819 if (sig != SIGALRM || sig != info->si_signo) {
820 fprintf(TH_LOG_STREAM,
821 "%s: SIGALRM handler caught signal %d!?\n",
822 t->name, sig != SIGALRM ? sig : info->si_signo);
823 abort();
824 }
825
826 t->timed_out = true;
827 kill(t->pid, SIGKILL);
828}
829
Kees Cookf46f5762020-03-13 16:12:51 -0700830void __wait_for_test(struct __test_metadata *t)
Kees Cookc99ee512015-06-16 10:54:14 -0700831{
Kees Cookc31801d2020-03-13 16:12:52 -0700832 struct sigaction action = {
833 .sa_sigaction = __timeout_handler,
834 .sa_flags = SA_SIGINFO,
835 };
836 struct sigaction saved_action;
Kees Cookc99ee512015-06-16 10:54:14 -0700837 int status;
838
Kees Cookc31801d2020-03-13 16:12:52 -0700839 if (sigaction(SIGALRM, &action, &saved_action)) {
840 t->passed = 0;
841 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000842 "%s: unable to install SIGALRM handler\n",
Kees Cookc31801d2020-03-13 16:12:52 -0700843 t->name);
844 return;
845 }
846 __active_test = t;
847 t->timed_out = false;
Kees Cookf46f5762020-03-13 16:12:51 -0700848 alarm(t->timeout);
849 waitpid(t->pid, &status, 0);
850 alarm(0);
Kees Cookc31801d2020-03-13 16:12:52 -0700851 if (sigaction(SIGALRM, &saved_action, NULL)) {
852 t->passed = 0;
853 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000854 "%s: unable to uninstall SIGALRM handler\n",
Kees Cookc31801d2020-03-13 16:12:52 -0700855 t->name);
856 return;
857 }
858 __active_test = NULL;
Kees Cookf46f5762020-03-13 16:12:51 -0700859
Kees Cookc31801d2020-03-13 16:12:52 -0700860 if (t->timed_out) {
861 t->passed = 0;
862 fprintf(TH_LOG_STREAM,
863 "%s: Test terminated by timeout\n", t->name);
864 } else if (WIFEXITED(status)) {
Kees Cookf46f5762020-03-13 16:12:51 -0700865 t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
866 if (t->termsig != -1) {
867 fprintf(TH_LOG_STREAM,
868 "%s: Test exited normally "
869 "instead of by signal (code: %d)\n",
870 t->name,
871 WEXITSTATUS(status));
872 } else if (!t->passed) {
873 fprintf(TH_LOG_STREAM,
874 "%s: Test failed at step #%d\n",
875 t->name,
876 WEXITSTATUS(status));
877 }
878 } else if (WIFSIGNALED(status)) {
879 t->passed = 0;
880 if (WTERMSIG(status) == SIGABRT) {
881 fprintf(TH_LOG_STREAM,
882 "%s: Test terminated by assertion\n",
883 t->name);
884 } else if (WTERMSIG(status) == t->termsig) {
885 t->passed = 1;
886 } else {
887 fprintf(TH_LOG_STREAM,
888 "%s: Test terminated unexpectedly "
889 "by signal %d\n",
890 t->name,
891 WTERMSIG(status));
892 }
893 } else {
894 fprintf(TH_LOG_STREAM,
895 "%s: Test ended in some other way [%u]\n",
896 t->name,
897 status);
898 }
899}
900
Jakub Kicinski142aca62020-04-27 18:03:48 -0700901void __run_test(struct __fixture_metadata *f,
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700902 struct __fixture_variant_metadata *variant,
Jakub Kicinski142aca62020-04-27 18:03:48 -0700903 struct __test_metadata *t)
Kees Cookf46f5762020-03-13 16:12:51 -0700904{
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700905 /* reset test struct */
Kees Cookc99ee512015-06-16 10:54:14 -0700906 t->passed = 1;
907 t->trigger = 0;
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700908 t->step = 0;
909 t->no_print = 0;
910
911 printf("[ RUN ] %s%s%s.%s\n",
912 f->name, variant->name[0] ? "." : "", variant->name, t->name);
Kees Cookf46f5762020-03-13 16:12:51 -0700913 t->pid = fork();
914 if (t->pid < 0) {
Kees Cookc99ee512015-06-16 10:54:14 -0700915 printf("ERROR SPAWNING TEST CHILD\n");
916 t->passed = 0;
Kees Cookf46f5762020-03-13 16:12:51 -0700917 } else if (t->pid == 0) {
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700918 t->fn(t, variant);
Mickaël Salaün369130b2017-08-07 01:23:37 +0200919 /* return the step that failed or 0 */
920 _exit(t->passed ? 0 : t->step);
Kees Cookc99ee512015-06-16 10:54:14 -0700921 } else {
Kees Cookf46f5762020-03-13 16:12:51 -0700922 __wait_for_test(t);
Kees Cookc99ee512015-06-16 10:54:14 -0700923 }
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700924 printf("[ %4s ] %s%s%s.%s\n", (t->passed ? "OK" : "FAIL"),
925 f->name, variant->name[0] ? "." : "", variant->name, t->name);
Kees Cookc99ee512015-06-16 10:54:14 -0700926}
927
928static int test_harness_run(int __attribute__((unused)) argc,
929 char __attribute__((unused)) **argv)
930{
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700931 struct __fixture_variant_metadata no_variant = { .name = "", };
932 struct __fixture_variant_metadata *v;
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700933 struct __fixture_metadata *f;
Kees Cookc99ee512015-06-16 10:54:14 -0700934 struct __test_metadata *t;
935 int ret = 0;
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700936 unsigned int case_count = 0, test_count = 0;
Kees Cookc99ee512015-06-16 10:54:14 -0700937 unsigned int count = 0;
938 unsigned int pass_count = 0;
939
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700940 for (f = __fixture_list; f; f = f->next) {
941 for (v = f->variant ?: &no_variant; v; v = v->next) {
942 case_count++;
943 for (t = f->tests; t; t = t->next)
944 test_count++;
945 }
946 }
947
Kees Cookc99ee512015-06-16 10:54:14 -0700948 /* TODO(wad) add optional arguments similar to gtest. */
949 printf("[==========] Running %u tests from %u test cases.\n",
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700950 test_count, case_count);
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700951 for (f = __fixture_list; f; f = f->next) {
Jakub Kicinski74bc7c92020-04-27 18:03:50 -0700952 for (v = f->variant ?: &no_variant; v; v = v->next) {
953 for (t = f->tests; t; t = t->next) {
954 count++;
955 __run_test(f, v, t);
956 if (t->passed)
957 pass_count++;
958 else
959 ret = 1;
960 }
Jakub Kicinskie7f30462020-04-27 18:03:49 -0700961 }
Kees Cookc99ee512015-06-16 10:54:14 -0700962 }
963 printf("[==========] %u / %u tests passed.\n", pass_count, count);
964 printf("[ %s ]\n", (ret ? "FAILED" : "PASSED"));
965 return ret;
966}
967
968static void __attribute__((constructor)) __constructor_order_first(void)
969{
970 if (!__constructor_order)
971 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
972}
973
Mickaël Salaündfa47d32017-05-26 20:43:57 +0200974#endif /* __KSELFTEST_HARNESS_H */