Initialize Tizen 2.3
[framework/multimedia/gstreamer0.10.git] / mobile / libs / gst / check / libcheck / check.c
1 /*
2  * Check: a unit test framework for C
3  * Copyright (C) 2001, 2002 Arien Malec
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27
28 #include "check.h"
29 #include "check_error.h"
30 #include "check_list.h"
31 #include "check_impl.h"
32 #include "check_msg.h"
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>             /* for _POSIX_VERSION */
36 #endif
37
38 #ifndef DEFAULT_TIMEOUT
39 #define DEFAULT_TIMEOUT 4
40 #endif
41
42 int check_major_version = CHECK_MAJOR_VERSION;
43 int check_minor_version = CHECK_MINOR_VERSION;
44 int check_micro_version = CHECK_MICRO_VERSION;
45
46 static int non_pass (int val);
47 static Fixture *fixture_create (SFun fun, int ischecked);
48 static void tcase_add_fixture (TCase * tc, SFun setup, SFun teardown,
49     int ischecked);
50 static void tr_init (TestResult * tr);
51 static void suite_free (Suite * s);
52 static void tcase_free (TCase * tc);
53
54 Suite *
55 suite_create (const char *name)
56 {
57   Suite *s;
58   s = emalloc (sizeof (Suite)); /* freed in suite_free */
59   if (name == NULL)
60     s->name = "";
61   else
62     s->name = name;
63   s->tclst = check_list_create ();
64   return s;
65 }
66
67 static void
68 suite_free (Suite * s)
69 {
70   List *l;
71   if (s == NULL)
72     return;
73   l = s->tclst;
74   for (list_front (l); !list_at_end (l); list_advance (l)) {
75     tcase_free (list_val (l));
76   }
77   list_free (s->tclst);
78   free (s);
79 }
80
81 TCase *
82 tcase_create (const char *name)
83 {
84   char *env;
85   int timeout = DEFAULT_TIMEOUT;
86   TCase *tc = emalloc (sizeof (TCase)); /*freed in tcase_free */
87   if (name == NULL)
88     tc->name = "";
89   else
90     tc->name = name;
91
92   env = getenv ("CK_DEFAULT_TIMEOUT");
93   if (env != NULL) {
94     int tmp = atoi (env);
95     if (tmp >= 0) {
96       timeout = tmp;
97     }
98   }
99
100   env = getenv ("CK_TIMEOUT_MULTIPLIER");
101   if (env != NULL) {
102     int tmp = atoi (env);
103     if (tmp >= 0) {
104       timeout = timeout * tmp;
105     }
106   }
107
108   tc->timeout = timeout;
109   tc->tflst = check_list_create ();
110   tc->unch_sflst = check_list_create ();
111   tc->ch_sflst = check_list_create ();
112   tc->unch_tflst = check_list_create ();
113   tc->ch_tflst = check_list_create ();
114
115   return tc;
116 }
117
118
119 static void
120 tcase_free (TCase * tc)
121 {
122   list_apply (tc->tflst, free);
123   list_apply (tc->unch_sflst, free);
124   list_apply (tc->ch_sflst, free);
125   list_apply (tc->unch_tflst, free);
126   list_apply (tc->ch_tflst, free);
127   list_free (tc->tflst);
128   list_free (tc->unch_sflst);
129   list_free (tc->ch_sflst);
130   list_free (tc->unch_tflst);
131   list_free (tc->ch_tflst);
132
133   free (tc);
134 }
135
136 void
137 suite_add_tcase (Suite * s, TCase * tc)
138 {
139   if (s == NULL || tc == NULL)
140     return;
141   list_add_end (s->tclst, tc);
142 }
143
144 void
145 _tcase_add_test (TCase * tc, TFun fn, const char *name, int _signal,
146     int allowed_exit_value, int start, int end)
147 {
148   TF *tf;
149   if (tc == NULL || fn == NULL || name == NULL)
150     return;
151   tf = emalloc (sizeof (TF));   /* freed in tcase_free */
152   tf->fn = fn;
153   tf->loop_start = start;
154   tf->loop_end = end;
155   tf->signal = _signal;         /* 0 means no signal expected */
156   tf->allowed_exit_value = allowed_exit_value;  /* 0 is default successful exit */
157   tf->name = name;
158   list_add_end (tc->tflst, tf);
159 }
160
161 static Fixture *
162 fixture_create (SFun fun, int ischecked)
163 {
164   Fixture *f;
165   f = emalloc (sizeof (Fixture));
166   f->fun = fun;
167   f->ischecked = ischecked;
168
169   return f;
170 }
171
172 void
173 tcase_add_unchecked_fixture (TCase * tc, SFun setup, SFun teardown)
174 {
175   tcase_add_fixture (tc, setup, teardown, 0);
176 }
177
178 void
179 tcase_add_checked_fixture (TCase * tc, SFun setup, SFun teardown)
180 {
181   tcase_add_fixture (tc, setup, teardown, 1);
182 }
183
184 static void
185 tcase_add_fixture (TCase * tc, SFun setup, SFun teardown, int ischecked)
186 {
187   if (setup) {
188     if (ischecked)
189       list_add_end (tc->ch_sflst, fixture_create (setup, ischecked));
190     else
191       list_add_end (tc->unch_sflst, fixture_create (setup, ischecked));
192   }
193
194   /* Add teardowns at front so they are run in reverse order. */
195   if (teardown) {
196     if (ischecked)
197       list_add_front (tc->ch_tflst, fixture_create (teardown, ischecked));
198     else
199       list_add_front (tc->unch_tflst, fixture_create (teardown, ischecked));
200   }
201 }
202
203 void
204 tcase_set_timeout (TCase * tc, int timeout)
205 {
206   if (timeout >= 0) {
207     char *env = getenv ("CK_TIMEOUT_MULTIPLIER");
208     if (env != NULL) {
209       int tmp = atoi (env);
210       if (tmp >= 0) {
211         timeout = timeout * tmp;
212       }
213     }
214     tc->timeout = timeout;
215   }
216 }
217
218 void
219 tcase_fn_start (const char *fname CK_ATTRIBUTE_UNUSED, const char *file,
220     int line)
221 {
222   send_ctx_info (CK_CTX_TEST);
223   send_loc_info (file, line);
224 }
225
226 void
227 _mark_point (const char *file, int line)
228 {
229   send_loc_info (file, line);
230 }
231
232 void
233 _fail_unless (int result, const char *file, int line, const char *expr, ...)
234 {
235   const char *msg;
236
237   send_loc_info (file, line);
238   if (!result) {
239     va_list ap;
240     char buf[BUFSIZ];
241
242     va_start (ap, expr);
243     msg = (const char *) va_arg (ap, char *);
244     if (msg == NULL)
245       msg = expr;
246     vsnprintf (buf, BUFSIZ, msg, ap);
247     va_end (ap);
248     send_failure_info (buf);
249     if (cur_fork_status () == CK_FORK) {
250 #ifdef _POSIX_VERSION
251       exit (1);
252 #endif /* _POSIX_VERSION */
253     }
254   }
255 }
256
257 SRunner *
258 srunner_create (Suite * s)
259 {
260   SRunner *sr = emalloc (sizeof (SRunner));     /* freed in srunner_free */
261   sr->slst = check_list_create ();
262   if (s != NULL)
263     list_add_end (sr->slst, s);
264   sr->stats = emalloc (sizeof (TestStats));     /* freed in srunner_free */
265   sr->stats->n_checked = sr->stats->n_failed = sr->stats->n_errors = 0;
266   sr->resultlst = check_list_create ();
267   sr->log_fname = NULL;
268   sr->xml_fname = NULL;
269   sr->loglst = NULL;
270   sr->fstat = CK_FORK_GETENV;
271   return sr;
272 }
273
274 void
275 srunner_add_suite (SRunner * sr, Suite * s)
276 {
277   if (s == NULL)
278     return;
279
280   list_add_end (sr->slst, s);
281 }
282
283 void
284 srunner_free (SRunner * sr)
285 {
286   List *l;
287   TestResult *tr;
288   if (sr == NULL)
289     return;
290
291   free (sr->stats);
292   l = sr->slst;
293   for (list_front (l); !list_at_end (l); list_advance (l)) {
294     suite_free (list_val (l));
295   }
296   list_free (sr->slst);
297
298   l = sr->resultlst;
299   for (list_front (l); !list_at_end (l); list_advance (l)) {
300     tr = list_val (l);
301     free (tr->file);
302     free (tr->msg);
303     free (tr);
304   }
305   list_free (sr->resultlst);
306
307   free (sr);
308 }
309
310 int
311 srunner_ntests_failed (SRunner * sr)
312 {
313   return sr->stats->n_failed + sr->stats->n_errors;
314 }
315
316 int
317 srunner_ntests_run (SRunner * sr)
318 {
319   return sr->stats->n_checked;
320 }
321
322 TestResult **
323 srunner_failures (SRunner * sr)
324 {
325   int i = 0;
326   TestResult **trarray;
327   List *rlst;
328   trarray = malloc (sizeof (trarray[0]) * srunner_ntests_failed (sr));
329
330   rlst = sr->resultlst;
331   for (list_front (rlst); !list_at_end (rlst); list_advance (rlst)) {
332     TestResult *tr = list_val (rlst);
333     if (non_pass (tr->rtype))
334       trarray[i++] = tr;
335
336   }
337   return trarray;
338 }
339
340 TestResult **
341 srunner_results (SRunner * sr)
342 {
343   int i = 0;
344   TestResult **trarray;
345   List *rlst;
346
347   trarray = malloc (sizeof (trarray[0]) * srunner_ntests_run (sr));
348
349   rlst = sr->resultlst;
350   for (list_front (rlst); !list_at_end (rlst); list_advance (rlst)) {
351     trarray[i++] = list_val (rlst);
352   }
353   return trarray;
354 }
355
356 static int
357 non_pass (int val)
358 {
359   return val != CK_PASS;
360 }
361
362 TestResult *
363 tr_create (void)
364 {
365   TestResult *tr;
366
367   tr = emalloc (sizeof (TestResult));
368   tr_init (tr);
369   return tr;
370 }
371
372 void
373 tr_reset (TestResult * tr)
374 {
375   tr_init (tr);
376 }
377
378 static void
379 tr_init (TestResult * tr)
380 {
381   tr->ctx = CK_CTX_INVALID;
382   tr->line = -1;
383   tr->rtype = CK_TEST_RESULT_INVALID;
384   tr->msg = NULL;
385   tr->file = NULL;
386   tr->tcname = NULL;
387   tr->tname = NULL;
388 }
389
390
391 const char *
392 tr_msg (TestResult * tr)
393 {
394   return tr->msg;
395 }
396
397 int
398 tr_lno (TestResult * tr)
399 {
400   return tr->line;
401 }
402
403 const char *
404 tr_lfile (TestResult * tr)
405 {
406   return tr->file;
407 }
408
409 int
410 tr_rtype (TestResult * tr)
411 {
412   return tr->rtype;
413 }
414
415 enum ck_result_ctx
416 tr_ctx (TestResult * tr)
417 {
418   return tr->ctx;
419 }
420
421 const char *
422 tr_tcname (TestResult * tr)
423 {
424   return tr->tcname;
425 }
426
427 static int _fstat = CK_FORK;
428
429 void
430 set_fork_status (enum fork_status fstat)
431 {
432   if (fstat == CK_FORK || fstat == CK_NOFORK || fstat == CK_FORK_GETENV)
433     _fstat = fstat;
434   else
435     eprintf ("Bad status in set_fork_status", __FILE__, __LINE__);
436 }
437
438 enum fork_status
439 cur_fork_status (void)
440 {
441   return _fstat;
442 }