Advertisement
tdulik

minunit.h with verbose output

Apr 27th, 2020
992
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.26 KB | None | 0 0
  1. /*
  2.  * Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining
  5.  * a copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sublicense, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19.  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20.  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  */
  23. #ifndef __MINUNIT_H__
  24. #define __MINUNIT_H__
  25.  
  26. #ifdef __cplusplus
  27.     extern "C" {
  28. #endif
  29.  
  30. #if defined(_WIN32)
  31. #include <windows.h>
  32. #if defined(_MSC_VER) && _MSC_VER < 1900
  33.   #define snprintf _snprintf
  34.   #define __func__ __FUNCTION__
  35. #endif
  36.  
  37. #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
  38.  
  39. /* Change POSIX C SOURCE version for pure c99 compilers */
  40. #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
  41. #undef _POSIX_C_SOURCE
  42. #define _POSIX_C_SOURCE 200112L
  43. #endif
  44.  
  45. #include <unistd.h> /* POSIX flags */
  46. #include <time.h>   /* clock_gettime(), time() */
  47. #include <sys/time.h>   /* gethrtime(), gettimeofday() */
  48. #include <sys/resource.h>
  49. #include <sys/times.h>
  50. #include <string.h>
  51.  
  52. #if defined(__MACH__) && defined(__APPLE__)
  53. #include <mach/mach.h>
  54. #include <mach/mach_time.h>
  55. #endif
  56.  
  57. #else
  58. #error "Unable to define timers for an unknown OS."
  59. #endif
  60.  
  61. #include <stdio.h>
  62. #include <math.h>
  63.  
  64. /*  Maximum length of last message */
  65. #define MINUNIT_MESSAGE_LEN 1024
  66. /*  Accuracy with which floats are compared */
  67. #define MINUNIT_EPSILON 1E-6
  68.  
  69. /* If you delete (or comment out) VERBOSE_TEST and/or VERBOSE_ASSERT symbols,
  70.  * there will be no verbose output for successful tests and assertions  */
  71.  
  72. #define VERBOSE_LEVEL 2
  73.  
  74. #ifdef VERBOSE_ALL
  75. #define VERBOSE_TEST
  76. #define VERBOSE_ASSERT
  77. #endif
  78.  
  79. #ifdef VERBOSE_TEST
  80. #define mu_print_test(test) printf("\nRunning "#test":")
  81. #else
  82. #define mu_print_test(test)
  83. #endif
  84.  
  85. #ifdef VERBOSE_ASSERT
  86. #define mu_print_intro(test) printf("\n  #%d: "#test" ? ", __LINE__)
  87. #define mu_str_OK "OK."
  88. #else
  89. #define mu_print_intro(test)
  90. #define mu_str_OK "."
  91. #endif
  92.  
  93.  
  94. /*  Misc. counters */
  95. static int minunit_run = 0;
  96. static int minunit_assert = 0;
  97. static int minunit_fail = 0;
  98. static int minunit_status = 0;
  99.  
  100. /*  Timers */
  101. static double minunit_real_timer = 0;
  102. static double minunit_proc_timer = 0;
  103.  
  104. /*  Last message */
  105. static char minunit_last_message[MINUNIT_MESSAGE_LEN];
  106.  
  107. /*  Test setup and teardown function pointers */
  108. static void (*minunit_setup)(void) = NULL;
  109. static void (*minunit_teardown)(void) = NULL;
  110.  
  111. /*  Definitions */
  112. #define MU_TEST(method_name) static void method_name(void)
  113. #define MU_TEST_SUITE(suite_name) static void suite_name(void)
  114.  
  115. #define MU__SAFE_BLOCK(block) do {\
  116.     block\
  117. } while(0)
  118.  
  119. /*  Run test suite and unset setup and teardown functions */
  120. #define MU_RUN_SUITE(suite_name) MU__SAFE_BLOCK(\
  121.     suite_name();\
  122.     minunit_setup = NULL;\
  123.     minunit_teardown = NULL;\
  124. )
  125.  
  126. /*  Configure setup and teardown functions */
  127. #define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) MU__SAFE_BLOCK(\
  128.     minunit_setup = setup_fun;\
  129.     minunit_teardown = teardown_fun;\
  130. )
  131.  
  132. /*  Test runner */
  133. #define MU_RUN_TEST(test) MU__SAFE_BLOCK(\
  134.     if (minunit_real_timer==0 && minunit_proc_timer==0) {\
  135.         minunit_real_timer = mu_timer_real();\
  136.         minunit_proc_timer = mu_timer_cpu();\
  137.     }\
  138.     if (minunit_setup) (*minunit_setup)();\
  139.     minunit_status = 0;\
  140.     mu_print_test(test);\
  141.     test();\
  142.     minunit_run++;\
  143.     if (minunit_status) {\
  144.         minunit_fail++;\
  145.         printf("F");\
  146.         printf("\n%s\n", minunit_last_message);\
  147.     }\
  148.     fflush(stdout);\
  149.     if (minunit_teardown) (*minunit_teardown)();\
  150. )
  151.  
  152. /*  Report */
  153. #define MU_REPORT() MU__SAFE_BLOCK(\
  154.     double minunit_end_real_timer;\
  155.     double minunit_end_proc_timer;\
  156.     printf("\n\n%d tests, %d assertions, %d failures\n", minunit_run, minunit_assert, minunit_fail);\
  157.     minunit_end_real_timer = mu_timer_real();\
  158.     minunit_end_proc_timer = mu_timer_cpu();\
  159.     printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n",\
  160.         minunit_end_real_timer - minunit_real_timer,\
  161.         minunit_end_proc_timer - minunit_proc_timer);\
  162. )
  163.  
  164. /*  Assertions */
  165. #define mu_check(test) MU__SAFE_BLOCK(\
  166.     minunit_assert++;\
  167.     mu_print_intro(test);\
  168.     if (!(test)) {\
  169.         snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, #test);\
  170.         minunit_status = 1;\
  171.         return;\
  172.     } else {\
  173.         printf(mu_str_OK);\
  174.     }\
  175. )
  176.  
  177. #define mu_fail(message) MU__SAFE_BLOCK(\
  178.     minunit_assert++;\
  179.     snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\
  180.     minunit_status = 1;\
  181.     return;\
  182. )
  183.  
  184. #define mu_assert(test, message) MU__SAFE_BLOCK(\
  185.     minunit_assert++;\
  186.     mu_print_intro(test);\
  187.     if (!(test)) {\
  188.         snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\
  189.         minunit_status = 1;\
  190.         return;\
  191.     } else {\
  192.         printf(mu_str_OK);\
  193.     }\
  194. )
  195.  
  196. #define mu_assert_int_eq(expected, result) MU__SAFE_BLOCK(\
  197.     int minunit_tmp_e;\
  198.     int minunit_tmp_r;\
  199.     minunit_assert++;\
  200.     mu_print_intro(result == expected);\
  201.     minunit_tmp_e = (expected);\
  202.     minunit_tmp_r = (result);\
  203.     if (minunit_tmp_e != minunit_tmp_r) {\
  204.         snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %d expected but was %d", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\
  205.         minunit_status = 1;\
  206.         return;\
  207.     } else {\
  208.         printf(mu_str_OK);\
  209.     }\
  210. )
  211.  
  212. #define mu_assert_double_eq(expected, result) MU__SAFE_BLOCK(\
  213.     double minunit_tmp_e;\
  214.     double minunit_tmp_r;\
  215.     minunit_assert++;\
  216.     mu_print_intro(result == expected);\
  217.     minunit_tmp_e = (expected);\
  218.     minunit_tmp_r = (result);\
  219.     if (fabs(minunit_tmp_e-minunit_tmp_r) > MINUNIT_EPSILON) {\
  220.         int minunit_significant_figures = 1 - log10(MINUNIT_EPSILON);\
  221.         snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %.*g expected but was %.*g", __func__, __FILE__, __LINE__, minunit_significant_figures, minunit_tmp_e, minunit_significant_figures, minunit_tmp_r);\
  222.         minunit_status = 1;\
  223.         return;\
  224.     } else {\
  225.         printf(mu_str_OK);\
  226.     }\
  227. )
  228.  
  229. #define mu_assert_string_eq(expected, result) MU__SAFE_BLOCK(\
  230.     const char* minunit_tmp_e = expected;\
  231.     const char* minunit_tmp_r = result;\
  232.     minunit_assert++;\
  233.     mu_print_intro(result == expected);\
  234.     if (!minunit_tmp_e) {\
  235.         minunit_tmp_e = "<null pointer>";\
  236.     }\
  237.     if (!minunit_tmp_r) {\
  238.         minunit_tmp_r = "<null pointer>";\
  239.     }\
  240.     if(strcmp(minunit_tmp_e, minunit_tmp_r)) {\
  241.         snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: '%s' expected but was '%s'", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\
  242.         minunit_status = 1;\
  243.         return;\
  244.     } else {\
  245.         printf(mu_str_OK);\
  246.     }\
  247. )
  248.  
  249. /*
  250.  * The following two functions were written by David Robert Nadeau
  251.  * from http://NadeauSoftware.com/ and distributed under the
  252.  * Creative Commons Attribution 3.0 Unported License
  253.  */
  254.  
  255. /**
  256.  * Returns the real time, in seconds, or -1.0 if an error occurred.
  257.  *
  258.  * Time is measured since an arbitrary and OS-dependent start time.
  259.  * The returned real time is only useful for computing an elapsed time
  260.  * between two calls to this function.
  261.  */
  262. static double mu_timer_real(void)
  263. {
  264. #if defined(_WIN32)
  265.     /* Windows 2000 and later. ---------------------------------- */
  266.     LARGE_INTEGER Time;
  267.     LARGE_INTEGER Frequency;
  268.  
  269.     QueryPerformanceFrequency(&Frequency);
  270.     QueryPerformanceCounter(&Time);
  271.  
  272.     Time.QuadPart *= 1000000;
  273.     Time.QuadPart /= Frequency.QuadPart;
  274.  
  275.     return (double)Time.QuadPart / 1000000.0;
  276.  
  277. #elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
  278.     /* HP-UX, Solaris. ------------------------------------------ */
  279.     return (double)gethrtime( ) / 1000000000.0;
  280.  
  281. #elif defined(__MACH__) && defined(__APPLE__)
  282.     /* OSX. ----------------------------------------------------- */
  283.     static double timeConvert = 0.0;
  284.     if ( timeConvert == 0.0 )
  285.     {
  286.         mach_timebase_info_data_t timeBase;
  287.         (void)mach_timebase_info( &timeBase );
  288.         timeConvert = (double)timeBase.numer /
  289.             (double)timeBase.denom /
  290.             1000000000.0;
  291.     }
  292.     return (double)mach_absolute_time( ) * timeConvert;
  293.  
  294. #elif defined(_POSIX_VERSION)
  295.     /* POSIX. --------------------------------------------------- */
  296.     struct timeval tm;
  297. #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
  298.     {
  299.         struct timespec ts;
  300. #if defined(CLOCK_MONOTONIC_PRECISE)
  301.         /* BSD. --------------------------------------------- */
  302.         const clockid_t id = CLOCK_MONOTONIC_PRECISE;
  303. #elif defined(CLOCK_MONOTONIC_RAW)
  304.         /* Linux. ------------------------------------------- */
  305.         const clockid_t id = CLOCK_MONOTONIC_RAW;
  306. #elif defined(CLOCK_HIGHRES)
  307.         /* Solaris. ----------------------------------------- */
  308.         const clockid_t id = CLOCK_HIGHRES;
  309. #elif defined(CLOCK_MONOTONIC)
  310.         /* AIX, BSD, Linux, POSIX, Solaris. ----------------- */
  311.         const clockid_t id = CLOCK_MONOTONIC;
  312. #elif defined(CLOCK_REALTIME)
  313.         /* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */
  314.         const clockid_t id = CLOCK_REALTIME;
  315. #else
  316.         const clockid_t id = (clockid_t)-1; /* Unknown. */
  317. #endif /* CLOCK_* */
  318.         if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 )
  319.             return (double)ts.tv_sec +
  320.                 (double)ts.tv_nsec / 1000000000.0;
  321.         /* Fall thru. */
  322.     }
  323. #endif /* _POSIX_TIMERS */
  324.  
  325.     /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */
  326.     gettimeofday( &tm, NULL );
  327.     return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0;
  328. #else
  329.     return -1.0;        /* Failed. */
  330. #endif
  331. }
  332.  
  333. /**
  334.  * Returns the amount of CPU time used by the current process,
  335.  * in seconds, or -1.0 if an error occurred.
  336.  */
  337. static double mu_timer_cpu(void)
  338. {
  339. #if defined(_WIN32)
  340.     /* Windows -------------------------------------------------- */
  341.     FILETIME createTime;
  342.     FILETIME exitTime;
  343.     FILETIME kernelTime;
  344.     FILETIME userTime;
  345.  
  346.     /* This approach has a resolution of 1/64 second. Unfortunately, Windows' API does not offer better */
  347.     if ( GetProcessTimes( GetCurrentProcess( ),
  348.         &createTime, &exitTime, &kernelTime, &userTime ) != 0 )
  349.     {
  350.         ULARGE_INTEGER userSystemTime;
  351.         memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER));
  352.         return (double)userSystemTime.QuadPart / 10000000.0;
  353.     }
  354.  
  355. #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
  356.     /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */
  357.  
  358. #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
  359.     /* Prefer high-res POSIX timers, when available. */
  360.     {
  361.         clockid_t id;
  362.         struct timespec ts;
  363. #if _POSIX_CPUTIME > 0
  364.         /* Clock ids vary by OS.  Query the id, if possible. */
  365.         if ( clock_getcpuclockid( 0, &id ) == -1 )
  366. #endif
  367. #if defined(CLOCK_PROCESS_CPUTIME_ID)
  368.             /* Use known clock id for AIX, Linux, or Solaris. */
  369.             id = CLOCK_PROCESS_CPUTIME_ID;
  370. #elif defined(CLOCK_VIRTUAL)
  371.             /* Use known clock id for BSD or HP-UX. */
  372.             id = CLOCK_VIRTUAL;
  373. #else
  374.             id = (clockid_t)-1;
  375. #endif
  376.         if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 )
  377.             return (double)ts.tv_sec +
  378.                 (double)ts.tv_nsec / 1000000000.0;
  379.     }
  380. #endif
  381.  
  382. #if defined(RUSAGE_SELF)
  383.     {
  384.         struct rusage rusage;
  385.         if ( getrusage( RUSAGE_SELF, &rusage ) != -1 )
  386.             return (double)rusage.ru_utime.tv_sec +
  387.                 (double)rusage.ru_utime.tv_usec / 1000000.0;
  388.     }
  389. #endif
  390.  
  391. #if defined(_SC_CLK_TCK)
  392.     {
  393.         const double ticks = (double)sysconf( _SC_CLK_TCK );
  394.         struct tms tms;
  395.         if ( times( &tms ) != (clock_t)-1 )
  396.             return (double)tms.tms_utime / ticks;
  397.     }
  398. #endif
  399.  
  400. #if defined(CLOCKS_PER_SEC)
  401.     {
  402.         clock_t cl = clock( );
  403.         if ( cl != (clock_t)-1 )
  404.             return (double)cl / (double)CLOCKS_PER_SEC;
  405.     }
  406. #endif
  407.  
  408. #endif
  409.  
  410.     return -1;      /* Failed. */
  411. }
  412.  
  413. #ifdef __cplusplus
  414. }
  415. #endif
  416.  
  417. #endif /* __MINUNIT_H__ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement