suite.c
Go to the documentation of this file.00001
00038 #include <compiler.h>
00039 #include <setjmp.h>
00040 #include <stdarg.h>
00041 #include <stdio.h>
00042 #include <test/suite.h>
00043
00049
00050 void *test_priv_data;
00051
00057 static jmp_buf test_failure_jmpbuf;
00058
00059 static void test_report_failure(const struct test_case *test,
00060 const char *stage, int result)
00061 {
00062 dbg_error("Test '%s' failed during '%s': %d\n",
00063 test->name, stage, result);
00064 }
00065
00076 static int test_call(void (*func)(const struct test_case *),
00077 const struct test_case *test)
00078 {
00079 int ret = 0;
00080
00081 if (!func)
00082 return TEST_PASS;
00083
00084
00085
00086
00087
00088
00089 ret = setjmp(test_failure_jmpbuf);
00090 if (ret)
00091 return ret;
00092
00093 func(test);
00094
00095 return TEST_PASS;
00096 }
00097
00098 static int test_case_run(const struct test_case *test)
00099 {
00100 int result;
00101
00102 dbg_info("Running test: %s\n", test->name);
00103 if (test->setup) {
00104 int ret;
00105 dbg("Setting up fixture\n");
00106 ret = test_call(test->setup, test);
00107 if (ret) {
00108 test_report_failure(test, "setup", ret);
00109 result = ret;
00110 goto out;
00111 }
00112 }
00113
00114 result = test_call(test->run, test);
00115 if (result)
00116 test_report_failure(test, "test", result);
00117
00118 if (test->cleanup) {
00119 int ret;
00120 dbg("Cleaning up fixture\n");
00121 ret = test_call(test->cleanup, test);
00122 if (ret && !result) {
00123 test_report_failure(test, "cleanup", ret);
00124 result = ret;
00125 }
00126 }
00127
00128 out:
00129
00130 return result;
00131 }
00132
00141 int test_suite_run(const struct test_suite *suite)
00142 {
00143 unsigned int nr_failures = 0;
00144 unsigned int nr_errors = 0;
00145 unsigned int nr_tests;
00146 const struct test_case *const *tests;
00147 unsigned int i;
00148 int ret;
00149
00150 dbg_info("Running test suite '%s'...\n", suite->name);
00151
00152 nr_tests = suite->nr_tests;
00153 tests = suite->tests;
00154
00155 for (i = 0; i < nr_tests; i++) {
00156 const struct test_case *test;
00157
00158 test = tests[i];
00159 ret = test_case_run(test);
00160 if (ret < 0)
00161 nr_errors++;
00162 else if (ret > 0)
00163 nr_failures++;
00164 }
00165
00166 dbg_info("Test suite '%s' complete: %u tests, %u failures, %u errors\n\n",
00167 suite->name,
00168 nr_tests, nr_failures, nr_errors);
00169
00170 return nr_errors + nr_failures;
00171 }
00172
00173
00174 void test_priv_fail(const struct test_case *test, int result,
00175 const char *file, unsigned int line,
00176 const char __progmem_arg *fmt, ...)
00177 {
00178 va_list ap;
00179
00180 dbg_error("Test '%s' failed at %s:%u:\n\t", test->name,
00181 file, line);
00182
00183 va_start(ap, fmt);
00184 dbg_vprintf_pgm(fmt, ap);
00185 va_end(ap);
00186 dbg_putchar('\n');
00187
00188
00189
00190
00191
00192 longjmp(test_failure_jmpbuf, result);
00193 }
00194