You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ctest.h 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. /* Copyright 2011-2016 Bas van den Berg
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #ifndef CTEST_H
  16. #define CTEST_H
  17. #if defined _WIN32 || defined __CYGWIN__
  18. #ifndef WIN32
  19. #define WIN32
  20. #endif
  21. #endif
  22. #ifndef WIN32
  23. #define WEAK __attribute__ ((weak))
  24. #else
  25. #define WEAK
  26. #endif
  27. #include <inttypes.h> /* intmax_t, uintmax_t, PRI* */
  28. #include <stddef.h> /* size_t */
  29. typedef void (*SetupFunc)(void*);
  30. typedef void (*TearDownFunc)(void*);
  31. typedef void (*RunWithDataFunc)(void*);
  32. struct ctest {
  33. const char* ssname; // suite name
  34. const char* ttname; // test name
  35. void (*run)();
  36. int skip;
  37. void* data;
  38. SetupFunc setup;
  39. TearDownFunc teardown;
  40. struct ctest *next;
  41. unsigned int magic;
  42. };
  43. #define __FNAME(sname, tname) __ctest_##sname##_##tname##_run
  44. #define __TNAME(sname, tname) __ctest_##sname##_##tname
  45. #define __PNAME(sname, tname) __ctest_##sname##_##tname##_pointer
  46. #ifdef __APPLE__
  47. #define __CTEST_APPLE
  48. #endif
  49. #ifdef __MINGW32__
  50. #undef CTEST_SEGFAULT
  51. #endif
  52. #if defined(_WIN32) && defined(_MSC_VER)
  53. #define __CTEST_MSVC
  54. #endif
  55. //config for MSVC compiler
  56. #ifdef __CTEST_MSVC
  57. #define __CTEST_NO_TIME
  58. #define CTEST_NO_COLORS
  59. #ifndef CTEST_ADD_TESTS_MANUALLY
  60. #pragma section(".ctest$a")
  61. #pragma section(".ctest$u")
  62. #pragma section(".ctest$z")
  63. #endif
  64. //clear this flag for msvc
  65. #ifdef CTEST_SEGFAULT
  66. #undef CTEST_SEGFAULT
  67. #endif
  68. #ifndef __cplusplus
  69. #define inline __inline
  70. #endif
  71. #endif
  72. #ifdef CTEST_NO_JMP
  73. #define __CTEST_NO_JMP
  74. #endif
  75. #define __CTEST_MAGIC (0xdeadbeef)
  76. #ifdef CTEST_ADD_TESTS_MANUALLY
  77. # define __Test_Section
  78. #else
  79. #ifdef __CTEST_APPLE
  80. #define __Test_Section __attribute__ ((used, section ("__DATA, .ctest")))
  81. #elif defined (__CTEST_MSVC)
  82. #define __Test_Section __declspec( allocate(".ctest$u"))
  83. #else
  84. #define __Test_Section __attribute__ ((used, section (".ctest")))
  85. #endif
  86. #endif
  87. #ifndef __CTEST_MSVC
  88. #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
  89. static struct ctest __TNAME(sname, tname) = { \
  90. .ssname=#sname, \
  91. .ttname=#tname, \
  92. .run = __FNAME(sname, tname), \
  93. .skip = _skip, \
  94. .data = __data, \
  95. .setup = (SetupFunc)__setup, \
  96. .teardown = (TearDownFunc)__teardown, \
  97. .next = NULL, \
  98. .magic = __CTEST_MAGIC}; \
  99. static void * __PNAME(sname, tname)[2] __Test_Section = {(void*)& __TNAME(sname,tname), (void*)__CTEST_MAGIC};
  100. #else
  101. //for msvc
  102. #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
  103. static struct ctest __TNAME(sname, tname) = { \
  104. #sname, \
  105. #tname, \
  106. __FNAME(sname, tname), \
  107. _skip, \
  108. __data, \
  109. (SetupFunc)__setup, \
  110. (TearDownFunc)__teardown, \
  111. NULL, \
  112. __CTEST_MAGIC}; \
  113. __Test_Section static void * __PNAME(sname, tname)[2]= {(void*)& __TNAME(sname,tname), (void *)__CTEST_MAGIC};
  114. #endif
  115. #define CTEST_DATA(sname) struct sname##_data
  116. #define CTEST_SETUP(sname) \
  117. void WEAK sname##_setup(struct sname##_data* data)
  118. #define CTEST_TEARDOWN(sname) \
  119. void WEAK sname##_teardown(struct sname##_data* data)
  120. #define __CTEST_INTERNAL(sname, tname, _skip) \
  121. void __FNAME(sname, tname)(); \
  122. __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \
  123. void __FNAME(sname, tname)()
  124. #ifdef __CTEST_APPLE
  125. #define SETUP_FNAME(sname) NULL
  126. #define TEARDOWN_FNAME(sname) NULL
  127. #else
  128. #define SETUP_FNAME(sname) sname##_setup
  129. #define TEARDOWN_FNAME(sname) sname##_teardown
  130. #endif
  131. #define __CTEST2_INTERNAL(sname, tname, _skip) \
  132. static struct sname##_data __ctest_##sname##_data; \
  133. CTEST_SETUP(sname); \
  134. CTEST_TEARDOWN(sname); \
  135. void __FNAME(sname, tname)(struct sname##_data* data); \
  136. __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \
  137. void __FNAME(sname, tname)(struct sname##_data* data)
  138. void CTEST_LOG(const char* fmt, ...);
  139. void CTEST_ERR(const char* fmt, ...); // doesn't return
  140. #define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0)
  141. #define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1)
  142. #define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0)
  143. #define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1)
  144. #ifdef CTEST_ADD_TESTS_MANUALLY
  145. void __ctest_addTest(struct ctest *);
  146. #define CTEST_ADD(sname, tname) do { \
  147. extern struct ctest __TNAME(sname, tname); \
  148. __ctest_addTest(&__TNAME(sname, tname)); \
  149. } while (0)
  150. #define CTEST_ADD2(sname, tname) do { \
  151. extern struct ctest __TNAME(sname, tname); \
  152. __ctest_addTest(&__TNAME(sname, tname)); \
  153. } while (0)
  154. #endif // CTEST_ADD_TESTS_MANUALLY
  155. void assert_str(const char* exp, const char* real, const char* caller, int line);
  156. #define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__)
  157. void assert_data(const unsigned char* exp, size_t expsize,
  158. const unsigned char* real, size_t realsize,
  159. const char* caller, int line);
  160. #define ASSERT_DATA(exp, expsize, real, realsize) \
  161. assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
  162. void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line);
  163. #define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
  164. void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
  165. #define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__)
  166. void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line);
  167. #define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__)
  168. void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
  169. #define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__)
  170. void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line);
  171. #define ASSERT_INTERVAL(exp1, exp2, real) assert_interval(exp1, exp2, real, __FILE__, __LINE__)
  172. void assert_null(void* real, const char* caller, int line);
  173. #define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__)
  174. void assert_not_null(const void* real, const char* caller, int line);
  175. #define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__)
  176. void assert_true(int real, const char* caller, int line);
  177. #define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__)
  178. void assert_false(int real, const char* caller, int line);
  179. #define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__)
  180. void assert_fail(const char* caller, int line);
  181. #define ASSERT_FAIL() assert_fail(__FILE__, __LINE__)
  182. /* If longjmp() is not available, integer flag will be used instead of jmp_buf.
  183. *
  184. * __CTEST_SETJMP() will clear the flag and return zero, and __CTEST_LONGJMP()
  185. * will set the flag to its argument. __CTEST_ERROR_CODE() will return that flag.
  186. *
  187. * If longjmp() is available, jmp_buf will be used as usual and __CTEST_ERROR_CODE()
  188. * will always return zero.
  189. *
  190. * You can check both __CTEST_SETJMP() and __CTEST_ERROR_CODE() return value
  191. * to detect error in a portable way.
  192. */
  193. #ifdef __CTEST_NO_JMP
  194. # define __CTEST_JMPBUF int
  195. # define __CTEST_ERROR_CODE(_var) (_var)
  196. # define __CTEST_SETJMP(_var) (_var = 0)
  197. # define __CTEST_LONGJMP(_var, _err) (_var = _err)
  198. #else // !__CTEST_NO_JMP
  199. # define __CTEST_JMPBUF jmp_buf
  200. # define __CTEST_ERROR_CODE(_var) (0)
  201. # define __CTEST_SETJMP(_var) setjmp(_var)
  202. # define __CTEST_LONGJMP(_var, _err) longjmp(_var, _err)
  203. #endif // __CTEST_NO_JMP
  204. void assert_dbl_near(double exp, double real, double tol, const char* caller, int line);
  205. #define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__)
  206. #define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__)
  207. void assert_dbl_far(double exp, double real, double tol, const char* caller, int line);
  208. #define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__)
  209. #define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__)
  210. #ifdef CTEST_MAIN
  211. #ifndef __CTEST_NO_JMP
  212. #include <setjmp.h>
  213. #endif
  214. #include <stdarg.h>
  215. #include <stdio.h>
  216. #include <string.h>
  217. #ifndef __CTEST_NO_TIME
  218. #include <sys/time.h>
  219. #endif
  220. #include <stdint.h>
  221. #ifdef __CTEST_MSVC
  222. #include <io.h>
  223. #else
  224. #include <unistd.h>
  225. #endif
  226. #include <stdlib.h>
  227. #ifdef __CTEST_APPLE
  228. #include <dlfcn.h>
  229. #endif
  230. static size_t ctest_errorsize;
  231. static char* ctest_errormsg;
  232. #define MSG_SIZE 4096
  233. static char ctest_errorbuffer[MSG_SIZE];
  234. static __CTEST_JMPBUF ctest_err;
  235. static int color_output = 1;
  236. static const char* suite_name;
  237. static const char* test_name;
  238. typedef int (*filter_func)(struct ctest*);
  239. #define ANSI_BLACK "\033[0;30m"
  240. #define ANSI_RED "\033[0;31m"
  241. #define ANSI_GREEN "\033[0;32m"
  242. #define ANSI_YELLOW "\033[0;33m"
  243. #define ANSI_BLUE "\033[0;34m"
  244. #define ANSI_MAGENTA "\033[0;35m"
  245. #define ANSI_CYAN "\033[0;36m"
  246. #define ANSI_GREY "\033[0;37m"
  247. #define ANSI_DARKGREY "\033[01;30m"
  248. #define ANSI_BRED "\033[01;31m"
  249. #define ANSI_BGREEN "\033[01;32m"
  250. #define ANSI_BYELLOW "\033[01;33m"
  251. #define ANSI_BBLUE "\033[01;34m"
  252. #define ANSI_BMAGENTA "\033[01;35m"
  253. #define ANSI_BCYAN "\033[01;36m"
  254. #define ANSI_WHITE "\033[01;37m"
  255. #define ANSI_NORMAL "\033[0m"
  256. #ifdef __CTEST_MSVC
  257. #ifndef CTEST_ADD_TESTS_MANUALLY
  258. __declspec(allocate(".ctest$a")) struct ctest * ctest_win_begin;
  259. __declspec(allocate(".ctest$z")) struct ctest * ctest_win_end;
  260. #endif
  261. #endif
  262. static CTEST(suite, test) { }
  263. #define __CTEST_POINTER_NEXT(_test) (struct ctest **)((struct ctest **)(_test) + 2)
  264. #define __CTEST_POINTER_PREV(_test) (struct ctest **)((struct ctest **)(_test) - 2)
  265. /* First element of test list.
  266. */
  267. static struct ctest * * __ctest_head_p = (struct ctest **)__PNAME(suite, test);
  268. #ifdef CTEST_ADD_TESTS_MANUALLY
  269. /* Last element of test list.
  270. */
  271. static struct ctest *__ctest_tail = &__TNAME(suite, test);
  272. /* Add test to linked list manually.
  273. */
  274. void __ctest_addTest(struct ctest *test)
  275. {
  276. __ctest_tail->next = test;
  277. __ctest_tail = test;
  278. }
  279. #else // !CTEST_ADD_TESTS_MANUALLY
  280. #ifndef __CTEST_MSVC
  281. /* Add all tests to linked list automatically.
  282. */
  283. static void __ctest_linkTests()
  284. {
  285. struct ctest ** test;
  286. struct ctest ** ctest_begin = (struct ctest **)__PNAME(suite, test);
  287. struct ctest ** ctest_end = (struct ctest **)__PNAME(suite, test);
  288. // find begin and end of section by comparing magics
  289. while (1) {
  290. struct ctest** t = __CTEST_POINTER_PREV(ctest_begin);
  291. if (t[0] == NULL) break;
  292. if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
  293. ctest_begin = t;
  294. }
  295. while (1) {
  296. struct ctest** t = __CTEST_POINTER_NEXT(ctest_end);
  297. if (t[0] == NULL) break;
  298. if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
  299. ctest_end = t;
  300. }
  301. ctest_end = __CTEST_POINTER_NEXT(ctest_end); // end after last one
  302. for (test = ctest_begin; test != ctest_end; test = __CTEST_POINTER_NEXT(test)) {
  303. struct ctest ** next_p = __CTEST_POINTER_NEXT(test);
  304. struct ctest * next;
  305. if (next_p == ctest_end)
  306. next = NULL;
  307. else
  308. next = next_p[0];
  309. (*test)->next = next;
  310. }
  311. __ctest_head_p = ctest_begin;
  312. }
  313. #else //for msvc
  314. static void __ctest_linkTests()
  315. {
  316. struct ctest ** ctest_start = __ctest_head_p;
  317. struct ctest ** test;
  318. struct ctest * cur=ctest_start[0];
  319. for(test=&ctest_win_begin; test!=&ctest_win_end; test++){
  320. //check
  321. if(test[1] == (struct ctest*)__CTEST_MAGIC){
  322. //skip the start
  323. if((test[0]) == ctest_start[0]) continue;
  324. cur->next = test[0];
  325. cur=cur->next;
  326. cur->next=NULL;
  327. }
  328. }
  329. }
  330. #endif
  331. #endif
  332. inline static void vprint_errormsg(const char* const fmt, va_list ap) {
  333. // (v)snprintf returns the number that would have been written
  334. const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap);
  335. if (ret < 0) {
  336. ctest_errormsg[0] = 0x00;
  337. } else {
  338. const size_t size = (size_t) ret;
  339. const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size);
  340. // ctest_errorsize may overflow at this point
  341. ctest_errorsize -= s;
  342. ctest_errormsg += s;
  343. }
  344. }
  345. inline static void print_errormsg(const char* const fmt, ...) {
  346. va_list argp;
  347. va_start(argp, fmt);
  348. vprint_errormsg(fmt, argp);
  349. va_end(argp);
  350. }
  351. static void msg_start(const char* color, const char* title) {
  352. if (color_output) {
  353. print_errormsg("%s", color);
  354. }
  355. print_errormsg(" %s: ", title);
  356. }
  357. static void msg_end() {
  358. if (color_output) {
  359. print_errormsg(ANSI_NORMAL);
  360. }
  361. print_errormsg("\n");
  362. }
  363. void CTEST_LOG(const char* fmt, ...)
  364. {
  365. va_list argp;
  366. msg_start(ANSI_BLUE, "LOG");
  367. va_start(argp, fmt);
  368. vprint_errormsg(fmt, argp);
  369. va_end(argp);
  370. msg_end();
  371. }
  372. void CTEST_ERR(const char* fmt, ...)
  373. {
  374. va_list argp;
  375. msg_start(ANSI_YELLOW, "ERR");
  376. va_start(argp, fmt);
  377. vprint_errormsg(fmt, argp);
  378. va_end(argp);
  379. msg_end();
  380. __CTEST_LONGJMP(ctest_err, 1);
  381. }
  382. void assert_str(const char* exp, const char* real, const char* caller, int line) {
  383. if ((exp == NULL && real != NULL) ||
  384. (exp != NULL && real == NULL) ||
  385. (exp && real && strcmp(exp, real) != 0)) {
  386. CTEST_ERR("%s:%d expected '%s', got '%s'", caller, line, exp, real);
  387. }
  388. }
  389. void assert_data(const unsigned char* exp, size_t expsize,
  390. const unsigned char* real, size_t realsize,
  391. const char* caller, int line) {
  392. size_t i;
  393. if (expsize != realsize) {
  394. CTEST_ERR("%s:%d expected %" PRIuMAX " bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
  395. }
  396. for (i=0; i<expsize; i++) {
  397. if (exp[i] != real[i]) {
  398. CTEST_ERR("%s:%d expected 0x%02x at offset %" PRIuMAX " got 0x%02x",
  399. caller, line, exp[i], (uintmax_t) i, real[i]);
  400. }
  401. }
  402. }
  403. void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
  404. if (exp != real) {
  405. CTEST_ERR("%s:%d expected %" PRIdMAX ", got %" PRIdMAX, caller, line, exp, real);
  406. }
  407. }
  408. void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
  409. if (exp != real) {
  410. CTEST_ERR("%s:%d expected %" PRIuMAX ", got %" PRIuMAX, caller, line, exp, real);
  411. }
  412. }
  413. void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
  414. if ((exp) == (real)) {
  415. CTEST_ERR("%s:%d should not be %" PRIdMAX, caller, line, real);
  416. }
  417. }
  418. void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
  419. if ((exp) == (real)) {
  420. CTEST_ERR("%s:%d should not be %" PRIuMAX, caller, line, real);
  421. }
  422. }
  423. void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line) {
  424. if (real < exp1 || real > exp2) {
  425. CTEST_ERR("%s:%d expected %" PRIdMAX "-%" PRIdMAX ", got %" PRIdMAX, caller, line, exp1, exp2, real);
  426. }
  427. }
  428. void assert_dbl_near(double exp, double real, double tol, const char* caller, int line) {
  429. double diff = exp - real;
  430. double absdiff = diff;
  431. /* avoid using fabs and linking with a math lib */
  432. if(diff < 0) {
  433. absdiff *= -1;
  434. }
  435. if (absdiff > tol) {
  436. CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
  437. }
  438. }
  439. void assert_dbl_far(double exp, double real, double tol, const char* caller, int line) {
  440. double diff = exp - real;
  441. double absdiff = diff;
  442. /* avoid using fabs and linking with a math lib */
  443. if(diff < 0) {
  444. absdiff *= -1;
  445. }
  446. if (absdiff <= tol) {
  447. CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
  448. }
  449. }
  450. void assert_null(void* real, const char* caller, int line) {
  451. if ((real) != NULL) {
  452. CTEST_ERR("%s:%d should be NULL", caller, line);
  453. }
  454. }
  455. void assert_not_null(const void* real, const char* caller, int line) {
  456. if (real == NULL) {
  457. CTEST_ERR("%s:%d should not be NULL", caller, line);
  458. }
  459. }
  460. void assert_true(int real, const char* caller, int line) {
  461. if ((real) == 0) {
  462. CTEST_ERR("%s:%d should be true", caller, line);
  463. }
  464. }
  465. void assert_false(int real, const char* caller, int line) {
  466. if ((real) != 0) {
  467. CTEST_ERR("%s:%d should be false", caller, line);
  468. }
  469. }
  470. void assert_fail(const char* caller, int line) {
  471. CTEST_ERR("%s:%d shouldn't come here", caller, line);
  472. }
  473. static int suite_all(struct ctest* t) {
  474. (void) t; // fix unused parameter warning
  475. return 1;
  476. }
  477. static int suite_filter(struct ctest* t) {
  478. return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
  479. }
  480. static int suite_test_filter(struct ctest* t) {
  481. int suit_match, test_match;
  482. suit_match=(strncmp(suite_name, t->ssname, strlen(suite_name)) == 0);
  483. test_match=(strncmp(test_name, t->ttname, strlen(test_name)) == 0);
  484. return (suit_match & test_match);
  485. }
  486. #ifndef __CTEST_NO_TIME
  487. static uint64_t getCurrentTime() {
  488. struct timeval now;
  489. gettimeofday(&now, NULL);
  490. uint64_t now64 = (uint64_t) now.tv_sec;
  491. now64 *= 1000000;
  492. now64 += ((uint64_t) now.tv_usec);
  493. return now64;
  494. }
  495. #endif
  496. static void color_print(const char* color, const char* text) {
  497. if (color_output)
  498. printf("%s%s"ANSI_NORMAL"\n", color, text);
  499. else
  500. printf("%s\n", text);
  501. }
  502. #ifdef __CTEST_APPLE
  503. static void *find_symbol(struct ctest *test, const char *fname)
  504. {
  505. size_t len = strlen(test->ssname) + 1 + strlen(fname);
  506. char *symbol_name = (char *) malloc(len + 1);
  507. memset(symbol_name, 0, len + 1);
  508. snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname);
  509. //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name);
  510. void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
  511. if (!symbol) {
  512. //fprintf(stderr, ">>>> ERROR: %s\n", dlerror());
  513. }
  514. // returns NULL on error
  515. free(symbol_name);
  516. return symbol;
  517. }
  518. #endif
  519. #ifdef CTEST_SEGFAULT
  520. #include <signal.h>
  521. static void sighandler(int signum)
  522. {
  523. char msg[128];
  524. snprintf(msg, sizeof(msg), "[SIGNAL %d: %s]", signum, strsignal(signum));
  525. color_print(ANSI_BRED, msg);
  526. fflush(stdout);
  527. /* "Unregister" the signal handler and send the signal back to the process
  528. * so it can terminate as expected */
  529. signal(signum, SIG_DFL);
  530. kill(getpid(), signum);
  531. }
  532. #endif
  533. int ctest_main(int argc, const char *argv[])
  534. {
  535. static int total = 0;
  536. static int num_ok = 0;
  537. static int num_fail = 0;
  538. static int num_skip = 0;
  539. static int index = 1;
  540. static filter_func filter = suite_all;
  541. const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
  542. char results[80];
  543. static struct ctest* test;
  544. #ifdef CTEST_SEGFAULT
  545. signal(SIGSEGV, sighandler);
  546. #endif
  547. if (argc == 2) {
  548. suite_name = argv[1];
  549. filter = suite_filter;
  550. }else if (argc == 3) {
  551. suite_name = argv[1];
  552. test_name = argv[2];
  553. filter = suite_test_filter;
  554. }
  555. #ifdef CTEST_NO_COLORS
  556. color_output = 0;
  557. #else
  558. color_output = isatty(1);
  559. #endif
  560. #ifndef __CTEST_NO_TIME
  561. uint64_t t1 = getCurrentTime();
  562. #endif
  563. #ifndef CTEST_ADD_TESTS_MANUALLY
  564. __ctest_linkTests();
  565. #endif
  566. for (test = *(__ctest_head_p); test != NULL; test=test->next) {
  567. if (test == &__ctest_suite_test) continue;
  568. if (filter(test)) total++;
  569. }
  570. for (test = *(__ctest_head_p); test != NULL; test=test->next) {
  571. if (test == &__ctest_suite_test) continue;
  572. if (filter(test)) {
  573. ctest_errorbuffer[0] = 0;
  574. ctest_errorsize = MSG_SIZE-1;
  575. ctest_errormsg = ctest_errorbuffer;
  576. printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname);
  577. fflush(stdout);
  578. if (test->skip) {
  579. color_print(ANSI_BYELLOW, "[SKIPPED]");
  580. num_skip++;
  581. } else {
  582. int result = __CTEST_SETJMP(ctest_err);
  583. if (result == 0) {
  584. #ifdef __CTEST_APPLE
  585. if (!test->setup) {
  586. test->setup = (SetupFunc) find_symbol(test, "setup");
  587. }
  588. if (!test->teardown) {
  589. test->teardown = (TearDownFunc) find_symbol(test, "teardown");
  590. }
  591. #endif
  592. if (test->setup) test->setup(test->data);
  593. if (test->data)
  594. ((RunWithDataFunc)test->run)(test->data);
  595. else
  596. test->run();
  597. if (test->teardown) test->teardown(test->data);
  598. // if we got here it's ok
  599. #ifdef CTEST_COLOR_OK
  600. color_print(ANSI_BGREEN, "[OK]");
  601. #else
  602. printf("[OK]\n");
  603. #endif
  604. num_ok++;
  605. } else {
  606. color_print(ANSI_BRED, "[FAIL]");
  607. num_fail++;
  608. }
  609. if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer);
  610. }
  611. index++;
  612. }
  613. }
  614. #ifndef __CTEST_NO_TIME
  615. uint64_t t2 = getCurrentTime();
  616. #endif
  617. #ifndef __CTEST_NO_TIME
  618. sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped) ran in %"PRIu64" ms", total, num_ok, num_fail, num_skip, (t2 - t1)/1000);
  619. #else
  620. sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped)", total, num_ok, num_fail, num_skip);
  621. #endif
  622. color_print(color, results);
  623. return num_fail;
  624. }
  625. #endif
  626. #endif