From 6d4c0a2e0c727e112c7c33d304452315d8c87d52 Mon Sep 17 00:00:00 2001 From: Brendan Bartels <bbartels@iastate.edu> Date: Thu, 9 Feb 2017 23:02:08 -0600 Subject: [PATCH] quad: add testing suite --- quad/lib/test/.gitignore | 1 + quad/lib/test/Makefile | 5 ++++ quad/lib/test/README.md | 30 ++++++++++++++++++++ quad/lib/test/example.c | 24 ++++++++++++++++ quad/lib/test/test.c | 61 ++++++++++++++++++++++++++++++++++++++++ quad/lib/test/test.h | 19 +++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 quad/lib/test/.gitignore create mode 100644 quad/lib/test/Makefile create mode 100644 quad/lib/test/README.md create mode 100644 quad/lib/test/example.c create mode 100644 quad/lib/test/test.c create mode 100644 quad/lib/test/test.h diff --git a/quad/lib/test/.gitignore b/quad/lib/test/.gitignore new file mode 100644 index 000000000..96236f815 --- /dev/null +++ b/quad/lib/test/.gitignore @@ -0,0 +1 @@ +example \ No newline at end of file diff --git a/quad/lib/test/Makefile b/quad/lib/test/Makefile new file mode 100644 index 000000000..d44ec7765 --- /dev/null +++ b/quad/lib/test/Makefile @@ -0,0 +1,5 @@ +example: example.c test.c test.h + gcc -g -o example example.c test.c test.h + +clean: + rm example diff --git a/quad/lib/test/README.md b/quad/lib/test/README.md new file mode 100644 index 000000000..8bec810e2 --- /dev/null +++ b/quad/lib/test/README.md @@ -0,0 +1,30 @@ +Basic Testing Suite in C +---- +This test suite helps you run tests. It handles the result of every test +whether it be a success, failure, or segfault, and keeps running until +all tests have been executed. It then gives a summary of the test results. + +To use, just write your tests using functions that return `int`s to indicate +failure. 1 means failure. 0 means success. + +Then in your main function for your tests, pass these functions to the `test()` +function along with a name you want included in the test report. + +```c +int main() { + test(test_func, "this test will pass!"); + test(another_func, "this one might fail..."); + ... +``` + +Then at the end of your main function, call the `test_summary()` function, and +return its return value from your main function. + +```c +int main() { + ... + return test_summary(); +} +``` + +An `example.c` file is included for reference. \ No newline at end of file diff --git a/quad/lib/test/example.c b/quad/lib/test/example.c new file mode 100644 index 000000000..b757c6e5d --- /dev/null +++ b/quad/lib/test/example.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include "test.h" + +int test1() { + puts("hi world."); + return 0; +} + +int test2() { + return 1; +} + +int test3() { + int *bad = NULL; + int x = *bad; + return 0; +} + +int main() { + test(test1, "print hello world"); + test(test2, "just fail"); + test(test3, "survive segfault"); + return test_summary(); +} diff --git a/quad/lib/test/test.c b/quad/lib/test/test.c new file mode 100644 index 000000000..dc2ef00ef --- /dev/null +++ b/quad/lib/test/test.c @@ -0,0 +1,61 @@ +#include "test.h" + +static int num_tests = 0; +static struct Test tests[128]; +static int longest_test_name = 0; + +void test(int (*function)(), char *test_name) { + int test_name_length = strlen(test_name); + if (test_name_length > longest_test_name) { + longest_test_name = test_name_length; + } + + pid_t pid = fork(); + if (pid == 0) { + // test process + int exit_status = function(); + exit(exit_status); + } else { + int status; + waitpid(pid, &status, 0); + + struct Test test; + strcpy(test.name, test_name); + + if (WIFEXITED(status)) { + int exit_status = WEXITSTATUS(status); + if (exit_status == 0) { + test.failed = 0; + strcpy(test.result_msg, "passed"); + } else { + test.failed = 1; + strcpy(test.result_msg, "FAILED"); + } + } else if (WIFSIGNALED(status)) { + test.failed = 1; + strcpy(test.result_msg, "ERROR!"); + } + + tests[num_tests++] = test; + } +} + +int test_summary() { + unsigned char at_least_one_test_failed = 0; + int num_failed = 0; + puts("---------------------------------"); + puts("Test results:"); + puts(""); + int i = 0; + for (i = 0; i < num_tests; i += 1) { + printf("#%3d: %-*s (%s)\n", i + 1, longest_test_name, tests[i].name, tests[i].result_msg); + num_failed += tests[i].failed; + at_least_one_test_failed |= tests[i].failed; + } + puts(""); + printf("Total: %3d of %-3d tests passed\n", num_tests - num_failed, num_tests); + puts("---------------------------------"); + num_tests = 0; + longest_test_name = 0; + return at_least_one_test_failed; +} diff --git a/quad/lib/test/test.h b/quad/lib/test/test.h new file mode 100644 index 000000000..862769fc3 --- /dev/null +++ b/quad/lib/test/test.h @@ -0,0 +1,19 @@ +#ifndef TEST_H +#define TEST_H + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> + +struct Test { + char name[64]; + char result_msg[32]; + unsigned char failed; +}; + +void test(int (*)(), char *); +int test_summary(); + +#endif -- GitLab