1 /* Copyright 2011-2016 Bas van den Berg
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #if defined _WIN32 || defined __CYGWIN__
26 #define WEAK __attribute__ ((weak))
32 #include <inttypes.h> /* intmax_t, uintmax_t, PRI* */
35 #include <stddef.h> /* size_t */
37 typedef void (*SetupFunc)(void*);
38 typedef void (*TearDownFunc)(void*);
39 typedef void (*RunWithDataFunc)(void*);
42 const char* ssname; // suite name
43 const char* ttname; // test name
49 TearDownFunc teardown;
56 #define __FNAME(sname, tname) __ctest_##sname##_##tname##_run
57 #define __TNAME(sname, tname) __ctest_##sname##_##tname
58 #define __PNAME(sname, tname) __ctest_##sname##_##tname##_pointer
69 #if defined(__clang__)
70 #define __CTEST_NO_TIME
72 #elif defined(_MSC_VER)
77 //config for MSVC compiler
80 #define __CTEST_NO_TIME
81 #define CTEST_NO_COLORS
87 #define CTEST_NO_INTTYPES
90 #ifndef CTEST_ADD_TESTS_MANUALLY
91 #pragma section(".ctest$a")
92 #pragma section(".ctest$u")
93 #pragma section(".ctest$z")
96 //clear this flag for msvc
102 #define inline __inline
107 #define __CTEST_NO_JMP
110 #define __CTEST_MAGIC (0xdeadbeef)
112 #ifdef CTEST_ADD_TESTS_MANUALLY
113 # define __Test_Section
116 #define __Test_Section __attribute__ ((used, section ("__DATA, .ctest")))
117 #elif defined (__CTEST_MSVC)
118 #define __Test_Section __declspec( allocate(".ctest$u"))
120 #define __Test_Section __attribute__ ((used, section (".ctest")))
125 #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
126 static struct ctest __TNAME(sname, tname) = { \
129 .run = __FNAME(sname, tname), \
132 .setup = (SetupFunc)__setup, \
133 .teardown = (TearDownFunc)__teardown, \
135 .magic = __CTEST_MAGIC}; \
136 static void * __PNAME(sname, tname)[2] __Test_Section = {(void*)& __TNAME(sname,tname), (void*)__CTEST_MAGIC};
139 #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
140 static struct ctest __TNAME(sname, tname) = { \
143 __FNAME(sname, tname), \
146 (SetupFunc)__setup, \
147 (TearDownFunc)__teardown, \
150 __Test_Section static void * __PNAME(sname, tname)[2]= {(void*)& __TNAME(sname,tname), (void *)__CTEST_MAGIC};
153 #define CTEST_DATA(sname) struct sname##_data
155 #define CTEST_SETUP(sname) \
156 void WEAK sname##_setup(struct sname##_data* data)
158 #define CTEST_TEARDOWN(sname) \
159 void WEAK sname##_teardown(struct sname##_data* data)
161 #define __CTEST_INTERNAL(sname, tname, _skip) \
162 void __FNAME(sname, tname)(); \
163 __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \
164 void __FNAME(sname, tname)()
167 #define SETUP_FNAME(sname) NULL
168 #define TEARDOWN_FNAME(sname) NULL
170 #define SETUP_FNAME(sname) sname##_setup
171 #define TEARDOWN_FNAME(sname) sname##_teardown
174 #define __CTEST2_INTERNAL(sname, tname, _skip) \
175 static struct sname##_data __ctest_##sname##_data; \
176 CTEST_SETUP(sname); \
177 CTEST_TEARDOWN(sname); \
178 void __FNAME(sname, tname)(struct sname##_data* data); \
179 __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \
180 void __FNAME(sname, tname)(struct sname##_data* data)
183 void CTEST_LOG(const char* fmt, ...);
184 void CTEST_ERR(const char* fmt, ...); // doesn't return
186 #define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0)
187 #define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1)
189 #define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0)
190 #define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1)
193 #ifdef CTEST_ADD_TESTS_MANUALLY
195 void __ctest_addTest(struct ctest *);
197 #define CTEST_ADD(sname, tname) do { \
198 extern struct ctest __TNAME(sname, tname); \
199 __ctest_addTest(&__TNAME(sname, tname)); \
202 #define CTEST_ADD2(sname, tname) do { \
203 extern struct ctest __TNAME(sname, tname); \
204 __ctest_addTest(&__TNAME(sname, tname)); \
207 #endif // CTEST_ADD_TESTS_MANUALLY
209 void assert_str(const char* exp, const char* real, const char* caller, int line);
210 #define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__)
212 void assert_data(const unsigned char* exp, size_t expsize,
213 const unsigned char* real, size_t realsize,
214 const char* caller, int line);
215 #define ASSERT_DATA(exp, expsize, real, realsize) \
216 assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
218 void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line);
219 #define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
221 void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
222 #define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__)
224 void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line);
225 #define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__)
227 void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
228 #define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__)
230 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line);
231 #define ASSERT_INTERVAL(exp1, exp2, real) assert_interval(exp1, exp2, real, __FILE__, __LINE__)
233 void assert_null(void* real, const char* caller, int line);
234 #define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__)
236 void assert_not_null(const void* real, const char* caller, int line);
237 #define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__)
239 void assert_true(int real, const char* caller, int line);
240 #define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__)
242 void assert_false(int real, const char* caller, int line);
243 #define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__)
245 void assert_fail(const char* caller, int line);
246 #define ASSERT_FAIL() assert_fail(__FILE__, __LINE__)
248 /* If longjmp() is not available, integer flag will be used instead of jmp_buf.
250 * __CTEST_SETJMP() will clear the flag and return zero, and __CTEST_LONGJMP()
251 * will set the flag to its argument. __CTEST_ERROR_CODE() will return that flag.
253 * If longjmp() is available, jmp_buf will be used as usual and __CTEST_ERROR_CODE()
254 * will always return zero.
256 * You can check both __CTEST_SETJMP() and __CTEST_ERROR_CODE() return value
257 * to detect error in a portable way.
259 #ifdef __CTEST_NO_JMP
260 # define __CTEST_JMPBUF int
261 # define __CTEST_ERROR_CODE(_var) (_var)
262 # define __CTEST_SETJMP(_var) (_var = 0)
263 # define __CTEST_LONGJMP(_var, _err) (_var = _err)
264 #else // !__CTEST_NO_JMP
265 # define __CTEST_JMPBUF jmp_buf
266 # define __CTEST_ERROR_CODE(_var) (0)
267 # define __CTEST_SETJMP(_var) setjmp(_var)
268 # define __CTEST_LONGJMP(_var, _err) longjmp(_var, _err)
269 #endif // __CTEST_NO_JMP
271 void assert_dbl_near(double exp, double real, double tol, const char* caller, int line);
272 #define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__)
273 #define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__)
275 void assert_dbl_far(double exp, double real, double tol, const char* caller, int line);
276 #define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__)
277 #define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__)
281 #ifndef __CTEST_NO_JMP
289 #ifndef __CTEST_NO_TIME
290 #include <sys/time.h>
306 static size_t ctest_errorsize;
307 static char* ctest_errormsg;
308 #define MSG_SIZE 4096
309 static char ctest_errorbuffer[MSG_SIZE];
310 static __CTEST_JMPBUF ctest_err;
311 static int color_output = 1;
312 static const char* suite_name;
313 static const char* test_name;
315 typedef int (*filter_func)(struct ctest*);
317 #define ANSI_BLACK "\033[0;30m"
318 #define ANSI_RED "\033[0;31m"
319 #define ANSI_GREEN "\033[0;32m"
320 #define ANSI_YELLOW "\033[0;33m"
321 #define ANSI_BLUE "\033[0;34m"
322 #define ANSI_MAGENTA "\033[0;35m"
323 #define ANSI_CYAN "\033[0;36m"
324 #define ANSI_GREY "\033[0;37m"
325 #define ANSI_DARKGREY "\033[01;30m"
326 #define ANSI_BRED "\033[01;31m"
327 #define ANSI_BGREEN "\033[01;32m"
328 #define ANSI_BYELLOW "\033[01;33m"
329 #define ANSI_BBLUE "\033[01;34m"
330 #define ANSI_BMAGENTA "\033[01;35m"
331 #define ANSI_BCYAN "\033[01;36m"
332 #define ANSI_WHITE "\033[01;37m"
333 #define ANSI_NORMAL "\033[0m"
336 #ifndef CTEST_ADD_TESTS_MANUALLY
337 __declspec(allocate(".ctest$a")) struct ctest * ctest_win_begin;
338 __declspec(allocate(".ctest$z")) struct ctest * ctest_win_end;
342 static CTEST(suite, test) { }
344 #define __CTEST_POINTER_NEXT(_test) (struct ctest **)((struct ctest **)(_test) + 2)
345 #define __CTEST_POINTER_PREV(_test) (struct ctest **)((struct ctest **)(_test) - 2)
347 /* First element of test list.
349 static struct ctest * * __ctest_head_p = (struct ctest **)__PNAME(suite, test);
351 #ifdef CTEST_ADD_TESTS_MANUALLY
353 /* Last element of test list.
355 static struct ctest *__ctest_tail = &__TNAME(suite, test);
357 /* Add test to linked list manually.
359 void __ctest_addTest(struct ctest *test)
361 __ctest_tail->next = test;
364 #else // !CTEST_ADD_TESTS_MANUALLY
367 /* Add all tests to linked list automatically.
369 static void __ctest_linkTests()
371 struct ctest ** test;
372 struct ctest ** ctest_begin = (struct ctest **)__PNAME(suite, test);
373 struct ctest ** ctest_end = (struct ctest **)__PNAME(suite, test);
375 // find begin and end of section by comparing magics
377 struct ctest** t = __CTEST_POINTER_PREV(ctest_begin);
378 if (t[0] == NULL) break;
379 if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
383 struct ctest** t = __CTEST_POINTER_NEXT(ctest_end);
384 if (t[0] == NULL) break;
385 if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
388 ctest_end = __CTEST_POINTER_NEXT(ctest_end); // end after last one
390 for (test = ctest_begin; test != ctest_end; test = __CTEST_POINTER_NEXT(test)) {
391 struct ctest ** next_p = __CTEST_POINTER_NEXT(test);
393 if (next_p == ctest_end)
398 (*test)->next = next;
401 __ctest_head_p = ctest_begin;
404 static void __ctest_linkTests()
406 struct ctest ** ctest_start = __ctest_head_p;
407 struct ctest ** test;
408 struct ctest * cur=ctest_start[0];
410 for(test=&ctest_win_begin; test!=&ctest_win_end; test++){
412 if(test[1] == (struct ctest*)__CTEST_MAGIC){
414 if((test[0]) == ctest_start[0]) continue;
425 inline static void vprint_errormsg(const char* const fmt, va_list ap) {
426 // (v)snprintf returns the number that would have been written
427 const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap);
429 ctest_errormsg[0] = 0x00;
431 const size_t size = (size_t) ret;
432 const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size);
433 // ctest_errorsize may overflow at this point
434 ctest_errorsize -= s;
439 inline static void print_errormsg(const char* const fmt, ...) {
442 vprint_errormsg(fmt, argp);
446 static void msg_start(const char* color, const char* title) {
448 print_errormsg("%s", color);
450 print_errormsg(" %s: ", title);
453 static void msg_end() {
455 print_errormsg(ANSI_NORMAL);
457 print_errormsg("\n");
460 void CTEST_LOG(const char* fmt, ...)
463 msg_start(ANSI_BLUE, "LOG");
466 vprint_errormsg(fmt, argp);
472 void CTEST_ERR(const char* fmt, ...)
475 msg_start(ANSI_YELLOW, "ERR");
478 vprint_errormsg(fmt, argp);
482 __CTEST_LONGJMP(ctest_err, 1);
485 void assert_str(const char* exp, const char* real, const char* caller, int line) {
486 if ((exp == NULL && real != NULL) ||
487 (exp != NULL && real == NULL) ||
488 (exp && real && strcmp(exp, real) != 0)) {
489 CTEST_ERR("%s:%d expected '%s', got '%s'", caller, line, exp, real);
493 void assert_data(const unsigned char* exp, size_t expsize,
494 const unsigned char* real, size_t realsize,
495 const char* caller, int line) {
497 if (expsize != realsize) {
498 #ifndef CTEST_NO_INTTYPES
499 CTEST_ERR("%s:%d expected %" PRIuMAX " bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
501 CTEST_ERR("%s:%d expected %u bytes, got %u", caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
504 for (i=0; i<expsize; i++) {
505 if (exp[i] != real[i]) {
506 #ifndef CTEST_NO_INTTYPES
507 CTEST_ERR("%s:%d expected 0x%02x at offset %" PRIuMAX " got 0x%02x",
509 CTEST_ERR("%s:%d expected 0x%02x at offset %u got 0x%02x",
511 caller, line, exp[i], (uintmax_t) i, real[i]);
516 void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
518 #ifndef CTEST_NO_INTTYPES
519 CTEST_ERR("%s:%d expected %" PRIdMAX ", got %" PRIdMAX, caller, line, exp, real);
521 CTEST_ERR("%s:%d expected %d, got %d", caller, line, exp, real);
526 void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
528 #ifndef CTEST_NO_INTTYPES
529 CTEST_ERR("%s:%d expected %" PRIuMAX ", got %" PRIuMAX, caller, line, exp, real);
531 CTEST_ERR("%s:%d expected %u, got %u", caller, line, exp, real);
536 void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
537 if ((exp) == (real)) {
538 #ifndef CTEST_NO_INTTYPES
539 CTEST_ERR("%s:%d should not be %" PRIdMAX, caller, line, real);
541 CTEST_ERR("%s:%d should not be %d", caller, line, real);
546 void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
547 if ((exp) == (real)) {
548 #ifndef CTEST_NO_INTTYPES
549 CTEST_ERR("%s:%d should not be %" PRIuMAX, caller, line, real);
551 CTEST_ERR("%s:%d should not be %u", caller, line, real);
556 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line) {
557 if (real < exp1 || real > exp2) {
558 #ifndef CTEST_NO_INTTYPES
559 CTEST_ERR("%s:%d expected %" PRIdMAX "-%" PRIdMAX ", got %" PRIdMAX, caller, line, exp1, exp2, real);
561 CTEST_ERR("%s:%d expected %d-%d, got %d", caller, line, exp1, exp2, real);
566 void assert_dbl_near(double exp, double real, double tol, const char* caller, int line) {
567 double diff = exp - real;
568 double absdiff = diff;
569 /* avoid using fabs and linking with a math lib */
574 CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
578 void assert_dbl_far(double exp, double real, double tol, const char* caller, int line) {
579 double diff = exp - real;
580 double absdiff = diff;
581 /* avoid using fabs and linking with a math lib */
585 if (absdiff <= tol) {
586 CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
590 void assert_null(void* real, const char* caller, int line) {
591 if ((real) != NULL) {
592 CTEST_ERR("%s:%d should be NULL", caller, line);
596 void assert_not_null(const void* real, const char* caller, int line) {
598 CTEST_ERR("%s:%d should not be NULL", caller, line);
602 void assert_true(int real, const char* caller, int line) {
604 CTEST_ERR("%s:%d should be true", caller, line);
608 void assert_false(int real, const char* caller, int line) {
610 CTEST_ERR("%s:%d should be false", caller, line);
614 void assert_fail(const char* caller, int line) {
615 CTEST_ERR("%s:%d shouldn't come here", caller, line);
619 static int suite_all(struct ctest* t) {
620 (void) t; // fix unused parameter warning
624 static int suite_filter(struct ctest* t) {
625 return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
628 static int suite_test_filter(struct ctest* t) {
629 int suit_match, test_match;
630 suit_match=(strncmp(suite_name, t->ssname, strlen(suite_name)) == 0);
631 test_match=(strncmp(test_name, t->ttname, strlen(test_name)) == 0);
632 return (suit_match & test_match);
636 #ifndef __CTEST_NO_TIME
637 static uint64_t getCurrentTime() {
639 gettimeofday(&now, NULL);
640 uint64_t now64 = (uint64_t) now.tv_sec;
642 now64 += ((uint64_t) now.tv_usec);
647 static void color_print(const char* color, const char* text) {
649 printf("%s%s"ANSI_NORMAL"\n", color, text);
651 printf("%s\n", text);
655 static void *find_symbol(struct ctest *test, const char *fname)
657 size_t len = strlen(test->ssname) + 1 + strlen(fname);
658 char *symbol_name = (char *) malloc(len + 1);
659 memset(symbol_name, 0, len + 1);
660 snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname);
662 //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name);
663 void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
665 //fprintf(stderr, ">>>> ERROR: %s\n", dlerror());
667 // returns NULL on error
674 #ifdef CTEST_SEGFAULT
676 static void sighandler(int signum)
679 snprintf(msg, sizeof(msg), "[SIGNAL %d: %s]", signum, strsignal(signum));
680 color_print(ANSI_BRED, msg);
683 /* "Unregister" the signal handler and send the signal back to the process
684 * so it can terminate as expected */
685 signal(signum, SIG_DFL);
686 kill(getpid(), signum);
690 int ctest_main(int argc, const char *argv[])
692 static int total = 0;
693 static int num_ok = 0;
694 static int num_fail = 0;
695 static int num_skip = 0;
696 static int index = 1;
697 static filter_func filter = suite_all;
699 const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
701 static struct ctest* test;
703 #ifdef CTEST_SEGFAULT
704 signal(SIGSEGV, sighandler);
708 suite_name = argv[1];
709 filter = suite_filter;
710 }else if (argc == 3) {
711 suite_name = argv[1];
713 filter = suite_test_filter;
716 #ifdef CTEST_NO_COLORS
719 color_output = isatty(1);
722 #ifndef __CTEST_NO_TIME
723 uint64_t t1 = getCurrentTime();
726 #ifndef CTEST_ADD_TESTS_MANUALLY
731 for (test = *(__ctest_head_p); test != NULL; test=test->next) {
732 if (test == &__ctest_suite_test) continue;
733 if (filter(test)) total++;
736 for (test = *(__ctest_head_p); test != NULL; test=test->next) {
737 if (test == &__ctest_suite_test) continue;
739 ctest_errorbuffer[0] = 0;
740 ctest_errorsize = MSG_SIZE-1;
741 ctest_errormsg = ctest_errorbuffer;
742 printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname);
745 color_print(ANSI_BYELLOW, "[SKIPPED]");
748 int result = __CTEST_SETJMP(ctest_err);
752 test->setup = (SetupFunc) find_symbol(test, "setup");
754 if (!test->teardown) {
755 test->teardown = (TearDownFunc) find_symbol(test, "teardown");
759 if (test->setup) test->setup(test->data);
761 ((RunWithDataFunc)test->run)(test->data);
764 if (test->teardown) test->teardown(test->data);
765 // if we got here it's ok
766 #ifdef CTEST_COLOR_OK
767 color_print(ANSI_BGREEN, "[OK]");
773 color_print(ANSI_BRED, "[FAIL]");
776 if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer);
781 #ifndef __CTEST_NO_TIME
782 uint64_t t2 = getCurrentTime();
785 #ifndef __CTEST_NO_TIME
786 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);
788 sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped)", total, num_ok, num_fail, num_skip);
790 color_print(color, results);