From 25251ba2e205261b9d6d4e0877a59cb09750e63b Mon Sep 17 00:00:00 2001 From: Alessio Chiapperini Date: Thu, 19 Sep 2024 11:59:33 +0200 Subject: [PATCH] setup function now returns an int While running the tests, the return value of the test specific setup fixture is checked. --- src/harness.c | 153 ++++++++++++++++++++++++++++++----------------------- src/harness.h | 2 +- src/harness_demo.c | 20 ++++++- 3 files changed, 108 insertions(+), 67 deletions(-) diff --git a/src/harness.c b/src/harness.c index 254ed46..65cd360 100644 --- a/src/harness.c +++ b/src/harness.c @@ -40,6 +40,15 @@ #define UNI_32BIT_INV 2.3283064365386962890625e-10 #define VNI_32BIT_INV 4.6566128730773925781250e-10 /* UNI_32BIT_INV * 2 */ +struct harness_report { + struct timeval total_time; + struct timeval suite_time; + int npass; + int nfail; + int nskip; + int nerror; +}; + static void timeval_sub(struct timeval t1, struct timeval t2, struct timeval *res) { @@ -255,17 +264,77 @@ harness_list_tests(char *test_suite) } } -int -harness_run(void *user_data) +static int +harness_run_test(int s, int t, struct harness_report *report) { - struct timeval total_time = {0}; - struct timeval suite_time = {0}; struct timeval test_time = {0}; struct timeval start_time = {0}; struct timeval end_time = {0}; + + int res = 0; + char *verdict = 0; + + (void)fprintf(stdout, "[ %-8s ] %s.%s\n", "RUN", + test_suites[s].suite_name, + test_suites[s].tests[t].test_name); + + (void)memset(&test_time, 0, sizeof(struct timeval)); + + if (test_suites[s].tests[t].setup != NULL) { + res = test_suites[s].tests[t].setup( + test_suites[s].tests[t].user_data); + if (res != HARNESS_PASS) { + goto print_report; + } + } - int res, npass, nfail, nskip, nerror; - char *verdict; + gettimeofday(&start_time, NULL); + res = test_suites[s].tests[t].test_function( + test_suites[s].tests[t].user_data); + gettimeofday(&end_time, NULL); + timeval_sub(start_time, end_time, &test_time); + +print_report: + switch (res) { + case HARNESS_PASS: + verdict = "PASS"; + report->npass++; + break; + case HARNESS_FAIL: + verdict = "FAIL"; + report->nfail++; + break; + case HARNESS_SKIP: + verdict = "SKIP"; + report->nskip++; + break; + default: + verdict = "ERROR"; + report->nerror++; + break; + } + + (void)fprintf(stdout, "[ %8s ] %s.%s " + "(%ld ms)\n", + verdict, + test_suites[s].suite_name, + test_suites[s].tests[t].test_name, + (test_time.tv_usec / 1000) + + test_time.tv_sec * 1000); + timeval_add(report->suite_time, test_time, &report->suite_time); + + if (test_suites[s].tests[t].teardown != NULL) { + test_suites[s].tests[t].teardown( + test_suites[s].tests[t].user_data); + } + + return (res); +} + +int +harness_run(void *user_data) +{ + struct harness_report report = {0}; if (cfg->setup != NULL) { cfg->setup(user_data); @@ -273,7 +342,6 @@ harness_run(void *user_data) "set-up.\n"); } - res = npass = nfail = nskip = nerror = 0; (void)fprintf(stdout, "[==========] Running %d test cases from %d " "test suites with seed 0x%08" PRIx32 ".\n", cfg->ntests, cfg->nsuites, cfg->seed); @@ -282,72 +350,27 @@ harness_run(void *user_data) (void)fprintf(stdout, "[----------] %d tests from %s.\n", test_suites[s].ntests, test_suites[s].suite_name); - (void)memset(&suite_time, 0, sizeof(struct timeval)); + (void)memset(&report.suite_time, 0, sizeof(struct timeval)); for (int t = 0; t < test_suites[s].ntests; t++) { - (void)fprintf(stdout, "[ %-8s ] %s.%s\n", "RUN", - test_suites[s].suite_name, - test_suites[s].tests[t].test_name); - - (void)memset(&test_time, 0, sizeof(struct timeval)); - - if (test_suites[s].tests[t].setup != NULL) { - test_suites[s].tests[t].setup( - test_suites[s].tests[t].user_data); - } - - gettimeofday(&start_time, NULL); - res = test_suites[s].tests[t].test_function( - test_suites[s].tests[t].user_data); - gettimeofday(&end_time, NULL); - timeval_sub(start_time, end_time, &test_time); - - switch (res) { - case HARNESS_PASS: - verdict = "PASS"; - npass++; - break; - case HARNESS_FAIL: - verdict = "FAIL"; - nfail++; - break; - case HARNESS_SKIP: - verdict = "SKIP"; - nskip++; - break; - default: - verdict = "ERROR"; - nerror++; - break; - } - - (void)fprintf(stdout, "[ %8s ] %s.%s " - "(%ld ms)\n", - verdict, - test_suites[s].suite_name, - test_suites[s].tests[t].test_name, - (test_time.tv_usec / 1000) + - test_time.tv_sec * 1000); - timeval_add(suite_time, test_time, &suite_time); - - if (test_suites[s].tests[t].teardown != NULL) { - test_suites[s].tests[t].teardown( - test_suites[s].tests[t].user_data); - } + (void)harness_run_test(s, t, &report); } (void)fprintf(stdout, "[----------] %d tests from %s (%ld ms " "total).\n", test_suites[s].ntests, test_suites[s].suite_name, - (suite_time.tv_usec / 1000) + suite_time.tv_sec * 1000); - timeval_add(total_time, suite_time, &total_time); + (report.suite_time.tv_usec / 1000) + + report.suite_time.tv_sec * 1000); + timeval_add(report.total_time, report.suite_time, + &report.total_time); } (void)fprintf(stdout, "[==========] %d test cases from %d test suites " "ran (%ld ms total).\n", cfg->ntests, cfg->nsuites, - (total_time.tv_usec / 1000) + total_time.tv_sec * 1000); - (void)fprintf(stdout, "[ PASSED ] %d tests.\n", npass); - (void)fprintf(stdout, "[ FAILED ] %d tests.\n", nfail); - (void)fprintf(stdout, "[ SKIPPED ] %d tests.\n", nskip); - (void)fprintf(stdout, "[ ERRORS ] %d tests.\n", nerror); + (report.total_time.tv_usec / 1000) + + report.total_time.tv_sec * 1000); + (void)fprintf(stdout, "[ PASSED ] %d tests.\n", report.npass); + (void)fprintf(stdout, "[ FAILED ] %d tests.\n", report.nfail); + (void)fprintf(stdout, "[ SKIPPED ] %d tests.\n", report.nskip); + (void)fprintf(stdout, "[ ERRORS ] %d tests.\n", report.nerror); if (cfg->teardown != NULL) { cfg->teardown(user_data); @@ -355,7 +378,7 @@ harness_run(void *user_data) "teardown.\n"); } - if (nfail != 0) { + if (report.nfail != 0) { return (EXIT_FAILURE); } diff --git a/src/harness.h b/src/harness.h index 3cab216..dd2712a 100644 --- a/src/harness.h +++ b/src/harness.h @@ -296,7 +296,7 @@ } \ } while (0) -typedef void setup_function(void *user_data); +typedef int setup_function(void *user_data); typedef void teardown_function(void *user_data); typedef int test_function(void *user_data); diff --git a/src/harness_demo.c b/src/harness_demo.c index f3866b9..e763fb2 100644 --- a/src/harness_demo.c +++ b/src/harness_demo.c @@ -31,10 +31,11 @@ #include #include -static void +static int setup(void *user_data) { (void)user_data; + return (HARNESS_ERROR); } static void @@ -81,6 +82,20 @@ test_long(void *user_data) } static int +test_setup_fail_setup(void *user_data) +{ + (void)user_data; + return (HARNESS_ERROR); +} + +static int +test_setup_fail_run(void *user_data) +{ + (void)user_data; + return (HARNESS_PASS); +} + +static int test_assert_eq(void *user_data) { (void)user_data; @@ -369,6 +384,9 @@ main(int argc, char *argv[]) harness_add_test("example_suite", "test_pass", test_pass, NULL, NULL, NULL); + harness_add_suite("test_setup", tests); + harness_add_test("test_setup", "test_setup", test_setup_fail_run, + test_setup_fail_setup, NULL, NULL); harness_list_tests(NULL); -- 2.11.4.GIT