Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add the new integrated files version (use xbt data structures instead my own data...
[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("checking unit %s...",root->fstream->name); \r
76         \r
77         /* launch the parsing of the unit */\r
78         fstream_parse(root->fstream, mutex);\r
79         \r
80         /* if the unit is not interrupted and not failed the unit, all the file is parsed\r
81          * so all the command are launched\r
82          */\r
83         if(!root->interrupted)\r
84         {\r
85                 root->parsed = 1;\r
86                 \r
87                 /* all the commands have terminated before the end of the parsing of the tesh file\r
88                  * so the unit release the semaphore itself\r
89                  */\r
90                 if(!root->released && (root->started_cmd_nb == (root->failed_cmd_nb + root->interrupted_cmd_nb + root->successeded_cmd_nb)))\r
91                         xbt_os_sem_release(root->sem);  \r
92         }\r
93         \r
94         /* wait the end of all the commands or a command failure or an interruption */\r
95         xbt_os_sem_acquire(root->sem);\r
96         \r
97         if(root->interrupted)\r
98         {\r
99                 xbt_dynar_foreach(root->commands, itc , command)\r
100                 {\r
101                         if(command->status == cs_in_progress)\r
102                                 command_interrupt(command);\r
103                 }\r
104                 \r
105                 /* interrupt all the running commands of the included units */\r
106                 include_nb = xbt_dynar_length(root->includes);\r
107                 \r
108                 xbt_dynar_foreach(root->includes, itu, include)\r
109                 {\r
110                         xbt_dynar_foreach(include->commands, itc, command)\r
111                         {\r
112                                 if(command->status == cs_in_progress)\r
113                                         command_interrupt(command);\r
114                         }\r
115                 }\r
116                 \r
117                 /* interrupt all the running commands of the unit */\r
118                 suite_nb = xbt_dynar_length(root->suites);\r
119                 \r
120                 xbt_dynar_foreach(root->suites, its, suite)\r
121                 {\r
122                         include_nb = xbt_dynar_length(suite->includes);\r
123 \r
124                         xbt_dynar_foreach(suite->includes, itu, include)\r
125                         {\r
126                                 xbt_dynar_foreach(include->commands, itc, command)\r
127                                 {\r
128                                         if(command->status == cs_in_progress)\r
129                                                 command_interrupt(command);\r
130                                 }\r
131                         }\r
132                 }\r
133         }\r
134         \r
135         /* wait the end of the command threads of the unit */\r
136         xbt_dynar_foreach(root->commands, itc, command)\r
137         {\r
138                 thread = command->thread;\r
139                 \r
140                 if(thread)\r
141                         xbt_os_thread_join(thread,NULL);\r
142         }\r
143         \r
144         /* wait the end of the command threads of the included units of the unit */\r
145         include_nb = xbt_dynar_length(root->includes);\r
146          \r
147         xbt_dynar_foreach(root->includes, itu, include)\r
148         {\r
149                 xbt_dynar_foreach(include->commands, itc, command)\r
150                 {\r
151                         thread = command->thread;\r
152                 \r
153                         if(thread)\r
154                                 xbt_os_thread_join(thread,NULL);\r
155                 }\r
156         }\r
157         \r
158         /* interrupt all the running commands of the unit */\r
159         suite_nb = xbt_dynar_length(root->suites);\r
160         \r
161         xbt_dynar_foreach(root->suites, its, suite)\r
162         {\r
163                 include_nb = xbt_dynar_length(suite->includes);\r
164                 \r
165                 xbt_dynar_foreach(suite->includes, itu, include)\r
166                 {\r
167                         xbt_dynar_foreach(include->commands, itc, command)\r
168                         {\r
169                                 thread = command->thread;\r
170                 \r
171                                 if(thread)\r
172                                         xbt_os_thread_join(thread,NULL);\r
173                         }\r
174                 }\r
175         }\r
176         \r
177         /* you can now destroy the mutex used to synchrone the command accesses to the properties of the unit */\r
178         xbt_os_mutex_destroy(mutex);\r
179         \r
180         /* update the number of ended units of the runner */\r
181         xbt_os_mutex_acquire(root->mutex);\r
182 \r
183         /* increment the number of ended units */\r
184         root->runner->number_of_ended_units++;\r
185         \r
186         /* if itc's the last unit, release the runner */\r
187         if((root->runner->number_of_runned_units == root->runner->number_of_ended_units))\r
188         {\r
189                 /* if all the commands of the unit are successeded itc's a successeded unit */\r
190                 if(root->successeded_cmd_nb == root->cmd_nb)\r
191                         root->successeded = 1;\r
192 \r
193                 /* first release the mutex */\r
194                 xbt_os_mutex_release(root->mutex);\r
195                 \r
196                 /* release the runner */\r
197                 xbt_os_sem_release(units_sem);\r
198         }\r
199         else\r
200                 xbt_os_mutex_release(root->mutex);\r
201         \r
202         /* release the jobs semaphore, then the next waiting unit can start */\r
203         xbt_os_sem_release(jobs_sem);\r
204         \r
205         return NULL;\r
206 \r
207 }\r
208 \r
209 \r
210 unit_t\r
211 unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream)\r
212 {\r
213         unit_t unit;\r
214         \r
215         /* TODO : check the parameters */\r
216         \r
217         unit = xbt_new0(s_unit_t, 1);\r
218         \r
219         /* instantiate the vector used to store all the commands of the unit */\r
220         unit->commands = xbt_dynar_new(sizeof(command_t), (void_f_pvoid_t)command_free);\r
221         \r
222         /* instantiate the vector used to store all the included units */\r
223         unit->includes = xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t)unit_free);\r
224         \r
225         /* instantiate the vector used to store all the included suites */\r
226         unit->suites = xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t)unit_free);\r
227         \r
228         /* the runner used to launch the tesh unit */\r
229         unit->runner = runner;\r
230         \r
231         /* the file stream object to use to parse the tesh file */\r
232         unit->fstream = fstream;\r
233         \r
234         if(fstream)\r
235                 fstream->unit = unit;\r
236         \r
237         /* if no root parameter specified assume that itc's the root of all the units */\r
238         unit->root = root ?  root : unit;\r
239         \r
240         /* the owner of the suite */\r
241         unit->owner = owner;\r
242         \r
243         unit->thread = NULL;\r
244         unit->started_cmd_nb = 0;\r
245         unit->interrupted_cmd_nb = 0;\r
246         unit->failed_cmd_nb = 0;\r
247         unit->successeded_cmd_nb = 0;\r
248         unit->terminated_cmd_nb = 0;\r
249         unit->waiting_cmd_nb = 0;\r
250         unit->interrupted = 0;\r
251         unit->failed = 0;\r
252         unit->successeded = 0;\r
253         unit->parsed = 0;\r
254         unit->released = 0;\r
255         unit->owner = owner;\r
256         unit->is_running_suite = 0;\r
257         unit->description = NULL;\r
258         unit->sem = NULL;\r
259         \r
260 \r
261         return unit;\r
262 }\r
263 \r
264 int\r
265 unit_free(unit_t* ptr)\r
266 {\r
267         \r
268         /* check the parameter */\r
269         if(!(*ptr))\r
270     {\r
271         errno = EINVAL;\r
272         return -1;\r
273     }\r
274 \r
275         xbt_dynar_free(&((*ptr)->commands));\r
276         \r
277         xbt_dynar_free(&((*ptr)->includes));\r
278 \r
279         xbt_dynar_free(&((*ptr)->suites));\r
280         \r
281         /* if the unit is interrupted during its run, the semaphore is NULL */\r
282         if((*ptr)->sem)\r
283                 xbt_os_sem_destroy((*ptr)->sem);\r
284                 \r
285         if((*ptr)->description)\r
286                 free((*ptr)->description);\r
287 \r
288         free(*ptr);\r
289         *ptr = NULL;\r
290         \r
291         return 0;\r
292 }\r
293 \r
294 int\r
295 unit_run(unit_t unit, xbt_os_mutex_t mutex)\r
296 {\r
297         /* check the parameters */\r
298         if(!(unit) || !mutex)\r
299     {\r
300         errno = EINVAL;\r
301         return -1;\r
302     }\r
303     \r
304         if(!interrupted)\r
305         {\r
306                 unit->mutex = mutex;\r
307                 \r
308                 unit->sem = xbt_os_sem_init(0);\r
309 \r
310                 /* start the unit */\r
311                 unit->thread = xbt_os_thread_create("", unit_start, unit);\r
312         }\r
313         else\r
314                 /* the unit is interrupted by the runner before its starting \r
315                  * in this case the unit semaphore is NULL take care of that\r
316                  * in the function unit_free()\r
317                  */\r
318                 unit->interrupted = 1;\r
319                 \r
320         return 0;\r
321         \r
322 }\r
323 \r
324 int\r
325 unit_interrupt(unit_t unit)\r
326 {\r
327         /* check the parameter */\r
328         if(!(unit))\r
329     {\r
330         errno = EINVAL;\r
331         return -1;\r
332     }\r
333     \r
334     /* if the unit is already interrupted, signal the error */\r
335     if(unit->interrupted)\r
336     {\r
337         errno = EALREADY;\r
338         return -1;\r
339     }\r
340     \r
341         /* interrupt the run of the specified unit */\r
342         unit->interrupted = 1;\r
343         xbt_os_sem_release(unit->sem);\r
344         \r
345         return 0;\r
346 }\r
347 \r
348 /* just print the title of the root unit or a suite (if any) */\r
349 static void \r
350 print_title(const char* description)\r
351 {\r
352         register int i;\r
353         char title[80];\r
354         size_t len = strlen(description);\r
355                 \r
356         title[0]=' ';\r
357                 \r
358         for (i = 1; i < 79; i++)\r
359                 title[i]='=';\r
360                 \r
361         title[i++]='\n';\r
362         title[79]='\0';\r
363         \r
364         sprintf(title + 40 - (len + 4)/2, "[ %s ]",description);\r
365         title[40 + (len + 5 ) / 2] = '=';\r
366                 \r
367         printf("\n%s\n",title); \r
368 }\r
369 \r
370 int\r
371 unit_summuarize(unit_t unit)\r
372 {\r
373         command_t command;\r
374         unsigned int itc, itu, its;\r
375         unit_t include;\r
376         unit_t suite;\r
377         char* p;\r
378         char title[PATH_MAX + 1] = {0};\r
379         \r
380         int number_of_tests = 0;                                                /* number of tests of a unit contained by this unit                                     */\r
381         int number_of_failed_tests = 0;                                 /* number of failed test of a unit contained by this unit                       */\r
382         int number_of_successeded_tests = 0;                    /* number of successeded tests of a unit contained by this unit         */\r
383         int number_of_interrupted_tests = 0;                    /* number of interrupted tests of a unit contained by this unit         */\r
384         \r
385         int number_of_tests_of_suite = 0;                               /* number of tests of a suite contained by this unit                            */\r
386         int number_of_interrupted_tests_of_suite = 0;   /* number of interrupted tests of a suite contained by this unit        */      \r
387         int number_of_failed_tests_of_suite = 0;                /* number of failed tests of a suite contained by this unit                                     */\r
388         int number_of_successeded_tests_of_suite = 0;   /* number of successeded tests of a suite contained by this                     */\r
389         \r
390         int number_of_units = 0;                                                /* number of units contained by a suite                                                         */\r
391         int number_of_failed_units = 0;                                 /* number of failed units contained by a suite                                          */\r
392         int number_of_successeded_units = 0;                    /* number of successeded units contained by a suite                                     */\r
393         int number_of_interrupted_units = 0;                    /* number of interrupted units contained by a suite                                     */\r
394         \r
395         int total_of_tests = 0;                                                 /* total of the tests contained by this unit                                            */\r
396         int total_of_failed_tests = 0;                                  /* total of failed tests contained by this unit                                         */\r
397         int total_of_successeded_tests = 0;                     /* total of successeded tests contained by this unit                            */\r
398         int total_of_interrupted_tests = 0;                             /* total of interrupted tests contained by this unit                            */\r
399         \r
400         int total_of_units = 0;                                                 /* total of units contained by this unit                                                        */\r
401         int total_of_failed_units = 0;                                  /* total of failed units contained by this unit                                         */\r
402         int total_of_successeded_units = 0;                             /* total of successeded units contained by this unit                            */\r
403         int total_of_interrupted_units = 0;                             /* total of interrutped units contained by this unit                            */\r
404         \r
405         int total_of_suites = 0;                                                /* total of suites contained by this unit                                                       */\r
406         int total_of_failed_suites = 0;                                 /* total of failed suites contained by this unit                                        */\r
407         int total_of_successeded_suites = 0;                    /* total of successeded suites contained by this unit                           */ \r
408         int total_of_interrupted_suites = 0;                    /* total of interrupted suites contained by this unit                           */\r
409         \r
410         \r
411         /* check the parameter */\r
412         if(!(unit))\r
413     {\r
414         errno = EINVAL;\r
415         return -1;\r
416     }\r
417         \r
418         if(unit->description)\r
419                 strcpy(title, unit->description);\r
420         else\r
421                 sprintf(title, "file : %s",unit->fstream->name);\r
422                 \r
423         if(unit->interrupted)\r
424                 strcat(title, " (interrupted)");\r
425                 \r
426         print_title(title);\r
427         \r
428         number_of_tests = xbt_dynar_length(unit->commands);\r
429         \r
430         /* tests */\r
431         xbt_dynar_foreach(unit->commands, itc, command)\r
432         {\r
433                 if(command->status == cs_interrupted)\r
434                         number_of_interrupted_tests++;\r
435                 else if(command->status == cs_failed)\r
436                         number_of_failed_tests++;\r
437                 else if(command->status == cs_successeded)\r
438                         number_of_successeded_tests++;\r
439         }\r
440 \r
441         \r
442         if(number_of_tests)\r
443         {\r
444                 asprintf(&p," Test(s): .........................................................................");\r
445                         \r
446                 p[70] = '\0';\r
447                 printf("%s", p);\r
448                 free(p);        \r
449         \r
450                 if(number_of_failed_tests > 0) \r
451                         printf(".. failed\n");\r
452                 else if(number_of_interrupted_tests > 0) \r
453                         printf("interrupt\n");\r
454                 else \r
455                         printf(".... ..ok\n"); \r
456 \r
457                 xbt_dynar_foreach(unit->commands, itc, command)\r
458                 {\r
459                         printf("        %s: %s [%s]\n", \r
460                                 command->status == cs_interrupted ? "INTR  " \r
461                                 : command->status == cs_failed ? "FAILED" \r
462                                 : command->status == cs_successeded ? "PASS  " \r
463                                 : "UNKNWN",\r
464                                 command->context->command_line, \r
465                                 command->context->line);\r
466                                 \r
467                         if(detail_summary_flag)\r
468                                 command_summarize(command);\r
469                 }\r
470         \r
471                 printf(" =====================================================================%s\n",\r
472                 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");\r
473                 \r
474                 printf("    Summary: Test(s): %.0f%% ok (%d test(s): %d ok",\r
475                 ((1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0),\r
476                  number_of_tests, number_of_successeded_tests);\r
477                 \r
478                 if(number_of_failed_tests > 0)\r
479                         printf(", %d failed", number_of_failed_tests);\r
480                 \r
481                 if(number_of_interrupted_tests > 0)\r
482                         printf(", %d interrupted)", number_of_interrupted_tests);\r
483                         \r
484                  printf(")\n\n");\r
485                                 \r
486                 total_of_tests = number_of_tests;\r
487                 total_of_failed_tests = number_of_failed_tests;\r
488                 total_of_interrupted_tests = number_of_interrupted_tests;\r
489                 total_of_successeded_tests = number_of_successeded_tests;\r
490         }\r
491         \r
492         \r
493         \r
494         /* includes */\r
495         total_of_failed_units = total_of_interrupted_units = total_of_successeded_units = 0;\r
496         number_of_failed_units = number_of_successeded_units = number_of_interrupted_units = 0;\r
497         number_of_units = xbt_dynar_length(unit->includes);\r
498         \r
499         xbt_dynar_foreach(unit->includes, itu, include)\r
500         {\r
501                 \r
502                 number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;\r
503                 \r
504                 number_of_tests = xbt_dynar_length(include->commands);\r
505 \r
506                 xbt_dynar_foreach(include->commands, itc, command)\r
507                 {\r
508                         if(command->status == cs_interrupted)\r
509                                 number_of_interrupted_tests++;\r
510                         else if(command->status == cs_failed)\r
511                                 number_of_failed_tests++;\r
512                         else if(command->status == cs_successeded)\r
513                                 number_of_successeded_tests++;  \r
514                 }\r
515                 \r
516                 asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);\r
517                         \r
518                 p[70] = '\0';\r
519                 printf("%s", p);\r
520                 free(p);        \r
521                 \r
522                 if(number_of_failed_tests > 0) \r
523                 {\r
524                         total_of_failed_units++;\r
525                         printf(".. failed\n");\r
526                 }\r
527                 else if(number_of_interrupted_tests > 0) \r
528                 {\r
529                         total_of_interrupted_units++;\r
530                         printf("interrupt\n");\r
531                 }\r
532                 else \r
533                 {\r
534                         total_of_successeded_units++;\r
535                         printf(".... ..ok\n"); \r
536                 }\r
537                 \r
538                 if(detail_summary_flag)\r
539                 {               \r
540 \r
541                         xbt_dynar_foreach(include->commands, itc, command)\r
542                         {\r
543                                 printf("        %s: %s [%s]\n", \r
544                                 command->status == cs_interrupted ? "INTR  " \r
545                                 : command->status == cs_failed ? "FAILED" \r
546                                 : command->status == cs_successeded ? "PASS  " \r
547                                 : "UNKNWN",\r
548                                 command->context->command_line, \r
549                                 command->context->line);\r
550                                 \r
551                                 command_summarize(command);\r
552                         }\r
553                         \r
554                                         \r
555                 }\r
556                 \r
557                 printf(" =====================================================================%s\n",\r
558                 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");\r
559         \r
560                 \r
561                 printf("    Summary: Test(s): %.0f%% ok (%d test(s): %d ok",\r
562                 (number_of_tests ? (1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0 : 100.0),\r
563                  number_of_tests, number_of_successeded_tests);\r
564                 \r
565                 if(number_of_failed_tests > 0)\r
566                         printf(", %d failed", number_of_failed_tests);\r
567                 \r
568                 if(number_of_interrupted_tests > 0)\r
569                         printf(", %d interrupted)", number_of_interrupted_tests);\r
570                         \r
571                  printf(")\n\n");       \r
572                  \r
573                 \r
574                 total_of_tests += number_of_tests;\r
575                 total_of_failed_tests += number_of_failed_tests;\r
576                 total_of_interrupted_tests += number_of_interrupted_tests;\r
577                 total_of_successeded_tests += number_of_successeded_tests;\r
578         }\r
579         \r
580         /* suites */\r
581         total_of_units = number_of_units;\r
582         \r
583         total_of_failed_suites = total_of_successeded_suites = total_of_interrupted_suites = 0;\r
584         \r
585         total_of_suites = xbt_dynar_length(unit->suites);\r
586 \r
587         xbt_dynar_foreach(unit->suites, its, suite)\r
588         {\r
589                 print_title(suite->description);\r
590                 \r
591                 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
592                 \r
593                 number_of_interrupted_units = number_of_failed_units = number_of_successeded_units = 0;\r
594                 \r
595                 number_of_units = xbt_dynar_length(suite->includes);\r
596                 \r
597                 xbt_dynar_foreach(suite->includes, itu, include)\r
598                 {\r
599                         number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;\r
600                         \r
601                         number_of_tests = xbt_dynar_length(include->commands);\r
602                         \r
603                         \r
604                         xbt_dynar_foreach(include->commands, itc, command)\r
605                         {\r
606                                 if(command->status == cs_interrupted)\r
607                                         number_of_interrupted_tests++;\r
608                                 else if(command->status == cs_failed)\r
609                                         number_of_failed_tests++;\r
610                                 else if(command->status == cs_successeded)\r
611                                         number_of_successeded_tests++;\r
612                         }\r
613                         \r
614                         asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);\r
615                         \r
616                         p[70] = '\0';\r
617                         printf("%s", p);\r
618                         free(p);        \r
619                 \r
620                         if(number_of_failed_tests > 0) \r
621                         {\r
622                                 number_of_failed_units++;\r
623                                 printf(".. failed\n");\r
624                         }\r
625                         else if(number_of_interrupted_tests > 0) \r
626                         {\r
627                                 number_of_interrupted_units++;\r
628                                 printf("interrupt\n");\r
629                         }\r
630                         else \r
631                         {\r
632                                 number_of_successeded_units++;\r
633                                 printf(".... ..ok\n"); \r
634                         } \r
635                         \r
636                         number_of_interrupted_tests_of_suite += number_of_interrupted_tests;\r
637                         number_of_failed_tests_of_suite += number_of_failed_tests;\r
638                         number_of_successeded_tests_of_suite += number_of_successeded_tests;\r
639                         \r
640                         number_of_tests_of_suite += number_of_tests;\r
641                         \r
642                         total_of_tests += number_of_tests;\r
643                         total_of_failed_tests += number_of_failed_tests;\r
644                         total_of_interrupted_tests += number_of_interrupted_tests;\r
645                         total_of_successeded_tests += number_of_successeded_tests;\r
646                         \r
647                         if(detail_summary_flag)\r
648                         {\r
649 \r
650                                 xbt_dynar_foreach(include->commands, itc, command)\r
651                                 {\r
652                                         printf("        %s: %s [%s]\n", \r
653                                         command->status == cs_interrupted ? "INTR  " \r
654                                         : command->status == cs_failed ? "FAILED" \r
655                                         : command->status == cs_successeded ? "PASS  " \r
656                                         : "UNKNWN",\r
657                                         command->context->command_line, \r
658                                         command->context->line);\r
659                                         \r
660                                         command_summarize(command);\r
661                                 }\r
662                                 \r
663                                 \r
664                         }\r
665                                 \r
666                 }\r
667                 \r
668                 printf(" =====================================================================%s\n",\r
669                 number_of_failed_tests_of_suite ? "== FAILED": number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");\r
670                 \r
671                 if(number_of_failed_tests_of_suite > 0)\r
672                         total_of_failed_suites++;\r
673                 else if(number_of_interrupted_tests_of_suite)\r
674                         total_of_interrupted_suites++;\r
675                 else\r
676                         total_of_successeded_suites++;\r
677                         \r
678                 total_of_failed_units += number_of_failed_units;\r
679                 total_of_interrupted_units += number_of_interrupted_units;\r
680                 total_of_successeded_units += number_of_successeded_units;\r
681                         \r
682                 total_of_units += number_of_units;\r
683                 \r
684                 printf("    Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok",\r
685                 (number_of_units ? (1-((double)number_of_failed_units + (double)number_of_interrupted_units)/(double)number_of_units)*100.0 : 100.0),\r
686                  number_of_units, number_of_successeded_units);\r
687                  \r
688                 if(number_of_failed_units > 0)\r
689                         printf(", %d failed", number_of_failed_units);\r
690                 \r
691                 if(number_of_interrupted_units > 0)\r
692                         printf(", %d interrupted)", number_of_interrupted_units);\r
693                         \r
694                 printf(")\n");  \r
695                 \r
696                 printf("             Test(s): %.0f%% ok (%d test(s): %d ok",\r
697                 (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
698                 number_of_tests_of_suite, number_of_successeded_tests_of_suite);\r
699                  \r
700                 if(number_of_failed_tests_of_suite > 0)\r
701                         printf(", %d failed", number_of_failed_tests_of_suite);\r
702                 \r
703                 if(number_of_interrupted_tests_of_suite > 0)\r
704                         printf(", %d interrupted)", number_of_interrupted_tests_of_suite);\r
705                         \r
706                  printf(")\n\n");       \r
707         }\r
708         \r
709         printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",\r
710                 (total_of_suites ? (1-((double)total_of_failed_suites + (double)total_of_interrupted_suites)/(double)total_of_suites)*100.0 : 100.0),\r
711                  total_of_suites, total_of_successeded_suites);\r
712         \r
713         if(total_of_failed_suites > 0)\r
714                         printf(", %d failed", total_of_failed_suites);\r
715                 \r
716         if(total_of_interrupted_suites > 0)\r
717                 printf(", %d interrupted)", total_of_interrupted_suites);\r
718                 \r
719         printf(")\n");  \r
720         \r
721         printf("         Unit(s):  %.0f%% ok (%d unit(s): %d ok",\r
722                 (total_of_units ? (1-((double)total_of_failed_units + (double)total_of_interrupted_units)/(double)total_of_units)*100.0 : 100.0),\r
723                  total_of_units, total_of_successeded_units);\r
724         \r
725         if(total_of_failed_units > 0)\r
726                         printf(", %d failed", total_of_failed_units);\r
727                 \r
728         if(total_of_interrupted_units > 0)\r
729                 printf(", %d interrupted)", total_of_interrupted_units);\r
730                 \r
731         printf(")\n");\r
732         \r
733         printf("         Test(s):  %.0f%% ok (%d test(s): %d ok",\r
734                 (total_of_tests ? (1-((double)total_of_failed_tests + (double)total_of_interrupted_tests)/(double)total_of_tests)*100.0 : 100.0),\r
735                  total_of_tests, total_of_successeded_tests); \r
736                  \r
737         if(total_of_failed_tests > 0)\r
738                         printf(", %d failed", total_of_failed_tests);\r
739                 \r
740         if(total_of_interrupted_tests > 0)\r
741                 printf(", %d interrupted)", total_of_interrupted_tests);\r
742                 \r
743         printf(")\n\n");\r
744         \r
745         if(unit->interrupted)\r
746                 unit->runner->total_of_interrupted_units++;\r
747         else if(total_of_failed_tests > 0)\r
748                 unit->runner->total_of_failed_units++;\r
749         else\r
750                 unit->runner->total_of_successeded_units++;\r
751         \r
752         unit->runner->total_of_tests += total_of_tests;\r
753         unit->runner->total_of_failed_tests += total_of_failed_tests;\r
754         unit->runner->total_of_successeded_tests += total_of_successeded_tests;\r
755         unit->runner->total_of_interrupted_tests += total_of_interrupted_tests;\r
756         \r
757         unit->runner->total_of_units += total_of_units + 1;\r
758         unit->runner->total_of_successeded_units += total_of_successeded_units;\r
759         unit->runner->total_of_failed_units += total_of_failed_units;\r
760         unit->runner->total_of_interrupted_units += total_of_interrupted_units;\r
761         \r
762         unit->runner->total_of_suites += total_of_suites;\r
763         unit->runner->total_of_successeded_suites += total_of_successeded_suites;\r
764         unit->runner->total_of_failed_suites += total_of_failed_suites;\r
765         unit->runner->total_of_interrupted_suites += total_of_interrupted_suites;\r
766         \r
767         return 0;\r
768 }\r
769 \r
770 int\r
771 unit_reset(unit_t unit)\r
772 {\r
773         fseek(unit->fstream->stream,0L, SEEK_SET);\r
774         unit->parsed = 0;\r
775         unit->cmd_nb = 0;\r
776         \r
777         return 0;\r
778 }\r