diff options
author | Bartosz Golaszewski <bartekgola@gmail.com> | 2014-06-22 18:30:41 +0400 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-22 18:30:41 +0400 |
commit | 3ed81cf0529145d04299c4cd48b1aaab2fe36193 (patch) | |
tree | f8d40bf4c55c9dadba0773543048a5d69b695002 /libbb | |
parent | 5d2e409ef8224dc32fde59702e8ec90b231441ed (diff) |
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 'libbb')
-rw-r--r-- | libbb/bbunit.c | 90 | ||||
-rw-r--r-- | libbb/obscure.c | 38 | ||||
-rw-r--r-- | libbb/strrstr.c | 19 |
3 files changed, 135 insertions, 12 deletions
diff --git a/libbb/bbunit.c b/libbb/bbunit.c new file mode 100644 index 000000000..256014441 --- /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 <bartekgola@gmail.com> + * + * 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; +} diff --git a/libbb/obscure.c b/libbb/obscure.c index 24c4ac917..ad17d1ff1 100644 --- a/libbb/obscure.c +++ b/libbb/obscure.c @@ -182,3 +182,41 @@ int FAST_FUNC obscure(const char *old, const char *newval, const struct passwd * } return 0; } + +#if ENABLE_UNIT_TEST + +/* Test obscure_msg() instead of obscure() in order not to print anything. */ + +static const struct passwd pw = { + .pw_name = (char *)"johndoe", + .pw_gecos = (char *)"John Doe", +}; + +BBUNIT_DEFINE_TEST(obscure_weak_pass) +{ + /* Empty password */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "", &pw)); + /* Pure numbers */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "23577315", &pw)); + /* Similar to pw_name */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "johndoe123%", &pw)); + /* Similar to pw_gecos, reversed */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "eoD nhoJ^44@", &pw)); + /* Similar to the old password */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "d4#21?'S", &pw)); + /* adjacent letters */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "qwerty123", &pw)); + /* Many similar chars */ + BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "^33Daaaaaa1", &pw)); + + BBUNIT_ENDTEST; +} + +BBUNIT_DEFINE_TEST(obscure_strong_pass) +{ + BBUNIT_ASSERT_NULL(obscure_msg("Rt4##2&:'|", "}(^#rrSX3S*22", &pw)); + + BBUNIT_ENDTEST; +} + +#endif /* ENABLE_UNIT_TEST */ diff --git a/libbb/strrstr.c b/libbb/strrstr.c index d8823fc51..93d970a1b 100644 --- a/libbb/strrstr.c +++ b/libbb/strrstr.c @@ -7,13 +7,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -#ifdef __DO_STRRSTR_TEST -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#else #include "libbb.h" -#endif /* * The strrstr() function finds the last occurrence of the substring needle @@ -34,8 +28,9 @@ char* FAST_FUNC strrstr(const char *haystack, const char *needle) } } -#ifdef __DO_STRRSTR_TEST -int main(int argc, char **argv) +#if ENABLE_UNIT_TEST + +BBUNIT_DEFINE_TEST(strrstr) { static const struct { const char *h, *n; @@ -59,13 +54,13 @@ int main(int argc, char **argv) i = 0; while (i < sizeof(test_array) / sizeof(test_array[0])) { const char *r = strrstr(test_array[i].h, test_array[i].n); - printf("'%s' vs. '%s': '%s' - ", test_array[i].h, test_array[i].n, r); if (r == NULL) r = test_array[i].h - 1; - printf("%s\n", r == test_array[i].h + test_array[i].pos ? "PASSED" : "FAILED"); + BBUNIT_ASSERT_EQ(r, test_array[i].h + test_array[i].pos); i++; } - return 0; + BBUNIT_ENDTEST; } -#endif + +#endif /* ENABLE_UNIT_TEST */ |