blob: de283fd6fc4db333346eee579c3a4af9f61ed8f5 [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); \
171 static struct __test_metadata _##test_name##_object = \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700172 { .name = #test_name, \
173 .fn = &test_name, \
174 .fixture = &_fixture_global, \
175 .termsig = _signal, \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200176 .timeout = TEST_TIMEOUT_DEFAULT, }; \
Kees Cookc99ee512015-06-16 10:54:14 -0700177 static void __attribute__((constructor)) _register_##test_name(void) \
178 { \
179 __register_test(&_##test_name##_object); \
180 } \
181 static void test_name( \
182 struct __test_metadata __attribute__((unused)) *_metadata)
183
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200184/**
185 * FIXTURE_DATA(datatype_name) - Wraps the struct name so we have one less
186 * argument to pass around
187 *
188 * @datatype_name: datatype name
189 *
190 * .. code-block:: c
191 *
192 * FIXTURE_DATA(datatype name)
193 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200194 * This call may be used when the type of the fixture data
195 * is needed. In general, this should not be needed unless
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200196 * the *self* is being passed to a helper directly.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200197 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200198#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
Kees Cookc99ee512015-06-16 10:54:14 -0700199
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200200/**
201 * FIXTURE(fixture_name) - Called once per fixture to setup the data and
202 * register
203 *
204 * @fixture_name: fixture name
205 *
206 * .. code-block:: c
207 *
208 * FIXTURE(datatype name) {
209 * type property1;
210 * ...
211 * };
212 *
213 * Defines the data provided to TEST_F()-defined tests as *self*. It should be
214 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().
Mickaël Salaün1256a522017-05-26 20:44:01 +0200215 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200216#define FIXTURE(fixture_name) \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700217 static struct __fixture_metadata _##fixture_name##_fixture_object = \
218 { .name = #fixture_name, }; \
Kees Cookc99ee512015-06-16 10:54:14 -0700219 static void __attribute__((constructor)) \
220 _register_##fixture_name##_data(void) \
221 { \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700222 __register_fixture(&_##fixture_name##_fixture_object); \
Kees Cookc99ee512015-06-16 10:54:14 -0700223 } \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200224 FIXTURE_DATA(fixture_name)
Kees Cookc99ee512015-06-16 10:54:14 -0700225
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200226/**
227 * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture.
Kees Cook6c3b6d52018-03-15 09:59:16 -0700228 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200229 *
230 * @fixture_name: fixture name
231 *
232 * .. code-block:: c
233 *
234 * FIXTURE_SETUP(fixture name) { implementation }
235 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200236 * Populates the required "setup" function for a fixture. An instance of the
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200237 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
Mickaël Salaün1256a522017-05-26 20:44:01 +0200238 * implementation.
239 *
240 * ASSERT_* are valid for use in this context and will prempt the execution
241 * of any dependent fixture tests.
242 *
243 * A bare "return;" statement may be used to return early.
244 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200245#define FIXTURE_SETUP(fixture_name) \
Kees Cookc99ee512015-06-16 10:54:14 -0700246 void fixture_name##_setup( \
247 struct __test_metadata __attribute__((unused)) *_metadata, \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200248 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200249/**
250 * FIXTURE_TEARDOWN(fixture_name)
Kees Cook6c3b6d52018-03-15 09:59:16 -0700251 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200252 *
253 * @fixture_name: fixture name
254 *
255 * .. code-block:: c
256 *
257 * FIXTURE_TEARDOWN(fixture name) { implementation }
258 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200259 * Populates the required "teardown" function for a fixture. An instance of the
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200260 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
Mickaël Salaün1256a522017-05-26 20:44:01 +0200261 * implementation to clean up.
262 *
263 * A bare "return;" statement may be used to return early.
264 */
265#define FIXTURE_TEARDOWN(fixture_name) \
Kees Cookc99ee512015-06-16 10:54:14 -0700266 void fixture_name##_teardown( \
267 struct __test_metadata __attribute__((unused)) *_metadata, \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200268 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
Kees Cookc99ee512015-06-16 10:54:14 -0700269
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200270/**
271 * TEST_F(fixture_name, test_name) - Emits test registration and helpers for
272 * fixture-based test cases
273 *
274 * @fixture_name: fixture name
275 * @test_name: test name
276 *
277 * .. code-block:: c
278 *
279 * TEST_F(fixture, name) { implementation }
280 *
Mickaël Salaün1256a522017-05-26 20:44:01 +0200281 * 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 +0200282 * Very similar to TEST() except that *self* is the setup instance of fixture's
Mickaël Salaün1256a522017-05-26 20:44:01 +0200283 * datatype exposed for use by the implementation.
Kees Cook6c3b6d52018-03-15 09:59:16 -0700284 *
285 * Warning: use of ASSERT_* here will skip TEARDOWN.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200286 */
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200287/* TODO(wad) register fixtures on dedicated test lists. */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200288#define TEST_F(fixture_name, test_name) \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200289 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
Kees Cookc99ee512015-06-16 10:54:14 -0700290
Mickaël Salaün1256a522017-05-26 20:44:01 +0200291#define TEST_F_SIGNAL(fixture_name, test_name, signal) \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200292 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
Kees Cookc99ee512015-06-16 10:54:14 -0700293
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200294#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
295 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
296
297#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
Kees Cookc99ee512015-06-16 10:54:14 -0700298 static void fixture_name##_##test_name( \
299 struct __test_metadata *_metadata, \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200300 FIXTURE_DATA(fixture_name) *self); \
Kees Cookc99ee512015-06-16 10:54:14 -0700301 static inline void wrapper_##fixture_name##_##test_name( \
302 struct __test_metadata *_metadata) \
303 { \
304 /* fixture data is alloced, setup, and torn down per call. */ \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200305 FIXTURE_DATA(fixture_name) self; \
306 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
Kees Cookc99ee512015-06-16 10:54:14 -0700307 fixture_name##_setup(_metadata, &self); \
308 /* Let setup failure terminate early. */ \
309 if (!_metadata->passed) \
310 return; \
311 fixture_name##_##test_name(_metadata, &self); \
312 fixture_name##_teardown(_metadata, &self); \
313 } \
314 static struct __test_metadata \
315 _##fixture_name##_##test_name##_object = { \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700316 .name = #test_name, \
Kees Cook121e3572019-01-27 01:42:51 -0800317 .fn = &wrapper_##fixture_name##_##test_name, \
Jakub Kicinski142aca62020-04-27 18:03:48 -0700318 .fixture = &_##fixture_name##_fixture_object, \
Kees Cook121e3572019-01-27 01:42:51 -0800319 .termsig = signal, \
Alexandre Bellonid51f1f12019-05-24 00:42:22 +0200320 .timeout = tmout, \
Kees Cookc99ee512015-06-16 10:54:14 -0700321 }; \
322 static void __attribute__((constructor)) \
323 _register_##fixture_name##_##test_name(void) \
324 { \
325 __register_test(&_##fixture_name##_##test_name##_object); \
326 } \
327 static void fixture_name##_##test_name( \
328 struct __test_metadata __attribute__((unused)) *_metadata, \
Mickaël Salaün1256a522017-05-26 20:44:01 +0200329 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
Kees Cookc99ee512015-06-16 10:54:14 -0700330
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200331/**
332 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness
333 *
334 * .. code-block:: c
335 *
336 * TEST_HARNESS_MAIN
337 *
338 * Use once to append a main() to the test file.
Mickaël Salaün1256a522017-05-26 20:44:01 +0200339 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200340#define TEST_HARNESS_MAIN \
Kees Cookc99ee512015-06-16 10:54:14 -0700341 static void __attribute__((constructor)) \
342 __constructor_order_last(void) \
343 { \
344 if (!__constructor_order) \
345 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
346 } \
347 int main(int argc, char **argv) { \
348 return test_harness_run(argc, argv); \
349 }
350
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200351/**
352 * DOC: operators
353 *
354 * Operators for use in TEST() and TEST_F().
Mickaël Salaün1256a522017-05-26 20:44:01 +0200355 * ASSERT_* calls will stop test execution immediately.
356 * EXPECT_* calls will emit a failure warning, note it, and continue.
357 */
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200358
359/**
360 * ASSERT_EQ(expected, seen)
361 *
362 * @expected: expected value
363 * @seen: measured value
364 *
365 * ASSERT_EQ(expected, measured): expected == measured
366 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200367#define ASSERT_EQ(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300368 __EXPECT(expected, #expected, seen, #seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200369
370/**
371 * ASSERT_NE(expected, seen)
372 *
373 * @expected: expected value
374 * @seen: measured value
375 *
376 * ASSERT_NE(expected, measured): expected != measured
377 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200378#define ASSERT_NE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300379 __EXPECT(expected, #expected, seen, #seen, !=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200380
381/**
382 * ASSERT_LT(expected, seen)
383 *
384 * @expected: expected value
385 * @seen: measured value
386 *
387 * ASSERT_LT(expected, measured): expected < measured
388 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200389#define ASSERT_LT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300390 __EXPECT(expected, #expected, seen, #seen, <, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200391
392/**
393 * ASSERT_LE(expected, seen)
394 *
395 * @expected: expected value
396 * @seen: measured value
397 *
398 * ASSERT_LE(expected, measured): expected <= measured
399 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200400#define ASSERT_LE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300401 __EXPECT(expected, #expected, seen, #seen, <=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200402
403/**
404 * ASSERT_GT(expected, seen)
405 *
406 * @expected: expected value
407 * @seen: measured value
408 *
409 * ASSERT_GT(expected, measured): expected > measured
410 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200411#define ASSERT_GT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300412 __EXPECT(expected, #expected, seen, #seen, >, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200413
414/**
415 * ASSERT_GE(expected, seen)
416 *
417 * @expected: expected value
418 * @seen: measured value
419 *
420 * ASSERT_GE(expected, measured): expected >= measured
421 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200422#define ASSERT_GE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300423 __EXPECT(expected, #expected, seen, #seen, >=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200424
425/**
426 * ASSERT_NULL(seen)
427 *
428 * @seen: measured value
429 *
430 * ASSERT_NULL(measured): NULL == measured
431 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200432#define ASSERT_NULL(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300433 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
Kees Cookc99ee512015-06-16 10:54:14 -0700434
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200435/**
436 * ASSERT_TRUE(seen)
437 *
438 * @seen: measured value
439 *
440 * ASSERT_TRUE(measured): measured != 0
441 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200442#define ASSERT_TRUE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300443 __EXPECT(0, "0", seen, #seen, !=, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200444
445/**
446 * ASSERT_FALSE(seen)
447 *
448 * @seen: measured value
449 *
450 * ASSERT_FALSE(measured): measured == 0
451 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200452#define ASSERT_FALSE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300453 __EXPECT(0, "0", seen, #seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200454
455/**
456 * ASSERT_STREQ(expected, seen)
457 *
458 * @expected: expected value
459 * @seen: measured value
460 *
461 * ASSERT_STREQ(expected, measured): !strcmp(expected, measured)
462 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200463#define ASSERT_STREQ(expected, seen) \
464 __EXPECT_STR(expected, seen, ==, 1)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200465
466/**
467 * ASSERT_STRNE(expected, seen)
468 *
469 * @expected: expected value
470 * @seen: measured value
471 *
472 * ASSERT_STRNE(expected, measured): strcmp(expected, measured)
473 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200474#define ASSERT_STRNE(expected, seen) \
475 __EXPECT_STR(expected, seen, !=, 1)
Kees Cookc99ee512015-06-16 10:54:14 -0700476
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200477/**
478 * EXPECT_EQ(expected, seen)
479 *
480 * @expected: expected value
481 * @seen: measured value
482 *
483 * EXPECT_EQ(expected, measured): expected == measured
484 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200485#define EXPECT_EQ(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300486 __EXPECT(expected, #expected, seen, #seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200487
488/**
489 * EXPECT_NE(expected, seen)
490 *
491 * @expected: expected value
492 * @seen: measured value
493 *
494 * EXPECT_NE(expected, measured): expected != measured
495 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200496#define EXPECT_NE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300497 __EXPECT(expected, #expected, seen, #seen, !=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200498
499/**
500 * EXPECT_LT(expected, seen)
501 *
502 * @expected: expected value
503 * @seen: measured value
504 *
505 * EXPECT_LT(expected, measured): expected < measured
506 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200507#define EXPECT_LT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300508 __EXPECT(expected, #expected, seen, #seen, <, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200509
510/**
511 * EXPECT_LE(expected, seen)
512 *
513 * @expected: expected value
514 * @seen: measured value
515 *
516 * EXPECT_LE(expected, measured): expected <= measured
517 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200518#define EXPECT_LE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300519 __EXPECT(expected, #expected, seen, #seen, <=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200520
521/**
522 * EXPECT_GT(expected, seen)
523 *
524 * @expected: expected value
525 * @seen: measured value
526 *
527 * EXPECT_GT(expected, measured): expected > measured
528 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200529#define EXPECT_GT(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300530 __EXPECT(expected, #expected, seen, #seen, >, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200531
532/**
533 * EXPECT_GE(expected, seen)
534 *
535 * @expected: expected value
536 * @seen: measured value
537 *
538 * EXPECT_GE(expected, measured): expected >= measured
539 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200540#define EXPECT_GE(expected, seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300541 __EXPECT(expected, #expected, seen, #seen, >=, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700542
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200543/**
544 * EXPECT_NULL(seen)
545 *
546 * @seen: measured value
547 *
548 * EXPECT_NULL(measured): NULL == measured
549 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200550#define EXPECT_NULL(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300551 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200552
553/**
554 * EXPECT_TRUE(seen)
555 *
556 * @seen: measured value
557 *
558 * EXPECT_TRUE(measured): 0 != measured
559 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200560#define EXPECT_TRUE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300561 __EXPECT(0, "0", seen, #seen, !=, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200562
563/**
564 * EXPECT_FALSE(seen)
565 *
566 * @seen: measured value
567 *
568 * EXPECT_FALSE(measured): 0 == measured
569 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200570#define EXPECT_FALSE(seen) \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300571 __EXPECT(0, "0", seen, #seen, ==, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700572
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200573/**
574 * EXPECT_STREQ(expected, seen)
575 *
576 * @expected: expected value
577 * @seen: measured value
578 *
579 * EXPECT_STREQ(expected, measured): !strcmp(expected, measured)
580 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200581#define EXPECT_STREQ(expected, seen) \
582 __EXPECT_STR(expected, seen, ==, 0)
Mickaël Salaün7e6a32a2017-06-05 20:37:17 +0200583
584/**
585 * EXPECT_STRNE(expected, seen)
586 *
587 * @expected: expected value
588 * @seen: measured value
589 *
590 * EXPECT_STRNE(expected, measured): strcmp(expected, measured)
591 */
Mickaël Salaün1256a522017-05-26 20:44:01 +0200592#define EXPECT_STRNE(expected, seen) \
593 __EXPECT_STR(expected, seen, !=, 0)
Kees Cookc99ee512015-06-16 10:54:14 -0700594
595#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
596
597/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is
598 * not thread-safe, but it should be fine in most sane test scenarios.
599 *
600 * Using __bail(), which optionally abort()s, is the easiest way to early
601 * return while still providing an optional block to the API consumer.
602 */
603#define OPTIONAL_HANDLER(_assert) \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200604 for (; _metadata->trigger; _metadata->trigger = \
605 __bail(_assert, _metadata->no_print, _metadata->step))
606
607#define __INC_STEP(_metadata) \
608 if (_metadata->passed && _metadata->step < 255) \
609 _metadata->step++;
Kees Cookc99ee512015-06-16 10:54:14 -0700610
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300611#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
Kees Cookc99ee512015-06-16 10:54:14 -0700612 /* Avoid multiple evaluation of the cases */ \
613 __typeof__(_expected) __exp = (_expected); \
614 __typeof__(_seen) __seen = (_seen); \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200615 if (_assert) __INC_STEP(_metadata); \
Kees Cookc99ee512015-06-16 10:54:14 -0700616 if (!(__exp _t __seen)) { \
Kees Cookb5bb6d32015-12-10 14:50:25 -0800617 unsigned long long __exp_print = (uintptr_t)__exp; \
618 unsigned long long __seen_print = (uintptr_t)__seen; \
Kees Cookc99ee512015-06-16 10:54:14 -0700619 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
Dmitry V. Levinb708a3cc2018-12-10 02:00:47 +0300620 _expected_str, __exp_print, #_t, \
621 _seen_str, __seen_print); \
Kees Cookc99ee512015-06-16 10:54:14 -0700622 _metadata->passed = 0; \
623 /* Ensure the optional handler is triggered */ \
624 _metadata->trigger = 1; \
625 } \
626} while (0); OPTIONAL_HANDLER(_assert)
627
628#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
629 const char *__exp = (_expected); \
630 const char *__seen = (_seen); \
Mickaël Salaün369130b2017-08-07 01:23:37 +0200631 if (_assert) __INC_STEP(_metadata); \
Kees Cookc99ee512015-06-16 10:54:14 -0700632 if (!(strcmp(__exp, __seen) _t 0)) { \
633 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
634 _metadata->passed = 0; \
635 _metadata->trigger = 1; \
636 } \
637} while (0); OPTIONAL_HANDLER(_assert)
638
Jakub Kicinski1a895952020-04-27 18:03:47 -0700639/* List helpers */
640#define __LIST_APPEND(head, item) \
641{ \
642 /* Circular linked list where only prev is circular. */ \
643 if (head == NULL) { \
644 head = item; \
645 item->next = NULL; \
646 item->prev = item; \
647 return; \
648 } \
649 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
650 item->next = NULL; \
651 item->prev = head->prev; \
652 item->prev->next = item; \
653 head->prev = item; \
654 } else { \
655 item->next = head; \
656 item->next->prev = item; \
657 item->prev = item; \
658 head = item; \
659 } \
660}
661
Jakub Kicinski142aca62020-04-27 18:03:48 -0700662/* Contains all the information about a fixture. */
663struct __fixture_metadata {
664 const char *name;
665 struct __fixture_metadata *prev, *next;
666} _fixture_global __attribute__((unused)) = {
667 .name = "global",
668 .prev = &_fixture_global,
669};
670
671static struct __fixture_metadata *__fixture_list = &_fixture_global;
672static unsigned int __fixture_count;
673static int __constructor_order;
674
675#define _CONSTRUCTOR_ORDER_FORWARD 1
676#define _CONSTRUCTOR_ORDER_BACKWARD -1
677
678static inline void __register_fixture(struct __fixture_metadata *f)
679{
680 __fixture_count++;
681 __LIST_APPEND(__fixture_list, f);
682}
683
Kees Cookc99ee512015-06-16 10:54:14 -0700684/* Contains all the information for test execution and status checking. */
685struct __test_metadata {
686 const char *name;
687 void (*fn)(struct __test_metadata *);
Kees Cookf46f5762020-03-13 16:12:51 -0700688 pid_t pid; /* pid of test when being run */
Jakub Kicinski142aca62020-04-27 18:03:48 -0700689 struct __fixture_metadata *fixture;
Kees Cookc99ee512015-06-16 10:54:14 -0700690 int termsig;
691 int passed;
692 int trigger; /* extra handler after the evaluation */
Kees Cookc31801d2020-03-13 16:12:52 -0700693 int timeout; /* seconds to wait for test timeout */
694 bool timed_out; /* did this test timeout instead of exiting? */
Mickaël Salaün369130b2017-08-07 01:23:37 +0200695 __u8 step;
696 bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
Kees Cookc99ee512015-06-16 10:54:14 -0700697 struct __test_metadata *prev, *next;
698};
699
700/* Storage for the (global) tests to be run. */
701static struct __test_metadata *__test_list;
702static unsigned int __test_count;
Kees Cookc99ee512015-06-16 10:54:14 -0700703
704/*
705 * Since constructors are called in reverse order, reverse the test
706 * list so tests are run in source declaration order.
707 * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
708 * However, it seems not all toolchains do this correctly, so use
709 * __constructor_order to detect which direction is called first
710 * and adjust list building logic to get things running in the right
711 * direction.
712 */
713static inline void __register_test(struct __test_metadata *t)
714{
715 __test_count++;
Jakub Kicinski1a895952020-04-27 18:03:47 -0700716 __LIST_APPEND(__test_list, t);
Kees Cookc99ee512015-06-16 10:54:14 -0700717}
718
Mickaël Salaün369130b2017-08-07 01:23:37 +0200719static inline int __bail(int for_realz, bool no_print, __u8 step)
Kees Cookc99ee512015-06-16 10:54:14 -0700720{
Mickaël Salaün369130b2017-08-07 01:23:37 +0200721 if (for_realz) {
722 if (no_print)
723 _exit(step);
Kees Cookc99ee512015-06-16 10:54:14 -0700724 abort();
Mickaël Salaün369130b2017-08-07 01:23:37 +0200725 }
Kees Cookc99ee512015-06-16 10:54:14 -0700726 return 0;
727}
728
Kees Cookc31801d2020-03-13 16:12:52 -0700729struct __test_metadata *__active_test;
730static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
731{
732 struct __test_metadata *t = __active_test;
733
734 /* Sanity check handler execution environment. */
735 if (!t) {
736 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000737 "no active test in SIGALRM handler!?\n");
Kees Cookc31801d2020-03-13 16:12:52 -0700738 abort();
739 }
740 if (sig != SIGALRM || sig != info->si_signo) {
741 fprintf(TH_LOG_STREAM,
742 "%s: SIGALRM handler caught signal %d!?\n",
743 t->name, sig != SIGALRM ? sig : info->si_signo);
744 abort();
745 }
746
747 t->timed_out = true;
748 kill(t->pid, SIGKILL);
749}
750
Kees Cookf46f5762020-03-13 16:12:51 -0700751void __wait_for_test(struct __test_metadata *t)
Kees Cookc99ee512015-06-16 10:54:14 -0700752{
Kees Cookc31801d2020-03-13 16:12:52 -0700753 struct sigaction action = {
754 .sa_sigaction = __timeout_handler,
755 .sa_flags = SA_SIGINFO,
756 };
757 struct sigaction saved_action;
Kees Cookc99ee512015-06-16 10:54:14 -0700758 int status;
759
Kees Cookc31801d2020-03-13 16:12:52 -0700760 if (sigaction(SIGALRM, &action, &saved_action)) {
761 t->passed = 0;
762 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000763 "%s: unable to install SIGALRM handler\n",
Kees Cookc31801d2020-03-13 16:12:52 -0700764 t->name);
765 return;
766 }
767 __active_test = t;
768 t->timed_out = false;
Kees Cookf46f5762020-03-13 16:12:51 -0700769 alarm(t->timeout);
770 waitpid(t->pid, &status, 0);
771 alarm(0);
Kees Cookc31801d2020-03-13 16:12:52 -0700772 if (sigaction(SIGALRM, &saved_action, NULL)) {
773 t->passed = 0;
774 fprintf(TH_LOG_STREAM,
Colin Ian Kingd925c892020-03-27 09:06:48 +0000775 "%s: unable to uninstall SIGALRM handler\n",
Kees Cookc31801d2020-03-13 16:12:52 -0700776 t->name);
777 return;
778 }
779 __active_test = NULL;
Kees Cookf46f5762020-03-13 16:12:51 -0700780
Kees Cookc31801d2020-03-13 16:12:52 -0700781 if (t->timed_out) {
782 t->passed = 0;
783 fprintf(TH_LOG_STREAM,
784 "%s: Test terminated by timeout\n", t->name);
785 } else if (WIFEXITED(status)) {
Kees Cookf46f5762020-03-13 16:12:51 -0700786 t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
787 if (t->termsig != -1) {
788 fprintf(TH_LOG_STREAM,
789 "%s: Test exited normally "
790 "instead of by signal (code: %d)\n",
791 t->name,
792 WEXITSTATUS(status));
793 } else if (!t->passed) {
794 fprintf(TH_LOG_STREAM,
795 "%s: Test failed at step #%d\n",
796 t->name,
797 WEXITSTATUS(status));
798 }
799 } else if (WIFSIGNALED(status)) {
800 t->passed = 0;
801 if (WTERMSIG(status) == SIGABRT) {
802 fprintf(TH_LOG_STREAM,
803 "%s: Test terminated by assertion\n",
804 t->name);
805 } else if (WTERMSIG(status) == t->termsig) {
806 t->passed = 1;
807 } else {
808 fprintf(TH_LOG_STREAM,
809 "%s: Test terminated unexpectedly "
810 "by signal %d\n",
811 t->name,
812 WTERMSIG(status));
813 }
814 } else {
815 fprintf(TH_LOG_STREAM,
816 "%s: Test ended in some other way [%u]\n",
817 t->name,
818 status);
819 }
820}
821
Jakub Kicinski142aca62020-04-27 18:03:48 -0700822void __run_test(struct __fixture_metadata *f,
823 struct __test_metadata *t)
Kees Cookf46f5762020-03-13 16:12:51 -0700824{
Kees Cookc99ee512015-06-16 10:54:14 -0700825 t->passed = 1;
826 t->trigger = 0;
Jakub Kicinski142aca62020-04-27 18:03:48 -0700827 printf("[ RUN ] %s.%s\n", f->name, t->name);
Kees Cookf46f5762020-03-13 16:12:51 -0700828 t->pid = fork();
829 if (t->pid < 0) {
Kees Cookc99ee512015-06-16 10:54:14 -0700830 printf("ERROR SPAWNING TEST CHILD\n");
831 t->passed = 0;
Kees Cookf46f5762020-03-13 16:12:51 -0700832 } else if (t->pid == 0) {
Kees Cookc99ee512015-06-16 10:54:14 -0700833 t->fn(t);
Mickaël Salaün369130b2017-08-07 01:23:37 +0200834 /* return the step that failed or 0 */
835 _exit(t->passed ? 0 : t->step);
Kees Cookc99ee512015-06-16 10:54:14 -0700836 } else {
Kees Cookf46f5762020-03-13 16:12:51 -0700837 __wait_for_test(t);
Kees Cookc99ee512015-06-16 10:54:14 -0700838 }
Jakub Kicinski142aca62020-04-27 18:03:48 -0700839 printf("[ %4s ] %s.%s\n", (t->passed ? "OK" : "FAIL"),
840 f->name, t->name);
Kees Cookc99ee512015-06-16 10:54:14 -0700841}
842
843static int test_harness_run(int __attribute__((unused)) argc,
844 char __attribute__((unused)) **argv)
845{
846 struct __test_metadata *t;
847 int ret = 0;
848 unsigned int count = 0;
849 unsigned int pass_count = 0;
850
851 /* TODO(wad) add optional arguments similar to gtest. */
852 printf("[==========] Running %u tests from %u test cases.\n",
853 __test_count, __fixture_count + 1);
854 for (t = __test_list; t; t = t->next) {
855 count++;
Jakub Kicinski142aca62020-04-27 18:03:48 -0700856 __run_test(t->fixture, t);
Kees Cookc99ee512015-06-16 10:54:14 -0700857 if (t->passed)
858 pass_count++;
859 else
860 ret = 1;
861 }
862 printf("[==========] %u / %u tests passed.\n", pass_count, count);
863 printf("[ %s ]\n", (ret ? "FAILED" : "PASSED"));
864 return ret;
865}
866
867static void __attribute__((constructor)) __constructor_order_first(void)
868{
869 if (!__constructor_order)
870 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
871}
872
Mickaël Salaündfa47d32017-05-26 20:43:57 +0200873#endif /* __KSELFTEST_HARNESS_H */