Logo AND Algorithmique Numérique Distribuée

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