bbunit.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * bbunit: Simple unit-testing framework for Busybox.
  4. *
  5. * Copyright (C) 2014 by Bartosz Golaszewski <bartekgola@gmail.com>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //kbuild:lib-$(CONFIG_UNIT_TEST) += bbunit.o
  10. //applet:IF_UNIT_TEST(APPLET(unit, BB_DIR_USR_BIN, BB_SUID_DROP))
  11. //usage:#define unit_trivial_usage
  12. //usage: ""
  13. //usage:#define unit_full_usage "\n\n"
  14. //usage: "Run the unit-test suite"
  15. #include "libbb.h"
  16. #define WANT_TIMING 0
  17. static llist_t *tests = NULL;
  18. static unsigned tests_registered = 0;
  19. static int test_retval;
  20. void bbunit_registertest(struct bbunit_listelem *test)
  21. {
  22. llist_add_to_end(&tests, test);
  23. tests_registered++;
  24. }
  25. void bbunit_settestfailed(void)
  26. {
  27. test_retval = -1;
  28. }
  29. #if WANT_TIMING
  30. static void timeval_diff(struct timeval* res,
  31. const struct timeval* x,
  32. const struct timeval* y)
  33. {
  34. long udiff = x->tv_usec - y->tv_usec;
  35. res->tv_sec = x->tv_sec - y->tv_sec - (udiff < 0);
  36. res->tv_usec = (udiff >= 0 ? udiff : udiff + 1000000);
  37. }
  38. #endif
  39. int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE;
  40. int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  41. {
  42. unsigned tests_run = 0;
  43. unsigned tests_failed = 0;
  44. #if WANT_TIMING
  45. struct timeval begin;
  46. struct timeval end;
  47. struct timeval time_spent;
  48. gettimeofday(&begin, NULL);
  49. #endif
  50. bb_error_msg("Running %d test(s)...", tests_registered);
  51. for (;;) {
  52. struct bbunit_listelem* el = llist_pop(&tests);
  53. if (!el)
  54. break;
  55. bb_error_msg("Case: [%s]", el->name);
  56. test_retval = 0;
  57. el->testfunc();
  58. if (test_retval < 0) {
  59. bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name);
  60. tests_failed++;
  61. }
  62. tests_run++;
  63. el = el->next;
  64. }
  65. #if WANT_TIMING
  66. gettimeofday(&end, NULL);
  67. timeval_diff(&time_spent, &end, &begin);
  68. bb_error_msg("Elapsed time %u.%06u seconds",
  69. (int)time_spent.tv_sec,
  70. (int)time_spent.tv_usec);
  71. #endif
  72. if (tests_failed > 0) {
  73. bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed);
  74. return EXIT_FAILURE;
  75. }
  76. bb_error_msg("All tests passed");
  77. return EXIT_SUCCESS;
  78. }