Git init
[framework/multimedia/gstreamer0.10.git] / libs / gst / check / libcheck / check.h.in
1 /*-*- mode:C; -*- */
2 /*
3  * Check: a unit test framework for C
4  * Copyright (C) 2001, 2002, Arien Malec
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifndef CHECK_H
23 #define CHECK_H
24
25 #include <stddef.h>
26 #include <string.h>
27
28 /* Check: a unit test framework for C
29
30    Check is a unit test framework for C. It features a simple
31    interface for defining unit tests, putting little in the way of the
32    developer. Tests are run in a separate address space, so Check can
33    catch both assertion failures and code errors that cause
34    segmentation faults or other signals. The output from unit tests
35    can be used within source code editors and IDEs.
36
37    Unit tests are created with the START_TEST/END_TEST macro
38    pair. The fail_unless and fail macros are used for creating
39    checks within unit tests; the mark_point macro is useful for
40    trapping the location of signals and/or early exits.
41
42
43    Test cases are created with tcase_create, unit tests are added
44    with tcase_add_test
45
46
47    Suites are created with suite_create; test cases are added
48    with suite_add_tcase
49
50    Suites are run through an SRunner, which is created with
51    srunner_create. Additional suites can be added to an SRunner with
52    srunner_add_suite. An SRunner is freed with srunner_free, which also
53    frees all suites added to the runner. 
54
55    Use srunner_run_all to run a suite and print results.
56
57    Macros and functions starting with _ (underscore) are internal and
58    may change without notice. You have been warned!.
59
60 */
61
62
63 #ifdef __cplusplus
64 #define CK_CPPSTART extern "C" {
65 #define CK_CPPEND }
66 CK_CPPSTART
67 #endif
68
69 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
70 #define GCC_VERSION_AT_LEAST(major, minor) \
71 ((__GNUC__ > (major)) || \
72  (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
73 #else
74 #define GCC_VERSION_AT_LEAST(major, minor) 0
75 #endif
76
77 #if GCC_VERSION_AT_LEAST(2,95)
78 #define CK_ATTRIBUTE_UNUSED __attribute__ ((unused))
79 #else
80 #define CK_ATTRIBUTE_UNUSED              
81 #endif /* GCC 2.95 */
82
83 #include <sys/types.h>
84
85 /* Used to create the linker script for hiding lib-local symbols. Shall
86    be put directly in front of the exported symbol. */
87 #define CK_EXPORT
88
89 /* check version numbers */
90   
91 #define CHECK_MAJOR_VERSION (@CHECK_MAJOR_VERSION@)
92 #define CHECK_MINOR_VERSION (@CHECK_MINOR_VERSION@)
93 #define CHECK_MICRO_VERSION (@CHECK_MICRO_VERSION@)
94
95 extern int CK_EXPORT check_major_version;
96 extern int CK_EXPORT check_minor_version;
97 extern int CK_EXPORT check_micro_version;
98
99 #ifndef NULL
100 #define NULL ((void*)0)
101 #endif
102
103 /* opaque type for a test case
104
105    A TCase represents a test case.  Create with tcase_create, free
106    with tcase_free.  For the moment, test cases can only be run
107    through a suite
108 */
109 typedef struct TCase TCase; 
110
111 /* type for a test function */
112 typedef void (*TFun) (int);
113
114 /* type for a setup/teardown function */
115 typedef void (*SFun) (void);
116  
117 /* Opaque type for a test suite */
118 typedef struct Suite Suite;
119  
120 /* Creates a test suite with the given name */
121 Suite * CK_EXPORT suite_create (const char *name);
122
123 /* Add a test case to a suite */
124 void CK_EXPORT suite_add_tcase (Suite *s, TCase *tc);
125
126 /* Create a test case */
127 TCase * CK_EXPORT tcase_create (const char *name);
128
129 /* Add a test function to a test case (macro version) */
130 #define tcase_add_test(tc,tf) tcase_add_test_raise_signal(tc,tf,0)
131
132 /* Add a test function with signal handling to a test case (macro version) */
133 #define tcase_add_test_raise_signal(tc,tf,signal) \
134    _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 0, 1)
135
136 /* Add a test function with an expected exit value to a test case (macro version) */
137 #define tcase_add_exit_test(tc, tf, expected_exit_value) \
138   _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),0,1)
139
140 /* Add a looping test function to a test case (macro version)
141
142    The test will be called in a for(i = s; i < e; i++) loop with each
143    iteration being executed in a new context. The loop variable 'i' is
144    available in the test.
145  */
146 #define tcase_add_loop_test(tc,tf,s,e) \
147   _tcase_add_test((tc),(tf),"" # tf "",0,0,(s),(e))
148  
149 /* Signal version of loop test.  
150    FIXME: add a test case; this is untested as part of Check's tests.
151  */
152 #define tcase_add_loop_test_raise_signal(tc,tf,signal,s,e) \
153   _tcase_add_test((tc),(tf),"" # tf "",(signal),0,(s),(e))
154
155 /* allowed exit value version of loop test. */
156 #define tcase_add_loop_exit_test(tc,tf,expected_exit_value,s,e) \
157   _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),(s),(e))
158
159 /* Add a test function to a test case
160   (function version -- use this when the macro won't work
161 */
162 void CK_EXPORT _tcase_add_test (TCase *tc, TFun tf, const char *fname, int _signal, int allowed_exit_value, int start, int end);
163
164 /* Add unchecked fixture setup/teardown functions to a test case
165
166    If unchecked fixture functions are run at the start and end of the
167    test case, and not before and after unit tests. Note that unchecked
168    setup/teardown functions are not run in a separate address space,
169    like test functions, and so must not exit or signal (e.g.,
170    segfault)
171
172    Also, when run in CK_NOFORK mode, unchecked fixture functions may
173    lead to different unit test behavior IF unit tests change data
174    setup by the fixture functions.
175 */
176 void CK_EXPORT tcase_add_unchecked_fixture (TCase *tc, SFun setup, SFun teardown);
177
178 /* Add fixture setup/teardown functions to a test case
179
180    Checked fixture functions are run before and after unit
181    tests. Unlike unchecked fixture functions, checked fixture
182    functions are run in the same separate address space as the test
183    program, and thus the test function will survive signals or
184    unexpected exits in the fixture function. Also, IF the setup
185    function is idempotent, unit test behavior will be the same in
186    CK_FORK and CK_NOFORK modes.
187
188    However, since fixture functions are run before and after each unit
189    test, they should not be expensive code.
190
191 */ 
192 void CK_EXPORT tcase_add_checked_fixture (TCase *tc, SFun setup, SFun teardown);
193
194 /* Set the timeout for all tests in a test case. A test that lasts longer
195    than the timeout (in seconds) will be killed and thus fail with an error.
196    The timeout can also be set globaly with the environment variable
197    CK_DEFAULT_TIMEOUT, the specific setting always takes precedence.
198 */
199 void CK_EXPORT tcase_set_timeout (TCase *tc, int timeout);
200  
201 /* Internal function to mark the start of a test function */
202 void CK_EXPORT tcase_fn_start (const char *fname, const char *file, int line);
203
204 /* Start a unit test with START_TEST(unit_name), end with END_TEST
205    One must use braces within a START_/END_ pair to declare new variables
206 */ 
207 #define START_TEST(__testname)\
208 static void __testname (int _i CK_ATTRIBUTE_UNUSED)\
209 {\
210   tcase_fn_start (""# __testname, __FILE__, __LINE__);
211
212 /* End a unit test */
213 #define END_TEST }
214
215 /* Fail the test case unless expr is true */
216 /* The space before the comma sign before ## is essential to be compatible
217    with gcc 2.95.3 and earlier.
218 */
219 #define fail_unless(expr, ...)\
220         _fail_unless(expr, __FILE__, __LINE__,\
221         "Assertion '"#expr"' failed" , ## __VA_ARGS__, NULL)
222
223 /* Fail the test case if expr is true */
224 /* The space before the comma sign before ## is essential to be compatible
225    with gcc 2.95.3 and earlier.
226 */
227
228 /* FIXME: these macros may conflict with C89 if expr is 
229    FIXME:   strcmp (str1, str2) due to excessive string length. */
230 #define fail_if(expr, ...)\
231         _fail_unless(!(expr), __FILE__, __LINE__,\
232         "Failure '"#expr"' occured" , ## __VA_ARGS__, NULL)
233
234 /* Always fail */
235 #define fail(...) _fail_unless(0, __FILE__, __LINE__, "Failed" , ## __VA_ARGS__, NULL)
236
237 /* Non macro version of #fail_unless, with more complicated interface */
238 void CK_EXPORT _fail_unless (int result, const char *file,
239                              int line, const char *expr, ...);
240
241 /* New check fail API. */
242 #define ck_abort() ck_abort_msg(NULL)
243 #define ck_abort_msg fail
244 #define ck_assert(C) ck_assert_msg(C, NULL)
245 #define ck_assert_msg fail_unless
246
247 /* Integer comparsion macros with improved output compared to fail_unless(). */
248 /* O may be any comparion operator. */
249 #define _ck_assert_int(X, O, Y) ck_assert_msg((X) O (Y), "Assertion '"#X#O#Y"' failed: "#X"==%d, "#Y"==%d", X, Y) 
250 #define ck_assert_int_eq(X, Y) _ck_assert_int(X, ==, Y) 
251 #define ck_assert_int_ne(X, Y) _ck_assert_int(X, !=, Y) 
252
253 /* String comparsion macros with improved output compared to fail_unless() */
254 #define _ck_assert_str(C, X, O, Y) ck_assert_msg(C, "Assertion '"#X#O#Y"' failed: "#X"==\"%s\", "#Y"==\"%s\"", X, Y) 
255 #define ck_assert_str_eq(X, Y) _ck_assert_str(!strcmp(X, Y), X, ==, Y)
256 #define ck_assert_str_ne(X, Y) _ck_assert_str(strcmp(X, Y), X, !=, Y)
257
258
259 /* Mark the last point reached in a unit test
260    (useful for tracking down where a segfault, etc. occurs)
261 */
262 #define mark_point() _mark_point(__FILE__,__LINE__)
263
264 /* Non macro version of #mark_point */
265 void CK_EXPORT _mark_point (const char *file, int line);
266
267 /* Result of a test */
268 enum test_result {
269   CK_TEST_RESULT_INVALID, /* Default value; should not encounter this */
270   CK_PASS, /* Test passed*/
271   CK_FAILURE, /* Test completed but failed */
272   CK_ERROR /* Test failed to complete
273               (unexpected signal or non-zero early exit) */ 
274 };
275
276 /* Specifies the how much output an SRunner should produce */
277 enum print_output {
278   CK_SILENT, /* No output */
279   CK_MINIMAL, /* Only summary output */
280   CK_NORMAL, /* All failed tests */
281   CK_VERBOSE, /* All tests */
282   CK_ENV, /* Look at environment var */
283 #if @ENABLE_SUBUNIT@
284   CK_SUBUNIT, /* Run as a subunit child process */
285 #endif
286   CK_LAST
287 };
288
289 /* Holds state for a running of a test suite */
290 typedef struct SRunner SRunner;
291
292 /* Opaque type for a test failure */
293 typedef struct TestResult TestResult;
294
295 /* accessors for tr fields */
296 enum ck_result_ctx {
297   CK_CTX_INVALID, /* Default value; should not encounter this */
298   CK_CTX_SETUP,
299   CK_CTX_TEST,
300   CK_CTX_TEARDOWN
301 };
302
303 /* Type of result */
304 int CK_EXPORT tr_rtype (TestResult *tr);
305 /* Context in which the result occurred */ 
306 enum ck_result_ctx CK_EXPORT tr_ctx (TestResult *tr); 
307 /* Failure message */
308 const char * CK_EXPORT tr_msg (TestResult *tr);
309 /* Line number at which failure occured */
310 int CK_EXPORT tr_lno (TestResult *tr);
311 /* File name at which failure occured */
312 const char * CK_EXPORT tr_lfile (TestResult *tr);
313 /* Test case in which unit test was run */
314 const char * CK_EXPORT tr_tcname (TestResult *tr);
315
316 /* Creates an SRunner for the given suite */
317 SRunner * CK_EXPORT srunner_create (Suite *s);
318
319 /* Adds a Suite to an SRunner */
320 void CK_EXPORT srunner_add_suite (SRunner *sr, Suite *s);
321
322 /* Frees an SRunner, all suites added to it and all contained test cases */
323 void CK_EXPORT srunner_free (SRunner *sr);
324
325  
326 /* Test running */
327
328 /* Runs an SRunner, printing results as specified (see enum print_output) */
329 void CK_EXPORT srunner_run_all (SRunner *sr, enum print_output print_mode);
330
331  
332 /* Next functions are valid only after the suite has been
333    completely run, of course */
334
335 /* Number of failed tests in a run suite. Includes failures + errors */
336 int CK_EXPORT srunner_ntests_failed (SRunner *sr);
337
338 /* Total number of tests run in a run suite */
339 int CK_EXPORT srunner_ntests_run (SRunner *sr);
340
341 /* Return an array of results for all failures
342   
343    Number of failures is equal to srunner_nfailed_tests.  Memory for
344    the array is malloc'ed and must be freed, but individual TestResults
345    must not
346 */
347 TestResult ** CK_EXPORT srunner_failures (SRunner *sr);
348
349 /* Return an array of results for all run tests
350
351    Number of results is equal to srunner_ntests_run, and excludes
352    failures due to setup function failure.
353
354    Memory is malloc'ed and must be freed, but individual TestResults
355    must not
356 */  
357 TestResult ** CK_EXPORT srunner_results (SRunner *sr);
358
359  
360 /* Printing */
361
362 /* Print the results contained in an SRunner */
363 void CK_EXPORT srunner_print (SRunner *sr, enum print_output print_mode);
364   
365   
366 /* Set a log file to which to write during test running.
367
368   Log file setting is an initialize only operation -- it should be
369   done immediatly after SRunner creation, and the log file can't be
370   changed after being set.
371 */
372 void CK_EXPORT srunner_set_log (SRunner *sr, const char *fname);
373
374 /* Does the SRunner have a log file? */
375 int CK_EXPORT srunner_has_log (SRunner *sr);
376
377 /* Return the name of the log file, or NULL if none */
378 const char * CK_EXPORT srunner_log_fname (SRunner *sr);
379
380 /* Set a xml file to which to write during test running.
381
382   XML file setting is an initialize only operation -- it should be
383   done immediatly after SRunner creation, and the XML file can't be
384   changed after being set.
385 */
386 void CK_EXPORT srunner_set_xml (SRunner *sr, const char *fname);
387
388 /* Does the SRunner have an XML log file? */
389 int CK_EXPORT srunner_has_xml (SRunner *sr);
390
391 /* Return the name of the XML file, or NULL if none */
392 const char * CK_EXPORT srunner_xml_fname (SRunner *sr);
393
394
395 /* Control forking */
396 enum fork_status {
397   CK_FORK_GETENV, /* look in the environment for CK_FORK */
398   CK_FORK,        /* call fork to run tests */
399   CK_NOFORK       /* don't call fork */
400 };
401  
402 /* Get the current fork status */
403 enum fork_status CK_EXPORT srunner_fork_status (SRunner *sr);
404
405 /* Set the current fork status */
406 void CK_EXPORT srunner_set_fork_status (SRunner *sr, enum fork_status fstat); 
407   
408 /* Fork in a test and make sure messaging and tests work. */
409 pid_t CK_EXPORT check_fork(void);
410
411 /* Wait for the pid and exit. If pid is zero, just exit. */
412 void CK_EXPORT check_waitpid_and_exit(pid_t pid);
413
414 #ifdef __cplusplus 
415 CK_CPPEND
416 #endif
417
418 #endif /* CHECK_H */