Path: blob/master/tools/testing/selftests/kselftest_harness.h
50378 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.3*4* kselftest_harness.h: simple C unit test helper.5*6* See documentation in Documentation/dev-tools/kselftest.rst7*8* API inspired by code.google.com/p/googletest9*/1011/**12* DOC: example13*14* .. code-block:: c15*16* #include "kselftest_harness.h"17*18* TEST(standalone_test) {19* do_some_stuff;20* EXPECT_GT(10, stuff) {21* stuff_state_t state;22* enumerate_stuff_state(&state);23* TH_LOG("expectation failed with state: %s", state.msg);24* }25* more_stuff;26* ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!");27* last_stuff;28* EXPECT_EQ(0, last_stuff);29* }30*31* FIXTURE(my_fixture) {32* mytype_t *data;33* int awesomeness_level;34* };35* FIXTURE_SETUP(my_fixture) {36* self->data = mytype_new();37* ASSERT_NE(NULL, self->data);38* }39* FIXTURE_TEARDOWN(my_fixture) {40* mytype_free(self->data);41* }42* TEST_F(my_fixture, data_is_good) {43* EXPECT_EQ(1, is_my_data_good(self->data));44* }45*46* TEST_HARNESS_MAIN47*/4849#ifndef __KSELFTEST_HARNESS_H50#define __KSELFTEST_HARNESS_H5152#ifndef _GNU_SOURCE53#define _GNU_SOURCE54#endif55#include <asm/types.h>56#include <ctype.h>57#include <errno.h>58#include <linux/unistd.h>59#include <poll.h>60#include <stdbool.h>61#include <stdint.h>62#include <stdio.h>63#include <stdlib.h>64#include <string.h>65#include <sys/mman.h>66#include <sys/types.h>67#include <sys/wait.h>68#include <unistd.h>6970#include "kselftest.h"7172static inline void __kselftest_memset_safe(void *s, int c, size_t n)73{74if (n > 0)75memset(s, c, n);76}7778#define TEST_TIMEOUT_DEFAULT 307980/* Utilities exposed to the test definitions */81#ifndef TH_LOG_STREAM82# define TH_LOG_STREAM stderr83#endif8485#ifndef TH_LOG_ENABLED86# define TH_LOG_ENABLED 187#endif8889/**90* TH_LOG()91*92* @fmt: format string93* @...: optional arguments94*95* .. code-block:: c96*97* TH_LOG(format, ...)98*99* Optional debug logging function available for use in tests.100* Logging may be enabled or disabled by defining TH_LOG_ENABLED.101* E.g., #define TH_LOG_ENABLED 1102*103* If no definition is provided, logging is enabled by default.104*/105#define TH_LOG(fmt, ...) do { \106if (TH_LOG_ENABLED) \107__TH_LOG(fmt, ##__VA_ARGS__); \108} while (0)109110/* Unconditional logger for internal use. */111#define __TH_LOG(fmt, ...) \112fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \113__FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)114115/**116* SKIP()117*118* @statement: statement to run after reporting SKIP119* @fmt: format string120* @...: optional arguments121*122* .. code-block:: c123*124* SKIP(statement, fmt, ...);125*126* This forces a "pass" after reporting why something is being skipped127* and runs "statement", which is usually "return" or "goto skip".128*/129#define SKIP(statement, fmt, ...) do { \130snprintf(_metadata->results->reason, \131sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \132if (TH_LOG_ENABLED) { \133fprintf(TH_LOG_STREAM, "# SKIP %s\n", \134_metadata->results->reason); \135} \136_metadata->exit_code = KSFT_SKIP; \137_metadata->trigger = 0; \138statement; \139} while (0)140141/**142* TEST() - Defines the test function and creates the registration143* stub144*145* @test_name: test name146*147* .. code-block:: c148*149* TEST(name) { implementation }150*151* Defines a test by name.152* Names must be unique and tests must not be run in parallel. The153* implementation containing block is a function and scoping should be treated154* as such. Returning early may be performed with a bare "return;" statement.155*156* EXPECT_* and ASSERT_* are valid in a TEST() { } context.157*/158#define TEST(test_name) __TEST_IMPL(test_name, -1)159160/**161* TEST_SIGNAL()162*163* @test_name: test name164* @signal: signal number165*166* .. code-block:: c167*168* TEST_SIGNAL(name, signal) { implementation }169*170* Defines a test by name and the expected term signal.171* Names must be unique and tests must not be run in parallel. The172* implementation containing block is a function and scoping should be treated173* as such. Returning early may be performed with a bare "return;" statement.174*175* EXPECT_* and ASSERT_* are valid in a TEST() { } context.176*/177#define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)178179#define __TEST_IMPL(test_name, _signal) \180static void test_name(struct __test_metadata *_metadata); \181static void wrapper_##test_name( \182struct __test_metadata *_metadata, \183struct __fixture_variant_metadata __attribute__((unused)) *variant) \184{ \185test_name(_metadata); \186} \187static struct __test_metadata _##test_name##_object = \188{ .name = #test_name, \189.fn = &wrapper_##test_name, \190.fixture = &_fixture_global, \191.termsig = _signal, \192.timeout = TEST_TIMEOUT_DEFAULT, }; \193static void __attribute__((constructor)) _register_##test_name(void) \194{ \195__register_test(&_##test_name##_object); \196} \197static void test_name( \198struct __test_metadata __attribute__((unused)) *_metadata)199200/**201* FIXTURE_DATA() - Wraps the struct name so we have one less202* argument to pass around203*204* @datatype_name: datatype name205*206* .. code-block:: c207*208* FIXTURE_DATA(datatype_name)209*210* Almost always, you want just FIXTURE() instead (see below).211* This call may be used when the type of the fixture data212* is needed. In general, this should not be needed unless213* the *self* is being passed to a helper directly.214*/215#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name216217/**218* FIXTURE() - Called once per fixture to setup the data and219* register220*221* @fixture_name: fixture name222*223* .. code-block:: c224*225* FIXTURE(fixture_name) {226* type property1;227* ...228* };229*230* Defines the data provided to TEST_F()-defined tests as *self*. It should be231* populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().232*/233#define FIXTURE(fixture_name) \234FIXTURE_VARIANT(fixture_name); \235static struct __fixture_metadata _##fixture_name##_fixture_object = \236{ .name = #fixture_name, }; \237static void __attribute__((constructor)) \238_register_##fixture_name##_data(void) \239{ \240__register_fixture(&_##fixture_name##_fixture_object); \241} \242FIXTURE_DATA(fixture_name)243244/**245* FIXTURE_SETUP() - Prepares the setup function for the fixture.246* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.247*248* @fixture_name: fixture name249*250* .. code-block:: c251*252* FIXTURE_SETUP(fixture_name) { implementation }253*254* Populates the required "setup" function for a fixture. An instance of the255* datatype defined with FIXTURE_DATA() will be exposed as *self* for the256* implementation.257*258* ASSERT_* are valid for use in this context and will prempt the execution259* of any dependent fixture tests.260*261* A bare "return;" statement may be used to return early.262*/263#define FIXTURE_SETUP(fixture_name) \264static void fixture_name##_setup( \265struct __test_metadata __attribute__((unused)) *_metadata, \266FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \267const FIXTURE_VARIANT(fixture_name) \268__attribute__((unused)) *variant)269270/**271* FIXTURE_TEARDOWN()272* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.273*274* @fixture_name: fixture name275*276* .. code-block:: c277*278* FIXTURE_TEARDOWN(fixture_name) { implementation }279*280* Populates the required "teardown" function for a fixture. An instance of the281* datatype defined with FIXTURE_DATA() will be exposed as *self* for the282* implementation to clean up.283*284* A bare "return;" statement may be used to return early.285*/286#define FIXTURE_TEARDOWN(fixture_name) \287static const bool fixture_name##_teardown_parent; \288__FIXTURE_TEARDOWN(fixture_name)289290/**291* FIXTURE_TEARDOWN_PARENT()292* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.293*294* @fixture_name: fixture name295*296* .. code-block:: c297*298* FIXTURE_TEARDOWN_PARENT(fixture_name) { implementation }299*300* Same as FIXTURE_TEARDOWN() but run this code in a parent process. This301* enables the test process to drop its privileges without impacting the302* related FIXTURE_TEARDOWN_PARENT() (e.g. to remove files from a directory303* where write access was dropped).304*305* To make it possible for the parent process to use *self*, share (MAP_SHARED)306* the fixture data between all forked processes.307*/308#define FIXTURE_TEARDOWN_PARENT(fixture_name) \309static const bool fixture_name##_teardown_parent = true; \310__FIXTURE_TEARDOWN(fixture_name)311312#define __FIXTURE_TEARDOWN(fixture_name) \313static void fixture_name##_teardown( \314struct __test_metadata __attribute__((unused)) *_metadata, \315FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \316const FIXTURE_VARIANT(fixture_name) \317__attribute__((unused)) *variant)318319/**320* FIXTURE_VARIANT() - Optionally called once per fixture321* to declare fixture variant322*323* @fixture_name: fixture name324*325* .. code-block:: c326*327* FIXTURE_VARIANT(fixture_name) {328* type property1;329* ...330* };331*332* Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and333* FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with334* different arguments.335*/336#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name337338/**339* FIXTURE_VARIANT_ADD() - Called once per fixture340* variant to setup and register the data341*342* @fixture_name: fixture name343* @variant_name: name of the parameter set344*345* .. code-block:: c346*347* FIXTURE_VARIANT_ADD(fixture_name, variant_name) {348* .property1 = val1,349* ...350* };351*352* Defines a variant of the test fixture, provided to FIXTURE_SETUP() and353* TEST_F() as *variant*. Tests of each fixture will be run once for each354* variant.355*/356#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \357extern const FIXTURE_VARIANT(fixture_name) \358_##fixture_name##_##variant_name##_variant; \359static struct __fixture_variant_metadata \360_##fixture_name##_##variant_name##_object = \361{ .name = #variant_name, \362.data = &_##fixture_name##_##variant_name##_variant}; \363static void __attribute__((constructor)) \364_register_##fixture_name##_##variant_name(void) \365{ \366__register_fixture_variant(&_##fixture_name##_fixture_object, \367&_##fixture_name##_##variant_name##_object); \368} \369const FIXTURE_VARIANT(fixture_name) \370_##fixture_name##_##variant_name##_variant =371372/**373* TEST_F() - Emits test registration and helpers for374* fixture-based test cases375*376* @fixture_name: fixture name377* @test_name: test name378*379* .. code-block:: c380*381* TEST_F(fixture, name) { implementation }382*383* Defines a test that depends on a fixture (e.g., is part of a test case).384* Very similar to TEST() except that *self* is the setup instance of fixture's385* datatype exposed for use by the implementation.386*387* The _metadata object is shared (MAP_SHARED) with all the potential forked388* processes, which enables them to use EXCEPT_*() and ASSERT_*().389*390* The *self* object is only shared with the potential forked processes if391* FIXTURE_TEARDOWN_PARENT() is used instead of FIXTURE_TEARDOWN().392*/393#define TEST_F(fixture_name, test_name) \394__TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)395396#define TEST_F_SIGNAL(fixture_name, test_name, signal) \397__TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)398399#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \400__TEST_F_IMPL(fixture_name, test_name, -1, timeout)401402#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \403static void fixture_name##_##test_name( \404struct __test_metadata *_metadata, \405FIXTURE_DATA(fixture_name) *self, \406const FIXTURE_VARIANT(fixture_name) *variant); \407static void wrapper_##fixture_name##_##test_name( \408struct __test_metadata *_metadata, \409struct __fixture_variant_metadata *variant) \410{ \411/* fixture data is alloced, setup, and torn down per call. */ \412FIXTURE_DATA(fixture_name) self_private, *self = NULL; \413pid_t child = 1; \414int status = 0; \415/* Makes sure there is only one teardown, even when child forks again. */ \416_metadata->no_teardown = mmap(NULL, sizeof(*_metadata->no_teardown), \417PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \418*_metadata->no_teardown = true; \419if (sizeof(*self) > 0) { \420if (fixture_name##_teardown_parent) { \421self = mmap(NULL, sizeof(*self), PROT_READ | PROT_WRITE, \422MAP_SHARED | MAP_ANONYMOUS, -1, 0); \423} else { \424__kselftest_memset_safe(&self_private, 0, sizeof(self_private)); \425self = &self_private; \426} \427} \428_metadata->variant = variant->data; \429_metadata->self = self; \430/* _metadata and potentially self are shared with all forks. */ \431child = fork(); \432if (child == 0) { \433fixture_name##_setup(_metadata, self, variant->data); \434/* Let setup failure terminate early. */ \435if (_metadata->exit_code) \436_exit(0); \437*_metadata->no_teardown = false; \438fixture_name##_##test_name(_metadata, self, variant->data); \439_metadata->teardown_fn(false, _metadata, self, variant->data); \440_exit(0); \441} else if (child < 0 || child != waitpid(child, &status, 0)) { \442ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \443_metadata->exit_code = KSFT_FAIL; \444} \445_metadata->teardown_fn(true, _metadata, self, variant->data); \446munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \447_metadata->no_teardown = NULL; \448if (self && fixture_name##_teardown_parent) \449munmap(self, sizeof(*self)); \450if (WIFEXITED(status)) { \451if (WEXITSTATUS(status)) \452_metadata->exit_code = WEXITSTATUS(status); \453} else if (WIFSIGNALED(status)) { \454/* Forward signal to __wait_for_test(). */ \455kill(getpid(), WTERMSIG(status)); \456} \457} \458static void wrapper_##fixture_name##_##test_name##_teardown( \459bool in_parent, struct __test_metadata *_metadata, \460void *self, const void *variant) \461{ \462if (fixture_name##_teardown_parent == in_parent && \463!__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \464fixture_name##_teardown(_metadata, self, variant); \465} \466static struct __test_metadata *_##fixture_name##_##test_name##_object; \467static void __attribute__((constructor)) \468_register_##fixture_name##_##test_name(void) \469{ \470struct __test_metadata *object = mmap(NULL, sizeof(*object), \471PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \472object->name = #test_name; \473object->fn = &wrapper_##fixture_name##_##test_name; \474object->fixture = &_##fixture_name##_fixture_object; \475object->teardown_fn = &wrapper_##fixture_name##_##test_name##_teardown; \476object->termsig = signal; \477object->timeout = tmout; \478_##fixture_name##_##test_name##_object = object; \479__register_test(object); \480} \481static void fixture_name##_##test_name( \482struct __test_metadata __attribute__((unused)) *_metadata, \483FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \484const FIXTURE_VARIANT(fixture_name) \485__attribute__((unused)) *variant)486487/**488* TEST_HARNESS_MAIN - Simple wrapper to run the test harness489*490* .. code-block:: c491*492* TEST_HARNESS_MAIN493*494* Use once to append a main() to the test file.495*/496#define TEST_HARNESS_MAIN \497int main(int argc, char **argv) { \498return test_harness_run(argc, argv); \499}500501/**502* DOC: operators503*504* Operators for use in TEST() and TEST_F().505* ASSERT_* calls will stop test execution immediately.506* EXPECT_* calls will emit a failure warning, note it, and continue.507*/508509/**510* ASSERT_EQ()511*512* @expected: expected value513* @seen: measured value514*515* ASSERT_EQ(expected, measured): expected == measured516*/517#define ASSERT_EQ(expected, seen) \518__EXPECT(expected, #expected, seen, #seen, ==, 1)519520/**521* ASSERT_NE()522*523* @expected: expected value524* @seen: measured value525*526* ASSERT_NE(expected, measured): expected != measured527*/528#define ASSERT_NE(expected, seen) \529__EXPECT(expected, #expected, seen, #seen, !=, 1)530531/**532* ASSERT_LT()533*534* @expected: expected value535* @seen: measured value536*537* ASSERT_LT(expected, measured): expected < measured538*/539#define ASSERT_LT(expected, seen) \540__EXPECT(expected, #expected, seen, #seen, <, 1)541542/**543* ASSERT_LE()544*545* @expected: expected value546* @seen: measured value547*548* ASSERT_LE(expected, measured): expected <= measured549*/550#define ASSERT_LE(expected, seen) \551__EXPECT(expected, #expected, seen, #seen, <=, 1)552553/**554* ASSERT_GT()555*556* @expected: expected value557* @seen: measured value558*559* ASSERT_GT(expected, measured): expected > measured560*/561#define ASSERT_GT(expected, seen) \562__EXPECT(expected, #expected, seen, #seen, >, 1)563564/**565* ASSERT_GE()566*567* @expected: expected value568* @seen: measured value569*570* ASSERT_GE(expected, measured): expected >= measured571*/572#define ASSERT_GE(expected, seen) \573__EXPECT(expected, #expected, seen, #seen, >=, 1)574575/**576* ASSERT_NULL()577*578* @seen: measured value579*580* ASSERT_NULL(measured): NULL == measured581*/582#define ASSERT_NULL(seen) \583__EXPECT(NULL, "NULL", seen, #seen, ==, 1)584585/**586* ASSERT_TRUE()587*588* @seen: measured value589*590* ASSERT_TRUE(measured): measured != 0591*/592#define ASSERT_TRUE(seen) \593__EXPECT(0, "0", seen, #seen, !=, 1)594595/**596* ASSERT_FALSE()597*598* @seen: measured value599*600* ASSERT_FALSE(measured): measured == 0601*/602#define ASSERT_FALSE(seen) \603__EXPECT(0, "0", seen, #seen, ==, 1)604605/**606* ASSERT_STREQ()607*608* @expected: expected value609* @seen: measured value610*611* ASSERT_STREQ(expected, measured): !strcmp(expected, measured)612*/613#define ASSERT_STREQ(expected, seen) \614__EXPECT_STR(expected, seen, ==, 1)615616/**617* ASSERT_STRNE()618*619* @expected: expected value620* @seen: measured value621*622* ASSERT_STRNE(expected, measured): strcmp(expected, measured)623*/624#define ASSERT_STRNE(expected, seen) \625__EXPECT_STR(expected, seen, !=, 1)626627/**628* EXPECT_EQ()629*630* @expected: expected value631* @seen: measured value632*633* EXPECT_EQ(expected, measured): expected == measured634*/635#define EXPECT_EQ(expected, seen) \636__EXPECT(expected, #expected, seen, #seen, ==, 0)637638/**639* EXPECT_NE()640*641* @expected: expected value642* @seen: measured value643*644* EXPECT_NE(expected, measured): expected != measured645*/646#define EXPECT_NE(expected, seen) \647__EXPECT(expected, #expected, seen, #seen, !=, 0)648649/**650* EXPECT_LT()651*652* @expected: expected value653* @seen: measured value654*655* EXPECT_LT(expected, measured): expected < measured656*/657#define EXPECT_LT(expected, seen) \658__EXPECT(expected, #expected, seen, #seen, <, 0)659660/**661* EXPECT_LE()662*663* @expected: expected value664* @seen: measured value665*666* EXPECT_LE(expected, measured): expected <= measured667*/668#define EXPECT_LE(expected, seen) \669__EXPECT(expected, #expected, seen, #seen, <=, 0)670671/**672* EXPECT_GT()673*674* @expected: expected value675* @seen: measured value676*677* EXPECT_GT(expected, measured): expected > measured678*/679#define EXPECT_GT(expected, seen) \680__EXPECT(expected, #expected, seen, #seen, >, 0)681682/**683* EXPECT_GE()684*685* @expected: expected value686* @seen: measured value687*688* EXPECT_GE(expected, measured): expected >= measured689*/690#define EXPECT_GE(expected, seen) \691__EXPECT(expected, #expected, seen, #seen, >=, 0)692693/**694* EXPECT_NULL()695*696* @seen: measured value697*698* EXPECT_NULL(measured): NULL == measured699*/700#define EXPECT_NULL(seen) \701__EXPECT(NULL, "NULL", seen, #seen, ==, 0)702703/**704* EXPECT_TRUE()705*706* @seen: measured value707*708* EXPECT_TRUE(measured): 0 != measured709*/710#define EXPECT_TRUE(seen) \711__EXPECT(0, "0", seen, #seen, !=, 0)712713/**714* EXPECT_FALSE()715*716* @seen: measured value717*718* EXPECT_FALSE(measured): 0 == measured719*/720#define EXPECT_FALSE(seen) \721__EXPECT(0, "0", seen, #seen, ==, 0)722723/**724* EXPECT_STREQ()725*726* @expected: expected value727* @seen: measured value728*729* EXPECT_STREQ(expected, measured): !strcmp(expected, measured)730*/731#define EXPECT_STREQ(expected, seen) \732__EXPECT_STR(expected, seen, ==, 0)733734/**735* EXPECT_STRNE()736*737* @expected: expected value738* @seen: measured value739*740* EXPECT_STRNE(expected, measured): strcmp(expected, measured)741*/742#define EXPECT_STRNE(expected, seen) \743__EXPECT_STR(expected, seen, !=, 0)744745#ifndef ARRAY_SIZE746#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))747#endif748749/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is750* not thread-safe, but it should be fine in most sane test scenarios.751*752* Using __bail(), which optionally abort()s, is the easiest way to early753* return while still providing an optional block to the API consumer.754*/755#define OPTIONAL_HANDLER(_assert) \756for (; _metadata->trigger; _metadata->trigger = \757__bail(_assert, _metadata))758759#define is_signed_var(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))760761#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \762/* Avoid multiple evaluation of the cases */ \763__typeof__(_expected) __exp = (_expected); \764__typeof__(_seen) __seen = (_seen); \765if (!(__exp _t __seen)) { \766/* Report with actual signedness to avoid weird output. */ \767switch (is_signed_var(__exp) * 2 + is_signed_var(__seen)) { \768case 0: { \769uintmax_t __exp_print = (uintmax_t)__exp; \770uintmax_t __seen_print = (uintmax_t)__seen; \771__TH_LOG("Expected %s (%ju) %s %s (%ju)", \772_expected_str, __exp_print, #_t, \773_seen_str, __seen_print); \774break; \775} \776case 1: { \777uintmax_t __exp_print = (uintmax_t)__exp; \778intmax_t __seen_print = (intmax_t)__seen; \779__TH_LOG("Expected %s (%ju) %s %s (%jd)", \780_expected_str, __exp_print, #_t, \781_seen_str, __seen_print); \782break; \783} \784case 2: { \785intmax_t __exp_print = (intmax_t)__exp; \786uintmax_t __seen_print = (uintmax_t)__seen; \787__TH_LOG("Expected %s (%jd) %s %s (%ju)", \788_expected_str, __exp_print, #_t, \789_seen_str, __seen_print); \790break; \791} \792case 3: { \793intmax_t __exp_print = (intmax_t)__exp; \794intmax_t __seen_print = (intmax_t)__seen; \795__TH_LOG("Expected %s (%jd) %s %s (%jd)", \796_expected_str, __exp_print, #_t, \797_seen_str, __seen_print); \798break; \799} \800} \801_metadata->exit_code = KSFT_FAIL; \802/* Ensure the optional handler is triggered */ \803_metadata->trigger = 1; \804} \805} while (0); OPTIONAL_HANDLER(_assert)806807#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \808const char *__exp = (_expected); \809const char *__seen = (_seen); \810if (!(strcmp(__exp, __seen) _t 0)) { \811__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \812_metadata->exit_code = KSFT_FAIL; \813_metadata->trigger = 1; \814} \815} while (0); OPTIONAL_HANDLER(_assert)816817/* List helpers */818#define __LIST_APPEND(head, item) \819{ \820/* Circular linked list where only prev is circular. */ \821if (head == NULL) { \822head = item; \823item->next = NULL; \824item->prev = item; \825return; \826} \827if (__constructor_order_forward) { \828item->next = NULL; \829item->prev = head->prev; \830item->prev->next = item; \831head->prev = item; \832} else { \833item->next = head; \834item->next->prev = item; \835item->prev = item; \836head = item; \837} \838}839840struct __test_results {841char reason[1024]; /* Reason for test result */842};843844struct __test_metadata;845struct __fixture_variant_metadata;846847/* Contains all the information about a fixture. */848struct __fixture_metadata {849const char *name;850struct __test_metadata *tests;851struct __fixture_variant_metadata *variant;852struct __fixture_metadata *prev, *next;853} _fixture_global __attribute__((unused)) = {854.name = "global",855.prev = &_fixture_global,856};857858struct __test_xfail {859struct __fixture_metadata *fixture;860struct __fixture_variant_metadata *variant;861struct __test_metadata *test;862struct __test_xfail *prev, *next;863};864865/**866* XFAIL_ADD() - mark variant + test case combination as expected to fail867* @fixture_name: name of the fixture868* @variant_name: name of the variant869* @test_name: name of the test case870*871* Mark a combination of variant + test case for a given fixture as expected872* to fail. Tests marked this way will report XPASS / XFAIL return codes,873* instead of PASS / FAIL,and use respective counters.874*/875#define XFAIL_ADD(fixture_name, variant_name, test_name) \876static struct __test_xfail \877_##fixture_name##_##variant_name##_##test_name##_xfail = \878{ \879.fixture = &_##fixture_name##_fixture_object, \880.variant = &_##fixture_name##_##variant_name##_object, \881}; \882static void __attribute__((constructor)) \883_register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \884{ \885_##fixture_name##_##variant_name##_##test_name##_xfail.test = \886_##fixture_name##_##test_name##_object; \887__register_xfail(&_##fixture_name##_##variant_name##_##test_name##_xfail); \888}889890static struct __fixture_metadata *__fixture_list = &_fixture_global;891static bool __constructor_order_forward;892893static inline void __register_fixture(struct __fixture_metadata *f)894{895__LIST_APPEND(__fixture_list, f);896}897898struct __fixture_variant_metadata {899const char *name;900const void *data;901struct __test_xfail *xfails;902struct __fixture_variant_metadata *prev, *next;903};904905static inline void906__register_fixture_variant(struct __fixture_metadata *f,907struct __fixture_variant_metadata *variant)908{909__LIST_APPEND(f->variant, variant);910}911912/* Contains all the information for test execution and status checking. */913struct __test_metadata {914const char *name;915void (*fn)(struct __test_metadata *,916struct __fixture_variant_metadata *);917pid_t pid; /* pid of test when being run */918struct __fixture_metadata *fixture;919void (*teardown_fn)(bool in_parent, struct __test_metadata *_metadata,920void *self, const void *variant);921int termsig;922int exit_code;923int trigger; /* extra handler after the evaluation */924int timeout; /* seconds to wait for test timeout */925bool aborted; /* stopped test due to failed ASSERT */926bool *no_teardown; /* fixture needs teardown */927void *self;928const void *variant;929struct __test_results *results;930struct __test_metadata *prev, *next;931};932933static inline bool __test_passed(struct __test_metadata *metadata)934{935return metadata->exit_code != KSFT_FAIL &&936metadata->exit_code <= KSFT_SKIP;937}938939/*940* Since constructors are called in reverse order, reverse the test941* list so tests are run in source declaration order.942* https://gcc.gnu.org/onlinedocs/gccint/Initialization.html943* However, it seems not all toolchains do this correctly, so use944* __constructor_order_foward to detect which direction is called first945* and adjust list building logic to get things running in the right946* direction.947*/948static inline void __register_test(struct __test_metadata *t)949{950__LIST_APPEND(t->fixture->tests, t);951}952953static inline void __register_xfail(struct __test_xfail *xf)954{955__LIST_APPEND(xf->variant->xfails, xf);956}957958static inline int __bail(int for_realz, struct __test_metadata *t)959{960/* if this is ASSERT, return immediately. */961if (for_realz) {962if (t->teardown_fn)963t->teardown_fn(false, t, t->self, t->variant);964abort();965}966/* otherwise, end the for loop and continue. */967return 0;968}969970static void __wait_for_test(struct __test_metadata *t)971{972/*973* Sets status so that WIFEXITED(status) returns true and974* WEXITSTATUS(status) returns KSFT_FAIL. This safe default value975* should never be evaluated because of the waitpid(2) check and976* timeout handling.977*/978int status = KSFT_FAIL << 8;979struct pollfd poll_child;980int ret, child, childfd;981bool timed_out = false;982983childfd = syscall(__NR_pidfd_open, t->pid, 0);984if (childfd == -1) {985t->exit_code = KSFT_FAIL;986fprintf(TH_LOG_STREAM,987"# %s: unable to open pidfd\n",988t->name);989return;990}991992poll_child.fd = childfd;993poll_child.events = POLLIN;994ret = poll(&poll_child, 1, t->timeout * 1000);995if (ret == -1) {996t->exit_code = KSFT_FAIL;997fprintf(TH_LOG_STREAM,998"# %s: unable to wait on child pidfd\n",999t->name);1000return;1001} else if (ret == 0) {1002timed_out = true;1003/* signal process group */1004kill(-(t->pid), SIGKILL);1005}1006child = waitpid(t->pid, &status, WNOHANG);1007if (child == -1 && errno != EINTR) {1008t->exit_code = KSFT_FAIL;1009fprintf(TH_LOG_STREAM,1010"# %s: Failed to wait for PID %d (errno: %d)\n",1011t->name, t->pid, errno);1012return;1013}10141015if (timed_out) {1016t->exit_code = KSFT_FAIL;1017fprintf(TH_LOG_STREAM,1018"# %s: Test terminated by timeout\n", t->name);1019} else if (WIFEXITED(status)) {1020if (WEXITSTATUS(status) == KSFT_SKIP ||1021WEXITSTATUS(status) == KSFT_XPASS ||1022WEXITSTATUS(status) == KSFT_XFAIL) {1023t->exit_code = WEXITSTATUS(status);1024} else if (t->termsig != -1) {1025t->exit_code = KSFT_FAIL;1026fprintf(TH_LOG_STREAM,1027"# %s: Test exited normally instead of by signal (code: %d)\n",1028t->name,1029WEXITSTATUS(status));1030} else {1031switch (WEXITSTATUS(status)) {1032/* Success */1033case KSFT_PASS:1034t->exit_code = KSFT_PASS;1035break;1036/* Failure */1037default:1038t->exit_code = KSFT_FAIL;1039fprintf(TH_LOG_STREAM,1040"# %s: Test failed\n",1041t->name);1042}1043}1044} else if (WIFSIGNALED(status)) {1045t->exit_code = KSFT_FAIL;1046if (WTERMSIG(status) == SIGABRT) {1047fprintf(TH_LOG_STREAM,1048"# %s: Test terminated by assertion\n",1049t->name);1050} else if (WTERMSIG(status) == t->termsig) {1051t->exit_code = KSFT_PASS;1052} else {1053fprintf(TH_LOG_STREAM,1054"# %s: Test terminated unexpectedly by signal %d\n",1055t->name,1056WTERMSIG(status));1057}1058} else {1059t->exit_code = KSFT_FAIL;1060fprintf(TH_LOG_STREAM,1061"# %s: Test ended in some other way [%u]\n",1062t->name,1063status);1064}1065}10661067static void test_harness_list_tests(void)1068{1069struct __fixture_variant_metadata *v;1070struct __fixture_metadata *f;1071struct __test_metadata *t;10721073for (f = __fixture_list; f; f = f->next) {1074v = f->variant;1075t = f->tests;10761077if (f == __fixture_list)1078fprintf(stderr, "%-20s %-25s %s\n",1079"# FIXTURE", "VARIANT", "TEST");1080else1081fprintf(stderr, "--------------------------------------------------------------------------------\n");10821083do {1084fprintf(stderr, "%-20s %-25s %s\n",1085t == f->tests ? f->name : "",1086v ? v->name : "",1087t ? t->name : "");10881089v = v ? v->next : NULL;1090t = t ? t->next : NULL;1091} while (v || t);1092}1093}10941095static int test_harness_argv_check(int argc, char **argv)1096{1097int opt;10981099while ((opt = getopt(argc, argv, "dhlF:f:V:v:t:T:r:")) != -1) {1100switch (opt) {1101case 'f':1102case 'F':1103case 'v':1104case 'V':1105case 't':1106case 'T':1107case 'r':1108break;1109case 'l':1110test_harness_list_tests();1111return KSFT_SKIP;1112case 'd':1113ksft_debug_enabled = true;1114break;1115case 'h':1116default:1117fprintf(stderr,1118"Usage: %s [-h|-l|-d] [-t|-T|-v|-V|-f|-F|-r name]\n"1119"\t-h print help\n"1120"\t-l list all tests\n"1121"\t-d enable debug prints\n"1122"\n"1123"\t-t name include test\n"1124"\t-T name exclude test\n"1125"\t-v name include variant\n"1126"\t-V name exclude variant\n"1127"\t-f name include fixture\n"1128"\t-F name exclude fixture\n"1129"\t-r name run specified test\n"1130"\n"1131"Test filter options can be specified "1132"multiple times. The filtering stops\n"1133"at the first match. For example to "1134"include all tests from variant 'bla'\n"1135"but not test 'foo' specify '-T foo -v bla'.\n"1136"", argv[0]);1137return opt == 'h' ? KSFT_SKIP : KSFT_FAIL;1138}1139}11401141return KSFT_PASS;1142}11431144static bool test_enabled(int argc, char **argv,1145struct __fixture_metadata *f,1146struct __fixture_variant_metadata *v,1147struct __test_metadata *t)1148{1149unsigned int flen = 0, vlen = 0, tlen = 0;1150bool has_positive = false;1151int opt;11521153optind = 1;1154while ((opt = getopt(argc, argv, "dF:f:V:v:t:T:r:")) != -1) {1155if (opt != 'd')1156has_positive |= islower(opt);11571158switch (tolower(opt)) {1159case 't':1160if (!strcmp(t->name, optarg))1161return islower(opt);1162break;1163case 'f':1164if (!strcmp(f->name, optarg))1165return islower(opt);1166break;1167case 'v':1168if (!strcmp(v->name, optarg))1169return islower(opt);1170break;1171case 'r':1172if (!tlen) {1173flen = strlen(f->name);1174vlen = strlen(v->name);1175tlen = strlen(t->name);1176}1177if (strlen(optarg) == flen + 1 + vlen + !!vlen + tlen &&1178!strncmp(f->name, &optarg[0], flen) &&1179!strncmp(v->name, &optarg[flen + 1], vlen) &&1180!strncmp(t->name, &optarg[flen + 1 + vlen + !!vlen], tlen))1181return true;1182break;1183}1184}11851186/*1187* If there are no positive tests then we assume user just wants1188* exclusions and everything else is a pass.1189*/1190return !has_positive;1191}11921193static void __run_test(struct __fixture_metadata *f,1194struct __fixture_variant_metadata *variant,1195struct __test_metadata *t)1196{1197struct __test_xfail *xfail;1198char test_name[1024];1199const char *diagnostic;1200int child;12011202/* reset test struct */1203t->exit_code = KSFT_PASS;1204t->trigger = 0;1205t->aborted = false;1206t->no_teardown = NULL;1207memset(t->results->reason, 0, sizeof(t->results->reason));12081209snprintf(test_name, sizeof(test_name), "%s%s%s.%s",1210f->name, variant->name[0] ? "." : "", variant->name, t->name);12111212ksft_print_msg(" RUN %s ...\n", test_name);12131214/* Make sure output buffers are flushed before fork */1215fflush(stdout);1216fflush(stderr);12171218child = fork();1219if (child < 0) {1220ksft_print_msg("ERROR SPAWNING TEST CHILD\n");1221t->exit_code = KSFT_FAIL;1222} else if (child == 0) {1223setpgrp();1224t->fn(t, variant);1225_exit(t->exit_code);1226} else {1227t->pid = child;1228__wait_for_test(t);1229}1230ksft_print_msg(" %4s %s\n",1231__test_passed(t) ? "OK" : "FAIL", test_name);12321233/* Check if we're expecting this test to fail */1234for (xfail = variant->xfails; xfail; xfail = xfail->next)1235if (xfail->test == t)1236break;1237if (xfail)1238t->exit_code = __test_passed(t) ? KSFT_XPASS : KSFT_XFAIL;12391240if (t->results->reason[0])1241diagnostic = t->results->reason;1242else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)1243diagnostic = NULL;1244else1245diagnostic = "unknown";12461247ksft_test_result_code(t->exit_code, test_name,1248diagnostic ? "%s" : NULL, diagnostic);1249}12501251static int test_harness_run(int argc, char **argv)1252{1253struct __fixture_variant_metadata no_variant = { .name = "", };1254struct __fixture_variant_metadata *v;1255struct __fixture_metadata *f;1256struct __test_results *results;1257struct __test_metadata *t;1258int ret;1259unsigned int case_count = 0, test_count = 0;1260unsigned int count = 0;1261unsigned int pass_count = 0;12621263ret = test_harness_argv_check(argc, argv);1264if (ret != KSFT_PASS)1265return ret;12661267for (f = __fixture_list; f; f = f->next) {1268for (v = f->variant ?: &no_variant; v; v = v->next) {1269unsigned int old_tests = test_count;12701271for (t = f->tests; t; t = t->next)1272if (test_enabled(argc, argv, f, v, t))1273test_count++;12741275if (old_tests != test_count)1276case_count++;1277}1278}12791280results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,1281MAP_SHARED | MAP_ANONYMOUS, -1, 0);12821283ksft_print_header();1284ksft_set_plan(test_count);1285ksft_print_msg("Starting %u tests from %u test cases.\n",1286test_count, case_count);1287for (f = __fixture_list; f; f = f->next) {1288for (v = f->variant ?: &no_variant; v; v = v->next) {1289for (t = f->tests; t; t = t->next) {1290if (!test_enabled(argc, argv, f, v, t))1291continue;1292count++;1293t->results = results;1294__run_test(f, v, t);1295t->results = NULL;1296if (__test_passed(t))1297pass_count++;1298else1299ret = 1;1300}1301}1302}1303munmap(results, sizeof(*results));13041305ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",1306pass_count, count);1307ksft_exit(ret == 0);13081309/* unreachable */1310return KSFT_FAIL;1311}13121313static void __attribute__((constructor)) __constructor_order_first(void)1314{1315__constructor_order_forward = true;1316}13171318#endif /* __KSELFTEST_HARNESS_H */131913201321