brintos

brintos / linux-shallow public Read only

0
0
Text · 35.2 KiB · a5a7241 Raw
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