#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; const char* note = ""; 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; } ec = WEXITSTATUS(status); switch (ec) { case 0: printf("%s " GREEN "[PASS]" RESET "\n", fullname); return 0; case 11: note = " (SIGSEGV)"; break; } printf("%s " RED "[FAIL] %d%s" RESET "\n", fullname, ec, note); return ec; } }