From 3ed81cf0529145d04299c4cd48b1aaab2fe36193 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Sun, 22 Jun 2014 16:30:41 +0200 Subject: 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 Signed-off-by: Denys Vlasenko --- libbb/bbunit.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 libbb/bbunit.c (limited to 'libbb/bbunit.c') diff --git a/libbb/bbunit.c b/libbb/bbunit.c new file mode 100644 index 0000000..2560144 --- /dev/null +++ b/libbb/bbunit.c @@ -0,0 +1,90 @@ +/* vi: set sw=4 ts=4: */ +/* + * bbunit: Simple unit-testing framework for Busybox. + * + * Copyright (C) 2014 by Bartosz Golaszewski + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//kbuild:lib-$(CONFIG_UNIT_TEST) += bbunit.o +//applet:IF_UNIT_TEST(APPLET(unit, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//usage:#define unit_trivial_usage +//usage: "" +//usage:#define unit_full_usage "\n\n" +//usage: "Run the unit-test suite" + +#include "libbb.h" + +#define WANT_TIMING 0 + +static llist_t *tests = NULL; +static unsigned tests_registered = 0; +static int test_retval; + +void bbunit_registertest(struct bbunit_listelem *test) +{ + llist_add_to_end(&tests, test); + tests_registered++; +} + +void bbunit_settestfailed(void) +{ + test_retval = -1; +} + +#if WANT_TIMING +static void timeval_diff(struct timeval* res, + const struct timeval* x, + const struct timeval* y) +{ + long udiff = x->tv_usec - y->tv_usec; + + res->tv_sec = x->tv_sec - y->tv_sec - (udiff < 0); + res->tv_usec = (udiff >= 0 ? udiff : udiff + 1000000); +} +#endif + +int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; +int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + unsigned tests_run = 0; + unsigned tests_failed = 0; +#if WANT_TIMING + struct timeval begin; + struct timeval end; + struct timeval time_spent; + gettimeofday(&begin, NULL); +#endif + + bb_error_msg("Running %d test(s)...", tests_registered); + for (;;) { + struct bbunit_listelem* el = llist_pop(&tests); + if (!el) + break; + bb_error_msg("Case: [%s]", el->name); + test_retval = 0; + el->testfunc(); + if (test_retval < 0) { + bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); + tests_failed++; + } + tests_run++; + el = el->next; + } + +#if WANT_TIMING + gettimeofday(&end, NULL); + timeval_diff(&time_spent, &end, &begin); + bb_error_msg("Elapsed time %u.%06u seconds" + (int)time_spent.tv_sec, + (int)time_spent.tv_usec); +#endif + if (tests_failed > 0) { + bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); + return EXIT_FAILURE; + } + bb_error_msg("All tests passed"); + return EXIT_SUCCESS; +} -- cgit v1.1