2 * src/unit.c - type representing the tesh unit concept.
\r
4 * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved.
\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
10 * This file contains all the definitions of the functions related with
\r
11 * the tesh unit concept.
\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
25 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
\r
27 /*! \brief unit_start - start the processing of the tesh file representing by the unit
\r
29 * \param p A void pointer to the unit representing the tesh file to process.
\r
31 * \return This function (thread routine always returns NULL)
\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
52 unit_start(void* p)
\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
61 unit_t root = (unit_t)p;
\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
68 /* must acquire the jobs semaphore to start */
\r
69 xbt_os_sem_acquire(jobs_sem);
\r
71 /* initialize the mutex used to synchronize the access to the properties of this unit */
\r
72 mutex = xbt_os_mutex_init();
\r
75 INFO1("Test unit from %s",root->fstream->name);
\r
77 INFO1("Checking unit %s...",root->fstream->name);
\r
79 /* launch the parsing of the unit */
\r
80 fstream_parse(root->fstream, mutex);
\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
85 if(!root->interrupted)
\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
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
96 /* wait the end of all the commands or a command failure or an interruption */
\r
98 xbt_os_sem_acquire(root->sem);
\r
101 if(root->interrupted)
\r
104 xbt_dynar_foreach(root->commands, itc , command)
\r
106 if(command->status == cs_in_progress)
\r
107 command_interrupt(command);
\r
110 /* interrupt all the running commands of the included units */
\r
111 include_nb = xbt_dynar_length(root->includes);
\r
113 xbt_dynar_foreach(root->includes, itu, include)
\r
115 xbt_dynar_foreach(include->commands, itc, command)
\r
117 if(command->status == cs_in_progress)
\r
118 command_interrupt(command);
\r
122 /* interrupt all the running commands of the unit */
\r
123 suite_nb = xbt_dynar_length(root->suites);
\r
125 xbt_dynar_foreach(root->suites, its, suite)
\r
127 include_nb = xbt_dynar_length(suite->includes);
\r
129 xbt_dynar_foreach(suite->includes, itu, include)
\r
131 xbt_dynar_foreach(include->commands, itc, command)
\r
133 if(command->status == cs_in_progress)
\r
134 command_interrupt(command);
\r
140 /* wait the end of the command threads of the unit */
\r
141 xbt_dynar_foreach(root->commands, itc, command)
\r
143 thread = command->thread;
\r
146 xbt_os_thread_join(thread,NULL);
\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
152 xbt_dynar_foreach(root->includes, itu, include)
\r
154 xbt_dynar_foreach(include->commands, itc, command)
\r
156 thread = command->thread;
\r
159 xbt_os_thread_join(thread,NULL);
\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 ERROR4("Include `(%s)' NOK : (<%s> %s (%d))", include->fstream->name, command->context->line, error_to_string(include->exit_code, include->err_kind), include->exit_code);
\r
168 else if(include->interrupted && !include->exit_code)
\r
169 INFO1("Include `(%s)' INTR",include->fstream->name);
\r
173 /* interrupt all the running commands of the unit */
\r
174 suite_nb = xbt_dynar_length(root->suites);
\r
176 xbt_dynar_foreach(root->suites, its, suite)
\r
178 include_nb = xbt_dynar_length(suite->includes);
\r
182 if(!suite->exit_code)
\r
184 unit_set_error(suite, ESYNTAX, 1);
\r
185 ERROR2("[%s] Empty suite `(%s)' detected (no includes added)", suite->filepos, suite->description);
\r
187 /* if the --keep-going option is not specified */
\r
188 if(!keep_going_flag)
\r
192 /* request an global interruption by the runner */
\r
195 /* release the runner */
\r
196 xbt_os_sem_release(units_sem);
\r
202 xbt_dynar_foreach(suite->includes, itu, include)
\r
204 xbt_dynar_foreach(include->commands, itc, command)
\r
206 thread = command->thread;
\r
209 xbt_os_thread_join(thread,NULL);
\r
212 if(!include->exit_code && !include->interrupted)
\r
215 INFO1("Include from %s OK",include->fstream->name);
\r
217 else if(include->exit_code)
\r
220 ERROR3("Include `(%s)' NOK : (<%s> %s)", include->fstream->name, command->context->pos, error_to_string(include->exit_code, include->err_kind));
\r
222 suite->exit_code = include->exit_code;
\r
223 suite->err_kind = include->err_kind;
\r
225 else if(include->interrupted && !include->exit_code)
\r
228 INFO1("Include `(%s)' INTR",include->fstream->name);
\r
230 suite->interrupted = 1;
\r
237 if(!suite->exit_code && !suite->interrupted)
\r
238 INFO1("Test suite from %s OK",suite->description);
\r
239 else if(suite->exit_code)
\r
240 ERROR3("Test suite `(%s)' NOK : (<%s> %s) ", suite->description, suite->filepos, error_to_string(suite->exit_code, suite->err_kind));
\r
241 else if(suite->interrupted && !suite->exit_code)
\r
242 INFO1("Test suite `(%s)' INTR",suite->description);
\r
246 /* you can now destroy the mutex used to synchrone the command accesses to the properties of the unit */
\r
247 xbt_os_mutex_destroy(mutex);
\r
249 /* update the number of ended units of the runner */
\r
250 xbt_os_mutex_acquire(root->mutex);
\r
252 /* increment the number of ended units */
\r
253 root->runner->number_of_ended_units++;
\r
257 if(root->interrupted && !root->exit_code)
\r
258 INFO1("Test unit from %s INTR",root->fstream->name);
\r
259 else if(!root->exit_code)
\r
260 INFO1("Test unit from %s OK",root->fstream->name);
\r
261 else if(root->exit_code)
\r
262 ERROR2("Test unit `(%s)' : NOK (%s)",root->fstream->name, error_to_string(root->exit_code, root->err_kind));
\r
265 /* if it's the last unit, release the runner */
\r
266 if((root->runner->number_of_runned_units == root->runner->number_of_ended_units))
\r
268 /* if all the commands of the unit are successeded itc's a successeded unit */
\r
269 if(root->successeded_cmd_nb == root->cmd_nb && !root->exit_code /* case of only one cd : nb = successeded = 0)*/)
\r
270 root->successeded = 1;
\r
272 /* first release the mutex */
\r
273 xbt_os_mutex_release(root->mutex);
\r
275 /* release the runner */
\r
276 xbt_os_sem_release(units_sem);
\r
279 xbt_os_mutex_release(root->mutex);
\r
281 /* release the jobs semaphore, then the next waiting unit can start */
\r
282 xbt_os_sem_release(jobs_sem);
\r
290 unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream)
\r
294 unit = xbt_new0(s_unit_t, 1);
\r
296 /* instantiate the vector used to store all the commands of the unit */
\r
297 unit->commands = xbt_dynar_new(sizeof(command_t), (void_f_pvoid_t)command_free);
\r
299 /* instantiate the vector used to store all the included units */
\r
300 unit->includes = xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t)unit_free);
\r
302 /* instantiate the vector used to store all the included suites */
\r
303 unit->suites = xbt_dynar_new(sizeof(unit_t), (void_f_pvoid_t)unit_free);
\r
305 /* the runner used to launch the tesh unit */
\r
306 unit->runner = runner;
\r
308 /* the file stream object to use to parse the tesh file */
\r
309 unit->fstream = fstream;
\r
312 fstream->unit = unit;
\r
314 /* if no root parameter specified assume that itc's the root of all the units */
\r
315 unit->root = root ? root : unit;
\r
317 /* the owner of the suite */
\r
318 unit->owner = owner;
\r
320 unit->thread = NULL;
\r
321 unit->started_cmd_nb = 0;
\r
322 unit->interrupted_cmd_nb = 0;
\r
323 unit->failed_cmd_nb = 0;
\r
324 unit->successeded_cmd_nb = 0;
\r
325 unit->terminated_cmd_nb = 0;
\r
326 unit->waiting_cmd_nb = 0;
\r
327 unit->interrupted = 0;
\r
329 unit->successeded = 0;
\r
331 unit->released = 0;
\r
332 unit->owner = owner;
\r
333 unit->is_running_suite = 0;
\r
334 unit->description = NULL;
\r
336 unit->exit_code = 0;
\r
337 unit->err_kind = 0;
\r
338 unit->filepos = NULL;
\r
346 unit_set_error(unit_t unit, int errcode, int kind)
\r
348 if(!unit->exit_code)
\r
350 unit->exit_code = errcode;
\r
351 unit->err_kind = kind;
\r
353 if(unit->root && !unit->root->exit_code)
\r
355 unit->root->exit_code = errcode;
\r
356 unit->root->err_kind = kind;
\r
362 exit_code = errcode;
\r
370 unit_free(unit_t* ptr)
\r
378 if((*ptr)->commands)
\r
379 xbt_dynar_free(&((*ptr)->commands));
\r
381 if((*ptr)->includes)
\r
382 xbt_dynar_free(&((*ptr)->includes));
\r
385 xbt_dynar_free(&((*ptr)->suites));
\r
387 /* if the unit is interrupted during its run, the semaphore is NULL */
\r
389 xbt_os_sem_destroy((*ptr)->sem);
\r
391 if((*ptr)->description)
\r
392 free((*ptr)->description);
\r
394 if((*ptr)->filepos)
\r
395 free((*ptr)->filepos);
\r
404 unit_run(unit_t unit, xbt_os_mutex_t mutex)
\r
406 /* check the parameters */
\r
407 if(!(unit) || !mutex)
\r
415 unit->mutex = mutex;
\r
417 unit->sem = xbt_os_sem_init(0);
\r
419 /* start the unit */
\r
420 unit->thread = xbt_os_thread_create("", unit_start, unit);
\r
423 /* the unit is interrupted by the runner before its starting
\r
424 * in this case the unit semaphore is NULL take care of that
\r
425 * in the function unit_free()
\r
427 unit->interrupted = 1;
\r
434 unit_interrupt(unit_t unit)
\r
436 /* check the parameter */
\r
443 /* if the unit is already interrupted, signal the error */
\r
444 if(unit->interrupted)
\r
450 /* interrupt the run of the specified unit */
\r
451 unit->interrupted = 1;
\r
452 xbt_os_sem_release(unit->sem);
\r
457 /* just print the title of the root unit or a suite (if any) */
\r
459 print_title(const char* description)
\r
463 size_t len = strlen(description);
\r
467 for (i = 1; i < 79; i++)
\r
473 sprintf(title + 40 - (len + 4)/2, "[ %s ]",description);
\r
474 title[40 + (len + 5 ) / 2] = '=';
\r
476 printf("\n%s\n",title);
\r
480 unit_summuarize(unit_t unit)
\r
483 unsigned int itc, itu, its;
\r
487 char title[PATH_MAX + 1] = {0};
\r
489 int number_of_tests = 0; /* number of tests of a unit contained by this unit */
\r
490 int number_of_failed_tests = 0; /* number of failed test of a unit contained by this unit */
\r
491 int number_of_successeded_tests = 0; /* number of successeded tests of a unit contained by this unit */
\r
492 int number_of_interrupted_tests = 0; /* number of interrupted tests of a unit contained by this unit */
\r
494 int number_of_tests_of_suite = 0; /* number of tests of a suite contained by this unit */
\r
495 int number_of_interrupted_tests_of_suite = 0; /* number of interrupted tests of a suite contained by this unit */
\r
496 int number_of_failed_tests_of_suite = 0; /* number of failed tests of a suite contained by this unit */
\r
497 int number_of_successeded_tests_of_suite = 0; /* number of successeded tests of a suite contained by this */
\r
499 int number_of_units = 0; /* number of units contained by a suite */
\r
500 int number_of_failed_units = 0; /* number of failed units contained by a suite */
\r
501 int number_of_successeded_units = 0; /* number of successeded units contained by a suite */
\r
502 int number_of_interrupted_units = 0; /* number of interrupted units contained by a suite */
\r
504 int total_of_tests = 0; /* total of the tests contained by this unit */
\r
505 int total_of_failed_tests = 0; /* total of failed tests contained by this unit */
\r
506 int total_of_successeded_tests = 0; /* total of successeded tests contained by this unit */
\r
507 int total_of_interrupted_tests = 0; /* total of interrupted tests contained by this unit */
\r
509 int total_of_units = 0; /* total of units contained by this unit */
\r
510 int total_of_failed_units = 0; /* total of failed units contained by this unit */
\r
511 int total_of_successeded_units = 0; /* total of successeded units contained by this unit */
\r
512 int total_of_interrupted_units = 0; /* total of interrutped units contained by this unit */
\r
514 int total_of_suites = 0; /* total of suites contained by this unit */
\r
515 int total_of_failed_suites = 0; /* total of failed suites contained by this unit */
\r
516 int total_of_successeded_suites = 0; /* total of successeded suites contained by this unit */
\r
517 int total_of_interrupted_suites = 0; /* total of interrupted suites contained by this unit */
\r
519 /* check the parameter */
\r
526 if(unit->description)
\r
527 strcpy(title, unit->description);
\r
529 sprintf(title, "file : %s",unit->fstream->name);
\r
531 if(unit->interrupted)
\r
532 strcat(title, " (interrupted)");
\r
534 print_title(title);
\r
536 number_of_tests = xbt_dynar_length(unit->commands);
\r
539 xbt_dynar_foreach(unit->commands, itc, command)
\r
541 if(command->status == cs_interrupted)
\r
542 number_of_interrupted_tests++;
\r
543 else if(command->status == cs_failed)
\r
544 number_of_failed_tests++;
\r
545 else if(command->status == cs_successeded)
\r
546 number_of_successeded_tests++;
\r
550 if(number_of_tests)
\r
552 asprintf(&p," Test(s): .........................................................................");
\r
558 if(number_of_failed_tests > 0)
\r
559 printf(".. failed\n");
\r
560 else if(number_of_interrupted_tests > 0)
\r
561 printf("interrupt\n");
\r
563 printf(".... ..ok\n");
\r
565 xbt_dynar_foreach(unit->commands, itc, command)
\r
567 printf(" %s: %s [%s]\n",
\r
568 command->status == cs_interrupted ? "INTR "
\r
569 : command->status == cs_failed ? "FAILED"
\r
570 : command->status == cs_successeded ? "PASS "
\r
572 command->context->command_line,
\r
573 command->context->pos);
\r
575 if(detail_summary_flag)
\r
576 command_summarize(command);
\r
579 printf(" =====================================================================%s\n",
\r
580 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
\r
582 printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
\r
583 ((1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0),
\r
584 number_of_tests, number_of_successeded_tests);
\r
586 if(number_of_failed_tests > 0)
\r
587 printf(", %d failed", number_of_failed_tests);
\r
589 if(number_of_interrupted_tests > 0)
\r
590 printf(", %d interrupted)", number_of_interrupted_tests);
\r
594 total_of_tests = number_of_tests;
\r
595 total_of_failed_tests = number_of_failed_tests;
\r
596 total_of_interrupted_tests = number_of_interrupted_tests;
\r
597 total_of_successeded_tests = number_of_successeded_tests;
\r
603 total_of_failed_units = total_of_interrupted_units = total_of_successeded_units = 0;
\r
604 number_of_failed_units = number_of_successeded_units = number_of_interrupted_units = 0;
\r
605 number_of_units = xbt_dynar_length(unit->includes);
\r
607 xbt_dynar_foreach(unit->includes, itu, include)
\r
610 number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
\r
612 number_of_tests = xbt_dynar_length(include->commands);
\r
614 xbt_dynar_foreach(include->commands, itc, command)
\r
616 if(command->status == cs_interrupted)
\r
617 number_of_interrupted_tests++;
\r
618 else if(command->status == cs_failed)
\r
619 number_of_failed_tests++;
\r
620 else if(command->status == cs_successeded)
\r
621 number_of_successeded_tests++;
\r
624 asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
\r
630 if(number_of_failed_tests > 0)
\r
632 total_of_failed_units++;
\r
633 printf(".. failed\n");
\r
635 else if(number_of_interrupted_tests > 0)
\r
637 total_of_interrupted_units++;
\r
638 printf("interrupt\n");
\r
642 total_of_successeded_units++;
\r
643 printf(".... ..ok\n");
\r
646 if(detail_summary_flag)
\r
649 xbt_dynar_foreach(include->commands, itc, command)
\r
651 printf(" %s: %s [%s]\n",
\r
652 command->status == cs_interrupted ? "INTR "
\r
653 : command->status == cs_failed ? "FAILED"
\r
654 : command->status == cs_successeded ? "PASS "
\r
656 command->context->command_line,
\r
657 command->context->pos);
\r
659 command_summarize(command);
\r
665 printf(" =====================================================================%s\n",
\r
666 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
\r
669 printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
\r
670 (number_of_tests ? (1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0 : 100.0),
\r
671 number_of_tests, number_of_successeded_tests);
\r
673 if(number_of_failed_tests > 0)
\r
674 printf(", %d failed", number_of_failed_tests);
\r
676 if(number_of_interrupted_tests > 0)
\r
677 printf(", %d interrupted)", number_of_interrupted_tests);
\r
682 total_of_tests += number_of_tests;
\r
683 total_of_failed_tests += number_of_failed_tests;
\r
684 total_of_interrupted_tests += number_of_interrupted_tests;
\r
685 total_of_successeded_tests += number_of_successeded_tests;
\r
689 total_of_units = number_of_units;
\r
691 total_of_failed_suites = total_of_successeded_suites = total_of_interrupted_suites = 0;
\r
693 total_of_suites = xbt_dynar_length(unit->suites);
\r
695 xbt_dynar_foreach(unit->suites, its, suite)
\r
697 print_title(suite->description);
\r
699 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
701 number_of_interrupted_units = number_of_failed_units = number_of_successeded_units = 0;
\r
703 number_of_units = xbt_dynar_length(suite->includes);
\r
705 xbt_dynar_foreach(suite->includes, itu, include)
\r
707 number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
\r
709 number_of_tests = xbt_dynar_length(include->commands);
\r
712 xbt_dynar_foreach(include->commands, itc, command)
\r
714 if(command->status == cs_interrupted)
\r
715 number_of_interrupted_tests++;
\r
716 else if(command->status == cs_failed)
\r
717 number_of_failed_tests++;
\r
718 else if(command->status == cs_successeded)
\r
719 number_of_successeded_tests++;
\r
722 asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
\r
728 if(number_of_failed_tests > 0)
\r
730 number_of_failed_units++;
\r
731 printf(".. failed\n");
\r
733 else if(number_of_interrupted_tests > 0)
\r
735 number_of_interrupted_units++;
\r
736 printf("interrupt\n");
\r
740 number_of_successeded_units++;
\r
741 printf(".... ..ok\n");
\r
744 number_of_interrupted_tests_of_suite += number_of_interrupted_tests;
\r
745 number_of_failed_tests_of_suite += number_of_failed_tests;
\r
746 number_of_successeded_tests_of_suite += number_of_successeded_tests;
\r
748 number_of_tests_of_suite += number_of_tests;
\r
750 total_of_tests += number_of_tests;
\r
751 total_of_failed_tests += number_of_failed_tests;
\r
752 total_of_interrupted_tests += number_of_interrupted_tests;
\r
753 total_of_successeded_tests += number_of_successeded_tests;
\r
755 if(detail_summary_flag)
\r
758 xbt_dynar_foreach(include->commands, itc, command)
\r
760 printf(" %s: %s [%s]\n",
\r
761 command->status == cs_interrupted ? "INTR "
\r
762 : command->status == cs_failed ? "FAILED"
\r
763 : command->status == cs_successeded ? "PASS "
\r
765 command->context->command_line,
\r
766 command->context->pos);
\r
768 command_summarize(command);
\r
776 printf(" =====================================================================%s\n",
\r
777 number_of_failed_tests_of_suite ? "== FAILED": number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");
\r
779 if(number_of_failed_tests_of_suite > 0)
\r
780 total_of_failed_suites++;
\r
781 else if(number_of_interrupted_tests_of_suite)
\r
782 total_of_interrupted_suites++;
\r
784 total_of_successeded_suites++;
\r
786 total_of_failed_units += number_of_failed_units;
\r
787 total_of_interrupted_units += number_of_interrupted_units;
\r
788 total_of_successeded_units += number_of_successeded_units;
\r
790 total_of_units += number_of_units;
\r
792 printf(" Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok",
\r
793 (number_of_units ? (1-((double)number_of_failed_units + (double)number_of_interrupted_units)/(double)number_of_units)*100.0 : 100.0),
\r
794 number_of_units, number_of_successeded_units);
\r
796 if(number_of_failed_units > 0)
\r
797 printf(", %d failed", number_of_failed_units);
\r
799 if(number_of_interrupted_units > 0)
\r
800 printf(", %d interrupted)", number_of_interrupted_units);
\r
804 printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
\r
805 (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
806 number_of_tests_of_suite, number_of_successeded_tests_of_suite);
\r
808 if(number_of_failed_tests_of_suite > 0)
\r
809 printf(", %d failed", number_of_failed_tests_of_suite);
\r
811 if(number_of_interrupted_tests_of_suite > 0)
\r
812 printf(", %d interrupted)", number_of_interrupted_tests_of_suite);
\r
817 printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
\r
818 (total_of_suites ? (1-((double)total_of_failed_suites + (double)total_of_interrupted_suites)/(double)total_of_suites)*100.0 : 100.0),
\r
819 total_of_suites, total_of_successeded_suites);
\r
821 if(total_of_failed_suites > 0)
\r
822 printf(", %d failed", total_of_failed_suites);
\r
824 if(total_of_interrupted_suites > 0)
\r
825 printf(", %d interrupted)", total_of_interrupted_suites);
\r
829 printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",
\r
830 (total_of_units ? (1-((double)total_of_failed_units + (double)total_of_interrupted_units)/(double)total_of_units)*100.0 : 100.0),
\r
831 total_of_units, total_of_successeded_units);
\r
833 if(total_of_failed_units > 0)
\r
834 printf(", %d failed", total_of_failed_units);
\r
836 if(total_of_interrupted_units > 0)
\r
837 printf(", %d interrupted)", total_of_interrupted_units);
\r
841 printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
\r
842 (total_of_tests ? (1-((double)total_of_failed_tests + (double)total_of_interrupted_tests)/(double)total_of_tests)*100.0 : 100.0),
\r
843 total_of_tests, total_of_successeded_tests);
\r
845 if(total_of_failed_tests > 0)
\r
846 printf(", %d failed", total_of_failed_tests);
\r
848 if(total_of_interrupted_tests > 0)
\r
849 printf(", %d interrupted)", total_of_interrupted_tests);
\r
853 if(unit->interrupted)
\r
854 unit->runner->total_of_interrupted_units++;
\r
855 else if(total_of_failed_tests > 0)
\r
856 unit->runner->total_of_failed_units++;
\r
858 unit->runner->total_of_successeded_units++;
\r
860 unit->runner->total_of_tests += total_of_tests;
\r
861 unit->runner->total_of_failed_tests += total_of_failed_tests;
\r
862 unit->runner->total_of_successeded_tests += total_of_successeded_tests;
\r
863 unit->runner->total_of_interrupted_tests += total_of_interrupted_tests;
\r
865 unit->runner->total_of_units += total_of_units + 1;
\r
866 unit->runner->total_of_successeded_units += total_of_successeded_units;
\r
867 unit->runner->total_of_failed_units += total_of_failed_units;
\r
868 unit->runner->total_of_interrupted_units += total_of_interrupted_units;
\r
870 unit->runner->total_of_suites += total_of_suites;
\r
871 unit->runner->total_of_successeded_suites += total_of_successeded_suites;
\r
872 unit->runner->total_of_failed_suites += total_of_failed_suites;
\r
873 unit->runner->total_of_interrupted_suites += total_of_interrupted_suites;
\r
879 unit_reset(unit_t unit)
\r
884 /* reset all the suites of the unit */
\r
885 xbt_dynar_foreach(unit->suites, i, cur)
\r
891 /* reset all the includes of the unit */
\r
892 xbt_dynar_foreach(unit->includes, i, cur)
\r
897 fseek(unit->fstream->stream,0L, SEEK_SET);
\r
900 unit->started_cmd_nb = 0;
\r
901 unit->interrupted_cmd_nb = 0;
\r
902 unit->failed_cmd_nb = 0;
\r
903 unit->successeded_cmd_nb = 0;
\r
904 unit->terminated_cmd_nb = 0;
\r
905 unit->waiting_cmd_nb = 0;
\r
906 unit->interrupted = 0;
\r
908 unit->successeded = 0;
\r
910 unit->released = 0;
\r
911 unit->is_running_suite = 0;
\r
913 if(unit->description)
\r
915 free(unit->description);
\r
916 unit->description = NULL;
\r
919 unit->exit_code = 0;
\r