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
# define _GNU_SOURCE
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>
# include <sys/types.h>
# include <sys/wait.h>
# include <unistd.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
/**
* TH_LOG ( fmt , . . . )
*
* @ 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, ...) \
fprintf ( TH_LOG_STREAM , " %s:%d:%s: " fmt " \n " , \
__FILE__ , __LINE__ , _metadata - > name , # # __VA_ARGS__ )
2015-06-16 20:54:14 +03:00
2018-03-15 19:59:16 +03:00
/**
* XFAIL ( statement , fmt , . . . )
*
* @ statement : statement to run after reporting XFAIL
* @ fmt : format string
* @ . . . : optional arguments
*
* This forces a " pass " after reporting a failure with an XFAIL prefix ,
* and runs " statement " , which is usually " return " or " goto skip " .
*/
# define XFAIL(statement, fmt, ...) do { \
if ( TH_LOG_ENABLED ) { \
fprintf ( TH_LOG_STREAM , " [ XFAIL! ] " fmt " \n " , \
# #__VA_ARGS__); \
} \
/* TODO: find a way to pass xfail to test runner process. */ \
_metadata - > passed = 1 ; \
_metadata - > trigger = 0 ; \
statement ; \
} while ( 0 )
2017-06-05 21:37:17 +03:00
/**
* TEST ( test_name ) - Defines the test function and creates the registration
* 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
/**
* TEST_SIGNAL ( test_name , signal )
*
* @ 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 ) ; \
static struct __test_metadata _ # # test_name # # _object = \
2019-01-27 12:42:51 +03:00
{ . name = " global. " # test_name , \
2019-05-24 01:42:22 +03:00
. fn = & test_name , . termsig = _signal , \
. 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
/**
* FIXTURE_DATA ( datatype_name ) - Wraps the struct name so we have one less
* argument to pass around
*
* @ datatype_name : datatype name
*
* . . code - block : : c
*
* FIXTURE_DATA ( datatype name )
*
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
/**
* FIXTURE ( fixture_name ) - Called once per fixture to setup the data and
* register
*
* @ fixture_name : fixture name
*
* . . code - block : : c
*
* FIXTURE ( datatype name ) {
* 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) \
static void __attribute__ ( ( constructor ) ) \
_register_ # # fixture_name # # _data ( void ) \
{ \
__fixture_count + + ; \
} \
FIXTURE_DATA ( fixture_name )
2015-06-16 20:54:14 +03:00
2017-06-05 21:37:17 +03:00
/**
* FIXTURE_SETUP ( fixture_name ) - 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
*
* FIXTURE_SETUP ( fixture name ) { implementation }
*
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 , \
FIXTURE_DATA ( fixture_name ) __attribute__ ( ( unused ) ) * self )
2017-06-05 21:37:17 +03:00
/**
* FIXTURE_TEARDOWN ( fixture_name )
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
*
* FIXTURE_TEARDOWN ( fixture name ) { implementation }
*
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
2017-06-05 21:37:17 +03:00
/**
* TEST_F ( fixture_name , test_name ) - Emits test registration and helpers for
* 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 , \
2017-05-26 21:44:01 +03:00
FIXTURE_DATA ( fixture_name ) * self ) ; \
2015-06-16 20:54:14 +03:00
static inline void wrapper_ # # fixture_name # # _ # # test_name ( \
struct __test_metadata * _metadata ) \
{ \
/* 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 ) ) ) ; \
2015-06-16 20:54:14 +03:00
fixture_name # # _setup ( _metadata , & self ) ; \
/* Let setup failure terminate early. */ \
if ( ! _metadata - > passed ) \
return ; \
fixture_name # # _ # # test_name ( _metadata , & self ) ; \
fixture_name # # _teardown ( _metadata , & self ) ; \
} \
static struct __test_metadata \
_ # # fixture_name # # _ # # test_name # # _object = { \
2019-01-27 12:42:51 +03:00
. name = # fixture_name " . " # test_name , \
. fn = & wrapper_ # # fixture_name # # _ # # test_name , \
. 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 , \
2017-05-26 21:44:01 +03:00
FIXTURE_DATA ( fixture_name ) __attribute__ ( ( unused ) ) * self )
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
/**
* ASSERT_EQ ( expected , seen )
*
* @ 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
/**
* ASSERT_NE ( expected , seen )
*
* @ 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
/**
* ASSERT_LT ( expected , seen )
*
* @ 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
/**
* ASSERT_LE ( expected , seen )
*
* @ 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
/**
* ASSERT_GT ( expected , seen )
*
* @ 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
/**
* ASSERT_GE ( expected , seen )
*
* @ 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
/**
* ASSERT_NULL ( seen )
*
* @ 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
/**
* ASSERT_TRUE ( seen )
*
* @ 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
/**
* ASSERT_FALSE ( seen )
*
* @ 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
/**
* ASSERT_STREQ ( expected , seen )
*
* @ 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
/**
* ASSERT_STRNE ( expected , seen )
*
* @ 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
/**
* EXPECT_EQ ( expected , seen )
*
* @ 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
/**
* EXPECT_NE ( expected , seen )
*
* @ 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
/**
* EXPECT_LT ( expected , seen )
*
* @ 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
/**
* EXPECT_LE ( expected , seen )
*
* @ 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
/**
* EXPECT_GT ( expected , seen )
*
* @ 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
/**
* EXPECT_GE ( expected , seen )
*
* @ 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
/**
* EXPECT_NULL ( seen )
*
* @ 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
/**
* EXPECT_TRUE ( seen )
*
* @ 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
/**
* EXPECT_FALSE ( seen )
*
* @ 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
/**
* EXPECT_STREQ ( expected , seen )
*
* @ 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
/**
* EXPECT_STRNE ( expected , seen )
*
* @ 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) \
if ( _metadata - > passed & & _metadata - > step < 255 ) \
_metadata - > step + + ;
2015-06-16 20:54:14 +03:00
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 ) ) { \
2015-12-11 01:50:25 +03:00
unsigned long long __exp_print = ( uintptr_t ) __exp ; \
unsigned long long __seen_print = ( uintptr_t ) __seen ; \
2015-06-16 20:54:14 +03:00
__TH_LOG ( " Expected %s (%llu) %s %s (%llu) " , \
2018-12-10 02:00:47 +03:00
_expected_str , __exp_print , # _t , \
_seen_str , __seen_print ) ; \
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 )
/* Contains all the information for test execution and status checking. */
struct __test_metadata {
const char * name ;
void ( * fn ) ( struct __test_metadata * ) ;
int termsig ;
int passed ;
int trigger ; /* extra handler after the evaluation */
2019-05-24 01:42:22 +03:00
int timeout ;
2017-08-07 02:23:37 +03:00
__u8 step ;
bool no_print ; /* manual trigger when TH_LOG_STREAM is not available */
2015-06-16 20:54:14 +03:00
struct __test_metadata * prev , * next ;
} ;
/* Storage for the (global) tests to be run. */
static struct __test_metadata * __test_list ;
static unsigned int __test_count ;
static unsigned int __fixture_count ;
static int __constructor_order ;
# define _CONSTRUCTOR_ORDER_FORWARD 1
# define _CONSTRUCTOR_ORDER_BACKWARD -1
/*
* 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 )
{
__test_count + + ;
/* Circular linked list where only prev is circular. */
if ( __test_list = = NULL ) {
__test_list = t ;
t - > next = NULL ;
t - > prev = t ;
return ;
}
if ( __constructor_order = = _CONSTRUCTOR_ORDER_FORWARD ) {
t - > next = NULL ;
t - > prev = __test_list - > prev ;
t - > prev - > next = t ;
__test_list - > prev = t ;
} else {
t - > next = __test_list ;
t - > next - > prev = t ;
t - > prev = t ;
__test_list = t ;
}
}
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 ;
}
void __run_test ( struct __test_metadata * t )
{
pid_t child_pid ;
int status ;
t - > passed = 1 ;
t - > trigger = 0 ;
printf ( " [ RUN ] %s \n " , t - > name ) ;
2019-05-24 01:42:22 +03:00
alarm ( t - > timeout ) ;
2015-06-16 20:54:14 +03:00
child_pid = fork ( ) ;
if ( child_pid < 0 ) {
printf ( " ERROR SPAWNING TEST CHILD \n " ) ;
t - > passed = 0 ;
} else if ( child_pid = = 0 ) {
t - > fn ( t ) ;
2017-08-07 02:23:37 +03:00
/* return the step that failed or 0 */
_exit ( t - > passed ? 0 : t - > step ) ;
2015-06-16 20:54:14 +03:00
} else {
/* TODO(wad) add timeout support. */
waitpid ( child_pid , & status , 0 ) ;
if ( WIFEXITED ( status ) ) {
2017-08-07 02:23:37 +03:00
t - > passed = t - > termsig = = - 1 ? ! WEXITSTATUS ( status ) : 0 ;
2015-06-16 20:54:14 +03:00
if ( t - > termsig ! = - 1 ) {
fprintf ( TH_LOG_STREAM ,
" %s: Test exited normally "
" instead of by signal (code: %d) \n " ,
t - > name ,
WEXITSTATUS ( status ) ) ;
2017-08-07 02:23:37 +03:00
} else if ( ! t - > passed ) {
fprintf ( TH_LOG_STREAM ,
" %s: Test failed at step #%d \n " ,
t - > name ,
WEXITSTATUS ( status ) ) ;
2015-06-16 20:54:14 +03:00
}
} else if ( WIFSIGNALED ( status ) ) {
t - > passed = 0 ;
if ( WTERMSIG ( status ) = = SIGABRT ) {
fprintf ( TH_LOG_STREAM ,
" %s: Test terminated by assertion \n " ,
t - > name ) ;
} else if ( WTERMSIG ( status ) = = t - > termsig ) {
t - > passed = 1 ;
} else {
fprintf ( TH_LOG_STREAM ,
" %s: Test terminated unexpectedly "
" by signal %d \n " ,
t - > name ,
WTERMSIG ( status ) ) ;
}
} else {
fprintf ( TH_LOG_STREAM ,
" %s: Test ended in some other way [%u] \n " ,
t - > name ,
status ) ;
}
}
printf ( " [ %4s ] %s \n " , ( t - > passed ? " OK " : " FAIL " ) , t - > name ) ;
2019-04-12 03:11:08 +03:00
alarm ( 0 ) ;
2015-06-16 20:54:14 +03:00
}
static int test_harness_run ( int __attribute__ ( ( unused ) ) argc ,
char __attribute__ ( ( unused ) ) * * argv )
{
struct __test_metadata * t ;
int ret = 0 ;
unsigned int count = 0 ;
unsigned int pass_count = 0 ;
/* TODO(wad) add optional arguments similar to gtest. */
printf ( " [==========] Running %u tests from %u test cases. \n " ,
__test_count , __fixture_count + 1 ) ;
for ( t = __test_list ; t ; t = t - > next ) {
count + + ;
__run_test ( t ) ;
if ( t - > passed )
pass_count + + ;
else
ret = 1 ;
}
printf ( " [==========] %u / %u tests passed. \n " , pass_count , count ) ;
printf ( " [ %s ] \n " , ( ret ? " FAILED " : " PASSED " ) ) ;
return ret ;
}
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 */