Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
sanitize the use of logs in unit testing of parmap to fix supernovae
[simgrid.git] / tools / tesh2 / src / unit.c
1 /*\r
2  * src/unit.c - type representing the tesh unit concept.\r
3  *\r
4  * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. \r
5  *\r
6  * This program is free software; you can redistribute it and/or modify it \r
7  * under the terms of the license (GNU LGPL) which comes with this package.\r
8  *\r
9  * Purpose:\r
10  *              This file contains all the definitions of the functions related with\r
11  *              the tesh unit concept.\r
12  *\r
13  */  \r
14     \r
15 #include <unit.h>\r
16 #include <command.h>\r
17 #include <context.h>\r
18 #include <fstream.h>\r
19 #include <variable.h>\r
20 #include <str_replace.h>\r
21 #include <xerrno.h>\r
22     \r\r\rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
23 \r\r
24 /*! \brief unit_start - start the processing of the tesh file representing by the unit\r
25  *\r
26  * \param p             A void pointer to the unit representing the tesh file to process.\r
27  *\r
28  * \return              This function (thread routine always returns NULL)\r
29  *\r
30  * Scenario :\r
31  *      \r
32  *      1) The unit increment the number of running unit of the runner.\r
33  *      2) The unit wait for the jobs semaphore to realy start its job.\r
34  *      3) The unit runs the parsing of its tesh file using an fstream object.\r
35  *              3.1) The fstream object parse the tesh file an launch each command with its context of execution.\r
36  *              3.2) If a syntax error is detected the fstream object handle the failure and signals it by setting\r
37  *                   the flag interrupted of the unit to one (depending of the keep-going and keep-going-unit flag values)\r
38  *              3.3) If a command failed (exit code do not match, timeout, ouptupt different from the expected..)\r
39  *                   the command handle the failure (see command_handle_failure() for more details).\r
40  *      4) After the parsing of the tesh file.\r
41  *              4.1) If all commands are successeded the last command release the unit by releasing its semaphore. \r
42  *              4.2) If a command failed or if the tesh file is malformated the unit interrupt all the commands in progress.\r
43  *      5) The unit wait for the end of all the threads associated with a command.\r
44  *      6) Its release the next waiting unit (if any) by releasing the jobs semaphore.\r
45  *      7) If its the last unit, it release the runner by releasing the semaphore used to wait for the end of all the units.\r
46  *          \r
47  */ \r
48 static void *\r unit_start(void *p) \r
49 {
50   \rxbt_os_thread_t thread;
51   \rxbt_os_mutex_t mutex;
52   \runit_t include, suite;
53   \runsigned int itc, itu, its;
54   \rint include_nb, suite_nb;
55   \rcommand_t command;
56   \r\runit_t root = (unit_t) p;
57   \r\r
58       /* increment the number of running units */ \r
59       xbt_os_mutex_acquire(root->mutex);
60   \rroot->runner->number_of_runned_units++;
61   \rxbt_os_mutex_release(root->mutex);
62   \r\r
63       /* must acquire the jobs semaphore to start */ \r
64       /*xbt_os_sem_acquire(jobs_sem); */ \r
65       \r
66       /* initialize the mutex used to synchronize the access to the properties of this unit */ \r
67       mutex = xbt_os_mutex_init();
68   \r\rif (!dry_run_flag)
69     \rINFO1("Test unit from %s", root->fstream->name);
70   \r
71   else
72     \rINFO1("Checking unit %s...", root->fstream->name);
73   \r\r
74       /* launch the parsing of the unit */ \r
75       fstream_parse(root->fstream, mutex);
76   \r\r
77       /* if the unit is not interrupted and not failed the unit, all the file is parsed\r
78        * so all the command are launched\r
79        */ \r
80       if (!root->interrupted)
81     \r {
82     \rroot->parsed = 1;
83     \r\r
84         /* all the commands have terminated before the end of the parsing of the tesh file\r
85          * so the unit release the semaphore itself\r
86          */ \r
87         if (!root->released
88             && (root->started_cmd_nb ==
89                 (root->failed_cmd_nb + root->interrupted_cmd_nb +
90                  root->successeded_cmd_nb)))
91       \rxbt_os_sem_release(root->sem);
92     \r}
93   \r\r
94       /* wait the end of all the commands or a command failure or an interruption */ \r
95       \rxbt_os_sem_acquire(root->sem);
96   \r\r\rif (root->interrupted)
97     \r {
98     \r\rxbt_dynar_foreach(root->commands, itc, command) \r {
99       \rif (command->status == cs_in_progress)
100         \rcommand_interrupt(command);
101     \r}
102     \r\r
103         /* interrupt all the running commands of the included units */ \r
104         include_nb = xbt_dynar_length(root->includes);
105     \r\rxbt_dynar_foreach(root->includes, itu, include) \r {
106       \rxbt_dynar_foreach(include->commands, itc, command) \r {
107         \rif (command->status == cs_in_progress)
108           \rcommand_interrupt(command);
109       \r}
110     \r}
111     \r\r
112         /* interrupt all the running commands of the unit */ \r
113         suite_nb = xbt_dynar_length(root->suites);
114     \r\rxbt_dynar_foreach(root->suites, its, suite) \r {
115       \rinclude_nb = xbt_dynar_length(suite->includes);
116       \r\rxbt_dynar_foreach(suite->includes, itu, include) \r {
117         \rxbt_dynar_foreach(include->commands, itc, command) \r {
118           \rif (command->status == cs_in_progress)
119             \rcommand_interrupt(command);
120         \r}
121       \r}
122     \r}
123     \r}
124   \r\r
125       /* wait the end of the command threads of the unit */ \r
126       xbt_dynar_foreach(root->commands, itc, command) \r {
127     \rthread = command->thread;
128     \r\rif (thread)
129       \rxbt_os_thread_join(thread, NULL);
130   \r}
131   \r\r
132       /* wait the end of the command threads of the included units of the unit */ \r
133       include_nb = xbt_dynar_length(root->includes);
134   \r\rxbt_dynar_foreach(root->includes, itu, include) \r {
135     \rxbt_dynar_foreach(include->commands, itc, command) \r {
136       \rthread = command->thread;
137       \r\rif (thread)
138         \rxbt_os_thread_join(thread, NULL);
139     \r}
140     \r\rif (!dry_run_flag)
141       \r {
142       \rif (!include->exit_code && !include->interrupted)
143         \rINFO1("Include from %s OK", include->fstream->name);
144       \r
145       else if (include->exit_code)
146         \rERROR3("Include `%s' NOK : (<%s> %s)", include->fstream->name,
147                 include->err_line, error_to_string(include->exit_code,
148                                                    include->err_kind));
149       \r
150       else if (include->interrupted && !include->exit_code)
151         \rINFO1("Include `(%s)' INTR", include->fstream->name);
152       \r}
153   \r}
154   \r\r
155       /* interrupt all the running commands of the unit */ \r
156       suite_nb = xbt_dynar_length(root->suites);
157   \r\rxbt_dynar_foreach(root->suites, its, suite) \r {
158     \rinclude_nb = xbt_dynar_length(suite->includes);
159     \r\rif (!include_nb)
160       \r {
161       \rif (!suite->exit_code)
162         \r {
163         \runit_set_error(suite, ESYNTAX, 1, suite->filepos);
164         \rERROR2("[%s] Empty suite `(%s)' detected (no includes added)",
165                 suite->filepos, suite->description);
166         \r\r
167             /* if the --keep-going option is not specified */ \r
168             if (!keep_going_flag)
169           \r {
170           \rif (!interrupted)
171             \r {
172             \r
173                 /* request an global interruption by the runner */ \r
174                 interrupted = 1;
175             \r\r
176                 /* release the runner */ \r
177                 xbt_os_sem_release(units_sem);
178             \r}
179           \r}
180         \r}
181       \r}
182     \r\rxbt_dynar_foreach(suite->includes, itu, include) \r {
183       \rxbt_dynar_foreach(include->commands, itc, command) \r {
184         \rthread = command->thread;
185         \r\rif (thread)
186           \rxbt_os_thread_join(thread, NULL);
187       \r}
188       \r\rif (!include->exit_code && !include->interrupted)
189         \r {
190         \rif (!dry_run_flag)
191           \rINFO1("Include from %s OK", include->fstream->name);
192         \r}
193       \r
194       else if (include->exit_code)
195         \r {
196         \rif (!dry_run_flag)
197           \rERROR3("Include `%s' NOK : (<%s> %s)", include->fstream->name,
198                   command->context->pos,
199                   error_to_string(include->exit_code, include->err_kind));
200         \r\rsuite->exit_code = include->exit_code;
201         \rsuite->err_kind = include->err_kind;
202         \rsuite->err_line = strdup(include->err_line);
203         \r}
204       \r
205       else if (include->interrupted && !include->exit_code)
206         \r {
207         \rif (!dry_run_flag)
208           \rINFO1("Include `(%s)' INTR", include->fstream->name);
209         \r\rsuite->interrupted = 1;
210         \r}
211     \r\r}
212     \r\rif (!dry_run_flag)
213       \r {
214       \rif (!suite->exit_code && !suite->interrupted)
215         \rINFO1("Test suite from %s OK", suite->description);
216       \r
217       else if (suite->exit_code)
218         \rERROR3("Test suite `%s' NOK : (<%s> %s) ", suite->description,
219                 suite->err_line, error_to_string(suite->exit_code,
220                                                  suite->err_kind));
221       \r
222       else if (suite->interrupted && !suite->exit_code)
223         \rINFO1("Test suite `(%s)' INTR", suite->description);
224       \r}
225   \r}
226   \r\r
227       /* you can now destroy the mutex used to synchrone the command accesses to the properties of the unit */ \r
228       xbt_os_mutex_destroy(mutex);
229   \r\r
230       /* update the number of ended units of the runner */ \r
231       xbt_os_mutex_acquire(root->mutex);
232   \r\r
233       /* increment the number of ended units */ \r
234       root->runner->number_of_ended_units++;
235   \r\rif (!dry_run_flag)
236     \r {
237     \rif (root->interrupted && !root->exit_code)
238       \rINFO1("Test unit from %s INTR", root->fstream->name);
239     \r
240     else if (!root->exit_code)
241       \rINFO1("Test unit from %s OK", root->fstream->name);
242     \r
243     else if (root->exit_code)
244       \rERROR3("Test unit `%s': NOK (<%s> %s)", root->fstream->name,
245               root->err_line, error_to_string(root->exit_code,
246                                               root->err_kind));
247     \r}
248   \r\r
249       /* if it's the last unit, release the runner */ \r
250       if ((root->runner->number_of_runned_units ==
251            root->runner->number_of_ended_units))
252     \r {
253     \r
254         /* if all the commands of the unit are successeded itc's a successeded unit */ \r
255         if (root->successeded_cmd_nb == root->cmd_nb
256             && !root->
257             exit_code /* case of only one cd : nb = successeded = 0) */ )
258       \rroot->successeded = 1;
259     \r\r
260         /* first release the mutex */ \r
261         xbt_os_mutex_release(root->mutex);
262     \r\r
263         /* release the runner */ \r
264         xbt_os_sem_release(units_sem);
265     \r}
266   \r
267   else
268     \rxbt_os_mutex_release(root->mutex);
269   \r\r
270       /* release the jobs semaphore, then the next waiting unit can start */ \r
271       xbt_os_sem_release(jobs_sem);
272   \r\rreturn NULL;
273 \r\r}
274
275 \r\r\runit_t \r
276 unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream) \r
277 {
278   \runit_t unit;
279   \r\runit = xbt_new0(s_unit_t, 1);
280   \r\r
281       /* instantiate the vector used to store all the commands of the unit */ \r
282       unit->commands =
283       xbt_dynar_new(sizeof(command_t), (void_f_pvoid_t) command_free);
284   \r\r
285       /* instantiate the vector used to store all the included units */ \r
286       unit->includes =
287       xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t) unit_free);
288   \r\r
289       /* instantiate the vector used to store all the included suites */ \r
290       unit->suites =
291       xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t) unit_free);
292   \r\r
293       /* the runner used to launch the tesh unit */ \r
294       unit->runner = runner;
295   \r\r
296       /* the file stream object to use to parse the tesh file */ \r
297       unit->fstream = fstream;
298   \r\rif (fstream)
299     \rfstream->unit = unit;
300   \r\r
301       /* if no root parameter specified assume that itc's the root of all the units */ \r
302       unit->root = root ? root : unit;
303   \r\r
304       /* the owner of the suite */ \r
305       unit->owner = owner;
306   \r\runit->thread = NULL;
307   \runit->started_cmd_nb = 0;
308   \runit->interrupted_cmd_nb = 0;
309   \runit->failed_cmd_nb = 0;
310   \runit->successeded_cmd_nb = 0;
311   \runit->terminated_cmd_nb = 0;
312   \runit->waiting_cmd_nb = 0;
313   \runit->interrupted = 0;
314   \runit->failed = 0;
315   \runit->successeded = 0;
316   \runit->parsed = 0;
317   \runit->released = 0;
318   \runit->owner = owner;
319   \runit->is_running_suite = 0;
320   \runit->description = NULL;
321   \runit->sem = NULL;
322   \runit->exit_code = 0;
323   \runit->err_kind = 0;
324   \runit->err_line = NULL;
325   \runit->filepos = NULL;
326   \r\r\r\rreturn unit;
327 \r}
328
329 \r\rvoid \r
330 unit_set_error(unit_t unit, int errcode, int kind, const char *line) \r
331 {
332   \rif (!unit->exit_code)
333     \r {
334     \runit->exit_code = errcode;
335     \runit->err_kind = kind;
336     \runit->err_line = strdup(line);
337     \r\rif (unit->root && !unit->root->exit_code)
338       \r {
339       \runit->root->exit_code = errcode;
340       \runit->root->err_kind = kind;
341       \runit->root->err_line = strdup(line);
342       \r}
343     \r\rif (!exit_code)
344       \r {
345       \r\rexit_code = errcode;
346       \rerr_kind = kind;
347       \rerr_line = strdup(line);
348       \r}
349     \r}
350 \r\r}
351
352 \r\rint \r unit_free(unit_t * ptr) \r
353 {
354   \rif (!(*ptr))
355     \r {
356     \rerrno = EINVAL;
357     \rreturn -1;
358     \r}
359   \r\rif ((*ptr)->commands)
360     \rxbt_dynar_free(&((*ptr)->commands));
361   \r\rif ((*ptr)->includes)
362     \rxbt_dynar_free(&((*ptr)->includes));
363   \r\rif ((*ptr)->suites)
364     \rxbt_dynar_free(&((*ptr)->suites));
365   \r\r
366       /* if the unit is interrupted during its run, the semaphore is NULL */ \r
367       if ((*ptr)->sem)
368     \rxbt_os_sem_destroy((*ptr)->sem);
369   \r\rif ((*ptr)->description)
370     \rfree((*ptr)->description);
371   \r\rif ((*ptr)->err_line)
372     \rfree((*ptr)->err_line);
373   \r\rif ((*ptr)->filepos)
374     \rfree((*ptr)->filepos);
375   \r\rfree(*ptr);
376   \r*ptr = NULL;
377   \r\rreturn 0;
378 \r}
379
380 \r\rint \r unit_run(unit_t unit, xbt_os_mutex_t mutex) \r
381 {
382   \r
383       /* check the parameters */ \r
384       if (!(unit) || !mutex)
385     \r {
386     \rerrno = EINVAL;
387     \rxbt_os_sem_release(jobs_sem);
388     \rreturn -1;
389     \r\r}
390   \r\rif (!interrupted)
391     \r {
392     \runit->mutex = mutex;
393     \r\runit->sem = xbt_os_sem_init(0);
394     \r\r
395         /* start the unit */ \r
396         unit->thread = xbt_os_thread_create("", unit_start, unit);
397     \r}
398   \r
399   else
400     \r {
401     \r
402         /* the unit is interrupted by the runner before its starting \r
403          * in this case the unit semaphore is NULL take care of that\r
404          * in the function unit_free()\r
405          */ \r
406         unit->interrupted = 1;
407     \rxbt_os_sem_release(jobs_sem);
408     \r}
409   \r\rreturn 0;
410 \r\r}
411
412 \r\rint \r unit_interrupt(unit_t unit) \r
413 {
414   \r
415       /* check the parameter */ \r
416       if (!(unit))
417     \r {
418     \rerrno = EINVAL;
419     \rreturn -1;
420     \r}
421   \r\r
422       /* if the unit is already interrupted, signal the error */ \r
423       if (unit->interrupted)
424     \r {
425     \rerrno = EALREADY;
426     \rreturn -1;
427     \r}
428   \r\r
429       /* interrupt the run of the specified unit */ \r
430       unit->interrupted = 1;
431   \rxbt_os_sem_release(unit->sem);
432   \r\rreturn 0;
433 \r}
434
435 \r\r
436 /* just print the title of the root unit or a suite (if any) */ \r
437 static void \r print_title(const char *description) \r
438 {
439   \rregister int i;
440   \rchar title[80];
441   \rsize_t len = strlen(description);
442   \r\rtitle[0] = ' ';
443   \r\rfor (i = 1; i < 79; i++)
444     \rtitle[i] = '=';
445   \r\rtitle[i++] = '\n';
446   \rtitle[79] = '\0';
447   \r\rsprintf(title + 40 - (len + 4) / 2, "[ %s ]", description);
448   \rtitle[40 + (len + 5) / 2] = '=';
449   \r\rprintf("\n%s\n", title);
450 \r}
451
452 \r\rint \r unit_summuarize(unit_t unit) \r
453 {
454   \rcommand_t command;
455   \runsigned int itc, itu, its;
456   \runit_t include;
457   \runit_t suite;
458   \rchar *p;
459   \rchar title[PATH_MAX + 1] = { 0 };
460   \r\rint number_of_tests = 0;    /* number of tests of a unit contained by this unit                                     */
461   \rint number_of_failed_tests = 0;      /* number of failed test of a unit contained by this unit                       */
462   \rint number_of_successeded_tests = 0; /* number of successeded tests of a unit contained by this unit         */
463   \rint number_of_interrupted_tests = 0; /* number of interrupted tests of a unit contained by this unit         */
464   \r\rint number_of_tests_of_suite = 0;   /* number of tests of a suite contained by this unit                            */
465   \rint number_of_interrupted_tests_of_suite = 0;        /* number of interrupted tests of a suite contained by this unit        */
466   \rint number_of_failed_tests_of_suite = 0;     /* number of failed tests of a suite contained by this unit                                     */
467   \rint number_of_successeded_tests_of_suite = 0;        /* number of successeded tests of a suite contained by this                     */
468   \r\rint number_of_units = 0;    /* number of units contained by a suite                                                         */
469   \rint number_of_failed_units = 0;      /* number of failed units contained by a suite                                          */
470   \rint number_of_successeded_units = 0; /* number of successeded units contained by a suite                                     */
471   \rint number_of_interrupted_units = 0; /* number of interrupted units contained by a suite                                     */
472   \r\rint total_of_tests = 0;     /* total of the tests contained by this unit                                            */
473   \rint total_of_failed_tests = 0;       /* total of failed tests contained by this unit                                         */
474   \rint total_of_successeded_tests = 0;  /* total of successeded tests contained by this unit                            */
475   \rint total_of_interrupted_tests = 0;  /* total of interrupted tests contained by this unit                            */
476   \r\rint total_of_units = 0;     /* total of units contained by this unit                                                        */
477   \rint total_of_failed_units = 0;       /* total of failed units contained by this unit                                         */
478   \rint total_of_successeded_units = 0;  /* total of successeded units contained by this unit                            */
479   \rint total_of_interrupted_units = 0;  /* total of interrutped units contained by this unit                            */
480   \r\rint total_of_suites = 0;    /* total of suites contained by this unit                                                       */
481   \rint total_of_failed_suites = 0;      /* total of failed suites contained by this unit                                        */
482   \rint total_of_successeded_suites = 0; /* total of successeded suites contained by this unit                           */
483   \rint total_of_interrupted_suites = 0; /* total of interrupted suites contained by this unit                           */
484   \r\r
485       /* check the parameter */ \r
486       if (!(unit))
487     \r {
488     \rerrno = EINVAL;
489     \rreturn -1;
490     \r}
491   \r\rif ((unit->description) && strlen(unit->description) < 76)
492     \rstrcpy(title, unit->description);
493   \r
494   else
495     \rsprintf(title, "file : %s", unit->fstream->name);
496   \r\rif (unit->interrupted)
497     \r {
498     \rif (strlen(title) + strlen(" (interrupted)") < 76)
499       \rstrcat(title, " (interrupted)");
500     \r
501     else
502       \r {
503       \rmemset(title, 0, PATH_MAX + 1);
504       \rsprintf(title, "file : %s", unit->fstream->name);
505       \rstrcat(title, " (interrupted)");
506       \r\r}
507     \r}
508   \r\rprint_title(title);
509   \r\rnumber_of_tests = xbt_dynar_length(unit->commands);
510   \r\r
511       /* tests */ \r
512       xbt_dynar_foreach(unit->commands, itc, command) \r {
513     \rif (command->status == cs_interrupted)
514       \rnumber_of_interrupted_tests++;
515     \r
516     else if (command->status == cs_failed)
517       \rnumber_of_failed_tests++;
518     \r
519     else if (command->status == cs_successeded)
520       \rnumber_of_successeded_tests++;
521   \r}
522   \r\r\rif (number_of_tests)
523     \r {
524     \rasprintf(&p,
525               " Test(s): .........................................................................");
526     \r\rp[70] = '\0';
527     \rprintf("%s", p);
528     \rfree(p);
529     \r\rif (number_of_failed_tests > 0)
530       \rprintf(".. failed\n");
531     \r
532     else if (number_of_interrupted_tests > 0)
533       \rprintf("interrupt\n");
534     \r
535     else
536       \rprintf(".... ..ok\n");
537     \r\rxbt_dynar_foreach(unit->commands, itc, command) \r {
538       \rprintf("        %s: %s [%s]\n",
539               \rcommand->status ==
540               cs_interrupted ? "INTR  " \r : command->status ==
541               cs_failed ? "FAILED" \r : command->status ==
542               cs_successeded ? "PASS  " \r : "UNKNWN",
543               \rcommand->context->command_line, \rcommand->context->pos);
544       \r\rif (detail_summary_flag)
545         \rcommand_summarize(command);
546     \r}
547     \r\rprintf
548         (" =====================================================================%s\n",
549          \rnumber_of_failed_tests ? "== FAILED" :
550          number_of_interrupted_tests ? "==== INTR" : "====== OK");
551     \r\rprintf("    Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
552              \r((1 -
553                 ((double) number_of_failed_tests +
554                  (double) number_of_interrupted_tests) /
555                 (double) number_of_tests) * 100.0), \rnumber_of_tests,
556              number_of_successeded_tests);
557     \r\rif (number_of_failed_tests > 0)
558       \rprintf(", %d failed", number_of_failed_tests);
559     \r\rif (number_of_interrupted_tests > 0)
560       \rprintf(", %d interrupted)", number_of_interrupted_tests);
561     \r\rprintf(")\n\n");
562     \r\rtotal_of_tests = number_of_tests;
563     \rtotal_of_failed_tests = number_of_failed_tests;
564     \rtotal_of_interrupted_tests = number_of_interrupted_tests;
565     \rtotal_of_successeded_tests = number_of_successeded_tests;
566     \r}
567   \r\r\r\r
568       /* includes */ \r
569       total_of_failed_units = total_of_interrupted_units =
570       total_of_successeded_units = 0;
571   \rnumber_of_failed_units = number_of_successeded_units =
572       number_of_interrupted_units = 0;
573   \rnumber_of_units = xbt_dynar_length(unit->includes);
574   \r\rxbt_dynar_foreach(unit->includes, itu, include) \r {
575     \r\rnumber_of_interrupted_tests = number_of_failed_tests =
576         number_of_successeded_tests = 0;
577     \r\rnumber_of_tests = xbt_dynar_length(include->commands);
578     \r\rxbt_dynar_foreach(include->commands, itc, command) \r {
579       \rif (command->status == cs_interrupted)
580         \rnumber_of_interrupted_tests++;
581       \r
582       else if (command->status == cs_failed)
583         \rnumber_of_failed_tests++;
584       \r
585       else if (command->status == cs_successeded)
586         \rnumber_of_successeded_tests++;
587     \r}
588     \r\rasprintf(&p,
589                " Unit: %s ............................................................................",
590                include->description
591                && strlen(include->description) <
592                60 ? include->description : include->fstream->name);
593     \r\rp[70] = '\0';
594     \rprintf("%s", p);
595     \rfree(p);
596     \r\rif (number_of_failed_tests > 0)
597       \r {
598       \rtotal_of_failed_units++;
599       \rprintf(".. failed\n");
600       \r}
601     \r
602     else if (number_of_interrupted_tests > 0)
603       \r {
604       \rtotal_of_interrupted_units++;
605       \rprintf("interrupt\n");
606       \r}
607     \r
608     else
609       \r {
610       \rtotal_of_successeded_units++;
611       \rprintf(".... ..ok\n");
612       \r}
613     \r\rif (detail_summary_flag)
614       \r {
615       \r\rxbt_dynar_foreach(include->commands, itc, command) \r {
616         \rprintf("        %s: %s [%s]\n",
617                 \rcommand->status ==
618                 cs_interrupted ? "INTR  " \r : command->status ==
619                 cs_failed ? "FAILED" \r : command->status ==
620                 cs_successeded ? "PASS  " \r : "UNKNWN",
621                 \rcommand->context->command_line, \rcommand->context->pos);
622         \r\rcommand_summarize(command);
623       \r}
624       \r\r\r}
625     \r\rprintf
626         (" =====================================================================%s\n",
627          \rnumber_of_failed_tests ? "== FAILED" :
628          number_of_interrupted_tests ? "==== INTR" : "====== OK");
629     \r\r\rprintf("    Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
630               \r(number_of_tests
631                 ? (1 -
632                    ((double) number_of_failed_tests +
633                     (double) number_of_interrupted_tests) /
634                    (double) number_of_tests) * 100.0 : 100.0),
635               \rnumber_of_tests, number_of_successeded_tests);
636     \r\rif (number_of_failed_tests > 0)
637       \rprintf(", %d failed", number_of_failed_tests);
638     \r\rif (number_of_interrupted_tests > 0)
639       \rprintf(", %d interrupted)", number_of_interrupted_tests);
640     \r\rprintf(")\n\n");
641     \r\r\rtotal_of_tests += number_of_tests;
642     \rtotal_of_failed_tests += number_of_failed_tests;
643     \rtotal_of_interrupted_tests += number_of_interrupted_tests;
644     \rtotal_of_successeded_tests += number_of_successeded_tests;
645   \r}
646   \r\r
647       /* suites */ \r
648       total_of_units = number_of_units;
649   \r\rtotal_of_failed_suites = total_of_successeded_suites =
650       total_of_interrupted_suites = 0;
651   \r\rtotal_of_suites = xbt_dynar_length(unit->suites);
652   \r\rxbt_dynar_foreach(unit->suites, its, suite) \r {
653     \rprint_title(suite->description);
654     \r\rnumber_of_tests_of_suite = number_of_interrupted_tests_of_suite =
655         number_of_failed_tests_of_suite =
656         number_of_successeded_tests_of_suite = 0;
657     \r\rnumber_of_interrupted_units = number_of_failed_units =
658         number_of_successeded_units = 0;
659     \r\rnumber_of_units = xbt_dynar_length(suite->includes);
660     \r\rxbt_dynar_foreach(suite->includes, itu, include) \r {
661       \rnumber_of_interrupted_tests = number_of_failed_tests =
662           number_of_successeded_tests = 0;
663       \r\rnumber_of_tests = xbt_dynar_length(include->commands);
664       \r\r\rxbt_dynar_foreach(include->commands, itc, command) \r {
665         \rif (command->status == cs_interrupted)
666           \rnumber_of_interrupted_tests++;
667         \r
668         else if (command->status == cs_failed)
669           \rnumber_of_failed_tests++;
670         \r
671         else if (command->status == cs_successeded)
672           \rnumber_of_successeded_tests++;
673       \r}
674       \r\rasprintf(&p,
675                  " Unit: %s ............................................................................",
676                  include->description
677                  && strlen(include->description) <
678                  60 ? include->description : include->fstream->name);
679       \r\rp[70] = '\0';
680       \rprintf("%s", p);
681       \rfree(p);
682       \r\rif (number_of_failed_tests > 0)
683         \r {
684         \rnumber_of_failed_units++;
685         \rprintf(".. failed\n");
686         \r}
687       \r
688       else if (number_of_interrupted_tests > 0)
689         \r {
690         \rnumber_of_interrupted_units++;
691         \rprintf("interrupt\n");
692         \r}
693       \r
694       else
695         \r {
696         \rnumber_of_successeded_units++;
697         \rprintf(".... ..ok\n");
698         \r}
699       \r\rnumber_of_interrupted_tests_of_suite +=
700           number_of_interrupted_tests;
701       \rnumber_of_failed_tests_of_suite += number_of_failed_tests;
702       \rnumber_of_successeded_tests_of_suite += number_of_successeded_tests;
703       \r\rnumber_of_tests_of_suite += number_of_tests;
704       \r\rtotal_of_tests += number_of_tests;
705       \rtotal_of_failed_tests += number_of_failed_tests;
706       \rtotal_of_interrupted_tests += number_of_interrupted_tests;
707       \rtotal_of_successeded_tests += number_of_successeded_tests;
708       \r\rif (detail_summary_flag)
709         \r {
710         \r\rxbt_dynar_foreach(include->commands, itc, command) \r {
711           \rprintf("        %s: %s [%s]\n",
712                   \rcommand->status ==
713                   cs_interrupted ? "INTR  " \r : command->status ==
714                   cs_failed ? "FAILED" \r : command->status ==
715                   cs_successeded ? "PASS  " \r : "UNKNWN",
716                   \rcommand->context->command_line, \rcommand->context->pos);
717           \r\rcommand_summarize(command);
718         \r}
719         \r\r\r}
720     \r\r}
721     \r\rprintf
722         (" =====================================================================%s\n",
723          \rnumber_of_failed_tests_of_suite ? "== FAILED" :
724          number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");
725     \r\rif (number_of_failed_tests_of_suite > 0)
726       \rtotal_of_failed_suites++;
727     \r
728     else if (number_of_interrupted_tests_of_suite)
729       \rtotal_of_interrupted_suites++;
730     \r
731     else
732       \rtotal_of_successeded_suites++;
733     \r\rtotal_of_failed_units += number_of_failed_units;
734     \rtotal_of_interrupted_units += number_of_interrupted_units;
735     \rtotal_of_successeded_units += number_of_successeded_units;
736     \r\rtotal_of_units += number_of_units;
737     \r\rprintf("    Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok", \r
738              (number_of_units
739               ? (1 -
740                  ((double) number_of_failed_units +
741                   (double) number_of_interrupted_units) /
742                  (double) number_of_units) * 100.0 : 100.0),
743              \rnumber_of_units, number_of_successeded_units);
744     \r\rif (number_of_failed_units > 0)
745       \rprintf(", %d failed", number_of_failed_units);
746     \r\rif (number_of_interrupted_units > 0)
747       \rprintf(", %d interrupted)", number_of_interrupted_units);
748     \r\rprintf(")\n");
749     \r\rprintf("             Test(s): %.0f%% ok (%d test(s): %d ok", \r
750              (number_of_tests_of_suite
751               ? (1 -
752                  ((double) number_of_failed_tests_of_suite +
753                   (double) number_of_interrupted_tests_of_suite) /
754                  (double) number_of_tests_of_suite) * 100.0 : 100.0),
755              \rnumber_of_tests_of_suite,
756              number_of_successeded_tests_of_suite);
757     \r\rif (number_of_failed_tests_of_suite > 0)
758       \rprintf(", %d failed", number_of_failed_tests_of_suite);
759     \r\rif (number_of_interrupted_tests_of_suite > 0)
760       \rprintf(", %d interrupted)", number_of_interrupted_tests_of_suite);
761     \r\rprintf(")\n\n");
762   \r}
763   \r\rprintf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok", \r
764            (total_of_suites
765             ? (1 -
766                ((double) total_of_failed_suites +
767                 (double) total_of_interrupted_suites) /
768                (double) total_of_suites) * 100.0 : 100.0),
769            \rtotal_of_suites, total_of_successeded_suites);
770   \r\rif (total_of_failed_suites > 0)
771     \rprintf(", %d failed", total_of_failed_suites);
772   \r\rif (total_of_interrupted_suites > 0)
773     \rprintf(", %d interrupted)", total_of_interrupted_suites);
774   \r\rprintf(")\n");
775   \r\rprintf("         Unit(s):  %.0f%% ok (%d unit(s): %d ok", \r
776            (total_of_units
777             ? (1 -
778                ((double) total_of_failed_units +
779                 (double) total_of_interrupted_units) /
780                (double) total_of_units) * 100.0 : 100.0), \rtotal_of_units,
781            total_of_successeded_units);
782   \r\rif (total_of_failed_units > 0)
783     \rprintf(", %d failed", total_of_failed_units);
784   \r\rif (total_of_interrupted_units > 0)
785     \rprintf(", %d interrupted)", total_of_interrupted_units);
786   \r\rprintf(")\n");
787   \r\rprintf("         Test(s):  %.0f%% ok (%d test(s): %d ok", \r
788            (total_of_tests
789             ? (1 -
790                ((double) total_of_failed_tests +
791                 (double) total_of_interrupted_tests) /
792                (double) total_of_tests) * 100.0 : 100.0), \rtotal_of_tests,
793            total_of_successeded_tests);
794   \r\rif (total_of_failed_tests > 0)
795     \rprintf(", %d failed", total_of_failed_tests);
796   \r\rif (total_of_interrupted_tests > 0)
797     \rprintf(", %d interrupted)", total_of_interrupted_tests);
798   \r\rprintf(")\n\n");
799   \r\rif (unit->interrupted)
800     \runit->runner->total_of_interrupted_units++;
801   \r
802   else if (total_of_failed_tests > 0)
803     \runit->runner->total_of_failed_units++;
804   \r
805   else
806     \runit->runner->total_of_successeded_units++;
807   \r\runit->runner->total_of_tests += total_of_tests;
808   \runit->runner->total_of_failed_tests += total_of_failed_tests;
809   \runit->runner->total_of_successeded_tests += total_of_successeded_tests;
810   \runit->runner->total_of_interrupted_tests += total_of_interrupted_tests;
811   \r\runit->runner->total_of_units += total_of_units + 1;
812   \runit->runner->total_of_successeded_units += total_of_successeded_units;
813   \runit->runner->total_of_failed_units += total_of_failed_units;
814   \runit->runner->total_of_interrupted_units += total_of_interrupted_units;
815   \r\runit->runner->total_of_suites += total_of_suites;
816   \runit->runner->total_of_successeded_suites +=
817       total_of_successeded_suites;
818   \runit->runner->total_of_failed_suites += total_of_failed_suites;
819   \runit->runner->total_of_interrupted_suites +=
820       total_of_interrupted_suites;
821   \r\rreturn 0;
822 \r}
823
824 \r\rint \r unit_reset(unit_t unit) \r
825 {
826   \runit_t cur;
827   \runsigned int i;
828   \r\r
829       /* reset all the suites of the unit */ \r
830       xbt_dynar_foreach(unit->suites, i, cur) \r {
831     \runit_reset(cur);
832   \r\r\r\r
833       /* reset all the includes of the unit */ \r
834       xbt_dynar_foreach(unit->includes, i, cur) \r {
835     \runit_reset(cur);
836   \r\r\rfseek(unit->fstream->stream, 0L, SEEK_SET);
837   \runit->parsed = 0;
838   \runit->cmd_nb = 0;
839   \runit->started_cmd_nb = 0;
840   \runit->interrupted_cmd_nb = 0;
841   \runit->failed_cmd_nb = 0;
842   \runit->successeded_cmd_nb = 0;
843   \runit->terminated_cmd_nb = 0;
844   \runit->waiting_cmd_nb = 0;
845   \runit->interrupted = 0;
846   \runit->failed = 0;
847   \runit->successeded = 0;
848   \runit->parsed = 0;
849   \runit->released = 0;
850   \runit->is_running_suite = 0;
851   \r\rif (unit->description)
852     \r {
853     \rfree(unit->description);
854     \runit->description = NULL;
855     \r}
856   \r\runit->exit_code = 0;
857   \r\rreturn 0;
858 \r}
859
860 \r