19 #if defined _WIN32 || defined __CYGWIN__ 26 #define WEAK __attribute__ ((weak)) 50 #define __FNAME(sname, tname) __ctest_##sname##_##tname##_run 51 #define __TNAME(sname, tname) __ctest_##sname##_##tname 53 #define __CTEST_MAGIC (0xdeadbeef) 55 #define __Test_Section __attribute__ ((used, section ("__DATA, .ctest"))) 57 #define __Test_Section __attribute__ ((used, section (".ctest"))) 60 #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \ 61 static struct ctest __TNAME(sname, tname) __Test_Section = { \ 64 .run = __FNAME(sname, tname), \ 67 .setup = (SetupFunc)__setup, \ 68 .teardown = (TearDownFunc)__teardown, \ 69 .magic = __CTEST_MAGIC }; 71 #define CTEST_DATA(sname) struct sname##_data 73 #define CTEST_SETUP(sname) \ 74 void WEAK sname##_setup(struct sname##_data* data) 76 #define CTEST_TEARDOWN(sname) \ 77 void WEAK sname##_teardown(struct sname##_data* data) 79 #define __CTEST_INTERNAL(sname, tname, _skip) \ 80 void __FNAME(sname, tname)(); \ 81 __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \ 82 void __FNAME(sname, tname)() 85 #define SETUP_FNAME(sname) NULL 86 #define TEARDOWN_FNAME(sname) NULL 88 #define SETUP_FNAME(sname) sname##_setup 89 #define TEARDOWN_FNAME(sname) sname##_teardown 92 #define __CTEST2_INTERNAL(sname, tname, _skip) \ 93 static struct sname##_data __ctest_##sname##_data; \ 95 CTEST_TEARDOWN(sname); \ 96 void __FNAME(sname, tname)(struct sname##_data* data); \ 97 __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \ 98 void __FNAME(sname, tname)(struct sname##_data* data) 104 #define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0) 105 #define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1) 107 #define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0) 108 #define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1) 111 void assert_str(
const char* exp,
const char* real,
const char* caller,
int line);
112 #define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__) 114 void assert_data(
const unsigned char* exp,
size_t expsize,
115 const unsigned char* real,
size_t realsize,
116 const char* caller,
int line);
117 #define ASSERT_DATA(exp, expsize, real, realsize) \ 118 assert_data(exp, expsize, real, realsize, __FILE__, __LINE__) 120 void assert_equal(intmax_t exp, intmax_t real,
const char* caller,
int line);
121 #define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__) 123 void assert_equal_u(uintmax_t exp, uintmax_t real,
const char* caller,
int line);
124 #define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__) 126 void assert_not_equal(intmax_t exp, intmax_t real,
const char* caller,
int line);
127 #define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__) 130 #define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__) 132 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real,
const char* caller,
int line);
133 #define ASSERT_INTERVAL(exp1, exp2, real) assert_interval(exp1, exp2, real, __FILE__, __LINE__) 135 void assert_null(
void* real,
const char* caller,
int line);
136 #define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__) 139 #define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__) 141 void assert_true(
int real,
const char* caller,
int line);
142 #define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__) 144 void assert_false(
int real,
const char* caller,
int line);
145 #define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__) 148 #define ASSERT_FAIL() assert_fail(__FILE__, __LINE__) 150 void assert_dbl_near(
double exp,
double real,
double tol,
const char* caller,
int line);
151 #define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__) 152 #define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__) 154 void assert_dbl_far(
double exp,
double real,
double tol,
const char* caller,
int line);
155 #define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__) 156 #define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__) 164 #include <sys/time.h> 173 static size_t ctest_errorsize;
174 static char* ctest_errormsg;
175 #define MSG_SIZE 4096 176 static char ctest_errorbuffer[MSG_SIZE];
177 static jmp_buf ctest_err;
178 static int color_output = 1;
179 static const char* suite_name;
181 typedef int (*filter_func)(
struct ctest*);
183 #define ANSI_BLACK "\033[0;30m" 184 #define ANSI_RED "\033[0;31m" 185 #define ANSI_GREEN "\033[0;32m" 186 #define ANSI_YELLOW "\033[0;33m" 187 #define ANSI_BLUE "\033[0;34m" 188 #define ANSI_MAGENTA "\033[0;35m" 189 #define ANSI_CYAN "\033[0;36m" 190 #define ANSI_GREY "\033[0;37m" 191 #define ANSI_DARKGREY "\033[01;30m" 192 #define ANSI_BRED "\033[01;31m" 193 #define ANSI_BGREEN "\033[01;32m" 194 #define ANSI_BYELLOW "\033[01;33m" 195 #define ANSI_BBLUE "\033[01;34m" 196 #define ANSI_BMAGENTA "\033[01;35m" 197 #define ANSI_BCYAN "\033[01;36m" 198 #define ANSI_WHITE "\033[01;37m" 199 #define ANSI_NORMAL "\033[0m" 201 static CTEST(suite, test) { }
203 inline static void vprint_errormsg(
const char*
const fmt, va_list ap) {
205 const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap);
207 ctest_errormsg[0] = 0x00;
209 const size_t size = (size_t) ret;
210 const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size);
212 ctest_errorsize -= s;
217 inline static void print_errormsg(
const char*
const fmt, ...) {
220 vprint_errormsg(fmt, argp);
224 static void msg_start(
const char* color,
const char* title) {
226 print_errormsg(
"%s", color);
228 print_errormsg(
" %s: ", title);
231 static void msg_end() {
233 print_errormsg(ANSI_NORMAL);
235 print_errormsg(
"\n");
241 msg_start(ANSI_BLUE,
"LOG");
244 vprint_errormsg(fmt, argp);
253 msg_start(ANSI_YELLOW,
"ERR");
256 vprint_errormsg(fmt, argp);
260 longjmp(ctest_err, 1);
263 void assert_str(
const char* exp,
const char* real,
const char* caller,
int line) {
264 if ((exp == NULL && real != NULL) ||
265 (exp != NULL && real == NULL) ||
266 (exp && real && strcmp(exp, real) != 0)) {
267 CTEST_ERR(
"%s:%d expected '%s', got '%s'", caller, line, exp, real);
271 void assert_data(
const unsigned char* exp,
size_t expsize,
272 const unsigned char* real,
size_t realsize,
273 const char* caller,
int line) {
275 if (expsize != realsize) {
276 CTEST_ERR(
"%s:%d expected %" PRIuMAX
" bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
278 for (i=0; i<expsize; i++) {
279 if (exp[i] != real[i]) {
280 CTEST_ERR(
"%s:%d expected 0x%02x at offset %" PRIuMAX
" got 0x%02x",
281 caller, line, exp[i], (uintmax_t) i, real[i]);
286 void assert_equal(intmax_t exp, intmax_t real,
const char* caller,
int line) {
288 CTEST_ERR(
"%s:%d expected %" PRIdMAX
", got %" PRIdMAX, caller, line, exp, real);
292 void assert_equal_u(uintmax_t exp, uintmax_t real,
const char* caller,
int line) {
294 CTEST_ERR(
"%s:%d expected %" PRIuMAX
", got %" PRIuMAX, caller, line, exp, real);
298 void assert_not_equal(intmax_t exp, intmax_t real,
const char* caller,
int line) {
299 if ((exp) == (real)) {
300 CTEST_ERR(
"%s:%d should not be %" PRIdMAX, caller, line, real);
304 void assert_not_equal_u(uintmax_t exp, uintmax_t real,
const char* caller,
int line) {
305 if ((exp) == (real)) {
306 CTEST_ERR(
"%s:%d should not be %" PRIuMAX, caller, line, real);
310 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real,
const char* caller,
int line) {
311 if (real < exp1 || real > exp2) {
312 CTEST_ERR(
"%s:%d expected %" PRIdMAX
"-%" PRIdMAX
", got %" PRIdMAX, caller, line, exp1, exp2, real);
316 void assert_dbl_near(
double exp,
double real,
double tol,
const char* caller,
int line) {
317 double diff = exp - real;
318 double absdiff = diff;
324 CTEST_ERR(
"%s:%d expected %0.6e, got %0.6e (diff %0.6e, tol %0.6e)", caller, line, exp, real, diff, tol);
328 void assert_dbl_far(
double exp,
double real,
double tol,
const char* caller,
int line) {
329 double diff = exp - real;
330 double absdiff = diff;
335 if (absdiff <= tol) {
336 CTEST_ERR(
"%s:%d expected %0.6e, got %0.6e (diff %0.6e, tol %0.6e)", caller, line, exp, real, diff, tol);
340 void assert_null(
void* real,
const char* caller,
int line) {
341 if ((real) != NULL) {
342 CTEST_ERR(
"%s:%d should be NULL", caller, line);
348 CTEST_ERR(
"%s:%d should not be NULL", caller, line);
352 void assert_true(
int real,
const char* caller,
int line) {
354 CTEST_ERR(
"%s:%d should be true", caller, line);
358 void assert_false(
int real,
const char* caller,
int line) {
360 CTEST_ERR(
"%s:%d should be false", caller, line);
365 CTEST_ERR(
"%s:%d shouldn't come here", caller, line);
369 static int suite_all(
struct ctest* t) {
374 static int suite_filter(
struct ctest* t) {
375 return strncmp(suite_name, t->
ssname, strlen(suite_name)) == 0;
378 static uint64_t getCurrentTime() {
380 gettimeofday(&now, NULL);
381 uint64_t now64 = (uint64_t) now.tv_sec;
383 now64 += ((uint64_t) now.tv_usec);
387 static void color_print(
const char* color,
const char* text) {
389 printf(
"%s%s"ANSI_NORMAL
"\n", color, text);
391 printf(
"%s\n", text);
395 static void *find_symbol(
struct ctest *test,
const char *fname)
397 size_t len = strlen(test->
ssname) + 1 + strlen(fname);
398 char *symbol_name = (
char *) malloc(len + 1);
399 memset(symbol_name, 0, len + 1);
400 snprintf(symbol_name, len + 1,
"%s_%s", test->
ssname, fname);
403 void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
414 #ifdef CTEST_SEGFAULT 416 static void sighandler(
int signum)
419 sprintf(msg,
"[SIGNAL %d: %s]", signum, sys_siglist[signum]);
420 color_print(ANSI_BRED, msg);
425 signal(signum, SIG_DFL);
426 kill(getpid(), signum);
430 int ctest_main(
int argc,
const char *argv[])
432 static int total = 0;
433 static int num_ok = 0;
434 static int num_fail = 0;
435 static int num_skip = 0;
436 static int index = 1;
437 static filter_func filter = suite_all;
439 #ifdef CTEST_SEGFAULT 440 signal(SIGSEGV, sighandler);
444 suite_name = argv[1];
445 filter = suite_filter;
447 #ifdef CTEST_NO_COLORS 450 color_output = isatty(1);
452 uint64_t t1 = getCurrentTime();
458 struct ctest* t = ctest_begin-1;
463 struct ctest* t = ctest_end+1;
469 static struct ctest* test;
470 for (test = ctest_begin; test != ctest_end; test++) {
471 if (test == &
__TNAME(suite, test))
continue;
472 if (filter(test)) total++;
475 for (test = ctest_begin; test != ctest_end; test++) {
476 if (test == &
__TNAME(suite, test))
continue;
478 ctest_errorbuffer[0] = 0;
479 ctest_errorsize = MSG_SIZE-1;
480 ctest_errormsg = ctest_errorbuffer;
481 printf(
"TEST %d/%d %s:%s ", index, total, test->
ssname, test->
ttname);
484 color_print(ANSI_BYELLOW,
"[SKIPPED]");
487 int result = setjmp(ctest_err);
505 #ifdef CTEST_COLOR_OK 506 color_print(ANSI_BGREEN,
"[OK]");
512 color_print(ANSI_BRED,
"[FAIL]");
515 if (ctest_errorsize != MSG_SIZE-1) printf(
"%s", ctest_errorbuffer);
520 uint64_t t2 = getCurrentTime();
522 const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
524 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);
525 color_print(color, results);
void(* run)()
Definition: ctest.h:40
void assert_equal(intmax_t exp, intmax_t real, const char *caller, int line)
#define CTEST(sname, tname)
Definition: ctest.h:104
void assert_dbl_near(double exp, double real, double tol, const char *caller, int line)
void CTEST_LOG(const char *fmt,...)
void assert_data(const unsigned char *exp, size_t expsize, const unsigned char *real, size_t realsize, const char *caller, int line)
void assert_not_equal(intmax_t exp, intmax_t real, const char *caller, int line)
void assert_null(void *real, const char *caller, int line)
void assert_dbl_far(double exp, double real, double tol, const char *caller, int line)
#define __TNAME(sname, tname)
Definition: ctest.h:51
void(* TearDownFunc)(void *)
Definition: ctest.h:35
void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char *caller, int line)
TearDownFunc teardown
Definition: ctest.h:45
void assert_equal_u(uintmax_t exp, uintmax_t real, const char *caller, int line)
unsigned int magic
Definition: ctest.h:47
void assert_str(const char *exp, const char *real, const char *caller, int line)
#define __CTEST_MAGIC
Definition: ctest.h:53
void assert_false(int real, const char *caller, int line)
void * data
Definition: ctest.h:43
void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char *caller, int line)
void assert_true(int real, const char *caller, int line)
SetupFunc setup
Definition: ctest.h:44
const char * ssname
Definition: ctest.h:38
const char * ttname
Definition: ctest.h:39
void assert_fail(const char *caller, int line)
int skip
Definition: ctest.h:41
void CTEST_ERR(const char *fmt,...)
void assert_not_null(const void *real, const char *caller, int line)
void(* SetupFunc)(void *)
Definition: ctest.h:34