2019-06-04 11:11:14 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2015-06-16 20:54:14 +03:00
/*
* Copyright ( c ) 2012 The Chromium OS Authors . All rights reserved .
*
2017-05-26 21:43:57 +03:00
* kselftest_harness . h : simple C unit test helper .
2015-06-16 20:54:14 +03:00
*
2017-06-05 21:37:17 +03:00
* See documentation in Documentation / dev - tools / kselftest . rst
2015-06-16 20:54:14 +03:00
*
* API inspired by code . google . com / p / googletest
*/
2017-05-26 21:43:57 +03:00
2017-06-05 21:37:17 +03:00
/**
* DOC : example
*
* . . code - block : : c
*
* # include " ../kselftest_harness.h "
*
* TEST ( standalone_test ) {
* do_some_stuff ;
* EXPECT_GT ( 10 , stuff ) {
* stuff_state_t state ;
* enumerate_stuff_state ( & state ) ;
* TH_LOG ( " expectation failed with state: %s " , state . msg ) ;
* }
* more_stuff ;
* ASSERT_NE ( some_stuff , NULL ) TH_LOG ( " how did it happen?! " ) ;
* last_stuff ;
* EXPECT_EQ ( 0 , last_stuff ) ;
* }
*
* FIXTURE ( my_fixture ) {
* mytype_t * data ;
* int awesomeness_level ;
* } ;
* FIXTURE_SETUP ( my_fixture ) {
* self - > data = mytype_new ( ) ;
* ASSERT_NE ( NULL , self - > data ) ;
* }
* FIXTURE_TEARDOWN ( my_fixture ) {
* mytype_free ( self - > data ) ;
* }
* TEST_F ( my_fixture , data_is_good ) {
* EXPECT_EQ ( 1 , is_my_data_good ( self - > data ) ) ;
* }
*
* TEST_HARNESS_MAIN
*/
2017-05-26 21:43:57 +03:00
# ifndef __KSELFTEST_HARNESS_H
# define __KSELFTEST_HARNESS_H
2015-06-16 20:54:14 +03:00
2020-06-22 21:16:48 +03:00
# ifndef _GNU_SOURCE
2015-06-16 20:54:14 +03:00
# define _GNU_SOURCE
2020-06-22 21:16:48 +03:00
# endif
2017-08-07 02:23:37 +03:00
# include <asm/types.h>
# include <errno.h>
# include <stdbool.h>
2015-12-11 01:50:25 +03:00
# include <stdint.h>
2015-06-16 20:54:14 +03:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2020-06-22 21:16:51 +03:00
# include <sys/mman.h>
2015-06-16 20:54:14 +03:00
# include <sys/types.h>
# include <sys/wait.h>
# include <unistd.h>
2020-06-22 21:16:48 +03:00
# include "kselftest.h"
2019-05-24 01:42:22 +03:00
# define TEST_TIMEOUT_DEFAULT 30
2015-06-16 20:54:14 +03:00
2017-05-26 21:44:01 +03:00
/* Utilities exposed to the test definitions */
# ifndef TH_LOG_STREAM
# define TH_LOG_STREAM stderr
# endif
# ifndef TH_LOG_ENABLED
# define TH_LOG_ENABLED 1
# endif
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* TH_LOG ( )
2017-06-05 21:37:17 +03:00
*
* @ fmt : format string
* @ . . . : optional arguments
*
* . . code - block : : c
*
* TH_LOG ( format , . . . )
*
2017-05-26 21:44:01 +03:00
* Optional debug logging function available for use in tests .
* Logging may be enabled or disabled by defining TH_LOG_ENABLED .
* E . g . , # define TH_LOG_ENABLED 1
2017-06-05 21:37:17 +03:00
*
2017-05-26 21:44:01 +03:00
* If no definition is provided , logging is enabled by default .
2017-08-07 02:23:37 +03:00
*
* If there is no way to print an error message for the process running the
* test ( e . g . not allowed to write to stderr ) , it is still possible to get the
* ASSERT_ * number for which the test failed . This behavior can be enabled by
* writing ` _metadata - > no_print = true ; ` before the check sequence that is
* unable to print . When an error occur , instead of printing an error message
* and calling ` abort ( 3 ) ` , the test process call ` _exit ( 2 ) ` with the assert
* number as argument , which is then printed by the parent process .
2015-06-16 20:54:14 +03:00
*/
2017-05-26 21:44:01 +03:00
# define TH_LOG(fmt, ...) do { \
if ( TH_LOG_ENABLED ) \
__TH_LOG ( fmt , # # __VA_ARGS__ ) ; \
} while ( 0 )
/* Unconditional logger for internal use. */
# define __TH_LOG(fmt, ...) \
2020-06-22 21:16:48 +03:00
fprintf ( TH_LOG_STREAM , " # %s:%d:%s: " fmt " \n " , \
2017-05-26 21:44:01 +03:00
__FILE__ , __LINE__ , _metadata - > name , # # __VA_ARGS__ )
2015-06-16 20:54:14 +03:00
2018-03-15 19:59:16 +03:00
/**
2021-01-14 11:04:46 +03:00
* SKIP ( )
2018-03-15 19:59:16 +03:00
*
2020-06-22 21:16:49 +03:00
* @ statement : statement to run after reporting SKIP
2018-03-15 19:59:16 +03:00
* @ fmt : format string
* @ . . . : optional arguments
*
2021-01-14 11:04:46 +03:00
* . . code - block : : c
*
* SKIP ( statement , fmt , . . . ) ;
*
2020-06-22 21:16:49 +03:00
* This forces a " pass " after reporting why something is being skipped
2018-03-15 19:59:16 +03:00
* and runs " statement " , which is usually " return " or " goto skip " .
*/
2020-06-22 21:16:49 +03:00
# define SKIP(statement, fmt, ...) do { \
2020-06-22 21:16:51 +03:00
snprintf ( _metadata - > results - > reason , \
sizeof ( _metadata - > results - > reason ) , fmt , # # __VA_ARGS__ ) ; \
2018-03-15 19:59:16 +03:00
if ( TH_LOG_ENABLED ) { \
2020-10-08 15:26:24 +03:00
fprintf ( TH_LOG_STREAM , " # SKIP %s \n " , \
2020-06-22 21:16:51 +03:00
_metadata - > results - > reason ) ; \
2018-03-15 19:59:16 +03:00
} \
_metadata - > passed = 1 ; \
2020-06-22 21:16:49 +03:00
_metadata - > skip = 1 ; \
2018-03-15 19:59:16 +03:00
_metadata - > trigger = 0 ; \
statement ; \
} while ( 0 )
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* TEST ( ) - Defines the test function and creates the registration
2017-06-05 21:37:17 +03:00
* stub
*
* @ test_name : test name
*
* . . code - block : : c
*
* TEST ( name ) { implementation }
*
2015-06-16 20:54:14 +03:00
* Defines a test by name .
* Names must be unique and tests must not be run in parallel . The
* implementation containing block is a function and scoping should be treated
* as such . Returning early may be performed with a bare " return; " statement .
*
* EXPECT_ * and ASSERT_ * are valid in a TEST ( ) { } context .
*/
2017-05-26 21:44:01 +03:00
# define TEST(test_name) __TEST_IMPL(test_name, -1)
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* TEST_SIGNAL ( )
2017-06-05 21:37:17 +03:00
*
* @ test_name : test name
* @ signal : signal number
*
* . . code - block : : c
*
* TEST_SIGNAL ( name , signal ) { implementation }
*
2015-06-16 20:54:14 +03:00
* Defines a test by name and the expected term signal .
* Names must be unique and tests must not be run in parallel . The
* implementation containing block is a function and scoping should be treated
* as such . Returning early may be performed with a bare " return; " statement .
*
* EXPECT_ * and ASSERT_ * are valid in a TEST ( ) { } context .
*/
2017-05-26 21:44:01 +03:00
# define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
# define __TEST_IMPL(test_name, _signal) \
static void test_name ( struct __test_metadata * _metadata ) ; \
2020-04-28 04:03:50 +03:00
static inline void wrapper_ # # test_name ( \
struct __test_metadata * _metadata , \
struct __fixture_variant_metadata * variant ) \
{ \
test_name ( _metadata ) ; \
} \
2017-05-26 21:44:01 +03:00
static struct __test_metadata _ # # test_name # # _object = \
2020-04-28 04:03:48 +03:00
{ . name = # test_name , \
2020-04-28 04:03:50 +03:00
. fn = & wrapper_ # # test_name , \
2020-04-28 04:03:48 +03:00
. fixture = & _fixture_global , \
. termsig = _signal , \
2019-05-24 01:42:22 +03:00
. timeout = TEST_TIMEOUT_DEFAULT , } ; \
2017-05-26 21:44:01 +03:00
static void __attribute__ ( ( constructor ) ) _register_ # # test_name ( void ) \
{ \
__register_test ( & _ # # test_name # # _object ) ; \
} \
static void test_name ( \
struct __test_metadata __attribute__ ( ( unused ) ) * _metadata )
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* FIXTURE_DATA ( ) - Wraps the struct name so we have one less
2017-06-05 21:37:17 +03:00
* argument to pass around
*
* @ datatype_name : datatype name
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE_DATA ( datatype_name )
2017-06-05 21:37:17 +03:00
*
2020-07-05 09:12:30 +03:00
* Almost always , you want just FIXTURE ( ) instead ( see below ) .
2017-05-26 21:44:01 +03:00
* This call may be used when the type of the fixture data
* is needed . In general , this should not be needed unless
2017-06-05 21:37:17 +03:00
* the * self * is being passed to a helper directly .
2017-05-26 21:44:01 +03:00
*/
# define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* FIXTURE ( ) - Called once per fixture to setup the data and
2017-06-05 21:37:17 +03:00
* register
*
* @ fixture_name : fixture name
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE ( fixture_name ) {
2017-06-05 21:37:17 +03:00
* type property1 ;
* . . .
* } ;
*
* Defines the data provided to TEST_F ( ) - defined tests as * self * . It should be
* populated and cleaned up using FIXTURE_SETUP ( ) and FIXTURE_TEARDOWN ( ) .
2015-06-16 20:54:14 +03:00
*/
2017-05-26 21:44:01 +03:00
# define FIXTURE(fixture_name) \
2020-04-28 04:03:50 +03:00
FIXTURE_VARIANT ( fixture_name ) ; \
2020-04-28 04:03:48 +03:00
static struct __fixture_metadata _ # # fixture_name # # _fixture_object = \
{ . name = # fixture_name , } ; \
2017-05-26 21:44:01 +03:00
static void __attribute__ ( ( constructor ) ) \
_register_ # # fixture_name # # _data ( void ) \
{ \
2020-04-28 04:03:48 +03:00
__register_fixture ( & _ # # fixture_name # # _fixture_object ) ; \
2017-05-26 21:44:01 +03:00
} \
FIXTURE_DATA ( fixture_name )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* FIXTURE_SETUP ( ) - Prepares the setup function for the fixture .
2018-03-15 19:59:16 +03:00
* * _metadata * is included so that EXPECT_ * and ASSERT_ * work correctly .
2017-06-05 21:37:17 +03:00
*
* @ fixture_name : fixture name
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE_SETUP ( fixture_name ) { implementation }
2017-06-05 21:37:17 +03:00
*
2015-06-16 20:54:14 +03:00
* Populates the required " setup " function for a fixture . An instance of the
2017-06-05 21:37:17 +03:00
* datatype defined with FIXTURE_DATA ( ) will be exposed as * self * for the
2015-06-16 20:54:14 +03:00
* implementation .
*
* ASSERT_ * are valid for use in this context and will prempt the execution
* of any dependent fixture tests .
*
* A bare " return; " statement may be used to return early .
*/
2017-05-26 21:44:01 +03:00
# define FIXTURE_SETUP(fixture_name) \
void fixture_name # # _setup ( \
struct __test_metadata __attribute__ ( ( unused ) ) * _metadata , \
2020-04-28 04:03:50 +03:00
FIXTURE_DATA ( fixture_name ) __attribute__ ( ( unused ) ) * self , \
const FIXTURE_VARIANT ( fixture_name ) \
__attribute__ ( ( unused ) ) * variant )
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* FIXTURE_TEARDOWN ( )
2018-03-15 19:59:16 +03:00
* * _metadata * is included so that EXPECT_ * and ASSERT_ * work correctly .
2017-06-05 21:37:17 +03:00
*
* @ fixture_name : fixture name
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE_TEARDOWN ( fixture_name ) { implementation }
2017-06-05 21:37:17 +03:00
*
2015-06-16 20:54:14 +03:00
* Populates the required " teardown " function for a fixture . An instance of the
2017-06-05 21:37:17 +03:00
* datatype defined with FIXTURE_DATA ( ) will be exposed as * self * for the
2015-06-16 20:54:14 +03:00
* implementation to clean up .
*
* A bare " return; " statement may be used to return early .
*/
2017-05-26 21:44:01 +03:00
# define FIXTURE_TEARDOWN(fixture_name) \
void fixture_name # # _teardown ( \
struct __test_metadata __attribute__ ( ( unused ) ) * _metadata , \
FIXTURE_DATA ( fixture_name ) __attribute__ ( ( unused ) ) * self )
2015-06-16 20:54:14 +03:00
2020-04-28 04:03:50 +03:00
/**
2021-01-14 11:04:46 +03:00
* FIXTURE_VARIANT ( ) - Optionally called once per fixture
2020-04-28 04:03:50 +03:00
* to declare fixture variant
*
* @ fixture_name : fixture name
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE_VARIANT ( fixture_name ) {
2020-04-28 04:03:50 +03:00
* type property1 ;
* . . .
* } ;
*
* Defines type of constant parameters provided to FIXTURE_SETUP ( ) and TEST_F ( )
* as * variant * . Variants allow the same tests to be run with different
* arguments .
*/
# define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
/**
2021-01-14 11:04:46 +03:00
* FIXTURE_VARIANT_ADD ( ) - Called once per fixture
2020-04-28 04:03:50 +03:00
* variant to setup and register the data
*
* @ fixture_name : fixture name
* @ variant_name : name of the parameter set
*
* . . code - block : : c
*
2020-07-05 09:12:30 +03:00
* FIXTURE_VARIANT_ADD ( fixture_name , variant_name ) {
* . property1 = val1 ,
2020-04-28 04:03:50 +03:00
* . . .
* } ;
*
* Defines a variant of the test fixture , provided to FIXTURE_SETUP ( ) and
* TEST_F ( ) as * variant * . Tests of each fixture will be run once for each
* variant .
*/
# define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
extern FIXTURE_VARIANT ( fixture_name ) \
_ # # fixture_name # # _ # # variant_name # # _variant ; \
static struct __fixture_variant_metadata \
_ # # fixture_name # # _ # # variant_name # # _object = \
{ . name = # variant_name , \
. data = & _ # # fixture_name # # _ # # variant_name # # _variant } ; \
static void __attribute__ ( ( constructor ) ) \
_register_ # # fixture_name # # _ # # variant_name ( void ) \
{ \
__register_fixture_variant ( & _ # # fixture_name # # _fixture_object , \
& _ # # fixture_name # # _ # # variant_name # # _object ) ; \
} \
FIXTURE_VARIANT ( fixture_name ) \
_ # # fixture_name # # _ # # variant_name # # _variant =
2017-06-05 21:37:17 +03:00
/**
2021-01-14 11:04:46 +03:00
* TEST_F ( ) - Emits test registration and helpers for
2017-06-05 21:37:17 +03:00
* fixture - based test cases
*
* @ fixture_name : fixture name
* @ test_name : test name
*
* . . code - block : : c
*
* TEST_F ( fixture , name ) { implementation }
*
2015-06-16 20:54:14 +03:00
* Defines a test that depends on a fixture ( e . g . , is part of a test case ) .
2017-06-05 21:37:17 +03:00
* Very similar to TEST ( ) except that * self * is the setup instance of fixture ' s
2015-06-16 20:54:14 +03:00
* datatype exposed for use by the implementation .
2018-03-15 19:59:16 +03:00
*
* Warning : use of ASSERT_ * here will skip TEARDOWN .
2015-06-16 20:54:14 +03:00
*/
2017-06-05 21:37:17 +03:00
/* TODO(wad) register fixtures on dedicated test lists. */
2017-05-26 21:44:01 +03:00
# define TEST_F(fixture_name, test_name) \
2019-05-24 01:42:22 +03:00
__TEST_F_IMPL ( fixture_name , test_name , - 1 , TEST_TIMEOUT_DEFAULT )
2015-06-16 20:54:14 +03:00
2017-05-26 21:44:01 +03:00
# define TEST_F_SIGNAL(fixture_name, test_name, signal) \
2019-05-24 01:42:22 +03:00
__TEST_F_IMPL ( fixture_name , test_name , signal , TEST_TIMEOUT_DEFAULT )
2015-06-16 20:54:14 +03:00
2019-05-24 01:42:22 +03:00
# define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
__TEST_F_IMPL ( fixture_name , test_name , - 1 , timeout )
# define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
2015-06-16 20:54:14 +03:00
static void fixture_name # # _ # # test_name ( \
struct __test_metadata * _metadata , \
2020-04-28 04:03:50 +03:00
FIXTURE_DATA ( fixture_name ) * self , \
const FIXTURE_VARIANT ( fixture_name ) * variant ) ; \
2015-06-16 20:54:14 +03:00
static inline void wrapper_ # # fixture_name # # _ # # test_name ( \
2020-04-28 04:03:50 +03:00
struct __test_metadata * _metadata , \
struct __fixture_variant_metadata * variant ) \
2015-06-16 20:54:14 +03:00
{ \
/* fixture data is alloced, setup, and torn down per call. */ \
2017-05-26 21:44:01 +03:00
FIXTURE_DATA ( fixture_name ) self ; \
memset ( & self , 0 , sizeof ( FIXTURE_DATA ( fixture_name ) ) ) ; \
2020-04-28 04:03:50 +03:00
fixture_name # # _setup ( _metadata , & self , variant - > data ) ; \
2015-06-16 20:54:14 +03:00
/* Let setup failure terminate early. */ \
if ( ! _metadata - > passed ) \
return ; \
2020-04-28 04:03:50 +03:00
fixture_name # # _ # # test_name ( _metadata , & self , variant - > data ) ; \
2015-06-16 20:54:14 +03:00
fixture_name # # _teardown ( _metadata , & self ) ; \
} \
static struct __test_metadata \
_ # # fixture_name # # _ # # test_name # # _object = { \
2020-04-28 04:03:48 +03:00
. name = # test_name , \
2019-01-27 12:42:51 +03:00
. fn = & wrapper_ # # fixture_name # # _ # # test_name , \
2020-04-28 04:03:48 +03:00
. fixture = & _ # # fixture_name # # _fixture_object , \
2019-01-27 12:42:51 +03:00
. termsig = signal , \
2019-05-24 01:42:22 +03:00
. timeout = tmout , \
2015-06-16 20:54:14 +03:00
} ; \
static void __attribute__ ( ( constructor ) ) \
_register_ # # fixture_name # # _ # # test_name ( void ) \
{ \
__register_test ( & _ # # fixture_name # # _ # # test_name # # _object ) ; \
} \
static void fixture_name # # _ # # test_name ( \
struct __test_metadata __attribute__ ( ( unused ) ) * _metadata , \
2020-04-28 04:03:50 +03:00
FIXTURE_DATA ( fixture_name ) __attribute__ ( ( unused ) ) * self , \
const FIXTURE_VARIANT ( fixture_name ) \
__attribute__ ( ( unused ) ) * variant )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
* TEST_HARNESS_MAIN - Simple wrapper to run the test harness
*
* . . code - block : : c
*
* TEST_HARNESS_MAIN
*
* Use once to append a main ( ) to the test file .
2017-05-26 21:44:01 +03:00
*/
# define TEST_HARNESS_MAIN \
2015-06-16 20:54:14 +03:00
static void __attribute__ ( ( constructor ) ) \
__constructor_order_last ( void ) \
{ \
if ( ! __constructor_order ) \
__constructor_order = _CONSTRUCTOR_ORDER_BACKWARD ; \
} \
int main ( int argc , char * * argv ) { \
return test_harness_run ( argc , argv ) ; \
}
2017-06-05 21:37:17 +03:00
/**
* DOC : operators
*
* Operators for use in TEST ( ) and TEST_F ( ) .
2017-05-26 21:44:01 +03:00
* ASSERT_ * calls will stop test execution immediately .
* EXPECT_ * calls will emit a failure warning , note it , and continue .
*/
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_EQ ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_EQ ( expected , measured ) : expected = = measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_EQ(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , = = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_NE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_NE ( expected , measured ) : expected ! = measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_NE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , ! = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_LT ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_LT ( expected , measured ) : expected < measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_LT(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , < , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_LE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_LE ( expected , measured ) : expected < = measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_LE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , < = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_GT ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_GT ( expected , measured ) : expected > measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_GT(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , > , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_GE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_GE ( expected , measured ) : expected > = measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_GE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , > = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_NULL ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* ASSERT_NULL ( measured ) : NULL = = measured
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_NULL(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( NULL , " NULL " , seen , # seen , = = , 1 )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_TRUE ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* ASSERT_TRUE ( measured ) : measured ! = 0
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_TRUE(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( 0 , " 0 " , seen , # seen , ! = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_FALSE ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* ASSERT_FALSE ( measured ) : measured = = 0
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_FALSE(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( 0 , " 0 " , seen , # seen , = = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_STREQ ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_STREQ ( expected , measured ) : ! strcmp ( expected , measured )
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_STREQ(expected, seen) \
__EXPECT_STR ( expected , seen , = = , 1 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* ASSERT_STRNE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* ASSERT_STRNE ( expected , measured ) : strcmp ( expected , measured )
*/
2017-05-26 21:44:01 +03:00
# define ASSERT_STRNE(expected, seen) \
__EXPECT_STR ( expected , seen , ! = , 1 )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_EQ ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_EQ ( expected , measured ) : expected = = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_EQ(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , = = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_NE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_NE ( expected , measured ) : expected ! = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_NE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , ! = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_LT ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_LT ( expected , measured ) : expected < measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_LT(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , < , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_LE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_LE ( expected , measured ) : expected < = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_LE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , < = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_GT ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_GT ( expected , measured ) : expected > measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_GT(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , > , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_GE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_GE ( expected , measured ) : expected > = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_GE(expected, seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( expected , # expected , seen , # seen , > = , 0 )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_NULL ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* EXPECT_NULL ( measured ) : NULL = = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_NULL(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( NULL , " NULL " , seen , # seen , = = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_TRUE ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* EXPECT_TRUE ( measured ) : 0 ! = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_TRUE(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( 0 , " 0 " , seen , # seen , ! = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_FALSE ( )
2017-06-05 21:37:17 +03:00
*
* @ seen : measured value
*
* EXPECT_FALSE ( measured ) : 0 = = measured
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_FALSE(seen) \
2018-12-10 02:00:47 +03:00
__EXPECT ( 0 , " 0 " , seen , # seen , = = , 0 )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_STREQ ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_STREQ ( expected , measured ) : ! strcmp ( expected , measured )
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_STREQ(expected, seen) \
__EXPECT_STR ( expected , seen , = = , 0 )
2017-06-05 21:37:17 +03:00
/**
2020-10-27 12:51:33 +03:00
* EXPECT_STRNE ( )
2017-06-05 21:37:17 +03:00
*
* @ expected : expected value
* @ seen : measured value
*
* EXPECT_STRNE ( expected , measured ) : strcmp ( expected , measured )
*/
2017-05-26 21:44:01 +03:00
# define EXPECT_STRNE(expected, seen) \
__EXPECT_STR ( expected , seen , ! = , 0 )
2015-06-16 20:54:14 +03:00
# define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is
* not thread - safe , but it should be fine in most sane test scenarios .
*
* Using __bail ( ) , which optionally abort ( ) s , is the easiest way to early
* return while still providing an optional block to the API consumer .
*/
# define OPTIONAL_HANDLER(_assert) \
2017-08-07 02:23:37 +03:00
for ( ; _metadata - > trigger ; _metadata - > trigger = \
__bail ( _assert , _metadata - > no_print , _metadata - > step ) )
# define __INC_STEP(_metadata) \
2020-07-14 21:30:23 +03:00
/* Keep "step" below 255 (which is used for "SKIP" reporting). */ \
if ( _metadata - > passed & & _metadata - > step < 253 ) \
2017-08-07 02:23:37 +03:00
_metadata - > step + + ;
2015-06-16 20:54:14 +03:00
2020-06-22 21:16:50 +03:00
# define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
2018-12-10 02:00:47 +03:00
# define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
2015-06-16 20:54:14 +03:00
/* Avoid multiple evaluation of the cases */ \
__typeof__ ( _expected ) __exp = ( _expected ) ; \
__typeof__ ( _seen ) __seen = ( _seen ) ; \
2017-08-07 02:23:37 +03:00
if ( _assert ) __INC_STEP ( _metadata ) ; \
2015-06-16 20:54:14 +03:00
if ( ! ( __exp _t __seen ) ) { \
2020-06-22 21:16:50 +03:00
/* Report with actual signedness to avoid weird output. */ \
switch ( is_signed_type ( __exp ) * 2 + is_signed_type ( __seen ) ) { \
case 0 : { \
unsigned long long __exp_print = ( uintptr_t ) __exp ; \
unsigned long long __seen_print = ( uintptr_t ) __seen ; \
__TH_LOG ( " Expected %s (%llu) %s %s (%llu) " , \
_expected_str , __exp_print , # _t , \
_seen_str , __seen_print ) ; \
break ; \
} \
case 1 : { \
unsigned long long __exp_print = ( uintptr_t ) __exp ; \
long long __seen_print = ( intptr_t ) __seen ; \
__TH_LOG ( " Expected %s (%llu) %s %s (%lld) " , \
_expected_str , __exp_print , # _t , \
_seen_str , __seen_print ) ; \
break ; \
} \
case 2 : { \
long long __exp_print = ( intptr_t ) __exp ; \
unsigned long long __seen_print = ( uintptr_t ) __seen ; \
__TH_LOG ( " Expected %s (%lld) %s %s (%llu) " , \
_expected_str , __exp_print , # _t , \
_seen_str , __seen_print ) ; \
break ; \
} \
case 3 : { \
long long __exp_print = ( intptr_t ) __exp ; \
long long __seen_print = ( intptr_t ) __seen ; \
__TH_LOG ( " Expected %s (%lld) %s %s (%lld) " , \
_expected_str , __exp_print , # _t , \
_seen_str , __seen_print ) ; \
break ; \
} \
} \
2015-06-16 20:54:14 +03:00
_metadata - > passed = 0 ; \
/* Ensure the optional handler is triggered */ \
_metadata - > trigger = 1 ; \
} \
} while ( 0 ) ; OPTIONAL_HANDLER ( _assert )
# define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
const char * __exp = ( _expected ) ; \
const char * __seen = ( _seen ) ; \
2017-08-07 02:23:37 +03:00
if ( _assert ) __INC_STEP ( _metadata ) ; \
2015-06-16 20:54:14 +03:00
if ( ! ( strcmp ( __exp , __seen ) _t 0 ) ) { \
__TH_LOG ( " Expected '%s' %s '%s'. " , __exp , # _t , __seen ) ; \
_metadata - > passed = 0 ; \
_metadata - > trigger = 1 ; \
} \
} while ( 0 ) ; OPTIONAL_HANDLER ( _assert )
2020-04-28 04:03:47 +03:00
/* List helpers */
# define __LIST_APPEND(head, item) \
{ \
/* Circular linked list where only prev is circular. */ \
if ( head = = NULL ) { \
head = item ; \
item - > next = NULL ; \
item - > prev = item ; \
return ; \
} \
if ( __constructor_order = = _CONSTRUCTOR_ORDER_FORWARD ) { \
item - > next = NULL ; \
item - > prev = head - > prev ; \
item - > prev - > next = item ; \
head - > prev = item ; \
} else { \
item - > next = head ; \
item - > next - > prev = item ; \
item - > prev = item ; \
head = item ; \
} \
}
2020-06-22 21:16:51 +03:00
struct __test_results {
char reason [ 1024 ] ; /* Reason for test result */
} ;
2020-04-28 04:03:49 +03:00
struct __test_metadata ;
2020-04-28 04:03:50 +03:00
struct __fixture_variant_metadata ;
2020-04-28 04:03:49 +03:00
2020-04-28 04:03:48 +03:00
/* Contains all the information about a fixture. */
struct __fixture_metadata {
const char * name ;
2020-04-28 04:03:49 +03:00
struct __test_metadata * tests ;
2020-04-28 04:03:50 +03:00
struct __fixture_variant_metadata * variant ;
2020-04-28 04:03:48 +03:00
struct __fixture_metadata * prev , * next ;
} _fixture_global __attribute__ ( ( unused ) ) = {
. name = " global " ,
. prev = & _fixture_global ,
} ;
static struct __fixture_metadata * __fixture_list = & _fixture_global ;
static int __constructor_order ;
# define _CONSTRUCTOR_ORDER_FORWARD 1
# define _CONSTRUCTOR_ORDER_BACKWARD -1
static inline void __register_fixture ( struct __fixture_metadata * f )
{
__LIST_APPEND ( __fixture_list , f ) ;
}
2020-04-28 04:03:50 +03:00
struct __fixture_variant_metadata {
const char * name ;
const void * data ;
struct __fixture_variant_metadata * prev , * next ;
} ;
static inline void
__register_fixture_variant ( struct __fixture_metadata * f ,
struct __fixture_variant_metadata * variant )
{
__LIST_APPEND ( f - > variant , variant ) ;
}
2015-06-16 20:54:14 +03:00
/* Contains all the information for test execution and status checking. */
struct __test_metadata {
const char * name ;
2020-04-28 04:03:50 +03:00
void ( * fn ) ( struct __test_metadata * ,
struct __fixture_variant_metadata * ) ;
2020-03-14 02:12:51 +03:00
pid_t pid ; /* pid of test when being run */
2020-04-28 04:03:48 +03:00
struct __fixture_metadata * fixture ;
2015-06-16 20:54:14 +03:00
int termsig ;
int passed ;
2020-06-22 21:16:49 +03:00
int skip ; /* did SKIP get used? */
2015-06-16 20:54:14 +03:00
int trigger ; /* extra handler after the evaluation */
2020-03-14 02:12:52 +03:00
int timeout ; /* seconds to wait for test timeout */
bool timed_out ; /* did this test timeout instead of exiting? */
2017-08-07 02:23:37 +03:00
__u8 step ;
bool no_print ; /* manual trigger when TH_LOG_STREAM is not available */
2020-06-22 21:16:51 +03:00
struct __test_results * results ;
2015-06-16 20:54:14 +03:00
struct __test_metadata * prev , * next ;
} ;
/*
* Since constructors are called in reverse order , reverse the test
* list so tests are run in source declaration order .
* https : //gcc.gnu.org/onlinedocs/gccint/Initialization.html
* However , it seems not all toolchains do this correctly , so use
* __constructor_order to detect which direction is called first
* and adjust list building logic to get things running in the right
* direction .
*/
static inline void __register_test ( struct __test_metadata * t )
{
2020-04-28 04:03:49 +03:00
__LIST_APPEND ( t - > fixture - > tests , t ) ;
2015-06-16 20:54:14 +03:00
}
2017-08-07 02:23:37 +03:00
static inline int __bail ( int for_realz , bool no_print , __u8 step )
2015-06-16 20:54:14 +03:00
{
2017-08-07 02:23:37 +03:00
if ( for_realz ) {
if ( no_print )
_exit ( step ) ;
2015-06-16 20:54:14 +03:00
abort ( ) ;
2017-08-07 02:23:37 +03:00
}
2015-06-16 20:54:14 +03:00
return 0 ;
}
2020-03-14 02:12:52 +03:00
struct __test_metadata * __active_test ;
static void __timeout_handler ( int sig , siginfo_t * info , void * ucontext )
{
struct __test_metadata * t = __active_test ;
/* Sanity check handler execution environment. */
if ( ! t ) {
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # no active test in SIGALRM handler!? \n " ) ;
2020-03-14 02:12:52 +03:00
abort ( ) ;
}
if ( sig ! = SIGALRM | | sig ! = info - > si_signo ) {
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: SIGALRM handler caught signal %d!? \n " ,
2020-03-14 02:12:52 +03:00
t - > name , sig ! = SIGALRM ? sig : info - > si_signo ) ;
abort ( ) ;
}
t - > timed_out = true ;
kill ( t - > pid , SIGKILL ) ;
}
2020-03-14 02:12:51 +03:00
void __wait_for_test ( struct __test_metadata * t )
2015-06-16 20:54:14 +03:00
{
2020-03-14 02:12:52 +03:00
struct sigaction action = {
. sa_sigaction = __timeout_handler ,
. sa_flags = SA_SIGINFO ,
} ;
struct sigaction saved_action ;
2015-06-16 20:54:14 +03:00
int status ;
2020-03-14 02:12:52 +03:00
if ( sigaction ( SIGALRM , & action , & saved_action ) ) {
t - > passed = 0 ;
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: unable to install SIGALRM handler \n " ,
2020-03-14 02:12:52 +03:00
t - > name ) ;
return ;
}
__active_test = t ;
t - > timed_out = false ;
2020-03-14 02:12:51 +03:00
alarm ( t - > timeout ) ;
waitpid ( t - > pid , & status , 0 ) ;
alarm ( 0 ) ;
2020-03-14 02:12:52 +03:00
if ( sigaction ( SIGALRM , & saved_action , NULL ) ) {
t - > passed = 0 ;
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: unable to uninstall SIGALRM handler \n " ,
2020-03-14 02:12:52 +03:00
t - > name ) ;
return ;
}
__active_test = NULL ;
2020-03-14 02:12:51 +03:00
2020-03-14 02:12:52 +03:00
if ( t - > timed_out ) {
t - > passed = 0 ;
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: Test terminated by timeout \n " , t - > name ) ;
2020-03-14 02:12:52 +03:00
} else if ( WIFEXITED ( status ) ) {
2020-03-14 02:12:51 +03:00
if ( t - > termsig ! = - 1 ) {
2020-06-22 21:16:49 +03:00
t - > passed = 0 ;
2020-03-14 02:12:51 +03:00
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: Test exited normally instead of by signal (code: %d) \n " ,
2020-03-14 02:12:51 +03:00
t - > name ,
WEXITSTATUS ( status ) ) ;
2020-06-22 21:16:49 +03:00
} else {
switch ( WEXITSTATUS ( status ) ) {
/* Success */
case 0 :
t - > passed = 1 ;
break ;
/* SKIP */
case 255 :
t - > passed = 1 ;
t - > skip = 1 ;
break ;
/* Other failure, assume step report. */
default :
t - > passed = 0 ;
fprintf ( TH_LOG_STREAM ,
" # %s: Test failed at step #%d \n " ,
t - > name ,
WEXITSTATUS ( status ) ) ;
}
2020-03-14 02:12:51 +03:00
}
} else if ( WIFSIGNALED ( status ) ) {
t - > passed = 0 ;
if ( WTERMSIG ( status ) = = SIGABRT ) {
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: Test terminated by assertion \n " ,
2020-03-14 02:12:51 +03:00
t - > name ) ;
} else if ( WTERMSIG ( status ) = = t - > termsig ) {
t - > passed = 1 ;
} else {
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: Test terminated unexpectedly by signal %d \n " ,
2020-03-14 02:12:51 +03:00
t - > name ,
WTERMSIG ( status ) ) ;
}
} else {
fprintf ( TH_LOG_STREAM ,
2020-06-22 21:16:48 +03:00
" # %s: Test ended in some other way [%u] \n " ,
2020-03-14 02:12:51 +03:00
t - > name ,
status ) ;
}
}
2020-04-28 04:03:48 +03:00
void __run_test ( struct __fixture_metadata * f ,
2020-04-28 04:03:50 +03:00
struct __fixture_variant_metadata * variant ,
2020-04-28 04:03:48 +03:00
struct __test_metadata * t )
2020-03-14 02:12:51 +03:00
{
2020-04-28 04:03:50 +03:00
/* reset test struct */
2015-06-16 20:54:14 +03:00
t - > passed = 1 ;
2020-06-22 21:16:49 +03:00
t - > skip = 0 ;
2015-06-16 20:54:14 +03:00
t - > trigger = 0 ;
2020-04-28 04:03:50 +03:00
t - > step = 0 ;
t - > no_print = 0 ;
2020-06-22 21:16:51 +03:00
memset ( t - > results - > reason , 0 , sizeof ( t - > results - > reason ) ) ;
2020-04-28 04:03:50 +03:00
2020-06-22 21:16:48 +03:00
ksft_print_msg ( " RUN %s%s%s.%s ... \n " ,
2020-04-28 04:03:50 +03:00
f - > name , variant - > name [ 0 ] ? " . " : " " , variant - > name , t - > name ) ;
2020-09-17 07:15:19 +03:00
/* Make sure output buffers are flushed before fork */
fflush ( stdout ) ;
fflush ( stderr ) ;
2020-03-14 02:12:51 +03:00
t - > pid = fork ( ) ;
if ( t - > pid < 0 ) {
2020-06-22 21:16:48 +03:00
ksft_print_msg ( " ERROR SPAWNING TEST CHILD \n " ) ;
2015-06-16 20:54:14 +03:00
t - > passed = 0 ;
2020-03-14 02:12:51 +03:00
} else if ( t - > pid = = 0 ) {
2020-04-28 04:03:50 +03:00
t - > fn ( t , variant ) ;
2020-06-22 21:16:49 +03:00
if ( t - > skip )
_exit ( 255 ) ;
/* Pass is exit 0 */
if ( t - > passed )
_exit ( 0 ) ;
/* Something else happened, report the step. */
_exit ( t - > step ) ;
2015-06-16 20:54:14 +03:00
} else {
2020-03-14 02:12:51 +03:00
__wait_for_test ( t ) ;
2015-06-16 20:54:14 +03:00
}
2020-06-22 21:16:48 +03:00
ksft_print_msg ( " %4s %s%s%s.%s \n " , t - > passed ? " OK " : " FAIL " ,
f - > name , variant - > name [ 0 ] ? " . " : " " , variant - > name , t - > name ) ;
2020-06-22 21:16:49 +03:00
if ( t - > skip )
2020-06-22 21:16:51 +03:00
ksft_test_result_skip ( " %s \n " , t - > results - > reason [ 0 ] ?
t - > results - > reason : " unknown " ) ;
2020-06-22 21:16:49 +03:00
else
ksft_test_result ( t - > passed , " %s%s%s.%s \n " ,
f - > name , variant - > name [ 0 ] ? " . " : " " , variant - > name , t - > name ) ;
2015-06-16 20:54:14 +03:00
}
static int test_harness_run ( int __attribute__ ( ( unused ) ) argc ,
char __attribute__ ( ( unused ) ) * * argv )
{
2020-04-28 04:03:50 +03:00
struct __fixture_variant_metadata no_variant = { . name = " " , } ;
struct __fixture_variant_metadata * v ;
2020-04-28 04:03:49 +03:00
struct __fixture_metadata * f ;
2020-06-22 21:16:51 +03:00
struct __test_results * results ;
2015-06-16 20:54:14 +03:00
struct __test_metadata * t ;
int ret = 0 ;
2020-04-28 04:03:50 +03:00
unsigned int case_count = 0 , test_count = 0 ;
2015-06-16 20:54:14 +03:00
unsigned int count = 0 ;
unsigned int pass_count = 0 ;
2020-04-28 04:03:50 +03:00
for ( f = __fixture_list ; f ; f = f - > next ) {
for ( v = f - > variant ? : & no_variant ; v ; v = v - > next ) {
case_count + + ;
for ( t = f - > tests ; t ; t = t - > next )
test_count + + ;
}
}
2020-06-22 21:16:51 +03:00
results = mmap ( NULL , sizeof ( * results ) , PROT_READ | PROT_WRITE ,
MAP_SHARED | MAP_ANONYMOUS , - 1 , 0 ) ;
2020-06-22 21:16:48 +03:00
ksft_print_header ( ) ;
ksft_set_plan ( test_count ) ;
ksft_print_msg ( " Starting %u tests from %u test cases. \n " ,
2020-04-28 04:03:50 +03:00
test_count , case_count ) ;
2020-04-28 04:03:49 +03:00
for ( f = __fixture_list ; f ; f = f - > next ) {
2020-04-28 04:03:50 +03:00
for ( v = f - > variant ? : & no_variant ; v ; v = v - > next ) {
for ( t = f - > tests ; t ; t = t - > next ) {
count + + ;
2020-06-22 21:16:51 +03:00
t - > results = results ;
2020-04-28 04:03:50 +03:00
__run_test ( f , v , t ) ;
2020-06-22 21:16:51 +03:00
t - > results = NULL ;
2020-04-28 04:03:50 +03:00
if ( t - > passed )
pass_count + + ;
else
ret = 1 ;
}
2020-04-28 04:03:49 +03:00
}
2015-06-16 20:54:14 +03:00
}
2020-06-22 21:16:51 +03:00
munmap ( results , sizeof ( * results ) ) ;
2020-06-22 21:16:48 +03:00
ksft_print_msg ( " %s: %u / %u tests passed. \n " , ret ? " FAILED " : " PASSED " ,
pass_count , count ) ;
ksft_exit ( ret = = 0 ) ;
/* unreachable */
return KSFT_FAIL ;
2015-06-16 20:54:14 +03:00
}
static void __attribute__ ( ( constructor ) ) __constructor_order_first ( void )
{
if ( ! __constructor_order )
__constructor_order = _CONSTRUCTOR_ORDER_FORWARD ;
}
2017-05-26 21:43:57 +03:00
# endif /* __KSELFTEST_HARNESS_H */