aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartekgola@gmail.com>2014-06-22 16:30:41 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-06-22 16:30:41 +0200
commit3ed81cf0529145d04299c4cd48b1aaab2fe36193 (patch)
treef8d40bf4c55c9dadba0773543048a5d69b695002 /include
parent5d2e409ef8224dc32fde59702e8ec90b231441ed (diff)
downloadbusybox-3ed81cf0529145d04299c4cd48b1aaab2fe36193.tar.gz
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.h135
-rw-r--r--include/platform.h3
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)
#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
+/* Simple unit-testing framework */
+
+typedef void (*bbunit_testfunc)(void);
+
+struct bbunit_listelem {
+ struct bbunit_listelem* next;
+ const char* name;
+ bbunit_testfunc testfunc;
+};
+
+void bbunit_registertest(struct bbunit_listelem* test);
+void bbunit_settestfailed(void);
+
+#define BBUNIT_DEFINE_TEST(NAME) \
+ static void bbunit_##NAME##_test(void); \
+ static struct bbunit_listelem bbunit_##NAME##_elem = { \
+ .name = #NAME, \
+ .testfunc = bbunit_##NAME##_test, \
+ }; \
+ static void INIT_LAST bbunit_##NAME##_register(void) \
+ { \
+ bbunit_registertest(&bbunit_##NAME##_elem); \
+ } \
+ static void bbunit_##NAME##_test(void)
+
+/*
+ * Both 'goto bbunit_end' and 'break' are here only to get rid
+ * of compiler warnings.
+ */
+#define BBUNIT_ENDTEST \
+ do { \
+ goto bbunit_end; \
+ bbunit_end: \
+ break; \
+ } while (0)
+
+#define BBUNIT_PRINTASSERTFAIL \
+ do { \
+ bb_error_msg( \
+ "[ERROR] Assertion failed in file %s, line %d", \
+ __FILE__, __LINE__); \
+ } while (0)
+
+#define BBUNIT_ASSERTION_FAILED \
+ do { \
+ bbunit_settestfailed(); \
+ goto bbunit_end; \
+ } while (0)
+
+/*
+ * Assertions.
+ * For now we only offer assertions which cause tests to fail
+ * immediately. In the future 'expects' might be added too -
+ * similar to those offered by the gtest framework.
+ */
+#define BBUNIT_ASSERT_EQ(EXPECTED, ACTUAL) \
+ do { \
+ if ((EXPECTED) != (ACTUAL)) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] '%s' isn't equal to '%s'", \
+ #EXPECTED, #ACTUAL); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_NOTEQ(EXPECTED, ACTUAL) \
+ do { \
+ if ((EXPECTED) == (ACTUAL)) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] '%s' is equal to '%s'", \
+ #EXPECTED, #ACTUAL); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_NOTNULL(PTR) \
+ do { \
+ if ((PTR) == NULL) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] '%s' is NULL!", #PTR); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_NULL(PTR) \
+ do { \
+ if ((PTR) != NULL) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] '%s' is not NULL!", #PTR); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_FALSE(STATEMENT) \
+ do { \
+ if ((STATEMENT)) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] Statement '%s' evaluated to true!", \
+ #STATEMENT); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_TRUE(STATEMENT) \
+ do { \
+ if (!(STATEMENT)) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] Statement '%s' evaluated to false!", \
+ #STATEMENT); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_STREQ(STR1, STR2) \
+ do { \
+ if (strcmp(STR1, STR2) != 0) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] Strings '%s' and '%s' " \
+ "are not the same", STR1, STR2); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+#define BBUNIT_ASSERT_STRNOTEQ(STR1, STR2) \
+ do { \
+ if (strcmp(STR1, STR2) == 0) { \
+ BBUNIT_PRINTASSERTFAIL; \
+ bb_error_msg("[ERROR] Strings '%s' and '%s' " \
+ "are the same, but were " \
+ "expected to differ", STR1, STR2); \
+ BBUNIT_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+
POP_SAVED_FUNCTION_VISIBILITY
#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 @@
# define UNUSED_PARAM_RESULT
#endif
+/* used by unit test machinery to run registration functions */
+#define INIT_LAST __attribute__ ((constructor(2000)))
+
/* -fwhole-program makes all symbols local. The attribute externally_visible
* forces a symbol global. */
#if __GNUC_PREREQ(4,1)