diff options
| author | Bartosz Golaszewski <bartekgola@gmail.com> | 2014-06-22 16:30:41 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-22 16:30:41 +0200 |
| commit | 3ed81cf0529145d04299c4cd48b1aaab2fe36193 (patch) | |
| tree | f8d40bf4c55c9dadba0773543048a5d69b695002 /include | |
| parent | 5d2e409ef8224dc32fde59702e8ec90b231441ed (diff) | |
| download | busybox-w32-3ed81cf0529145d04299c4cd48b1aaab2fe36193.tar.gz busybox-w32-3ed81cf0529145d04299c4cd48b1aaab2fe36193.tar.bz2 busybox-w32-3ed81cf0529145d04299c4cd48b1aaab2fe36193.zip | |
unit-tests: implement the unit-testing framework
This set of patches adds a simple unit-testing framework to Busybox
unit-tests: add some helper macros for unit-test framework implementation
unit-tests: implement the unit-testing framework
unit-tests: add basic documentation on writing the unit test cases
unit-tests: modify the Makefile 'test' target to run unit-tests too
unit-tests: add two example test cases
unit-tests: modify the existing strrstr test code to use the unit-test framework
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/libbb.h | 135 | ||||
| -rw-r--r-- | include/platform.h | 3 |
2 files changed, 138 insertions, 0 deletions
diff --git a/include/libbb.h b/include/libbb.h index 7a3610bb9..cede50cc2 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -1941,6 +1941,141 @@ static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a) | |||
| 1941 | #define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20) | 1941 | #define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20) |
| 1942 | 1942 | ||
| 1943 | 1943 | ||
| 1944 | /* Simple unit-testing framework */ | ||
| 1945 | |||
| 1946 | typedef void (*bbunit_testfunc)(void); | ||
| 1947 | |||
| 1948 | struct bbunit_listelem { | ||
| 1949 | struct bbunit_listelem* next; | ||
| 1950 | const char* name; | ||
| 1951 | bbunit_testfunc testfunc; | ||
| 1952 | }; | ||
| 1953 | |||
| 1954 | void bbunit_registertest(struct bbunit_listelem* test); | ||
| 1955 | void bbunit_settestfailed(void); | ||
| 1956 | |||
| 1957 | #define BBUNIT_DEFINE_TEST(NAME) \ | ||
| 1958 | static void bbunit_##NAME##_test(void); \ | ||
| 1959 | static struct bbunit_listelem bbunit_##NAME##_elem = { \ | ||
| 1960 | .name = #NAME, \ | ||
| 1961 | .testfunc = bbunit_##NAME##_test, \ | ||
| 1962 | }; \ | ||
| 1963 | static void INIT_LAST bbunit_##NAME##_register(void) \ | ||
| 1964 | { \ | ||
| 1965 | bbunit_registertest(&bbunit_##NAME##_elem); \ | ||
| 1966 | } \ | ||
| 1967 | static void bbunit_##NAME##_test(void) | ||
| 1968 | |||
| 1969 | /* | ||
| 1970 | * Both 'goto bbunit_end' and 'break' are here only to get rid | ||
| 1971 | * of compiler warnings. | ||
| 1972 | */ | ||
| 1973 | #define BBUNIT_ENDTEST \ | ||
| 1974 | do { \ | ||
| 1975 | goto bbunit_end; \ | ||
| 1976 | bbunit_end: \ | ||
| 1977 | break; \ | ||
| 1978 | } while (0) | ||
| 1979 | |||
| 1980 | #define BBUNIT_PRINTASSERTFAIL \ | ||
| 1981 | do { \ | ||
| 1982 | bb_error_msg( \ | ||
| 1983 | "[ERROR] Assertion failed in file %s, line %d", \ | ||
| 1984 | __FILE__, __LINE__); \ | ||
| 1985 | } while (0) | ||
| 1986 | |||
| 1987 | #define BBUNIT_ASSERTION_FAILED \ | ||
| 1988 | do { \ | ||
| 1989 | bbunit_settestfailed(); \ | ||
| 1990 | goto bbunit_end; \ | ||
| 1991 | } while (0) | ||
| 1992 | |||
| 1993 | /* | ||
| 1994 | * Assertions. | ||
| 1995 | * For now we only offer assertions which cause tests to fail | ||
| 1996 | * immediately. In the future 'expects' might be added too - | ||
| 1997 | * similar to those offered by the gtest framework. | ||
| 1998 | */ | ||
| 1999 | #define BBUNIT_ASSERT_EQ(EXPECTED, ACTUAL) \ | ||
| 2000 | do { \ | ||
| 2001 | if ((EXPECTED) != (ACTUAL)) { \ | ||
| 2002 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2003 | bb_error_msg("[ERROR] '%s' isn't equal to '%s'", \ | ||
| 2004 | #EXPECTED, #ACTUAL); \ | ||
| 2005 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2006 | } \ | ||
| 2007 | } while (0) | ||
| 2008 | |||
| 2009 | #define BBUNIT_ASSERT_NOTEQ(EXPECTED, ACTUAL) \ | ||
| 2010 | do { \ | ||
| 2011 | if ((EXPECTED) == (ACTUAL)) { \ | ||
| 2012 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2013 | bb_error_msg("[ERROR] '%s' is equal to '%s'", \ | ||
| 2014 | #EXPECTED, #ACTUAL); \ | ||
| 2015 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2016 | } \ | ||
| 2017 | } while (0) | ||
| 2018 | |||
| 2019 | #define BBUNIT_ASSERT_NOTNULL(PTR) \ | ||
| 2020 | do { \ | ||
| 2021 | if ((PTR) == NULL) { \ | ||
| 2022 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2023 | bb_error_msg("[ERROR] '%s' is NULL!", #PTR); \ | ||
| 2024 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2025 | } \ | ||
| 2026 | } while (0) | ||
| 2027 | |||
| 2028 | #define BBUNIT_ASSERT_NULL(PTR) \ | ||
| 2029 | do { \ | ||
| 2030 | if ((PTR) != NULL) { \ | ||
| 2031 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2032 | bb_error_msg("[ERROR] '%s' is not NULL!", #PTR); \ | ||
| 2033 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2034 | } \ | ||
| 2035 | } while (0) | ||
| 2036 | |||
| 2037 | #define BBUNIT_ASSERT_FALSE(STATEMENT) \ | ||
| 2038 | do { \ | ||
| 2039 | if ((STATEMENT)) { \ | ||
| 2040 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2041 | bb_error_msg("[ERROR] Statement '%s' evaluated to true!", \ | ||
| 2042 | #STATEMENT); \ | ||
| 2043 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2044 | } \ | ||
| 2045 | } while (0) | ||
| 2046 | |||
| 2047 | #define BBUNIT_ASSERT_TRUE(STATEMENT) \ | ||
| 2048 | do { \ | ||
| 2049 | if (!(STATEMENT)) { \ | ||
| 2050 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2051 | bb_error_msg("[ERROR] Statement '%s' evaluated to false!", \ | ||
| 2052 | #STATEMENT); \ | ||
| 2053 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2054 | } \ | ||
| 2055 | } while (0) | ||
| 2056 | |||
| 2057 | #define BBUNIT_ASSERT_STREQ(STR1, STR2) \ | ||
| 2058 | do { \ | ||
| 2059 | if (strcmp(STR1, STR2) != 0) { \ | ||
| 2060 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2061 | bb_error_msg("[ERROR] Strings '%s' and '%s' " \ | ||
| 2062 | "are not the same", STR1, STR2); \ | ||
| 2063 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2064 | } \ | ||
| 2065 | } while (0) | ||
| 2066 | |||
| 2067 | #define BBUNIT_ASSERT_STRNOTEQ(STR1, STR2) \ | ||
| 2068 | do { \ | ||
| 2069 | if (strcmp(STR1, STR2) == 0) { \ | ||
| 2070 | BBUNIT_PRINTASSERTFAIL; \ | ||
| 2071 | bb_error_msg("[ERROR] Strings '%s' and '%s' " \ | ||
| 2072 | "are the same, but were " \ | ||
| 2073 | "expected to differ", STR1, STR2); \ | ||
| 2074 | BBUNIT_ASSERTION_FAILED; \ | ||
| 2075 | } \ | ||
| 2076 | } while (0) | ||
| 2077 | |||
| 2078 | |||
| 1944 | POP_SAVED_FUNCTION_VISIBILITY | 2079 | POP_SAVED_FUNCTION_VISIBILITY |
| 1945 | 2080 | ||
| 1946 | #endif | 2081 | #endif |
diff --git a/include/platform.h b/include/platform.h index 92f775551..413c2224c 100644 --- a/include/platform.h +++ b/include/platform.h | |||
| @@ -76,6 +76,9 @@ | |||
| 76 | # define UNUSED_PARAM_RESULT | 76 | # define UNUSED_PARAM_RESULT |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
| 79 | /* used by unit test machinery to run registration functions */ | ||
| 80 | #define INIT_LAST __attribute__ ((constructor(2000))) | ||
| 81 | |||
| 79 | /* -fwhole-program makes all symbols local. The attribute externally_visible | 82 | /* -fwhole-program makes all symbols local. The attribute externally_visible |
| 80 | * forces a symbol global. */ | 83 | * forces a symbol global. */ |
| 81 | #if __GNUC_PREREQ(4,1) | 84 | #if __GNUC_PREREQ(4,1) |
