1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
5 * kselftest_harness.h: simple C unit test helper.
7 * See documentation in Documentation/dev-tools/kselftest.rst
9 * API inspired by code.google.com/p/googletest
17 * #include "../kselftest_harness.h"
19 * TEST(standalone_test) {
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);
27 * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!");
29 * EXPECT_EQ(0, last_stuff);
32 * FIXTURE(my_fixture) {
34 * int awesomeness_level;
36 * FIXTURE_SETUP(my_fixture) {
37 * self->data = mytype_new();
38 * ASSERT_NE(NULL, self->data);
40 * FIXTURE_TEARDOWN(my_fixture) {
41 * mytype_free(self->data);
43 * TEST_F(my_fixture, data_is_good) {
44 * EXPECT_EQ(1, is_my_data_good(self->data));
50 #ifndef __KSELFTEST_HARNESS_H
51 #define __KSELFTEST_HARNESS_H
56 #include <asm/types.h>
66 #include <sys/types.h>
71 #include "kselftest.h"
73 #define TEST_TIMEOUT_DEFAULT 30
75 /* Utilities exposed to the test definitions */
77 # define TH_LOG_STREAM stderr
80 #ifndef TH_LOG_ENABLED
81 # define TH_LOG_ENABLED 1
88 * @...: optional arguments
94 * Optional debug logging function available for use in tests.
95 * Logging may be enabled or disabled by defining TH_LOG_ENABLED.
96 * E.g., #define TH_LOG_ENABLED 1
98 * If no definition is provided, logging is enabled by default.
100 #define TH_LOG(fmt, ...) do { \
101 if (TH_LOG_ENABLED) \
102 __TH_LOG(fmt, ##__VA_ARGS__); \
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__)
113 * @statement: statement to run after reporting SKIP
114 * @fmt: format string
115 * @...: optional arguments
119 * SKIP(statement, fmt, ...);
121 * This forces a "pass" after reporting why something is being skipped
122 * and runs "statement", which is usually "return" or "goto skip".
124 #define SKIP(statement, fmt, ...) do { \
125 snprintf(_metadata->results->reason, \
126 sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \
127 if (TH_LOG_ENABLED) { \
128 fprintf(TH_LOG_STREAM, "# SKIP %s\n", \
129 _metadata->results->reason); \
131 _metadata->exit_code = KSFT_SKIP; \
132 _metadata->trigger = 0; \
137 * TEST() - Defines the test function and creates the registration
140 * @test_name: test name
144 * TEST(name) { implementation }
146 * Defines a test by name.
147 * Names must be unique and tests must not be run in parallel. The
148 * implementation containing block is a function and scoping should be treated
149 * as such. Returning early may be performed with a bare "return;" statement.
151 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
153 #define TEST(test_name) __TEST_IMPL(test_name, -1)
158 * @test_name: test name
159 * @signal: signal number
163 * TEST_SIGNAL(name, signal) { implementation }
165 * Defines a test by name and the expected term signal.
166 * Names must be unique and tests must not be run in parallel. The
167 * implementation containing block is a function and scoping should be treated
168 * as such. Returning early may be performed with a bare "return;" statement.
170 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
172 #define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
174 #define __TEST_IMPL(test_name, _signal) \
175 static void test_name(struct __test_metadata *_metadata); \
176 static inline void wrapper_##test_name( \
177 struct __test_metadata *_metadata, \
178 struct __fixture_variant_metadata *variant) \
180 _metadata->setup_completed = true; \
181 if (setjmp(_metadata->env) == 0) \
182 test_name(_metadata); \
183 __test_check_assert(_metadata); \
185 static struct __test_metadata _##test_name##_object = \
186 { .name = #test_name, \
187 .fn = &wrapper_##test_name, \
188 .fixture = &_fixture_global, \
189 .termsig = _signal, \
190 .timeout = TEST_TIMEOUT_DEFAULT, }; \
191 static void __attribute__((constructor)) _register_##test_name(void) \
193 __register_test(&_##test_name##_object); \
195 static void test_name( \
196 struct __test_metadata __attribute__((unused)) *_metadata)
199 * FIXTURE_DATA() - Wraps the struct name so we have one less
200 * argument to pass around
202 * @datatype_name: datatype name
206 * FIXTURE_DATA(datatype_name)
208 * Almost always, you want just FIXTURE() instead (see below).
209 * This call may be used when the type of the fixture data
210 * is needed. In general, this should not be needed unless
211 * the *self* is being passed to a helper directly.
213 #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
216 * FIXTURE() - Called once per fixture to setup the data and
219 * @fixture_name: fixture name
223 * FIXTURE(fixture_name) {
228 * Defines the data provided to TEST_F()-defined tests as *self*. It should be
229 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().
231 #define FIXTURE(fixture_name) \
232 FIXTURE_VARIANT(fixture_name); \
233 static struct __fixture_metadata _##fixture_name##_fixture_object = \
234 { .name = #fixture_name, }; \
235 static void __attribute__((constructor)) \
236 _register_##fixture_name##_data(void) \
238 __register_fixture(&_##fixture_name##_fixture_object); \
240 FIXTURE_DATA(fixture_name)
243 * FIXTURE_SETUP() - Prepares the setup function for the fixture.
244 * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.
246 * @fixture_name: fixture name
250 * FIXTURE_SETUP(fixture_name) { implementation }
252 * Populates the required "setup" function for a fixture. An instance of the
253 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
256 * ASSERT_* are valid for use in this context and will prempt the execution
257 * of any dependent fixture tests.
259 * A bare "return;" statement may be used to return early.
261 #define FIXTURE_SETUP(fixture_name) \
262 void fixture_name##_setup( \
263 struct __test_metadata __attribute__((unused)) *_metadata, \
264 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
265 const FIXTURE_VARIANT(fixture_name) \
266 __attribute__((unused)) *variant)
270 * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.
272 * @fixture_name: fixture name
276 * FIXTURE_TEARDOWN(fixture_name) { implementation }
278 * Populates the required "teardown" function for a fixture. An instance of the
279 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
280 * implementation to clean up.
282 * A bare "return;" statement may be used to return early.
284 #define FIXTURE_TEARDOWN(fixture_name) \
285 void fixture_name##_teardown( \
286 struct __test_metadata __attribute__((unused)) *_metadata, \
287 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
288 const FIXTURE_VARIANT(fixture_name) \
289 __attribute__((unused)) *variant)
292 * FIXTURE_VARIANT() - Optionally called once per fixture
293 * to declare fixture variant
295 * @fixture_name: fixture name
299 * FIXTURE_VARIANT(fixture_name) {
304 * Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and
305 * FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with
306 * different arguments.
308 #define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
311 * FIXTURE_VARIANT_ADD() - Called once per fixture
312 * variant to setup and register the data
314 * @fixture_name: fixture name
315 * @variant_name: name of the parameter set
319 * FIXTURE_VARIANT_ADD(fixture_name, variant_name) {
324 * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and
325 * TEST_F() as *variant*. Tests of each fixture will be run once for each
328 #define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
329 extern FIXTURE_VARIANT(fixture_name) \
330 _##fixture_name##_##variant_name##_variant; \
331 static struct __fixture_variant_metadata \
332 _##fixture_name##_##variant_name##_object = \
333 { .name = #variant_name, \
334 .data = &_##fixture_name##_##variant_name##_variant}; \
335 static void __attribute__((constructor)) \
336 _register_##fixture_name##_##variant_name(void) \
338 __register_fixture_variant(&_##fixture_name##_fixture_object, \
339 &_##fixture_name##_##variant_name##_object); \
341 FIXTURE_VARIANT(fixture_name) \
342 _##fixture_name##_##variant_name##_variant =
345 * TEST_F() - Emits test registration and helpers for
346 * fixture-based test cases
348 * @fixture_name: fixture name
349 * @test_name: test name
353 * TEST_F(fixture, name) { implementation }
355 * Defines a test that depends on a fixture (e.g., is part of a test case).
356 * Very similar to TEST() except that *self* is the setup instance of fixture's
357 * datatype exposed for use by the implementation.
359 * The @test_name code is run in a separate process sharing the same memory
360 * (i.e. vfork), which means that the test process can update its privileges
361 * without impacting the related FIXTURE_TEARDOWN() (e.g. to remove files from
362 * a directory where write access was dropped).
364 #define TEST_F(fixture_name, test_name) \
365 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
367 #define TEST_F_SIGNAL(fixture_name, test_name, signal) \
368 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
370 #define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
371 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
373 #define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
374 static void fixture_name##_##test_name( \
375 struct __test_metadata *_metadata, \
376 FIXTURE_DATA(fixture_name) *self, \
377 const FIXTURE_VARIANT(fixture_name) *variant); \
378 static inline void wrapper_##fixture_name##_##test_name( \
379 struct __test_metadata *_metadata, \
380 struct __fixture_variant_metadata *variant) \
382 /* fixture data is alloced, setup, and torn down per call. */ \
383 FIXTURE_DATA(fixture_name) self; \
387 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
388 if (setjmp(_metadata->env) == 0) { \
389 /* Use the same _metadata. */ \
392 fixture_name##_setup(_metadata, &self, variant->data); \
393 /* Let setup failure terminate early. */ \
394 if (_metadata->exit_code) \
396 _metadata->setup_completed = true; \
397 fixture_name##_##test_name(_metadata, &self, variant->data); \
398 } else if (child < 0 || child != waitpid(child, &status, 0)) { \
399 ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
400 _metadata->exit_code = KSFT_FAIL; \
406 if (_metadata->setup_completed && !_metadata->teardown_parent && !jmp) \
407 fixture_name##_teardown(_metadata, &self, variant->data); \
410 if (_metadata->setup_completed && _metadata->teardown_parent) \
411 fixture_name##_teardown(_metadata, &self, variant->data); \
412 if (!WIFEXITED(status) && WIFSIGNALED(status)) \
413 /* Forward signal to __wait_for_test(). */ \
414 kill(getpid(), WTERMSIG(status)); \
415 __test_check_assert(_metadata); \
417 static struct __test_metadata \
418 _##fixture_name##_##test_name##_object = { \
419 .name = #test_name, \
420 .fn = &wrapper_##fixture_name##_##test_name, \
421 .fixture = &_##fixture_name##_fixture_object, \
424 .teardown_parent = false, \
426 static void __attribute__((constructor)) \
427 _register_##fixture_name##_##test_name(void) \
429 __register_test(&_##fixture_name##_##test_name##_object); \
431 static void fixture_name##_##test_name( \
432 struct __test_metadata __attribute__((unused)) *_metadata, \
433 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
434 const FIXTURE_VARIANT(fixture_name) \
435 __attribute__((unused)) *variant)
438 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness
444 * Use once to append a main() to the test file.
446 #define TEST_HARNESS_MAIN \
447 static void __attribute__((constructor)) \
448 __constructor_order_last(void) \
450 if (!__constructor_order) \
451 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
453 int main(int argc, char **argv) { \
454 return test_harness_run(argc, argv); \
460 * Operators for use in TEST() and TEST_F().
461 * ASSERT_* calls will stop test execution immediately.
462 * EXPECT_* calls will emit a failure warning, note it, and continue.
468 * @expected: expected value
469 * @seen: measured value
471 * ASSERT_EQ(expected, measured): expected == measured
473 #define ASSERT_EQ(expected, seen) \
474 __EXPECT(expected, #expected, seen, #seen, ==, 1)
479 * @expected: expected value
480 * @seen: measured value
482 * ASSERT_NE(expected, measured): expected != measured
484 #define ASSERT_NE(expected, seen) \
485 __EXPECT(expected, #expected, seen, #seen, !=, 1)
490 * @expected: expected value
491 * @seen: measured value
493 * ASSERT_LT(expected, measured): expected < measured
495 #define ASSERT_LT(expected, seen) \
496 __EXPECT(expected, #expected, seen, #seen, <, 1)
501 * @expected: expected value
502 * @seen: measured value
504 * ASSERT_LE(expected, measured): expected <= measured
506 #define ASSERT_LE(expected, seen) \
507 __EXPECT(expected, #expected, seen, #seen, <=, 1)
512 * @expected: expected value
513 * @seen: measured value
515 * ASSERT_GT(expected, measured): expected > measured
517 #define ASSERT_GT(expected, seen) \
518 __EXPECT(expected, #expected, seen, #seen, >, 1)
523 * @expected: expected value
524 * @seen: measured value
526 * ASSERT_GE(expected, measured): expected >= measured
528 #define ASSERT_GE(expected, seen) \
529 __EXPECT(expected, #expected, seen, #seen, >=, 1)
534 * @seen: measured value
536 * ASSERT_NULL(measured): NULL == measured
538 #define ASSERT_NULL(seen) \
539 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
544 * @seen: measured value
546 * ASSERT_TRUE(measured): measured != 0
548 #define ASSERT_TRUE(seen) \
549 __EXPECT(0, "0", seen, #seen, !=, 1)
554 * @seen: measured value
556 * ASSERT_FALSE(measured): measured == 0
558 #define ASSERT_FALSE(seen) \
559 __EXPECT(0, "0", seen, #seen, ==, 1)
564 * @expected: expected value
565 * @seen: measured value
567 * ASSERT_STREQ(expected, measured): !strcmp(expected, measured)
569 #define ASSERT_STREQ(expected, seen) \
570 __EXPECT_STR(expected, seen, ==, 1)
575 * @expected: expected value
576 * @seen: measured value
578 * ASSERT_STRNE(expected, measured): strcmp(expected, measured)
580 #define ASSERT_STRNE(expected, seen) \
581 __EXPECT_STR(expected, seen, !=, 1)
586 * @expected: expected value
587 * @seen: measured value
589 * EXPECT_EQ(expected, measured): expected == measured
591 #define EXPECT_EQ(expected, seen) \
592 __EXPECT(expected, #expected, seen, #seen, ==, 0)
597 * @expected: expected value
598 * @seen: measured value
600 * EXPECT_NE(expected, measured): expected != measured
602 #define EXPECT_NE(expected, seen) \
603 __EXPECT(expected, #expected, seen, #seen, !=, 0)
608 * @expected: expected value
609 * @seen: measured value
611 * EXPECT_LT(expected, measured): expected < measured
613 #define EXPECT_LT(expected, seen) \
614 __EXPECT(expected, #expected, seen, #seen, <, 0)
619 * @expected: expected value
620 * @seen: measured value
622 * EXPECT_LE(expected, measured): expected <= measured
624 #define EXPECT_LE(expected, seen) \
625 __EXPECT(expected, #expected, seen, #seen, <=, 0)
630 * @expected: expected value
631 * @seen: measured value
633 * EXPECT_GT(expected, measured): expected > measured
635 #define EXPECT_GT(expected, seen) \
636 __EXPECT(expected, #expected, seen, #seen, >, 0)
641 * @expected: expected value
642 * @seen: measured value
644 * EXPECT_GE(expected, measured): expected >= measured
646 #define EXPECT_GE(expected, seen) \
647 __EXPECT(expected, #expected, seen, #seen, >=, 0)
652 * @seen: measured value
654 * EXPECT_NULL(measured): NULL == measured
656 #define EXPECT_NULL(seen) \
657 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
662 * @seen: measured value
664 * EXPECT_TRUE(measured): 0 != measured
666 #define EXPECT_TRUE(seen) \
667 __EXPECT(0, "0", seen, #seen, !=, 0)
672 * @seen: measured value
674 * EXPECT_FALSE(measured): 0 == measured
676 #define EXPECT_FALSE(seen) \
677 __EXPECT(0, "0", seen, #seen, ==, 0)
682 * @expected: expected value
683 * @seen: measured value
685 * EXPECT_STREQ(expected, measured): !strcmp(expected, measured)
687 #define EXPECT_STREQ(expected, seen) \
688 __EXPECT_STR(expected, seen, ==, 0)
693 * @expected: expected value
694 * @seen: measured value
696 * EXPECT_STRNE(expected, measured): strcmp(expected, measured)
698 #define EXPECT_STRNE(expected, seen) \
699 __EXPECT_STR(expected, seen, !=, 0)
702 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
705 /* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is
706 * not thread-safe, but it should be fine in most sane test scenarios.
708 * Using __bail(), which optionally abort()s, is the easiest way to early
709 * return while still providing an optional block to the API consumer.
711 #define OPTIONAL_HANDLER(_assert) \
712 for (; _metadata->trigger; _metadata->trigger = \
713 __bail(_assert, _metadata))
715 #define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
717 #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
718 /* Avoid multiple evaluation of the cases */ \
719 __typeof__(_expected) __exp = (_expected); \
720 __typeof__(_seen) __seen = (_seen); \
721 if (!(__exp _t __seen)) { \
722 /* Report with actual signedness to avoid weird output. */ \
723 switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \
725 unsigned long long __exp_print = (uintptr_t)__exp; \
726 unsigned long long __seen_print = (uintptr_t)__seen; \
727 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
728 _expected_str, __exp_print, #_t, \
729 _seen_str, __seen_print); \
733 unsigned long long __exp_print = (uintptr_t)__exp; \
734 long long __seen_print = (intptr_t)__seen; \
735 __TH_LOG("Expected %s (%llu) %s %s (%lld)", \
736 _expected_str, __exp_print, #_t, \
737 _seen_str, __seen_print); \
741 long long __exp_print = (intptr_t)__exp; \
742 unsigned long long __seen_print = (uintptr_t)__seen; \
743 __TH_LOG("Expected %s (%lld) %s %s (%llu)", \
744 _expected_str, __exp_print, #_t, \
745 _seen_str, __seen_print); \
749 long long __exp_print = (intptr_t)__exp; \
750 long long __seen_print = (intptr_t)__seen; \
751 __TH_LOG("Expected %s (%lld) %s %s (%lld)", \
752 _expected_str, __exp_print, #_t, \
753 _seen_str, __seen_print); \
757 _metadata->exit_code = KSFT_FAIL; \
758 /* Ensure the optional handler is triggered */ \
759 _metadata->trigger = 1; \
761 } while (0); OPTIONAL_HANDLER(_assert)
763 #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
764 const char *__exp = (_expected); \
765 const char *__seen = (_seen); \
766 if (!(strcmp(__exp, __seen) _t 0)) { \
767 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
768 _metadata->exit_code = KSFT_FAIL; \
769 _metadata->trigger = 1; \
771 } while (0); OPTIONAL_HANDLER(_assert)
774 #define __LIST_APPEND(head, item) \
776 /* Circular linked list where only prev is circular. */ \
777 if (head == NULL) { \
783 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
785 item->prev = head->prev; \
786 item->prev->next = item; \
790 item->next->prev = item; \
796 struct __test_results {
797 char reason[1024]; /* Reason for test result */
800 struct __test_metadata;
801 struct __fixture_variant_metadata;
803 /* Contains all the information about a fixture. */
804 struct __fixture_metadata {
806 struct __test_metadata *tests;
807 struct __fixture_variant_metadata *variant;
808 struct __fixture_metadata *prev, *next;
809 } _fixture_global __attribute__((unused)) = {
811 .prev = &_fixture_global,
814 struct __test_xfail {
815 struct __fixture_metadata *fixture;
816 struct __fixture_variant_metadata *variant;
817 struct __test_metadata *test;
818 struct __test_xfail *prev, *next;
822 * XFAIL_ADD() - mark variant + test case combination as expected to fail
823 * @fixture_name: name of the fixture
824 * @variant_name: name of the variant
825 * @test_name: name of the test case
827 * Mark a combination of variant + test case for a given fixture as expected
828 * to fail. Tests marked this way will report XPASS / XFAIL return codes,
829 * instead of PASS / FAIL,and use respective counters.
831 #define XFAIL_ADD(fixture_name, variant_name, test_name) \
832 static struct __test_xfail \
833 _##fixture_name##_##variant_name##_##test_name##_xfail = \
835 .fixture = &_##fixture_name##_fixture_object, \
836 .variant = &_##fixture_name##_##variant_name##_object, \
837 .test = &_##fixture_name##_##test_name##_object, \
839 static void __attribute__((constructor)) \
840 _register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \
842 __register_xfail(&_##fixture_name##_##variant_name##_##test_name##_xfail); \
845 static struct __fixture_metadata *__fixture_list = &_fixture_global;
846 static int __constructor_order;
848 #define _CONSTRUCTOR_ORDER_FORWARD 1
849 #define _CONSTRUCTOR_ORDER_BACKWARD -1
851 static inline void __register_fixture(struct __fixture_metadata *f)
853 __LIST_APPEND(__fixture_list, f);
856 struct __fixture_variant_metadata {
859 struct __test_xfail *xfails;
860 struct __fixture_variant_metadata *prev, *next;
864 __register_fixture_variant(struct __fixture_metadata *f,
865 struct __fixture_variant_metadata *variant)
867 __LIST_APPEND(f->variant, variant);
870 /* Contains all the information for test execution and status checking. */
871 struct __test_metadata {
873 void (*fn)(struct __test_metadata *,
874 struct __fixture_variant_metadata *);
875 pid_t pid; /* pid of test when being run */
876 struct __fixture_metadata *fixture;
879 int trigger; /* extra handler after the evaluation */
880 int timeout; /* seconds to wait for test timeout */
881 bool timed_out; /* did this test timeout instead of exiting? */
882 bool aborted; /* stopped test due to failed ASSERT */
883 bool setup_completed; /* did setup finish? */
884 bool teardown_parent; /* run teardown in a parent process */
885 jmp_buf env; /* for exiting out of test early */
886 struct __test_results *results;
887 struct __test_metadata *prev, *next;
890 static inline bool __test_passed(struct __test_metadata *metadata)
892 return metadata->exit_code != KSFT_FAIL &&
893 metadata->exit_code <= KSFT_SKIP;
897 * Since constructors are called in reverse order, reverse the test
898 * list so tests are run in source declaration order.
899 * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
900 * However, it seems not all toolchains do this correctly, so use
901 * __constructor_order to detect which direction is called first
902 * and adjust list building logic to get things running in the right
905 static inline void __register_test(struct __test_metadata *t)
907 __LIST_APPEND(t->fixture->tests, t);
910 static inline void __register_xfail(struct __test_xfail *xf)
912 __LIST_APPEND(xf->variant->xfails, xf);
915 static inline int __bail(int for_realz, struct __test_metadata *t)
917 /* if this is ASSERT, return immediately. */
922 /* otherwise, end the for loop and continue. */
926 static inline void __test_check_assert(struct __test_metadata *t)
932 struct __test_metadata *__active_test;
933 static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
935 struct __test_metadata *t = __active_test;
937 /* Sanity check handler execution environment. */
939 fprintf(TH_LOG_STREAM,
940 "# no active test in SIGALRM handler!?\n");
943 if (sig != SIGALRM || sig != info->si_signo) {
944 fprintf(TH_LOG_STREAM,
945 "# %s: SIGALRM handler caught signal %d!?\n",
946 t->name, sig != SIGALRM ? sig : info->si_signo);
951 // signal process group
952 kill(-(t->pid), SIGKILL);
955 void __wait_for_test(struct __test_metadata *t)
957 struct sigaction action = {
958 .sa_sigaction = __timeout_handler,
959 .sa_flags = SA_SIGINFO,
961 struct sigaction saved_action;
964 if (sigaction(SIGALRM, &action, &saved_action)) {
965 t->exit_code = KSFT_FAIL;
966 fprintf(TH_LOG_STREAM,
967 "# %s: unable to install SIGALRM handler\n",
972 t->timed_out = false;
974 waitpid(t->pid, &status, 0);
976 if (sigaction(SIGALRM, &saved_action, NULL)) {
977 t->exit_code = KSFT_FAIL;
978 fprintf(TH_LOG_STREAM,
979 "# %s: unable to uninstall SIGALRM handler\n",
983 __active_test = NULL;
986 t->exit_code = KSFT_FAIL;
987 fprintf(TH_LOG_STREAM,
988 "# %s: Test terminated by timeout\n", t->name);
989 } else if (WIFEXITED(status)) {
990 if (WEXITSTATUS(status) == KSFT_SKIP ||
991 WEXITSTATUS(status) == KSFT_XPASS ||
992 WEXITSTATUS(status) == KSFT_XFAIL) {
993 t->exit_code = WEXITSTATUS(status);
994 } else if (t->termsig != -1) {
995 t->exit_code = KSFT_FAIL;
996 fprintf(TH_LOG_STREAM,
997 "# %s: Test exited normally instead of by signal (code: %d)\n",
999 WEXITSTATUS(status));
1001 switch (WEXITSTATUS(status)) {
1004 t->exit_code = KSFT_PASS;
1008 t->exit_code = KSFT_FAIL;
1009 fprintf(TH_LOG_STREAM,
1010 "# %s: Test failed\n",
1014 } else if (WIFSIGNALED(status)) {
1015 t->exit_code = KSFT_FAIL;
1016 if (WTERMSIG(status) == SIGABRT) {
1017 fprintf(TH_LOG_STREAM,
1018 "# %s: Test terminated by assertion\n",
1020 } else if (WTERMSIG(status) == t->termsig) {
1021 t->exit_code = KSFT_PASS;
1023 fprintf(TH_LOG_STREAM,
1024 "# %s: Test terminated unexpectedly by signal %d\n",
1029 fprintf(TH_LOG_STREAM,
1030 "# %s: Test ended in some other way [%u]\n",
1036 static void test_harness_list_tests(void)
1038 struct __fixture_variant_metadata *v;
1039 struct __fixture_metadata *f;
1040 struct __test_metadata *t;
1042 for (f = __fixture_list; f; f = f->next) {
1046 if (f == __fixture_list)
1047 fprintf(stderr, "%-20s %-25s %s\n",
1048 "# FIXTURE", "VARIANT", "TEST");
1050 fprintf(stderr, "--------------------------------------------------------------------------------\n");
1053 fprintf(stderr, "%-20s %-25s %s\n",
1054 t == f->tests ? f->name : "",
1058 v = v ? v->next : NULL;
1059 t = t ? t->next : NULL;
1064 static int test_harness_argv_check(int argc, char **argv)
1068 while ((opt = getopt(argc, argv, "hlF:f:V:v:t:T:r:")) != -1) {
1079 test_harness_list_tests();
1084 "Usage: %s [-h|-l] [-t|-T|-v|-V|-f|-F|-r name]\n"
1086 "\t-l list all tests\n"
1088 "\t-t name include test\n"
1089 "\t-T name exclude test\n"
1090 "\t-v name include variant\n"
1091 "\t-V name exclude variant\n"
1092 "\t-f name include fixture\n"
1093 "\t-F name exclude fixture\n"
1094 "\t-r name run specified test\n"
1096 "Test filter options can be specified "
1097 "multiple times. The filtering stops\n"
1098 "at the first match. For example to "
1099 "include all tests from variant 'bla'\n"
1100 "but not test 'foo' specify '-T foo -v bla'.\n"
1102 return opt == 'h' ? KSFT_SKIP : KSFT_FAIL;
1109 static bool test_enabled(int argc, char **argv,
1110 struct __fixture_metadata *f,
1111 struct __fixture_variant_metadata *v,
1112 struct __test_metadata *t)
1114 unsigned int flen = 0, vlen = 0, tlen = 0;
1115 bool has_positive = false;
1119 while ((opt = getopt(argc, argv, "F:f:V:v:t:T:r:")) != -1) {
1120 has_positive |= islower(opt);
1122 switch (tolower(opt)) {
1124 if (!strcmp(t->name, optarg))
1125 return islower(opt);
1128 if (!strcmp(f->name, optarg))
1129 return islower(opt);
1132 if (!strcmp(v->name, optarg))
1133 return islower(opt);
1137 flen = strlen(f->name);
1138 vlen = strlen(v->name);
1139 tlen = strlen(t->name);
1141 if (strlen(optarg) == flen + 1 + vlen + !!vlen + tlen &&
1142 !strncmp(f->name, &optarg[0], flen) &&
1143 !strncmp(v->name, &optarg[flen + 1], vlen) &&
1144 !strncmp(t->name, &optarg[flen + 1 + vlen + !!vlen], tlen))
1151 * If there are no positive tests then we assume user just wants
1152 * exclusions and everything else is a pass.
1154 return !has_positive;
1157 void __run_test(struct __fixture_metadata *f,
1158 struct __fixture_variant_metadata *variant,
1159 struct __test_metadata *t)
1161 struct __test_xfail *xfail;
1162 char test_name[LINE_MAX];
1163 const char *diagnostic;
1165 /* reset test struct */
1166 t->exit_code = KSFT_PASS;
1168 memset(t->results->reason, 0, sizeof(t->results->reason));
1170 snprintf(test_name, sizeof(test_name), "%s%s%s.%s",
1171 f->name, variant->name[0] ? "." : "", variant->name, t->name);
1173 ksft_print_msg(" RUN %s ...\n", test_name);
1175 /* Make sure output buffers are flushed before fork */
1181 ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
1182 t->exit_code = KSFT_FAIL;
1183 } else if (t->pid == 0) {
1186 _exit(t->exit_code);
1190 ksft_print_msg(" %4s %s\n",
1191 __test_passed(t) ? "OK" : "FAIL", test_name);
1193 /* Check if we're expecting this test to fail */
1194 for (xfail = variant->xfails; xfail; xfail = xfail->next)
1195 if (xfail->test == t)
1198 t->exit_code = __test_passed(t) ? KSFT_XPASS : KSFT_XFAIL;
1200 if (t->results->reason[0])
1201 diagnostic = t->results->reason;
1202 else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)
1205 diagnostic = "unknown";
1207 ksft_test_result_code(t->exit_code, test_name,
1208 diagnostic ? "%s" : NULL, diagnostic);
1211 static int test_harness_run(int argc, char **argv)
1213 struct __fixture_variant_metadata no_variant = { .name = "", };
1214 struct __fixture_variant_metadata *v;
1215 struct __fixture_metadata *f;
1216 struct __test_results *results;
1217 struct __test_metadata *t;
1219 unsigned int case_count = 0, test_count = 0;
1220 unsigned int count = 0;
1221 unsigned int pass_count = 0;
1223 ret = test_harness_argv_check(argc, argv);
1224 if (ret != KSFT_PASS)
1227 for (f = __fixture_list; f; f = f->next) {
1228 for (v = f->variant ?: &no_variant; v; v = v->next) {
1229 unsigned int old_tests = test_count;
1231 for (t = f->tests; t; t = t->next)
1232 if (test_enabled(argc, argv, f, v, t))
1235 if (old_tests != test_count)
1240 results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,
1241 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
1243 ksft_print_header();
1244 ksft_set_plan(test_count);
1245 ksft_print_msg("Starting %u tests from %u test cases.\n",
1246 test_count, case_count);
1247 for (f = __fixture_list; f; f = f->next) {
1248 for (v = f->variant ?: &no_variant; v; v = v->next) {
1249 for (t = f->tests; t; t = t->next) {
1250 if (!test_enabled(argc, argv, f, v, t))
1253 t->results = results;
1254 __run_test(f, v, t);
1256 if (__test_passed(t))
1263 munmap(results, sizeof(*results));
1265 ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",
1267 ksft_exit(ret == 0);
1273 static void __attribute__((constructor)) __constructor_order_first(void)
1275 if (!__constructor_order)
1276 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
1279 #endif /* __KSELFTEST_HARNESS_H */