Path: blob/master/tools/testing/selftests/kselftest_harness.h
26282 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"7172#define TEST_TIMEOUT_DEFAULT 307374/* Utilities exposed to the test definitions */75#ifndef TH_LOG_STREAM76# define TH_LOG_STREAM stderr77#endif7879#ifndef TH_LOG_ENABLED80# define TH_LOG_ENABLED 181#endif8283/**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 { \100if (TH_LOG_ENABLED) \101__TH_LOG(fmt, ##__VA_ARGS__); \102} while (0)103104/* Unconditional logger for internal use. */105#define __TH_LOG(fmt, ...) \106fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \107__FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)108109/**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 { \124snprintf(_metadata->results->reason, \125sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \126if (TH_LOG_ENABLED) { \127fprintf(TH_LOG_STREAM, "# SKIP %s\n", \128_metadata->results->reason); \129} \130_metadata->exit_code = KSFT_SKIP; \131_metadata->trigger = 0; \132statement; \133} while (0)134135/**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)153154/**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)172173#define __TEST_IMPL(test_name, _signal) \174static void test_name(struct __test_metadata *_metadata); \175static void wrapper_##test_name( \176struct __test_metadata *_metadata, \177struct __fixture_variant_metadata __attribute__((unused)) *variant) \178{ \179test_name(_metadata); \180} \181static struct __test_metadata _##test_name##_object = \182{ .name = #test_name, \183.fn = &wrapper_##test_name, \184.fixture = &_fixture_global, \185.termsig = _signal, \186.timeout = TEST_TIMEOUT_DEFAULT, }; \187static void __attribute__((constructor)) _register_##test_name(void) \188{ \189__register_test(&_##test_name##_object); \190} \191static void test_name( \192struct __test_metadata __attribute__((unused)) *_metadata)193194/**195* FIXTURE_DATA() - Wraps the struct name so we have one less196* argument to pass around197*198* @datatype_name: datatype name199*200* .. code-block:: c201*202* FIXTURE_DATA(datatype_name)203*204* Almost always, you want just FIXTURE() instead (see below).205* This call may be used when the type of the fixture data206* is needed. In general, this should not be needed unless207* the *self* is being passed to a helper directly.208*/209#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name210211/**212* FIXTURE() - Called once per fixture to setup the data and213* register214*215* @fixture_name: fixture name216*217* .. code-block:: c218*219* FIXTURE(fixture_name) {220* type property1;221* ...222* };223*224* Defines the data provided to TEST_F()-defined tests as *self*. It should be225* populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().226*/227#define FIXTURE(fixture_name) \228FIXTURE_VARIANT(fixture_name); \229static struct __fixture_metadata _##fixture_name##_fixture_object = \230{ .name = #fixture_name, }; \231static void __attribute__((constructor)) \232_register_##fixture_name##_data(void) \233{ \234__register_fixture(&_##fixture_name##_fixture_object); \235} \236FIXTURE_DATA(fixture_name)237238/**239* FIXTURE_SETUP() - Prepares the setup function for the fixture.240* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.241*242* @fixture_name: fixture name243*244* .. code-block:: c245*246* FIXTURE_SETUP(fixture_name) { implementation }247*248* Populates the required "setup" function for a fixture. An instance of the249* datatype defined with FIXTURE_DATA() will be exposed as *self* for the250* implementation.251*252* ASSERT_* are valid for use in this context and will prempt the execution253* of any dependent fixture tests.254*255* A bare "return;" statement may be used to return early.256*/257#define FIXTURE_SETUP(fixture_name) \258static void fixture_name##_setup( \259struct __test_metadata __attribute__((unused)) *_metadata, \260FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \261const FIXTURE_VARIANT(fixture_name) \262__attribute__((unused)) *variant)263264/**265* FIXTURE_TEARDOWN()266* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.267*268* @fixture_name: fixture name269*270* .. code-block:: c271*272* FIXTURE_TEARDOWN(fixture_name) { implementation }273*274* Populates the required "teardown" function for a fixture. An instance of the275* datatype defined with FIXTURE_DATA() will be exposed as *self* for the276* implementation to clean up.277*278* A bare "return;" statement may be used to return early.279*/280#define FIXTURE_TEARDOWN(fixture_name) \281static const bool fixture_name##_teardown_parent; \282__FIXTURE_TEARDOWN(fixture_name)283284/**285* FIXTURE_TEARDOWN_PARENT()286* *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.287*288* @fixture_name: fixture name289*290* .. code-block:: c291*292* FIXTURE_TEARDOWN_PARENT(fixture_name) { implementation }293*294* Same as FIXTURE_TEARDOWN() but run this code in a parent process. This295* enables the test process to drop its privileges without impacting the296* related FIXTURE_TEARDOWN_PARENT() (e.g. to remove files from a directory297* where write access was dropped).298*299* To make it possible for the parent process to use *self*, share (MAP_SHARED)300* the fixture data between all forked processes.301*/302#define FIXTURE_TEARDOWN_PARENT(fixture_name) \303static const bool fixture_name##_teardown_parent = true; \304__FIXTURE_TEARDOWN(fixture_name)305306#define __FIXTURE_TEARDOWN(fixture_name) \307static void fixture_name##_teardown( \308struct __test_metadata __attribute__((unused)) *_metadata, \309FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \310const FIXTURE_VARIANT(fixture_name) \311__attribute__((unused)) *variant)312313/**314* FIXTURE_VARIANT() - Optionally called once per fixture315* to declare fixture variant316*317* @fixture_name: fixture name318*319* .. code-block:: c320*321* FIXTURE_VARIANT(fixture_name) {322* type property1;323* ...324* };325*326* Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and327* FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with328* different arguments.329*/330#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name331332/**333* FIXTURE_VARIANT_ADD() - Called once per fixture334* variant to setup and register the data335*336* @fixture_name: fixture name337* @variant_name: name of the parameter set338*339* .. code-block:: c340*341* FIXTURE_VARIANT_ADD(fixture_name, variant_name) {342* .property1 = val1,343* ...344* };345*346* Defines a variant of the test fixture, provided to FIXTURE_SETUP() and347* TEST_F() as *variant*. Tests of each fixture will be run once for each348* variant.349*/350#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \351extern const FIXTURE_VARIANT(fixture_name) \352_##fixture_name##_##variant_name##_variant; \353static struct __fixture_variant_metadata \354_##fixture_name##_##variant_name##_object = \355{ .name = #variant_name, \356.data = &_##fixture_name##_##variant_name##_variant}; \357static void __attribute__((constructor)) \358_register_##fixture_name##_##variant_name(void) \359{ \360__register_fixture_variant(&_##fixture_name##_fixture_object, \361&_##fixture_name##_##variant_name##_object); \362} \363const FIXTURE_VARIANT(fixture_name) \364_##fixture_name##_##variant_name##_variant =365366/**367* TEST_F() - Emits test registration and helpers for368* fixture-based test cases369*370* @fixture_name: fixture name371* @test_name: test name372*373* .. code-block:: c374*375* TEST_F(fixture, name) { implementation }376*377* Defines a test that depends on a fixture (e.g., is part of a test case).378* Very similar to TEST() except that *self* is the setup instance of fixture's379* datatype exposed for use by the implementation.380*381* The _metadata object is shared (MAP_SHARED) with all the potential forked382* processes, which enables them to use EXCEPT_*() and ASSERT_*().383*384* The *self* object is only shared with the potential forked processes if385* FIXTURE_TEARDOWN_PARENT() is used instead of FIXTURE_TEARDOWN().386*/387#define TEST_F(fixture_name, test_name) \388__TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)389390#define TEST_F_SIGNAL(fixture_name, test_name, signal) \391__TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)392393#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \394__TEST_F_IMPL(fixture_name, test_name, -1, timeout)395396#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \397static void fixture_name##_##test_name( \398struct __test_metadata *_metadata, \399FIXTURE_DATA(fixture_name) *self, \400const FIXTURE_VARIANT(fixture_name) *variant); \401static void wrapper_##fixture_name##_##test_name( \402struct __test_metadata *_metadata, \403struct __fixture_variant_metadata *variant) \404{ \405/* fixture data is alloced, setup, and torn down per call. */ \406FIXTURE_DATA(fixture_name) self_private, *self = NULL; \407pid_t child = 1; \408int status = 0; \409/* Makes sure there is only one teardown, even when child forks again. */ \410_metadata->no_teardown = mmap(NULL, sizeof(*_metadata->no_teardown), \411PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \412*_metadata->no_teardown = true; \413if (sizeof(*self) > 0) { \414if (fixture_name##_teardown_parent) { \415self = mmap(NULL, sizeof(*self), PROT_READ | PROT_WRITE, \416MAP_SHARED | MAP_ANONYMOUS, -1, 0); \417} else { \418memset(&self_private, 0, sizeof(self_private)); \419self = &self_private; \420} \421} \422_metadata->variant = variant->data; \423_metadata->self = self; \424/* _metadata and potentially self are shared with all forks. */ \425child = fork(); \426if (child == 0) { \427fixture_name##_setup(_metadata, self, variant->data); \428/* Let setup failure terminate early. */ \429if (_metadata->exit_code) \430_exit(0); \431*_metadata->no_teardown = false; \432fixture_name##_##test_name(_metadata, self, variant->data); \433_metadata->teardown_fn(false, _metadata, self, variant->data); \434_exit(0); \435} else if (child < 0 || child != waitpid(child, &status, 0)) { \436ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \437_metadata->exit_code = KSFT_FAIL; \438} \439_metadata->teardown_fn(true, _metadata, self, variant->data); \440munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \441_metadata->no_teardown = NULL; \442if (self && fixture_name##_teardown_parent) \443munmap(self, sizeof(*self)); \444if (WIFEXITED(status)) { \445if (WEXITSTATUS(status)) \446_metadata->exit_code = WEXITSTATUS(status); \447} else if (WIFSIGNALED(status)) { \448/* Forward signal to __wait_for_test(). */ \449kill(getpid(), WTERMSIG(status)); \450} \451} \452static void wrapper_##fixture_name##_##test_name##_teardown( \453bool in_parent, struct __test_metadata *_metadata, \454void *self, const void *variant) \455{ \456if (fixture_name##_teardown_parent == in_parent && \457!__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \458fixture_name##_teardown(_metadata, self, variant); \459} \460static struct __test_metadata *_##fixture_name##_##test_name##_object; \461static void __attribute__((constructor)) \462_register_##fixture_name##_##test_name(void) \463{ \464struct __test_metadata *object = mmap(NULL, sizeof(*object), \465PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \466object->name = #test_name; \467object->fn = &wrapper_##fixture_name##_##test_name; \468object->fixture = &_##fixture_name##_fixture_object; \469object->teardown_fn = &wrapper_##fixture_name##_##test_name##_teardown; \470object->termsig = signal; \471object->timeout = tmout; \472_##fixture_name##_##test_name##_object = object; \473__register_test(object); \474} \475static void fixture_name##_##test_name( \476struct __test_metadata __attribute__((unused)) *_metadata, \477FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \478const FIXTURE_VARIANT(fixture_name) \479__attribute__((unused)) *variant)480481/**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 \491int main(int argc, char **argv) { \492return test_harness_run(argc, argv); \493}494495/**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*/502503/**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)513514/**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)524525/**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)535536/**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)546547/**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)557558/**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)568569/**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)578579/**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)588589/**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)598599/**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)609610/**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)620621/**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)631632/**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)642643/**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)653654/**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)664665/**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)675676/**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)686687/**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)696697/**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)706707/**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)716717/**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)727728/**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)738739#ifndef ARRAY_SIZE740#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))741#endif742743/* 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) \750for (; _metadata->trigger; _metadata->trigger = \751__bail(_assert, _metadata))752753#define is_signed_var(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))754755#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); \759if (!(__exp _t __seen)) { \760/* Report with actual signedness to avoid weird output. */ \761switch (is_signed_var(__exp) * 2 + is_signed_var(__seen)) { \762case 0: { \763uintmax_t __exp_print = (uintmax_t)__exp; \764uintmax_t __seen_print = (uintmax_t)__seen; \765__TH_LOG("Expected %s (%ju) %s %s (%ju)", \766_expected_str, __exp_print, #_t, \767_seen_str, __seen_print); \768break; \769} \770case 1: { \771uintmax_t __exp_print = (uintmax_t)__exp; \772intmax_t __seen_print = (intmax_t)__seen; \773__TH_LOG("Expected %s (%ju) %s %s (%jd)", \774_expected_str, __exp_print, #_t, \775_seen_str, __seen_print); \776break; \777} \778case 2: { \779intmax_t __exp_print = (intmax_t)__exp; \780uintmax_t __seen_print = (uintmax_t)__seen; \781__TH_LOG("Expected %s (%jd) %s %s (%ju)", \782_expected_str, __exp_print, #_t, \783_seen_str, __seen_print); \784break; \785} \786case 3: { \787intmax_t __exp_print = (intmax_t)__exp; \788intmax_t __seen_print = (intmax_t)__seen; \789__TH_LOG("Expected %s (%jd) %s %s (%jd)", \790_expected_str, __exp_print, #_t, \791_seen_str, __seen_print); \792break; \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)800801#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \802const char *__exp = (_expected); \803const char *__seen = (_seen); \804if (!(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)810811/* List helpers */812#define __LIST_APPEND(head, item) \813{ \814/* Circular linked list where only prev is circular. */ \815if (head == NULL) { \816head = item; \817item->next = NULL; \818item->prev = item; \819return; \820} \821if (__constructor_order_forward) { \822item->next = NULL; \823item->prev = head->prev; \824item->prev->next = item; \825head->prev = item; \826} else { \827item->next = head; \828item->next->prev = item; \829item->prev = item; \830head = item; \831} \832}833834struct __test_results {835char reason[1024]; /* Reason for test result */836};837838struct __test_metadata;839struct __fixture_variant_metadata;840841/* Contains all the information about a fixture. */842struct __fixture_metadata {843const char *name;844struct __test_metadata *tests;845struct __fixture_variant_metadata *variant;846struct __fixture_metadata *prev, *next;847} _fixture_global __attribute__((unused)) = {848.name = "global",849.prev = &_fixture_global,850};851852struct __test_xfail {853struct __fixture_metadata *fixture;854struct __fixture_variant_metadata *variant;855struct __test_metadata *test;856struct __test_xfail *prev, *next;857};858859/**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) \870static 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}; \876static 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}883884static struct __fixture_metadata *__fixture_list = &_fixture_global;885static bool __constructor_order_forward;886887static inline void __register_fixture(struct __fixture_metadata *f)888{889__LIST_APPEND(__fixture_list, f);890}891892struct __fixture_variant_metadata {893const char *name;894const void *data;895struct __test_xfail *xfails;896struct __fixture_variant_metadata *prev, *next;897};898899static inline void900__register_fixture_variant(struct __fixture_metadata *f,901struct __fixture_variant_metadata *variant)902{903__LIST_APPEND(f->variant, variant);904}905906/* Contains all the information for test execution and status checking. */907struct __test_metadata {908const char *name;909void (*fn)(struct __test_metadata *,910struct __fixture_variant_metadata *);911pid_t pid; /* pid of test when being run */912struct __fixture_metadata *fixture;913void (*teardown_fn)(bool in_parent, struct __test_metadata *_metadata,914void *self, const void *variant);915int termsig;916int exit_code;917int trigger; /* extra handler after the evaluation */918int timeout; /* seconds to wait for test timeout */919bool aborted; /* stopped test due to failed ASSERT */920bool *no_teardown; /* fixture needs teardown */921void *self;922const void *variant;923struct __test_results *results;924struct __test_metadata *prev, *next;925};926927static inline bool __test_passed(struct __test_metadata *metadata)928{929return metadata->exit_code != KSFT_FAIL &&930metadata->exit_code <= KSFT_SKIP;931}932933/*934* Since constructors are called in reverse order, reverse the test935* list so tests are run in source declaration order.936* https://gcc.gnu.org/onlinedocs/gccint/Initialization.html937* However, it seems not all toolchains do this correctly, so use938* __constructor_order_foward to detect which direction is called first939* and adjust list building logic to get things running in the right940* direction.941*/942static inline void __register_test(struct __test_metadata *t)943{944__LIST_APPEND(t->fixture->tests, t);945}946947static inline void __register_xfail(struct __test_xfail *xf)948{949__LIST_APPEND(xf->variant->xfails, xf);950}951952static inline int __bail(int for_realz, struct __test_metadata *t)953{954/* if this is ASSERT, return immediately. */955if (for_realz) {956if (t->teardown_fn)957t->teardown_fn(false, t, t->self, t->variant);958abort();959}960/* otherwise, end the for loop and continue. */961return 0;962}963964static void __wait_for_test(struct __test_metadata *t)965{966/*967* Sets status so that WIFEXITED(status) returns true and968* WEXITSTATUS(status) returns KSFT_FAIL. This safe default value969* should never be evaluated because of the waitpid(2) check and970* timeout handling.971*/972int status = KSFT_FAIL << 8;973struct pollfd poll_child;974int ret, child, childfd;975bool timed_out = false;976977childfd = syscall(__NR_pidfd_open, t->pid, 0);978if (childfd == -1) {979t->exit_code = KSFT_FAIL;980fprintf(TH_LOG_STREAM,981"# %s: unable to open pidfd\n",982t->name);983return;984}985986poll_child.fd = childfd;987poll_child.events = POLLIN;988ret = poll(&poll_child, 1, t->timeout * 1000);989if (ret == -1) {990t->exit_code = KSFT_FAIL;991fprintf(TH_LOG_STREAM,992"# %s: unable to wait on child pidfd\n",993t->name);994return;995} else if (ret == 0) {996timed_out = true;997/* signal process group */998kill(-(t->pid), SIGKILL);999}1000child = waitpid(t->pid, &status, WNOHANG);1001if (child == -1 && errno != EINTR) {1002t->exit_code = KSFT_FAIL;1003fprintf(TH_LOG_STREAM,1004"# %s: Failed to wait for PID %d (errno: %d)\n",1005t->name, t->pid, errno);1006return;1007}10081009if (timed_out) {1010t->exit_code = KSFT_FAIL;1011fprintf(TH_LOG_STREAM,1012"# %s: Test terminated by timeout\n", t->name);1013} else if (WIFEXITED(status)) {1014if (WEXITSTATUS(status) == KSFT_SKIP ||1015WEXITSTATUS(status) == KSFT_XPASS ||1016WEXITSTATUS(status) == KSFT_XFAIL) {1017t->exit_code = WEXITSTATUS(status);1018} else if (t->termsig != -1) {1019t->exit_code = KSFT_FAIL;1020fprintf(TH_LOG_STREAM,1021"# %s: Test exited normally instead of by signal (code: %d)\n",1022t->name,1023WEXITSTATUS(status));1024} else {1025switch (WEXITSTATUS(status)) {1026/* Success */1027case KSFT_PASS:1028t->exit_code = KSFT_PASS;1029break;1030/* Failure */1031default:1032t->exit_code = KSFT_FAIL;1033fprintf(TH_LOG_STREAM,1034"# %s: Test failed\n",1035t->name);1036}1037}1038} else if (WIFSIGNALED(status)) {1039t->exit_code = KSFT_FAIL;1040if (WTERMSIG(status) == SIGABRT) {1041fprintf(TH_LOG_STREAM,1042"# %s: Test terminated by assertion\n",1043t->name);1044} else if (WTERMSIG(status) == t->termsig) {1045t->exit_code = KSFT_PASS;1046} else {1047fprintf(TH_LOG_STREAM,1048"# %s: Test terminated unexpectedly by signal %d\n",1049t->name,1050WTERMSIG(status));1051}1052} else {1053t->exit_code = KSFT_FAIL;1054fprintf(TH_LOG_STREAM,1055"# %s: Test ended in some other way [%u]\n",1056t->name,1057status);1058}1059}10601061static void test_harness_list_tests(void)1062{1063struct __fixture_variant_metadata *v;1064struct __fixture_metadata *f;1065struct __test_metadata *t;10661067for (f = __fixture_list; f; f = f->next) {1068v = f->variant;1069t = f->tests;10701071if (f == __fixture_list)1072fprintf(stderr, "%-20s %-25s %s\n",1073"# FIXTURE", "VARIANT", "TEST");1074else1075fprintf(stderr, "--------------------------------------------------------------------------------\n");10761077do {1078fprintf(stderr, "%-20s %-25s %s\n",1079t == f->tests ? f->name : "",1080v ? v->name : "",1081t ? t->name : "");10821083v = v ? v->next : NULL;1084t = t ? t->next : NULL;1085} while (v || t);1086}1087}10881089static int test_harness_argv_check(int argc, char **argv)1090{1091int opt;10921093while ((opt = getopt(argc, argv, "hlF:f:V:v:t:T:r:")) != -1) {1094switch (opt) {1095case 'f':1096case 'F':1097case 'v':1098case 'V':1099case 't':1100case 'T':1101case 'r':1102break;1103case 'l':1104test_harness_list_tests();1105return KSFT_SKIP;1106case 'h':1107default:1108fprintf(stderr,1109"Usage: %s [-h|-l] [-t|-T|-v|-V|-f|-F|-r name]\n"1110"\t-h print help\n"1111"\t-l list all tests\n"1112"\n"1113"\t-t name include test\n"1114"\t-T name exclude test\n"1115"\t-v name include variant\n"1116"\t-V name exclude variant\n"1117"\t-f name include fixture\n"1118"\t-F name exclude fixture\n"1119"\t-r name run specified test\n"1120"\n"1121"Test filter options can be specified "1122"multiple times. The filtering stops\n"1123"at the first match. For example to "1124"include all tests from variant 'bla'\n"1125"but not test 'foo' specify '-T foo -v bla'.\n"1126"", argv[0]);1127return opt == 'h' ? KSFT_SKIP : KSFT_FAIL;1128}1129}11301131return KSFT_PASS;1132}11331134static bool test_enabled(int argc, char **argv,1135struct __fixture_metadata *f,1136struct __fixture_variant_metadata *v,1137struct __test_metadata *t)1138{1139unsigned int flen = 0, vlen = 0, tlen = 0;1140bool has_positive = false;1141int opt;11421143optind = 1;1144while ((opt = getopt(argc, argv, "F:f:V:v:t:T:r:")) != -1) {1145has_positive |= islower(opt);11461147switch (tolower(opt)) {1148case 't':1149if (!strcmp(t->name, optarg))1150return islower(opt);1151break;1152case 'f':1153if (!strcmp(f->name, optarg))1154return islower(opt);1155break;1156case 'v':1157if (!strcmp(v->name, optarg))1158return islower(opt);1159break;1160case 'r':1161if (!tlen) {1162flen = strlen(f->name);1163vlen = strlen(v->name);1164tlen = strlen(t->name);1165}1166if (strlen(optarg) == flen + 1 + vlen + !!vlen + tlen &&1167!strncmp(f->name, &optarg[0], flen) &&1168!strncmp(v->name, &optarg[flen + 1], vlen) &&1169!strncmp(t->name, &optarg[flen + 1 + vlen + !!vlen], tlen))1170return true;1171break;1172}1173}11741175/*1176* If there are no positive tests then we assume user just wants1177* exclusions and everything else is a pass.1178*/1179return !has_positive;1180}11811182static void __run_test(struct __fixture_metadata *f,1183struct __fixture_variant_metadata *variant,1184struct __test_metadata *t)1185{1186struct __test_xfail *xfail;1187char test_name[1024];1188const char *diagnostic;1189int child;11901191/* reset test struct */1192t->exit_code = KSFT_PASS;1193t->trigger = 0;1194t->aborted = false;1195t->no_teardown = NULL;1196memset(t->results->reason, 0, sizeof(t->results->reason));11971198snprintf(test_name, sizeof(test_name), "%s%s%s.%s",1199f->name, variant->name[0] ? "." : "", variant->name, t->name);12001201ksft_print_msg(" RUN %s ...\n", test_name);12021203/* Make sure output buffers are flushed before fork */1204fflush(stdout);1205fflush(stderr);12061207child = fork();1208if (child < 0) {1209ksft_print_msg("ERROR SPAWNING TEST CHILD\n");1210t->exit_code = KSFT_FAIL;1211} else if (child == 0) {1212setpgrp();1213t->fn(t, variant);1214_exit(t->exit_code);1215} else {1216t->pid = child;1217__wait_for_test(t);1218}1219ksft_print_msg(" %4s %s\n",1220__test_passed(t) ? "OK" : "FAIL", test_name);12211222/* Check if we're expecting this test to fail */1223for (xfail = variant->xfails; xfail; xfail = xfail->next)1224if (xfail->test == t)1225break;1226if (xfail)1227t->exit_code = __test_passed(t) ? KSFT_XPASS : KSFT_XFAIL;12281229if (t->results->reason[0])1230diagnostic = t->results->reason;1231else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)1232diagnostic = NULL;1233else1234diagnostic = "unknown";12351236ksft_test_result_code(t->exit_code, test_name,1237diagnostic ? "%s" : NULL, diagnostic);1238}12391240static int test_harness_run(int argc, char **argv)1241{1242struct __fixture_variant_metadata no_variant = { .name = "", };1243struct __fixture_variant_metadata *v;1244struct __fixture_metadata *f;1245struct __test_results *results;1246struct __test_metadata *t;1247int ret;1248unsigned int case_count = 0, test_count = 0;1249unsigned int count = 0;1250unsigned int pass_count = 0;12511252ret = test_harness_argv_check(argc, argv);1253if (ret != KSFT_PASS)1254return ret;12551256for (f = __fixture_list; f; f = f->next) {1257for (v = f->variant ?: &no_variant; v; v = v->next) {1258unsigned int old_tests = test_count;12591260for (t = f->tests; t; t = t->next)1261if (test_enabled(argc, argv, f, v, t))1262test_count++;12631264if (old_tests != test_count)1265case_count++;1266}1267}12681269results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,1270MAP_SHARED | MAP_ANONYMOUS, -1, 0);12711272ksft_print_header();1273ksft_set_plan(test_count);1274ksft_print_msg("Starting %u tests from %u test cases.\n",1275test_count, case_count);1276for (f = __fixture_list; f; f = f->next) {1277for (v = f->variant ?: &no_variant; v; v = v->next) {1278for (t = f->tests; t; t = t->next) {1279if (!test_enabled(argc, argv, f, v, t))1280continue;1281count++;1282t->results = results;1283__run_test(f, v, t);1284t->results = NULL;1285if (__test_passed(t))1286pass_count++;1287else1288ret = 1;1289}1290}1291}1292munmap(results, sizeof(*results));12931294ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",1295pass_count, count);1296ksft_exit(ret == 0);12971298/* unreachable */1299return KSFT_FAIL;1300}13011302static void __attribute__((constructor)) __constructor_order_first(void)1303{1304__constructor_order_forward = true;1305}13061307#endif /* __KSELFTEST_HARNESS_H */130813091310