2 * Copyright (C) 2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2013 Martin Willi
5 * Copyright (C) 2013 revosec AG
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * @defgroup test_suite test_suite
30 #include <utils/debug.h>
31 #include <utils/backtrace.h>
32 #include <collections/array.h>
34 typedef struct test_suite_t test_suite_t
;
35 typedef struct test_case_t test_case_t
;
36 typedef struct test_function_t test_function_t
;
37 typedef struct test_fixture_t test_fixture_t
;
40 * Default timeout for a single test function
42 #define TEST_FUNCTION_DEFAULT_TIMEOUT 2
45 * Test function implementation
47 typedef void (*test_function_cb_t
)(int);
50 * Fixture for a test case.
52 typedef void (*test_fixture_cb_t
)(void);
55 * A test suite; a collection of test cases with fixtures
58 /** name of the test suite */
60 /** test cases registered, as test_case_t* */
65 * A test case; multiple test functions using the same fixtures
68 /** name of the test case */
70 /** tests registered, as test_function_t */
72 /** fixture for tests, as test_fixture_t */
74 /** timeout for each function, in s */
79 * A test function, with optional loop setup
81 struct test_function_t
{
82 /** name of test function */
84 /** tests function registered, test_function_t* */
85 test_function_cb_t cb
;
86 /** start for loop test */
88 /** end for loop test */
93 * Registered fixture for a test case
95 struct test_fixture_t
{
96 test_fixture_cb_t setup
;
97 test_fixture_cb_t teardown
;
101 * Create a new test suite
103 * @param name name of the test suite
106 test_suite_t
* test_suite_create(const char *name
);
109 * Create a new test case
111 * @param name name of test case
114 test_case_t
* test_case_create(const char *name
);
117 * Add a setup/teardown function to the test case
119 * @param tcase test case to add a fixture to
120 * @param setup setup function called before each test
121 * @param teardown cleanup function called after each test
123 void test_case_add_checked_fixture(test_case_t
*tcase
, test_fixture_cb_t setup
,
124 test_fixture_cb_t teardown
);
127 * Add a test function to a test case, with a name, looped several times
129 * @param name name of the test case
130 * @param tcase test case to add test function to
131 * @param cb callback function to invoke for test
132 * @param start start of loop counter
133 * @param end end of loop counter
135 void test_case_add_test_name(test_case_t
*tcase
, char *name
,
136 test_function_cb_t cb
, int start
, int end
);
139 * Add a test function to a test case
141 * @param tcase test case to add test function to
142 * @param cb callback function to invoke for test
144 #define test_case_add_test(tcase, cb) \
145 test_case_add_test_name(tcase, #cb, cb, 0, 1)
148 * Add a test function to a test case, looped several times
150 * @param tcase test case to add test function to
151 * @param cb callback function to invoke for test
152 * @param start start of loop counter
153 * @param end end of loop counter
155 #define test_case_add_loop_test(tcase, cb, start, end) \
156 test_case_add_test_name(tcase, #cb, cb, start, end)
159 * Set a custom timeout for test functions in a test case
161 * @param tcase test case to set timeout for
162 * @param s test timeout in s
164 void test_case_set_timeout(test_case_t
*tcase
, int s
);
167 * Add a test function to a test case, looped several times
169 * @param suite test suite to add test case to
170 * @param tcase test case to add
172 void test_suite_add_case(test_suite_t
*suite
, test_case_t
*tcase
);
175 * sigjmp restore point used by test_restore_point
178 extern jmp_buf test_restore_point_env
;
180 extern sigjmp_buf test_restore_point_env
;
184 * Set or return from an execution restore point
186 * This call sets a restore execution point and returns TRUE after it has
187 * been set up. On test failure, the execution is returned to the restore point
188 * and FALSE is returned to indicate test failure.
190 * @return TRUE if restore point set, FALSE when restored
193 # define test_restore_point() (setjmp(test_restore_point_env) == 0)
195 # define test_restore_point() (sigsetjmp(test_restore_point_env, 1) == 0)
199 * Set up signal handlers for test cases
201 void test_setup_handler();
204 * Set up a timeout to let a test fail
206 * @param s timeout, 0 to disable timeout
208 void test_setup_timeout(int s
);
211 * Get info about a test failure
213 * @param msg buffer receiving failure info
214 * @param len size of msg buffer
215 * @param file pointer receiving source code file
216 * @return source code line number
218 int test_failure_get(char *msg
, int len
, const char **file
);
221 * Get a backtrace for a failure.
223 * @return allocated backtrace of test failure, if any
225 backtrace_t
*test_failure_backtrace();
228 * Let a test fail and set a message using vprintf style arguments.
230 * @param file source code file name
231 * @param line source code line number
232 * @param fmt printf format string
233 * @param args argument list for fmt
235 void test_fail_vmsg(const char *file
, int line
, char *fmt
, va_list args
);
238 * Let a test fail and set a message using printf style arguments.
240 * @param file source code file name
241 * @param line source code line number
242 * @param fmt printf format string
243 * @param ... arguments for fmt
245 void test_fail_msg(const char *file
, int line
, char *fmt
, ...);
248 * Let a test fail if one of the worker threads has failed (only if called from
251 void test_fail_if_worker_failed();
254 * Check if two integers equal, fail test if not
256 * @param a first integer
257 * @param b second integer
259 #define test_int_eq(a, b) \
263 test_fail_if_worker_failed(); \
266 test_fail_msg(__FILE__, __LINE__, #a " != " #b " (%d != %d)", _a, _b); \
271 * Check if two strings equal, fail test if not
273 * @param a first string
274 * @param b second string
276 #define test_str_eq(a, b) \
278 char* _a = (char*)a; \
279 char* _b = (char*)b; \
280 test_fail_if_worker_failed(); \
281 if (!_a || !_b || !streq(_a, _b)) \
283 test_fail_msg(__FILE__, __LINE__, \
284 #a " != " #b " (\"%s\" != \"%s\")", _a, _b); \
289 * Check if two chunks are equal, fail test if not
291 * @param a first chunk
292 * @param b second chunk
294 #define test_chunk_eq(a, b) \
296 chunk_t _a = (chunk_t)a; \
297 chunk_t _b = (chunk_t)b; \
298 test_fail_if_worker_failed(); \
299 if (_a.len != _b.len || !memeq(a.ptr, b.ptr, a.len)) \
301 test_fail_msg(__FILE__, __LINE__, \
302 #a " != " #b " (\"%#B\" != \"%#B\")", &_a, &_b); \
307 * Check if a statement evaluates to TRUE, fail test if not
309 * @param x statement to evaluate
311 #define test_assert(x) \
313 test_fail_if_worker_failed(); \
316 test_fail_msg(__FILE__, __LINE__, #x); \
321 * Check if a statement evaluates to TRUE, fail and print a message if not
323 * @param x statement to evaluate
324 * @param fmt message format string
325 * @param ... fmt printf arguments
327 #define test_assert_msg(x, fmt, ...) \
329 test_fail_if_worker_failed(); \
332 test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \
338 /* "check unit testing" compatibility */
339 #define Suite test_suite_t
340 #define TCase test_case_t
341 #define ck_assert_int_eq test_int_eq
342 #define ck_assert test_assert
343 #define ck_assert_msg test_assert_msg
344 #define ck_assert_str_eq test_str_eq
345 #define ck_assert_chunk_eq test_chunk_eq
346 #define fail(fmt, ...) test_fail_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
347 #define fail_if(x, fmt, ...) \
349 test_fail_if_worker_failed(); \
352 test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \
355 #define fail_unless test_assert_msg
356 #define suite_create test_suite_create
357 #define tcase_create test_case_create
358 #define tcase_add_checked_fixture test_case_add_checked_fixture
359 #define tcase_add_test test_case_add_test
360 #define tcase_add_loop_test test_case_add_loop_test
361 #define tcase_set_timeout test_case_set_timeout
362 #define suite_add_tcase test_suite_add_case
363 #define START_TEST(name) static void name (int _i) {
364 #define END_TEST test_fail_if_worker_failed(); }
365 #define START_SETUP(name) static void name() {
366 #define END_SETUP test_fail_if_worker_failed(); }
367 #define START_TEARDOWN(name) static void name() {
368 #define END_TEARDOWN test_fail_if_worker_failed(); }
370 #endif /** TEST_SUITE_H_ @}*/