#include "test_harness.h" #include #include #include #include #include #include #include static jmp_buf jmpbuf; volatile test_t dummy __attribute((__section__("tests"))) __attribute((__used__)) = { "dummy", "dummy", NULL }; extern test_t __start_tests; extern test_t __stop_tests; test_t* iter = &__start_tests; static int execute_test(test_t* test); int main() { for( ; iter < &__stop_tests; ++ iter) { if (iter->fn_ptr != NULL) { execute_test(iter); } } } void test_harness_abort(int ec) { longjmp(jmpbuf, ec); assert("Long jump failed.\n"); } static int execute_test(test_t* test) { char fullname[512]; int status; int ec; pid_t pid; snprintf( fullname, sizeof(fullname), "%s::%s", iter->test_suite, iter->test_name); if (!(pid = fork())) { // child if ((ec = setjmp(jmpbuf))) { exit(ec); } else { test->fn_ptr(); exit(0); } } else { if (waitpid(pid, &status, 0) == -1) { fprintf(stderr, "waitpid() failed\n"); return 1; } if (WIFEXITED(status)) { switch ((ec = WEXITSTATUS(status))) { case 0: printf("%s " GREEN "[PASS]" RESET "\n", fullname); return 0; default: printf("%s " RED "[FAIL] %d" RESET "\n", fullname, ec); return ec; } } else if (WIFSIGNALED(status)) { int ec = WTERMSIG(status); printf("%s " RED "[FAIL] signaled %d" RESET "\n", fullname, ec); return ec; } return ec; } }