configure: Make sure Python is available for static builds
[strongswan.git] / src / libstrongswan / tests / test_suite.h
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2013 Martin Willi
5 * Copyright (C) 2013 revosec AG
6 *
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>.
11 *
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
15 * for more details.
16 */
17
18 /**
19 * @defgroup test_suite test_suite
20 * @{ @ingroup libtest
21 */
22
23 #ifndef TEST_SUITE_H_
24 #define TEST_SUITE_H_
25
26 #define _GNU_SOURCE
27 #include <setjmp.h>
28
29 #include <library.h>
30 #include <utils/debug.h>
31 #include <utils/backtrace.h>
32 #include <collections/array.h>
33
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;
38
39 /**
40 * Default timeout for a single test function
41 */
42 #ifndef TEST_FUNCTION_DEFAULT_TIMEOUT
43 #define TEST_FUNCTION_DEFAULT_TIMEOUT 2
44 #endif
45
46 /**
47 * Test function implementation
48 */
49 typedef void (*test_function_cb_t)(int);
50
51 /**
52 * Fixture for a test case.
53 */
54 typedef void (*test_fixture_cb_t)(void);
55
56 /**
57 * A test suite; a collection of test cases with fixtures
58 */
59 struct test_suite_t {
60 /** name of the test suite */
61 const char *name;
62 /** test cases registered, as test_case_t* */
63 array_t *tcases;
64 };
65
66 /**
67 * A test case; multiple test functions using the same fixtures
68 */
69 struct test_case_t {
70 /** name of the test case */
71 const char *name;
72 /** tests registered, as test_function_t */
73 array_t *functions;
74 /** fixture for tests, as test_fixture_t */
75 array_t *fixtures;
76 /** timeout for each function, in s */
77 int timeout;
78 };
79
80 /**
81 * A test function, with optional loop setup
82 */
83 struct test_function_t {
84 /** name of test function */
85 char *name;
86 /** tests function registered, test_function_t* */
87 test_function_cb_t cb;
88 /** start for loop test */
89 int start;
90 /** end for loop test */
91 int end;
92 };
93
94 /**
95 * Registered fixture for a test case
96 */
97 struct test_fixture_t {
98 test_fixture_cb_t setup;
99 test_fixture_cb_t teardown;
100 };
101
102 /**
103 * Create a new test suite
104 *
105 * @param name name of the test suite
106 * @return test suite
107 */
108 test_suite_t* test_suite_create(const char *name);
109
110 /**
111 * Create a new test case
112 *
113 * @param name name of test case
114 * @return test case
115 */
116 test_case_t* test_case_create(const char *name);
117
118 /**
119 * Add a setup/teardown function to the test case
120 *
121 * @param tcase test case to add a fixture to
122 * @param setup setup function called before each test
123 * @param teardown cleanup function called after each test
124 */
125 void test_case_add_checked_fixture(test_case_t *tcase, test_fixture_cb_t setup,
126 test_fixture_cb_t teardown);
127
128 /**
129 * Add a test function to a test case, with a name, looped several times
130 *
131 * @param name name of the test case
132 * @param tcase test case to add test function to
133 * @param cb callback function to invoke for test
134 * @param start start of loop counter
135 * @param end end of loop counter
136 */
137 void test_case_add_test_name(test_case_t *tcase, char *name,
138 test_function_cb_t cb, int start, int end);
139
140 /**
141 * Add a test function to a test case
142 *
143 * @param tcase test case to add test function to
144 * @param cb callback function to invoke for test
145 */
146 #define test_case_add_test(tcase, cb) \
147 test_case_add_test_name(tcase, #cb, cb, 0, 1)
148
149 /**
150 * Add a test function to a test case, looped several times
151 *
152 * @param tcase test case to add test function to
153 * @param cb callback function to invoke for test
154 * @param start start of loop counter
155 * @param end end of loop counter
156 */
157 #define test_case_add_loop_test(tcase, cb, start, end) \
158 test_case_add_test_name(tcase, #cb, cb, start, end)
159
160 /**
161 * Set a custom timeout for test functions in a test case
162 *
163 * @param tcase test case to set timeout for
164 * @param s test timeout in s
165 */
166 void test_case_set_timeout(test_case_t *tcase, int s);
167
168 /**
169 * Add a test function to a test case, looped several times
170 *
171 * @param suite test suite to add test case to
172 * @param tcase test case to add
173 */
174 void test_suite_add_case(test_suite_t *suite, test_case_t *tcase);
175
176 /**
177 * sigjmp restore point used by test_restore_point
178 */
179 #ifdef WIN32
180 extern jmp_buf test_restore_point_env;
181 #else
182 extern sigjmp_buf test_restore_point_env;
183 #endif
184
185 /**
186 * Set or return from an execution restore point
187 *
188 * This call sets a restore execution point and returns TRUE after it has
189 * been set up. On test failure, the execution is returned to the restore point
190 * and FALSE is returned to indicate test failure.
191 *
192 * @return TRUE if restore point set, FALSE when restored
193 */
194 #ifdef WIN32
195 # define test_restore_point() (setjmp(test_restore_point_env) == 0)
196 #else
197 # define test_restore_point() (sigsetjmp(test_restore_point_env, 1) == 0)
198 #endif
199
200 /**
201 * Set up signal handlers for test cases
202 */
203 void test_setup_handler();
204
205 /**
206 * Set up a timeout to let a test fail
207 *
208 * @param s timeout, 0 to disable timeout
209 */
210 void test_setup_timeout(int s);
211
212 /**
213 * Get info about a test failure
214 *
215 * @param msg buffer receiving failure info
216 * @param len size of msg buffer
217 * @param file pointer receiving source code file
218 * @return source code line number
219 */
220 int test_failure_get(char *msg, int len, const char **file);
221
222 /**
223 * Get info about a warning if one was issued during the test. Resets the
224 * warning state.
225 *
226 * @param msg buffer receiving warning
227 * @param len size of msg buffer
228 * @param file pointer receiving source code file
229 * @return source code line number, 0 if no warning issued
230 */
231 int test_warning_get(char *msg, int len, const char **file);
232
233 /**
234 * Get a backtrace for a failure.
235 *
236 * @return allocated backtrace of test failure, if any
237 */
238 backtrace_t *test_failure_backtrace();
239
240 /**
241 * Let a test fail and set a message using vprintf style arguments.
242 *
243 * @param file source code file name
244 * @param line source code line number
245 * @param fmt printf format string
246 * @param args argument list for fmt
247 */
248 void test_fail_vmsg(const char *file, int line, char *fmt, va_list args);
249
250 /**
251 * Let a test fail and set a message using printf style arguments.
252 *
253 * @param file source code file name
254 * @param line source code line number
255 * @param fmt printf format string
256 * @param ... arguments for fmt
257 */
258 void test_fail_msg(const char *file, int line, char *fmt, ...);
259
260 /**
261 * Issue a warning for a particular test with a message using printf style
262 * arguments. This does not fail the test, and only the last warning for each
263 * test is kept.
264 *
265 * @param file source code file name
266 * @param line source code line number
267 * @param fmt printf format string
268 * @param ... arguments for fmt
269 */
270 void test_warn_msg(const char *file, int line, char *fmt, ...);
271
272 /**
273 * Let a test fail if one of the worker threads has failed (only if called from
274 * the main thread).
275 */
276 void test_fail_if_worker_failed();
277
278 /**
279 * Check if two integers equal, fail test if not
280 *
281 * @param a first integer
282 * @param b second integer
283 */
284 #define test_int_eq(a, b) \
285 ({ \
286 typeof(a) _a = a; \
287 typeof(b) _b = b; \
288 test_fail_if_worker_failed(); \
289 if (_a != _b) \
290 { \
291 test_fail_msg(__FILE__, __LINE__, #a " != " #b " (%d != %d)", _a, _b); \
292 } \
293 })
294
295 /**
296 * Check if two strings equal, fail test if not
297 *
298 * @param a first string
299 * @param b second string
300 */
301 #define test_str_eq(a, b) \
302 ({ \
303 char* _a = (char*)a; \
304 char* _b = (char*)b; \
305 test_fail_if_worker_failed(); \
306 if (!_a || !_b || !streq(_a, _b)) \
307 { \
308 test_fail_msg(__FILE__, __LINE__, \
309 #a " != " #b " (\"%s\" != \"%s\")", _a, _b); \
310 } \
311 })
312
313 /**
314 * Check if two chunks are equal, fail test if not
315 *
316 * @param a first chunk
317 * @param b second chunk
318 */
319 #define test_chunk_eq(a, b) \
320 ({ \
321 chunk_t _a = (chunk_t)a; \
322 chunk_t _b = (chunk_t)b; \
323 test_fail_if_worker_failed(); \
324 if (_a.len != _b.len || !memeq(_a.ptr, _b.ptr, _a.len)) \
325 { \
326 test_fail_msg(__FILE__, __LINE__, \
327 #a " != " #b " (\"%#B\" != \"%#B\")", &_a, &_b); \
328 } \
329 })
330
331 /**
332 * Check if a statement evaluates to TRUE, fail test if not
333 *
334 * @param x statement to evaluate
335 */
336 #define test_assert(x) \
337 ({ \
338 test_fail_if_worker_failed(); \
339 if (!(x)) \
340 { \
341 test_fail_msg(__FILE__, __LINE__, "%s", #x); \
342 } \
343 })
344
345 /**
346 * Check if a statement evaluates to TRUE, fail and print a message if not
347 *
348 * @param x statement to evaluate
349 * @param fmt message format string
350 * @param ... fmt printf arguments
351 */
352 #define test_assert_msg(x, fmt, ...) \
353 ({ \
354 test_fail_if_worker_failed(); \
355 if (!(x)) \
356 { \
357 test_fail_msg(__FILE__, __LINE__, "%s: " fmt, #x, ##__VA_ARGS__); \
358 } \
359 })
360
361
362
363 /* "check unit testing" compatibility */
364 #define Suite test_suite_t
365 #define TCase test_case_t
366 #define ck_assert_int_eq test_int_eq
367 #define ck_assert test_assert
368 #define ck_assert_msg test_assert_msg
369 #define ck_assert_str_eq test_str_eq
370 #define ck_assert_chunk_eq test_chunk_eq
371 #define warn(fmt, ...) test_warn_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
372 #define fail(fmt, ...) test_fail_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
373 #define fail_if(x, fmt, ...) \
374 ({ \
375 test_fail_if_worker_failed(); \
376 if (x) \
377 { \
378 test_fail_msg(__FILE__, __LINE__, "%s : " fmt, #x, ##__VA_ARGS__); \
379 } \
380 })
381 #define fail_unless test_assert_msg
382 #define suite_create test_suite_create
383 #define tcase_create test_case_create
384 #define tcase_add_checked_fixture test_case_add_checked_fixture
385 #define tcase_add_test test_case_add_test
386 #define tcase_add_loop_test test_case_add_loop_test
387 #define tcase_set_timeout test_case_set_timeout
388 #define suite_add_tcase test_suite_add_case
389 #define START_TEST(name) static void name (int _i) {
390 #define END_TEST test_fail_if_worker_failed(); }
391 #define START_SETUP(name) static void name() {
392 #define END_SETUP test_fail_if_worker_failed(); }
393 #define START_TEARDOWN(name) static void name() {
394 #define END_TEARDOWN test_fail_if_worker_failed(); }
395
396 #endif /** TEST_SUITE_H_ @}*/