1335 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.4 *5 * kselftest_harness.h: simple C unit test helper.6 *7 * See documentation in Documentation/dev-tools/kselftest.rst8 *9 * API inspired by code.google.com/p/googletest10 */11 12/**13 * DOC: example14 *15 * .. code-block:: c16 *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_MAIN48 */49 50#ifndef __KSELFTEST_HARNESS_H51#define __KSELFTEST_HARNESS_H52 53#ifndef _GNU_SOURCE54#define _GNU_SOURCE55#endif56#include <asm/types.h>57#include <ctype.h>58#include <errno.h>59#include <stdbool.h>60#include <stdint.h>61#include <stdio.h>62#include <stdlib.h>63#include <string.h>64#include <sys/mman.h>65#include <sys/types.h>66#include <sys/wait.h>67#include <unistd.h>68#include <setjmp.h>69 70#include "kselftest.h"71 72#define TEST_TIMEOUT_DEFAULT 3073 74/* Utilities exposed to the test definitions */75#ifndef TH_LOG_STREAM76# define TH_LOG_STREAM stderr77#endif78 79#ifndef TH_LOG_ENABLED80# define TH_LOG_ENABLED 181#endif82 83/**84 * TH_LOG()85 *86 * @fmt: format string87 * @...: optional arguments88 *89 * .. code-block:: c90 *91 * TH_LOG(format, ...)92 *93 * Optional debug logging function available for use in tests.94 * Logging may be enabled or disabled by defining TH_LOG_ENABLED.95 * E.g., #define TH_LOG_ENABLED 196 *97 * If no definition is provided, logging is enabled by default.98 */99#define TH_LOG(fmt, ...) do { \100 if (TH_LOG_ENABLED) \101 __TH_LOG(fmt, ##__VA_ARGS__); \102} while (0)103 104/* Unconditional logger for internal use. */105#define __TH_LOG(fmt, ...) \106 fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \107 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)108 109/**110 * SKIP()111 *112 * @statement: statement to run after reporting SKIP113 * @fmt: format string114 * @...: optional arguments115 *116 * .. code-block:: c117 *118 * SKIP(statement, fmt, ...);119 *120 * This forces a "pass" after reporting why something is being skipped121 * and runs "statement", which is usually "return" or "goto skip".122 */123#define SKIP(statement, fmt, ...) do { \124 snprintf(_metadata->results->reason, \125 sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \126 if (TH_LOG_ENABLED) { \127 fprintf(TH_LOG_STREAM, "# SKIP %s\n", \128 _metadata->results->reason); \129 } \130 _metadata->exit_code = KSFT_SKIP; \131 _metadata->trigger = 0; \132 statement; \133} while (0)134 135/**136 * TEST() - Defines the test function and creates the registration137 * stub138 *139 * @test_name: test name140 *141 * .. code-block:: c142 *143 * TEST(name) { implementation }144 *145 * Defines a test by name.146 * Names must be unique and tests must not be run in parallel. The147 * implementation containing block is a function and scoping should be treated148 * as such. Returning early may be performed with a bare "return;" statement.149 *150 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.151 */152#define TEST(test_name) __TEST_IMPL(test_name, -1)153 154/**155 * TEST_SIGNAL()156 *157 * @test_name: test name158 * @signal: signal number159 *160 * .. code-block:: c161 *162 * TEST_SIGNAL(name, signal) { implementation }163 *164 * Defines a test by name and the expected term signal.165 * Names must be unique and tests must not be run in parallel. The166 * implementation containing block is a function and scoping should be treated167 * as such. Returning early may be performed with a bare "return;" statement.168 *169 * EXPECT_* and ASSERT_* are valid in a TEST() { } context.170 */171#define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)172 173#define __TEST_IMPL(test_name, _signal) \174 static void test_name(struct __test_metadata *_metadata); \175 static inline void wrapper_##test_name( \176 struct __test_metadata *_metadata, \177 struct __fixture_variant_metadata *variant) \178 { \179 _metadata->setup_completed = true; \180 if (setjmp(_metadata->env) == 0) \181 test_name(_metadata); \182 __test_check_assert(_metadata); \183 } \184 static struct __test_metadata _##test_name##_object = \185 { .name = #test_name, \186 .fn = &wrapper_##test_name, \187 .fixture = &_fixture_global, \188 .termsig = _signal, \189 .timeout = TEST_TIMEOUT_DEFAULT, }; \190 static void __attribute__((constructor)) _register_##test_name(void) \191 { \192 __register_test(&_##test_name##_object); \193 } \194 static void test_name( \195 struct __test_metadata __attribute__((unused)) *_metadata)196 197/**198 * FIXTURE_DATA() - Wraps the struct name so we have one less199 * argument to pass around200 *201 * @datatype_name: datatype name202 *203 * .. code-block:: c204 *205 * FIXTURE_DATA(datatype_name)206 *207 * Almost always, you want just FIXTURE() instead (see below).208 * This call may be used when the type of the fixture data209 * is needed. In general, this should not be needed unless210 * the *self* is being passed to a helper directly.211 */212#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name213 214/**215 * FIXTURE() - Called once per fixture to setup the data and216 * register217 *218 * @fixture_name: fixture name219 *220 * .. code-block:: c221 *222 * FIXTURE(fixture_name) {223 * type property1;224 * ...225 * };226 *227 * Defines the data provided to TEST_F()-defined tests as *self*. It should be228 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().229 */230#define FIXTURE(fixture_name) \231 FIXTURE_VARIANT(fixture_name); \232 static struct __fixture_metadata _##fixture_name##_fixture_object = \233 { .name = #fixture_name, }; \234 static void __attribute__((constructor)) \235 _register_##fixture_name##_data(void) \236 { \237 __register_fixture(&_##fixture_name##_fixture_object); \238 } \239 FIXTURE_DATA(fixture_name)240 241/**242 * FIXTURE_SETUP() - Prepares the setup function for the fixture.243 * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.244 *245 * @fixture_name: fixture name246 *247 * .. code-block:: c248 *249 * FIXTURE_SETUP(fixture_name) { implementation }250 *251 * Populates the required "setup" function for a fixture. An instance of the252 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the253 * implementation.254 *255 * ASSERT_* are valid for use in this context and will prempt the execution256 * of any dependent fixture tests.257 *258 * A bare "return;" statement may be used to return early.259 */260#define FIXTURE_SETUP(fixture_name) \261 void fixture_name##_setup( \262 struct __test_metadata __attribute__((unused)) *_metadata, \263 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \264 const FIXTURE_VARIANT(fixture_name) \265 __attribute__((unused)) *variant)266 267/**268 * FIXTURE_TEARDOWN()269 * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.270 *271 * @fixture_name: fixture name272 *273 * .. code-block:: c274 *275 * FIXTURE_TEARDOWN(fixture_name) { implementation }276 *277 * Populates the required "teardown" function for a fixture. An instance of the278 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the279 * implementation to clean up.280 *281 * A bare "return;" statement may be used to return early.282 */283#define FIXTURE_TEARDOWN(fixture_name) \284 static const bool fixture_name##_teardown_parent; \285 __FIXTURE_TEARDOWN(fixture_name)286 287/**288 * FIXTURE_TEARDOWN_PARENT()289 * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.290 *291 * @fixture_name: fixture name292 *293 * .. code-block:: c294 *295 * FIXTURE_TEARDOWN_PARENT(fixture_name) { implementation }296 *297 * Same as FIXTURE_TEARDOWN() but run this code in a parent process. This298 * enables the test process to drop its privileges without impacting the299 * related FIXTURE_TEARDOWN_PARENT() (e.g. to remove files from a directory300 * where write access was dropped).301 *302 * To make it possible for the parent process to use *self*, share (MAP_SHARED)303 * the fixture data between all forked processes.304 */305#define FIXTURE_TEARDOWN_PARENT(fixture_name) \306 static const bool fixture_name##_teardown_parent = true; \307 __FIXTURE_TEARDOWN(fixture_name)308 309#define __FIXTURE_TEARDOWN(fixture_name) \310 void fixture_name##_teardown( \311 struct __test_metadata __attribute__((unused)) *_metadata, \312 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \313 const FIXTURE_VARIANT(fixture_name) \314 __attribute__((unused)) *variant)315 316/**317 * FIXTURE_VARIANT() - Optionally called once per fixture318 * to declare fixture variant319 *320 * @fixture_name: fixture name321 *322 * .. code-block:: c323 *324 * FIXTURE_VARIANT(fixture_name) {325 * type property1;326 * ...327 * };328 *329 * Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and330 * FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with331 * different arguments.332 */333#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name334 335/**336 * FIXTURE_VARIANT_ADD() - Called once per fixture337 * variant to setup and register the data338 *339 * @fixture_name: fixture name340 * @variant_name: name of the parameter set341 *342 * .. code-block:: c343 *344 * FIXTURE_VARIANT_ADD(fixture_name, variant_name) {345 * .property1 = val1,346 * ...347 * };348 *349 * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and350 * TEST_F() as *variant*. Tests of each fixture will be run once for each351 * variant.352 */353#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \354 extern const FIXTURE_VARIANT(fixture_name) \355 _##fixture_name##_##variant_name##_variant; \356 static struct __fixture_variant_metadata \357 _##fixture_name##_##variant_name##_object = \358 { .name = #variant_name, \359 .data = &_##fixture_name##_##variant_name##_variant}; \360 static void __attribute__((constructor)) \361 _register_##fixture_name##_##variant_name(void) \362 { \363 __register_fixture_variant(&_##fixture_name##_fixture_object, \364 &_##fixture_name##_##variant_name##_object); \365 } \366 const FIXTURE_VARIANT(fixture_name) \367 _##fixture_name##_##variant_name##_variant =368 369/**370 * TEST_F() - Emits test registration and helpers for371 * fixture-based test cases372 *373 * @fixture_name: fixture name374 * @test_name: test name375 *376 * .. code-block:: c377 *378 * TEST_F(fixture, name) { implementation }379 *380 * Defines a test that depends on a fixture (e.g., is part of a test case).381 * Very similar to TEST() except that *self* is the setup instance of fixture's382 * datatype exposed for use by the implementation.383 *384 * The _metadata object is shared (MAP_SHARED) with all the potential forked385 * processes, which enables them to use EXCEPT_*() and ASSERT_*().386 *387 * The *self* object is only shared with the potential forked processes if388 * FIXTURE_TEARDOWN_PARENT() is used instead of FIXTURE_TEARDOWN().389 */390#define TEST_F(fixture_name, test_name) \391 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)392 393#define TEST_F_SIGNAL(fixture_name, test_name, signal) \394 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)395 396#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \397 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)398 399#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \400 static void fixture_name##_##test_name( \401 struct __test_metadata *_metadata, \402 FIXTURE_DATA(fixture_name) *self, \403 const FIXTURE_VARIANT(fixture_name) *variant); \404 static inline void wrapper_##fixture_name##_##test_name( \405 struct __test_metadata *_metadata, \406 struct __fixture_variant_metadata *variant) \407 { \408 /* fixture data is alloced, setup, and torn down per call. */ \409 FIXTURE_DATA(fixture_name) self_private, *self = NULL; \410 pid_t child = 1; \411 int status = 0; \412 /* Makes sure there is only one teardown, even when child forks again. */ \413 bool *teardown = mmap(NULL, sizeof(*teardown), \414 PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \415 *teardown = false; \416 if (sizeof(*self) > 0) { \417 if (fixture_name##_teardown_parent) { \418 self = mmap(NULL, sizeof(*self), PROT_READ | PROT_WRITE, \419 MAP_SHARED | MAP_ANONYMOUS, -1, 0); \420 } else { \421 memset(&self_private, 0, sizeof(self_private)); \422 self = &self_private; \423 } \424 } \425 if (setjmp(_metadata->env) == 0) { \426 /* _metadata and potentially self are shared with all forks. */ \427 child = fork(); \428 if (child == 0) { \429 fixture_name##_setup(_metadata, self, variant->data); \430 /* Let setup failure terminate early. */ \431 if (_metadata->exit_code) \432 _exit(0); \433 _metadata->setup_completed = true; \434 fixture_name##_##test_name(_metadata, self, variant->data); \435 } else if (child < 0 || child != waitpid(child, &status, 0)) { \436 ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \437 _metadata->exit_code = KSFT_FAIL; \438 } \439 } \440 if (child == 0) { \441 if (_metadata->setup_completed && !fixture_name##_teardown_parent && \442 __sync_bool_compare_and_swap(teardown, false, true)) \443 fixture_name##_teardown(_metadata, self, variant->data); \444 _exit(0); \445 } \446 if (_metadata->setup_completed && fixture_name##_teardown_parent && \447 __sync_bool_compare_and_swap(teardown, false, true)) \448 fixture_name##_teardown(_metadata, self, variant->data); \449 munmap(teardown, sizeof(*teardown)); \450 if (self && fixture_name##_teardown_parent) \451 munmap(self, sizeof(*self)); \452 if (WIFEXITED(status)) { \453 if (WEXITSTATUS(status)) \454 _metadata->exit_code = WEXITSTATUS(status); \455 } else if (WIFSIGNALED(status)) { \456 /* Forward signal to __wait_for_test(). */ \457 kill(getpid(), WTERMSIG(status)); \458 } \459 __test_check_assert(_metadata); \460 } \461 static struct __test_metadata *_##fixture_name##_##test_name##_object; \462 static void __attribute__((constructor)) \463 _register_##fixture_name##_##test_name(void) \464 { \465 struct __test_metadata *object = mmap(NULL, sizeof(*object), \466 PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \467 object->name = #test_name; \468 object->fn = &wrapper_##fixture_name##_##test_name; \469 object->fixture = &_##fixture_name##_fixture_object; \470 object->termsig = signal; \471 object->timeout = tmout; \472 _##fixture_name##_##test_name##_object = object; \473 __register_test(object); \474 } \475 static void fixture_name##_##test_name( \476 struct __test_metadata __attribute__((unused)) *_metadata, \477 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \478 const FIXTURE_VARIANT(fixture_name) \479 __attribute__((unused)) *variant)480 481/**482 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness483 *484 * .. code-block:: c485 *486 * TEST_HARNESS_MAIN487 *488 * Use once to append a main() to the test file.489 */490#define TEST_HARNESS_MAIN \491 int main(int argc, char **argv) { \492 return test_harness_run(argc, argv); \493 }494 495/**496 * DOC: operators497 *498 * Operators for use in TEST() and TEST_F().499 * ASSERT_* calls will stop test execution immediately.500 * EXPECT_* calls will emit a failure warning, note it, and continue.501 */502 503/**504 * ASSERT_EQ()505 *506 * @expected: expected value507 * @seen: measured value508 *509 * ASSERT_EQ(expected, measured): expected == measured510 */511#define ASSERT_EQ(expected, seen) \512 __EXPECT(expected, #expected, seen, #seen, ==, 1)513 514/**515 * ASSERT_NE()516 *517 * @expected: expected value518 * @seen: measured value519 *520 * ASSERT_NE(expected, measured): expected != measured521 */522#define ASSERT_NE(expected, seen) \523 __EXPECT(expected, #expected, seen, #seen, !=, 1)524 525/**526 * ASSERT_LT()527 *528 * @expected: expected value529 * @seen: measured value530 *531 * ASSERT_LT(expected, measured): expected < measured532 */533#define ASSERT_LT(expected, seen) \534 __EXPECT(expected, #expected, seen, #seen, <, 1)535 536/**537 * ASSERT_LE()538 *539 * @expected: expected value540 * @seen: measured value541 *542 * ASSERT_LE(expected, measured): expected <= measured543 */544#define ASSERT_LE(expected, seen) \545 __EXPECT(expected, #expected, seen, #seen, <=, 1)546 547/**548 * ASSERT_GT()549 *550 * @expected: expected value551 * @seen: measured value552 *553 * ASSERT_GT(expected, measured): expected > measured554 */555#define ASSERT_GT(expected, seen) \556 __EXPECT(expected, #expected, seen, #seen, >, 1)557 558/**559 * ASSERT_GE()560 *561 * @expected: expected value562 * @seen: measured value563 *564 * ASSERT_GE(expected, measured): expected >= measured565 */566#define ASSERT_GE(expected, seen) \567 __EXPECT(expected, #expected, seen, #seen, >=, 1)568 569/**570 * ASSERT_NULL()571 *572 * @seen: measured value573 *574 * ASSERT_NULL(measured): NULL == measured575 */576#define ASSERT_NULL(seen) \577 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)578 579/**580 * ASSERT_TRUE()581 *582 * @seen: measured value583 *584 * ASSERT_TRUE(measured): measured != 0585 */586#define ASSERT_TRUE(seen) \587 __EXPECT(0, "0", seen, #seen, !=, 1)588 589/**590 * ASSERT_FALSE()591 *592 * @seen: measured value593 *594 * ASSERT_FALSE(measured): measured == 0595 */596#define ASSERT_FALSE(seen) \597 __EXPECT(0, "0", seen, #seen, ==, 1)598 599/**600 * ASSERT_STREQ()601 *602 * @expected: expected value603 * @seen: measured value604 *605 * ASSERT_STREQ(expected, measured): !strcmp(expected, measured)606 */607#define ASSERT_STREQ(expected, seen) \608 __EXPECT_STR(expected, seen, ==, 1)609 610/**611 * ASSERT_STRNE()612 *613 * @expected: expected value614 * @seen: measured value615 *616 * ASSERT_STRNE(expected, measured): strcmp(expected, measured)617 */618#define ASSERT_STRNE(expected, seen) \619 __EXPECT_STR(expected, seen, !=, 1)620 621/**622 * EXPECT_EQ()623 *624 * @expected: expected value625 * @seen: measured value626 *627 * EXPECT_EQ(expected, measured): expected == measured628 */629#define EXPECT_EQ(expected, seen) \630 __EXPECT(expected, #expected, seen, #seen, ==, 0)631 632/**633 * EXPECT_NE()634 *635 * @expected: expected value636 * @seen: measured value637 *638 * EXPECT_NE(expected, measured): expected != measured639 */640#define EXPECT_NE(expected, seen) \641 __EXPECT(expected, #expected, seen, #seen, !=, 0)642 643/**644 * EXPECT_LT()645 *646 * @expected: expected value647 * @seen: measured value648 *649 * EXPECT_LT(expected, measured): expected < measured650 */651#define EXPECT_LT(expected, seen) \652 __EXPECT(expected, #expected, seen, #seen, <, 0)653 654/**655 * EXPECT_LE()656 *657 * @expected: expected value658 * @seen: measured value659 *660 * EXPECT_LE(expected, measured): expected <= measured661 */662#define EXPECT_LE(expected, seen) \663 __EXPECT(expected, #expected, seen, #seen, <=, 0)664 665/**666 * EXPECT_GT()667 *668 * @expected: expected value669 * @seen: measured value670 *671 * EXPECT_GT(expected, measured): expected > measured672 */673#define EXPECT_GT(expected, seen) \674 __EXPECT(expected, #expected, seen, #seen, >, 0)675 676/**677 * EXPECT_GE()678 *679 * @expected: expected value680 * @seen: measured value681 *682 * EXPECT_GE(expected, measured): expected >= measured683 */684#define EXPECT_GE(expected, seen) \685 __EXPECT(expected, #expected, seen, #seen, >=, 0)686 687/**688 * EXPECT_NULL()689 *690 * @seen: measured value691 *692 * EXPECT_NULL(measured): NULL == measured693 */694#define EXPECT_NULL(seen) \695 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)696 697/**698 * EXPECT_TRUE()699 *700 * @seen: measured value701 *702 * EXPECT_TRUE(measured): 0 != measured703 */704#define EXPECT_TRUE(seen) \705 __EXPECT(0, "0", seen, #seen, !=, 0)706 707/**708 * EXPECT_FALSE()709 *710 * @seen: measured value711 *712 * EXPECT_FALSE(measured): 0 == measured713 */714#define EXPECT_FALSE(seen) \715 __EXPECT(0, "0", seen, #seen, ==, 0)716 717/**718 * EXPECT_STREQ()719 *720 * @expected: expected value721 * @seen: measured value722 *723 * EXPECT_STREQ(expected, measured): !strcmp(expected, measured)724 */725#define EXPECT_STREQ(expected, seen) \726 __EXPECT_STR(expected, seen, ==, 0)727 728/**729 * EXPECT_STRNE()730 *731 * @expected: expected value732 * @seen: measured value733 *734 * EXPECT_STRNE(expected, measured): strcmp(expected, measured)735 */736#define EXPECT_STRNE(expected, seen) \737 __EXPECT_STR(expected, seen, !=, 0)738 739#ifndef ARRAY_SIZE740#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))741#endif742 743/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is744 * not thread-safe, but it should be fine in most sane test scenarios.745 *746 * Using __bail(), which optionally abort()s, is the easiest way to early747 * return while still providing an optional block to the API consumer.748 */749#define OPTIONAL_HANDLER(_assert) \750 for (; _metadata->trigger; _metadata->trigger = \751 __bail(_assert, _metadata))752 753#define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))754 755#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \756 /* Avoid multiple evaluation of the cases */ \757 __typeof__(_expected) __exp = (_expected); \758 __typeof__(_seen) __seen = (_seen); \759 if (!(__exp _t __seen)) { \760 /* Report with actual signedness to avoid weird output. */ \761 switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \762 case 0: { \763 unsigned long long __exp_print = (uintptr_t)__exp; \764 unsigned long long __seen_print = (uintptr_t)__seen; \765 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \766 _expected_str, __exp_print, #_t, \767 _seen_str, __seen_print); \768 break; \769 } \770 case 1: { \771 unsigned long long __exp_print = (uintptr_t)__exp; \772 long long __seen_print = (intptr_t)__seen; \773 __TH_LOG("Expected %s (%llu) %s %s (%lld)", \774 _expected_str, __exp_print, #_t, \775 _seen_str, __seen_print); \776 break; \777 } \778 case 2: { \779 long long __exp_print = (intptr_t)__exp; \780 unsigned long long __seen_print = (uintptr_t)__seen; \781 __TH_LOG("Expected %s (%lld) %s %s (%llu)", \782 _expected_str, __exp_print, #_t, \783 _seen_str, __seen_print); \784 break; \785 } \786 case 3: { \787 long long __exp_print = (intptr_t)__exp; \788 long long __seen_print = (intptr_t)__seen; \789 __TH_LOG("Expected %s (%lld) %s %s (%lld)", \790 _expected_str, __exp_print, #_t, \791 _seen_str, __seen_print); \792 break; \793 } \794 } \795 _metadata->exit_code = KSFT_FAIL; \796 /* Ensure the optional handler is triggered */ \797 _metadata->trigger = 1; \798 } \799} while (0); OPTIONAL_HANDLER(_assert)800 801#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \802 const char *__exp = (_expected); \803 const char *__seen = (_seen); \804 if (!(strcmp(__exp, __seen) _t 0)) { \805 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \806 _metadata->exit_code = KSFT_FAIL; \807 _metadata->trigger = 1; \808 } \809} while (0); OPTIONAL_HANDLER(_assert)810 811/* List helpers */812#define __LIST_APPEND(head, item) \813{ \814 /* Circular linked list where only prev is circular. */ \815 if (head == NULL) { \816 head = item; \817 item->next = NULL; \818 item->prev = item; \819 return; \820 } \821 if (__constructor_order_forward) { \822 item->next = NULL; \823 item->prev = head->prev; \824 item->prev->next = item; \825 head->prev = item; \826 } else { \827 item->next = head; \828 item->next->prev = item; \829 item->prev = item; \830 head = item; \831 } \832}833 834struct __test_results {835 char reason[1024]; /* Reason for test result */836};837 838struct __test_metadata;839struct __fixture_variant_metadata;840 841/* Contains all the information about a fixture. */842struct __fixture_metadata {843 const char *name;844 struct __test_metadata *tests;845 struct __fixture_variant_metadata *variant;846 struct __fixture_metadata *prev, *next;847} _fixture_global __attribute__((unused)) = {848 .name = "global",849 .prev = &_fixture_global,850};851 852struct __test_xfail {853 struct __fixture_metadata *fixture;854 struct __fixture_variant_metadata *variant;855 struct __test_metadata *test;856 struct __test_xfail *prev, *next;857};858 859/**860 * XFAIL_ADD() - mark variant + test case combination as expected to fail861 * @fixture_name: name of the fixture862 * @variant_name: name of the variant863 * @test_name: name of the test case864 *865 * Mark a combination of variant + test case for a given fixture as expected866 * to fail. Tests marked this way will report XPASS / XFAIL return codes,867 * instead of PASS / FAIL,and use respective counters.868 */869#define XFAIL_ADD(fixture_name, variant_name, test_name) \870 static struct __test_xfail \871 _##fixture_name##_##variant_name##_##test_name##_xfail = \872 { \873 .fixture = &_##fixture_name##_fixture_object, \874 .variant = &_##fixture_name##_##variant_name##_object, \875 }; \876 static void __attribute__((constructor)) \877 _register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \878 { \879 _##fixture_name##_##variant_name##_##test_name##_xfail.test = \880 _##fixture_name##_##test_name##_object; \881 __register_xfail(&_##fixture_name##_##variant_name##_##test_name##_xfail); \882 }883 884static struct __fixture_metadata *__fixture_list = &_fixture_global;885static bool __constructor_order_forward;886 887static inline void __register_fixture(struct __fixture_metadata *f)888{889 __LIST_APPEND(__fixture_list, f);890}891 892struct __fixture_variant_metadata {893 const char *name;894 const void *data;895 struct __test_xfail *xfails;896 struct __fixture_variant_metadata *prev, *next;897};898 899static inline void900__register_fixture_variant(struct __fixture_metadata *f,901 struct __fixture_variant_metadata *variant)902{903 __LIST_APPEND(f->variant, variant);904}905 906/* Contains all the information for test execution and status checking. */907struct __test_metadata {908 const char *name;909 void (*fn)(struct __test_metadata *,910 struct __fixture_variant_metadata *);911 pid_t pid; /* pid of test when being run */912 struct __fixture_metadata *fixture;913 int termsig;914 int exit_code;915 int trigger; /* extra handler after the evaluation */916 int timeout; /* seconds to wait for test timeout */917 bool timed_out; /* did this test timeout instead of exiting? */918 bool aborted; /* stopped test due to failed ASSERT */919 bool setup_completed; /* did setup finish? */920 jmp_buf env; /* for exiting out of test early */921 struct __test_results *results;922 struct __test_metadata *prev, *next;923};924 925static inline bool __test_passed(struct __test_metadata *metadata)926{927 return metadata->exit_code != KSFT_FAIL &&928 metadata->exit_code <= KSFT_SKIP;929}930 931/*932 * Since constructors are called in reverse order, reverse the test933 * list so tests are run in source declaration order.934 * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html935 * However, it seems not all toolchains do this correctly, so use936 * __constructor_order_foward to detect which direction is called first937 * and adjust list building logic to get things running in the right938 * direction.939 */940static inline void __register_test(struct __test_metadata *t)941{942 __LIST_APPEND(t->fixture->tests, t);943}944 945static inline void __register_xfail(struct __test_xfail *xf)946{947 __LIST_APPEND(xf->variant->xfails, xf);948}949 950static inline int __bail(int for_realz, struct __test_metadata *t)951{952 /* if this is ASSERT, return immediately. */953 if (for_realz) {954 t->aborted = true;955 longjmp(t->env, 1);956 }957 /* otherwise, end the for loop and continue. */958 return 0;959}960 961static inline void __test_check_assert(struct __test_metadata *t)962{963 if (t->aborted)964 abort();965}966 967struct __test_metadata *__active_test;968static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)969{970 struct __test_metadata *t = __active_test;971 972 /* Sanity check handler execution environment. */973 if (!t) {974 fprintf(TH_LOG_STREAM,975 "# no active test in SIGALRM handler!?\n");976 abort();977 }978 if (sig != SIGALRM || sig != info->si_signo) {979 fprintf(TH_LOG_STREAM,980 "# %s: SIGALRM handler caught signal %d!?\n",981 t->name, sig != SIGALRM ? sig : info->si_signo);982 abort();983 }984 985 t->timed_out = true;986 // signal process group987 kill(-(t->pid), SIGKILL);988}989 990void __wait_for_test(struct __test_metadata *t)991{992 struct sigaction action = {993 .sa_sigaction = __timeout_handler,994 .sa_flags = SA_SIGINFO,995 };996 struct sigaction saved_action;997 /*998 * Sets status so that WIFEXITED(status) returns true and999 * WEXITSTATUS(status) returns KSFT_FAIL. This safe default value1000 * should never be evaluated because of the waitpid(2) check and1001 * SIGALRM handling.1002 */1003 int status = KSFT_FAIL << 8;1004 int child;1005 1006 if (sigaction(SIGALRM, &action, &saved_action)) {1007 t->exit_code = KSFT_FAIL;1008 fprintf(TH_LOG_STREAM,1009 "# %s: unable to install SIGALRM handler\n",1010 t->name);1011 return;1012 }1013 __active_test = t;1014 t->timed_out = false;1015 alarm(t->timeout);1016 child = waitpid(t->pid, &status, 0);1017 if (child == -1 && errno != EINTR) {1018 t->exit_code = KSFT_FAIL;1019 fprintf(TH_LOG_STREAM,1020 "# %s: Failed to wait for PID %d (errno: %d)\n",1021 t->name, t->pid, errno);1022 return;1023 }1024 1025 alarm(0);1026 if (sigaction(SIGALRM, &saved_action, NULL)) {1027 t->exit_code = KSFT_FAIL;1028 fprintf(TH_LOG_STREAM,1029 "# %s: unable to uninstall SIGALRM handler\n",1030 t->name);1031 return;1032 }1033 __active_test = NULL;1034 1035 if (t->timed_out) {1036 t->exit_code = KSFT_FAIL;1037 fprintf(TH_LOG_STREAM,1038 "# %s: Test terminated by timeout\n", t->name);1039 } else if (WIFEXITED(status)) {1040 if (WEXITSTATUS(status) == KSFT_SKIP ||1041 WEXITSTATUS(status) == KSFT_XPASS ||1042 WEXITSTATUS(status) == KSFT_XFAIL) {1043 t->exit_code = WEXITSTATUS(status);1044 } else if (t->termsig != -1) {1045 t->exit_code = KSFT_FAIL;1046 fprintf(TH_LOG_STREAM,1047 "# %s: Test exited normally instead of by signal (code: %d)\n",1048 t->name,1049 WEXITSTATUS(status));1050 } else {1051 switch (WEXITSTATUS(status)) {1052 /* Success */1053 case KSFT_PASS:1054 t->exit_code = KSFT_PASS;1055 break;1056 /* Failure */1057 default:1058 t->exit_code = KSFT_FAIL;1059 fprintf(TH_LOG_STREAM,1060 "# %s: Test failed\n",1061 t->name);1062 }1063 }1064 } else if (WIFSIGNALED(status)) {1065 t->exit_code = KSFT_FAIL;1066 if (WTERMSIG(status) == SIGABRT) {1067 fprintf(TH_LOG_STREAM,1068 "# %s: Test terminated by assertion\n",1069 t->name);1070 } else if (WTERMSIG(status) == t->termsig) {1071 t->exit_code = KSFT_PASS;1072 } else {1073 fprintf(TH_LOG_STREAM,1074 "# %s: Test terminated unexpectedly by signal %d\n",1075 t->name,1076 WTERMSIG(status));1077 }1078 } else {1079 t->exit_code = KSFT_FAIL;1080 fprintf(TH_LOG_STREAM,1081 "# %s: Test ended in some other way [%u]\n",1082 t->name,1083 status);1084 }1085}1086 1087static void test_harness_list_tests(void)1088{1089 struct __fixture_variant_metadata *v;1090 struct __fixture_metadata *f;1091 struct __test_metadata *t;1092 1093 for (f = __fixture_list; f; f = f->next) {1094 v = f->variant;1095 t = f->tests;1096 1097 if (f == __fixture_list)1098 fprintf(stderr, "%-20s %-25s %s\n",1099 "# FIXTURE", "VARIANT", "TEST");1100 else1101 fprintf(stderr, "--------------------------------------------------------------------------------\n");1102 1103 do {1104 fprintf(stderr, "%-20s %-25s %s\n",1105 t == f->tests ? f->name : "",1106 v ? v->name : "",1107 t ? t->name : "");1108 1109 v = v ? v->next : NULL;1110 t = t ? t->next : NULL;1111 } while (v || t);1112 }1113}1114 1115static int test_harness_argv_check(int argc, char **argv)1116{1117 int opt;1118 1119 while ((opt = getopt(argc, argv, "hlF:f:V:v:t:T:r:")) != -1) {1120 switch (opt) {1121 case 'f':1122 case 'F':1123 case 'v':1124 case 'V':1125 case 't':1126 case 'T':1127 case 'r':1128 break;1129 case 'l':1130 test_harness_list_tests();1131 return KSFT_SKIP;1132 case 'h':1133 default:1134 fprintf(stderr,1135 "Usage: %s [-h|-l] [-t|-T|-v|-V|-f|-F|-r name]\n"1136 "\t-h print help\n"1137 "\t-l list all tests\n"1138 "\n"1139 "\t-t name include test\n"1140 "\t-T name exclude test\n"1141 "\t-v name include variant\n"1142 "\t-V name exclude variant\n"1143 "\t-f name include fixture\n"1144 "\t-F name exclude fixture\n"1145 "\t-r name run specified test\n"1146 "\n"1147 "Test filter options can be specified "1148 "multiple times. The filtering stops\n"1149 "at the first match. For example to "1150 "include all tests from variant 'bla'\n"1151 "but not test 'foo' specify '-T foo -v bla'.\n"1152 "", argv[0]);1153 return opt == 'h' ? KSFT_SKIP : KSFT_FAIL;1154 }1155 }1156 1157 return KSFT_PASS;1158}1159 1160static bool test_enabled(int argc, char **argv,1161 struct __fixture_metadata *f,1162 struct __fixture_variant_metadata *v,1163 struct __test_metadata *t)1164{1165 unsigned int flen = 0, vlen = 0, tlen = 0;1166 bool has_positive = false;1167 int opt;1168 1169 optind = 1;1170 while ((opt = getopt(argc, argv, "F:f:V:v:t:T:r:")) != -1) {1171 has_positive |= islower(opt);1172 1173 switch (tolower(opt)) {1174 case 't':1175 if (!strcmp(t->name, optarg))1176 return islower(opt);1177 break;1178 case 'f':1179 if (!strcmp(f->name, optarg))1180 return islower(opt);1181 break;1182 case 'v':1183 if (!strcmp(v->name, optarg))1184 return islower(opt);1185 break;1186 case 'r':1187 if (!tlen) {1188 flen = strlen(f->name);1189 vlen = strlen(v->name);1190 tlen = strlen(t->name);1191 }1192 if (strlen(optarg) == flen + 1 + vlen + !!vlen + tlen &&1193 !strncmp(f->name, &optarg[0], flen) &&1194 !strncmp(v->name, &optarg[flen + 1], vlen) &&1195 !strncmp(t->name, &optarg[flen + 1 + vlen + !!vlen], tlen))1196 return true;1197 break;1198 }1199 }1200 1201 /*1202 * If there are no positive tests then we assume user just wants1203 * exclusions and everything else is a pass.1204 */1205 return !has_positive;1206}1207 1208void __run_test(struct __fixture_metadata *f,1209 struct __fixture_variant_metadata *variant,1210 struct __test_metadata *t)1211{1212 struct __test_xfail *xfail;1213 char test_name[1024];1214 const char *diagnostic;1215 int child;1216 1217 /* reset test struct */1218 t->exit_code = KSFT_PASS;1219 t->trigger = 0;1220 t->aborted = false;1221 t->setup_completed = false;1222 memset(t->env, 0, sizeof(t->env));1223 memset(t->results->reason, 0, sizeof(t->results->reason));1224 1225 snprintf(test_name, sizeof(test_name), "%s%s%s.%s",1226 f->name, variant->name[0] ? "." : "", variant->name, t->name);1227 1228 ksft_print_msg(" RUN %s ...\n", test_name);1229 1230 /* Make sure output buffers are flushed before fork */1231 fflush(stdout);1232 fflush(stderr);1233 1234 child = fork();1235 if (child < 0) {1236 ksft_print_msg("ERROR SPAWNING TEST CHILD\n");1237 t->exit_code = KSFT_FAIL;1238 } else if (child == 0) {1239 setpgrp();1240 t->fn(t, variant);1241 _exit(t->exit_code);1242 } else {1243 t->pid = child;1244 __wait_for_test(t);1245 }1246 ksft_print_msg(" %4s %s\n",1247 __test_passed(t) ? "OK" : "FAIL", test_name);1248 1249 /* Check if we're expecting this test to fail */1250 for (xfail = variant->xfails; xfail; xfail = xfail->next)1251 if (xfail->test == t)1252 break;1253 if (xfail)1254 t->exit_code = __test_passed(t) ? KSFT_XPASS : KSFT_XFAIL;1255 1256 if (t->results->reason[0])1257 diagnostic = t->results->reason;1258 else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)1259 diagnostic = NULL;1260 else1261 diagnostic = "unknown";1262 1263 ksft_test_result_code(t->exit_code, test_name,1264 diagnostic ? "%s" : NULL, diagnostic);1265}1266 1267static int test_harness_run(int argc, char **argv)1268{1269 struct __fixture_variant_metadata no_variant = { .name = "", };1270 struct __fixture_variant_metadata *v;1271 struct __fixture_metadata *f;1272 struct __test_results *results;1273 struct __test_metadata *t;1274 int ret;1275 unsigned int case_count = 0, test_count = 0;1276 unsigned int count = 0;1277 unsigned int pass_count = 0;1278 1279 ret = test_harness_argv_check(argc, argv);1280 if (ret != KSFT_PASS)1281 return ret;1282 1283 for (f = __fixture_list; f; f = f->next) {1284 for (v = f->variant ?: &no_variant; v; v = v->next) {1285 unsigned int old_tests = test_count;1286 1287 for (t = f->tests; t; t = t->next)1288 if (test_enabled(argc, argv, f, v, t))1289 test_count++;1290 1291 if (old_tests != test_count)1292 case_count++;1293 }1294 }1295 1296 results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,1297 MAP_SHARED | MAP_ANONYMOUS, -1, 0);1298 1299 ksft_print_header();1300 ksft_set_plan(test_count);1301 ksft_print_msg("Starting %u tests from %u test cases.\n",1302 test_count, case_count);1303 for (f = __fixture_list; f; f = f->next) {1304 for (v = f->variant ?: &no_variant; v; v = v->next) {1305 for (t = f->tests; t; t = t->next) {1306 if (!test_enabled(argc, argv, f, v, t))1307 continue;1308 count++;1309 t->results = results;1310 __run_test(f, v, t);1311 t->results = NULL;1312 if (__test_passed(t))1313 pass_count++;1314 else1315 ret = 1;1316 }1317 }1318 }1319 munmap(results, sizeof(*results));1320 1321 ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",1322 pass_count, count);1323 ksft_exit(ret == 0);1324 1325 /* unreachable */1326 return KSFT_FAIL;1327}1328 1329static void __attribute__((constructor)) __constructor_order_first(void)1330{1331 __constructor_order_forward = true;1332}1333 1334#endif /* __KSELFTEST_HARNESS_H */1335