|
1 | 1 | #ifndef _GUARD_case_main_h_ |
2 | 2 | #define _GUARD_case_main_h_ |
3 | 3 |
|
| 4 | +static void case_run(case_t* test_case, int i, int total, int* pass, int* fail) |
| 5 | +{ |
| 6 | + printf("\033[0;34m[%d/%d]\033[0;0m \033[1;33m[RUN]\033[0;0m %s ...", i + 1, total, test_case->name); |
| 7 | + fflush(stdout); |
| 8 | + int result = 0; |
| 9 | + test_case->func(test_case->name, &result); |
| 10 | + if (result == 0) |
| 11 | + { |
| 12 | + (*pass)++; |
| 13 | + printf("\r\033[0;34m[%d/%d]\033[0;0m \033[1;32m[PASS]\033[0;0m %s \n", i + 1, total, test_case->name); |
| 14 | + } else { |
| 15 | + (*fail)++; |
| 16 | + printf("\n\033[0;34m[%d/%d]\033[0;0m \033[1;31m[FAIL]\033[0;0m %s\n", i + 1, total, test_case->name); |
| 17 | + } |
| 18 | +} |
| 19 | + |
| 20 | +static void case_conclude(int pass, int fail) |
| 21 | +{ |
| 22 | + if (fail == 0) |
| 23 | + printf("\033[0;32mall test case(s) passed, congratulations!\033[0;0m\n"); |
| 24 | + else |
| 25 | + printf("\033[0;31m%d of %d test case(s) passed\033[0;0m\n", pass, fail + pass); |
| 26 | +} |
| 27 | + |
| 28 | +#ifdef __ELF__ |
| 29 | +// in ELF object format, we can simply query custom section rather than scan through the whole binary memory |
| 30 | +// to find function pointer. We do this whenever possible because in this way, we don't have access error |
| 31 | +// when hooking up with memory checkers such as address sanitizer or valgrind |
| 32 | +extern case_t __start_case_data[]; |
| 33 | +extern case_t __stop_case_data[]; |
| 34 | + |
| 35 | +int main(int argc, char** argv) |
| 36 | +{ |
| 37 | + int total = __stop_case_data - __start_case_data; |
| 38 | + int i, pass = 0, fail = 0; |
| 39 | + for (i = 0; i < total; i++) |
| 40 | + { |
| 41 | + case_t* test_case = __start_case_data + i; |
| 42 | + case_run(test_case, i, total, &pass, &fail); |
| 43 | + } |
| 44 | + case_conclude(pass, fail); |
| 45 | + return fail; |
| 46 | +} |
| 47 | + |
| 48 | +#else |
| 49 | + |
4 | 50 | #include <stdio.h> |
5 | 51 | #include <unistd.h> |
6 | 52 | #include <stdlib.h> |
@@ -309,36 +355,20 @@ int main(int argc, char** argv) |
309 | 355 | int i; |
310 | 356 | for (i = 0; i < len; i++) |
311 | 357 | { |
312 | | - case_t* test_suite = (case_t*)(start_pointer + i); |
313 | | - if (test_suite->sig_head == the_sig && test_suite->sig_tail == the_sig) |
| 358 | + case_t* test_case = (case_t*)(start_pointer + i); |
| 359 | + if (test_case->sig_head == the_sig && test_case->sig_tail == the_sig) |
314 | 360 | total++; |
315 | 361 | } |
316 | | - int j = 1, pass = 0, fail = 0; |
| 362 | + int j = 0, pass = 0, fail = 0; |
317 | 363 | for (i = 0; i < len; i++) |
318 | 364 | { |
319 | | - case_t* test_suite = (case_t*)(start_pointer + i); |
320 | | - if (test_suite->sig_head == the_sig && test_suite->sig_tail == the_sig) |
321 | | - { |
322 | | - printf("\033[0;34m[%d/%d]\033[0;0m \033[1;33m[RUN]\033[0;0m %s ...", j, total, test_suite->name); |
323 | | - fflush(stdout); |
324 | | - int result = 0; |
325 | | - test_suite->driver(test_suite->name, &result); |
326 | | - if (result == 0) |
327 | | - { |
328 | | - pass++; |
329 | | - printf("\r\033[0;34m[%d/%d]\033[0;0m \033[1;32m[PASS]\033[0;0m %s \n", j, total, test_suite->name); |
330 | | - } else { |
331 | | - fail++; |
332 | | - printf("\n\033[0;34m[%d/%d]\033[0;0m \033[1;31m[FAIL]\033[0;0m %s\n", j, total, test_suite->name); |
333 | | - } |
334 | | - j++; |
335 | | - } |
| 365 | + case_t* test_case = (case_t*)(start_pointer + i); |
| 366 | + if (test_case->sig_head == the_sig && test_case->sig_tail == the_sig) |
| 367 | + case_run(test_case, j++, total, &pass, &fail); |
336 | 368 | } |
337 | | - if (fail == 0) |
338 | | - printf("\033[0;32mall test case(s) passed, congratulations!\033[0;0m\n"); |
339 | | - else |
340 | | - printf("\033[0;31m%d of %d test case(s) passed\033[0;0m\n", pass, fail + pass); |
| 369 | + case_conclude(pass, fail); |
341 | 370 | return fail; |
342 | 371 | } |
343 | 372 |
|
344 | 373 | #endif |
| 374 | +#endif |
0 commit comments