7 #include <str_replace.h>
9 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
12 replace_variables(unit_t unit, char** line)
15 char name[MAX_PATH + 1] = {0};
17 /* check if some commands have setted some environment variables */
20 /*printf("repalce all the variables of the line %s\n", *line);*/
23 xbt_os_mutex_acquire(unit->mutex);
25 vector_rewind(unit->runner->variables);
27 while((variable = vector_get(unit->runner->variables)))
29 sprintf(name, "$%s", variable->name);
30 /*printf("try to replace all the variable %s\n",name);*/
31 str_replace_all(line, name, variable->val);
33 vector_move_next(unit->runner->variables);
34 memset(name, 0, MAX_PATH + 1);
37 xbt_os_mutex_release(unit->mutex);
39 /*printf("line after the variables replacement %s\n",*line);*/
43 /* the unit thread start routine */
48 unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream)
50 unit_t unit = xbt_new0(s_unit_t, 1);
52 /* set the owner of the unit */
53 unit->runner = runner;
55 unit->fstream = fstream;
59 unit->commands = vector_new(DEFAULT_COMMANDS_CAPACITY, (fn_finalize_t)command_free);
60 unit->includes = vector_new(DEFAULT_INCLUDES, (fn_finalize_t)unit_free);
64 unit->number_of_started_commands = 0;
65 unit->number_of_interrupted_commands = 0;
66 unit->number_of_failed_commands = 0;
67 unit->number_of_successeded_commands = 0;
68 unit->number_of_terminated_commands = 0;
69 unit->number_of_waiting_commands = 0;
70 unit->interrupted = 0;
72 unit->successeded = 0;
75 unit->parsing_include_file = 0;
80 unit->root = root ? root : unit;
84 unit->suites = vector_new(DEFAULT_SUITES_CAPACITY, (fn_finalize_t)unit_free);
87 unit->running_suite = 0;
89 unit->description = NULL;
96 unit_add_suite(unit_t unit, suite_t suite)
98 vector_push_back(unit->suites, suite);
102 unit_free(void** unitptr)
104 unit_t* __unitptr = (unit_t*)unitptr;
106 vector_free(&((*__unitptr)->commands));
108 vector_free(&((*__unitptr)->includes));
110 vector_free(&((*__unitptr)->suites));
112 /* if the unit is interrupted during its run, the semaphore is NULL */
113 if((*__unitptr)->sem)
114 xbt_os_sem_destroy((*__unitptr)->sem);
116 if((*__unitptr)->description)
117 free((*__unitptr)->description);
119 free((*__unitptr)->suites);
132 xbt_os_thread_t thread;
133 xbt_os_mutex_t mutex;
134 /*context_t context;*/
137 unit_t unit = (unit_t)p;
140 xbt_os_mutex_acquire(unit->mutex);
141 unit->runner->number_of_runned_units++;
142 xbt_os_mutex_release(unit->mutex);
144 /* try to acquire the jobs semaphore to start */
145 xbt_os_sem_acquire(jobs_sem);
147 mutex = xbt_os_mutex_init();
148 /*context = context_new();*/
151 INFO1("checking unit %s...",unit->fstream->name);
154 /*unit_parse(unit, context, mutex, unit->fstream->name, unit->fstream->stream);*/
156 fstream_parse(unit->fstream, unit, mutex);
159 /* if the unit is not interrupted and not failed the unit, all the file is parsed
160 * so all the command are launched
164 if(!unit->interrupted)
168 /* all the commands have terminate before the end of the parsing of the tesh file
169 * so the unit release the semaphore itself
171 if(!unit->released && (unit->number_of_started_commands == (unit->number_of_failed_commands + unit->number_of_interrupted_commands + unit->number_of_successeded_commands)))
173 /*INFO1("the unit %s is released", unit->fstream->name);*/
174 xbt_os_sem_release(unit->sem);
179 INFO1("the unit %s is not released", unit->fstream->name);
180 INFO1("number of started commands %d", unit->number_of_started_commands);
181 INFO1("number of failed commands %d", unit->number_of_failed_commands);
182 INFO1("number of interrupted commands %d", unit->number_of_interrupted_commands);
183 INFO1("number of successeded commands %d", unit->number_of_successeded_commands);
184 INFO1("number of waiting commands %d", unit->number_of_waiting_commands);
187 if(unit->number_of_waiting_commands)
192 for(i = 0; i < vector_get_size(unit->includes) ; i++)
194 include = vector_get_at(unit->includes, i);
196 for(j = 0; j < vector_get_size(include->commands); j++)
198 command = vector_get_at(include->commands, j);
200 if(command->status == cs_in_progress)
202 INFO2("the command %s PID %d is in process", command->context->command_line, command->pid);
204 if(command->writer->done)
205 INFO2("the writer of the command %s PID %d done", command->context->command_line, command->pid);
207 INFO2("the writer of the command %s PID %d doesn't done", command->context->command_line, command->pid);
217 /* wait the end of all the commands or a command failure or an interruption */
218 xbt_os_sem_acquire(unit->sem);
221 if(unit->interrupted)
225 /* interrupt all the running commands of the unit */
226 for(i = 0; i < vector_get_size(unit->commands); i++)
228 command = vector_get_at(unit->commands, i);
230 if(command->status == cs_in_progress)
231 command_interrupt(command);
234 for(i = 0; i < vector_get_size(unit->includes); i++)
236 include = vector_get_at(unit->includes, i);
238 for(j = 0; j < vector_get_size(include->commands); j++)
240 command = vector_get_at(include->commands, j);
242 if(command->status == cs_in_progress)
243 command_interrupt(command);
249 /* wait the end of the threads */
250 for(i = 0; i < vector_get_size(unit->commands); i++)
252 command_t command = vector_get_at(unit->commands, i);
253 thread = command->thread;
256 xbt_os_thread_join(thread,NULL);
259 for(i = 0; i < vector_get_size(unit->includes); i++)
261 include = vector_get_at(unit->includes, i);
263 for(j = 0; j < vector_get_size(include->commands); j++)
265 command_t command = vector_get_at(include->commands, j);
266 thread = command->thread;
269 xbt_os_thread_join(thread,NULL);
273 /*context_free(&context);*/
275 xbt_os_mutex_destroy(mutex);
278 xbt_os_mutex_acquire(unit->mutex);
280 /* increment the number of ended units */
281 unit->runner->number_of_ended_units++;
283 /* it's the last unit, release the runner */
284 if(/*!unit->interrupted &&*/ (unit->runner->number_of_runned_units == unit->runner->number_of_ended_units))
286 if(unit->number_of_successeded_commands == unit->number_of_commands)
287 unit->successeded = 1;
289 /* first release the mutex */
290 xbt_os_mutex_release(unit->mutex);
292 xbt_os_sem_release(units_sem);
295 xbt_os_mutex_release(unit->mutex);
297 /* release the jobs semaphore, then the next unit can start */
298 xbt_os_sem_release(jobs_sem);
305 unit_parse(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, FILE* stream)
314 /* Count the line length while checking wheather it's blank */
317 /* Deal with \ at the end of the line, and call handle_line on result */
320 buff=xbt_strbuff_new();
322 while(!unit->interrupted && getline(&line, &len, stream) != -1)
330 while(line[linelen] != '\0')
332 if (line[linelen] != ' ' && line[linelen] != '\t' && line[linelen]!='\n' && line[linelen]!='\r')
340 if(!context->command_line && (context->input->used || context->output->used))
342 ERROR1("[%d] Error: no command found in this chunk of lines.",buffbegin);
344 if(unit->parsing_include_file)
345 ERROR1("Unit `%s': NOK (syntax error)", unit->fstream->name);
347 ERROR2("Unit `%s' inclued in `%s' : NOK (syntax error)", file_name, unit->fstream->name);
350 unit_handle_failure(unit);
353 else if(unit->running_suite)
359 if(context->command_line)
363 command_t command = command_new(unit, context, mutex);
364 command_run(command);
367 context_reset(context);
375 if(linelen>1 && line[linelen-2]=='\\')
377 if (linelen>2 && line[linelen-3] == '\\')
379 /* Damn. Escaped \ */
380 line[linelen-2] = '\n';
381 line[linelen-1] = '\0';
386 line[linelen-2] = '\0';
390 buffbegin = line_num;
394 if(buff->used || to_be_continued)
396 xbt_strbuff_append(buff,line);
398 if (!to_be_continued)
400 snprintf(file_pos,256,"%s:%d",file_name,buffbegin);
401 unit_handle_line(unit, context, mutex, file_pos, buff->data);
402 xbt_strbuff_empty(buff);
407 snprintf(file_pos,256,"%s:%d",file_name,line_num);
408 unit_handle_line(unit, context, mutex, file_pos, line);
412 /* Check that last command of the file ran well */
413 if(context->command_line)
417 command_t command = command_new(unit, context, mutex);
418 command_run(command);
421 context_reset(context);
428 xbt_strbuff_free(buff);
434 unit_handle_line(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char * filepos, char *line)
438 xbt_str_rtrim(line+2,"\n");
440 line2 = strdup(line);
442 replace_variables(unit, &line2);
452 context->async = (line2[0] == '&');
454 /* further trim useless chars which are significant for in/output */
455 xbt_str_rtrim(line2+2," \t");
457 /* Deal with CD commands here, not in rctx */
458 if(!strncmp("cd ",line2 + 2, 3))
460 /*char *dir=line2+4; */
461 char* dir = strdup(line2 + 4);
463 if(context->command_line)
467 command_t command = command_new(unit, context, mutex);
468 command_run(command);
471 context_reset(context);
474 /* search begining */
475 while (*(dir++) == ' ');
479 VERB1("Saw cd '%s'",dir);
487 ERROR2("Chdir to %s failed: %s",dir,strerror(errno));
488 ERROR1("Test suite `%s': NOK (system error)", unit->fstream->name);
490 unit_handle_failure(unit);
497 } /* else, pushline */
500 unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
507 unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
512 INFO2("[%s] %s",filepos,line2+2);
517 CRITICAL2("[%s] %s",filepos,line2+2);
521 if(unit->description)
522 WARN2("description already specified %s %s", filepos, line2);
524 unit->description = strdup(line2 + 2);
528 ERROR2("[%s] Syntax error: %s",filepos, line2);
529 ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
531 unit_handle_failure(unit);
539 unit_pushline(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* filepos, char kind, char *line)
546 if(context->command_line)
550 if(context->output->used || context->input->used)
552 ERROR2("[%s] More than one command in this chunk of lines (previous: %s).\nDunno which input/output belongs to which command.",filepos,context->command_line);
553 ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
555 unit_handle_failure(unit);
561 command = command_new(unit, context, mutex);
562 command_run(command);
565 context_reset(context);
567 VERB1("[%s] More than one command in this chunk of lines",filepos);
570 context->command_line = strdup(line);
573 context->line = strdup(filepos);
574 /*INFO2("[%s] %s",filepos,context->command_line);*/
579 xbt_strbuff_append(context->input,line);
580 xbt_strbuff_append(context->input,"\n");
584 xbt_strbuff_append(context->output,line);
585 xbt_strbuff_append(context->output,"\n");
590 if(context->command_line)
594 command_t command = command_new(unit, context, mutex);
595 command_run(command);
598 context_reset(context);
601 if(!strncmp(line,"timeout no",strlen("timeout no")))
603 VERB1("[%s] (disable timeout)", filepos);
604 context->timeout = INDEFINITE;
606 else if(!strncmp(line,"timeout ",strlen("timeout ")))
609 char* p = line + strlen("timeout ");
616 ERROR2("Invalid timeout value `%s' at %s ", line + strlen("timeout "), filepos);
617 unit_handle_failure(unit);
623 context->timeout = atoi(line + strlen("timeout"));
624 VERB2("[%s] (new timeout value: %d)",filepos,context->timeout);
627 else if (!strncmp(line,"expect signal ",strlen("expect signal ")))
629 context->signal = strdup(line + strlen("expect signal "));
632 if(!strstr(context->signal,"SIGSEGVSIGTRAPSIGBUSSIGFPESIGILL"))
635 /*ERROR2("Signal `%s' not supported at %s", line + strlen("expect signal "), filepos);*/
636 unit_handle_failure(unit);
640 xbt_str_trim(context->signal," \n");
641 VERB2("[%s] (next command must raise signal %s)", filepos, context->signal);
644 else if (!strncmp(line,"expect return ",strlen("expect return ")))
648 char* p = line + strlen("expect return ");
656 ERROR2("Invalid exit code value `%s' at %s ", line + strlen("expect return "), filepos);
657 unit_handle_failure(unit);
663 context->exit_code = atoi(line+strlen("expect return "));
664 VERB2("[%s] (next command must return code %d)",filepos, context->exit_code);
667 else if (!strncmp(line,"output ignore",strlen("output ignore")))
669 context->output_handling = oh_ignore;
670 VERB1("[%s] (ignore output of next command)", filepos);
673 else if (!strncmp(line,"output display",strlen("output display")))
675 context->output_handling = oh_display;
676 VERB1("[%s] (ignore output of next command)", filepos);
679 else if(!strncmp(line,"include ", strlen("include ")))
684 p1 = line + strlen("include");
686 while(*p1 == ' ' || *p1 == '\t')
694 ERROR1("include file not specified %s ", filepos);
695 unit_handle_failure(unit);
699 char file_name[MAX_PATH + 1] = {0};
701 /*INFO1("p1 is %s",p1);*/
705 while(*p2 != '\0' && *p2 != ' ' && *p2 != '\t')
707 /*INFO1("p2 is %s",p2);*/
711 /*INFO1("p2 is %s",p2);*/
713 strncpy(file_name, p1, p2 - p1);
715 /*INFO1("filename is %s", file_name);*/
718 while(*p2 == ' ' || *p2 == '\t')
721 unit_handle_include(unit, context, mutex, file_name, p2[0] != '\0' ? p2 : NULL);
725 else if(!strncmp(line,"suite ", strlen("suite ")))
727 unit_handle_suite(unit, context, mutex, line + strlen("suite "));
729 else if(!strncmp(line,"unsetenv ", strlen("unsetenv ")))
732 int number_of_variables;
736 char* name = line + strlen("unsetenv ");
738 xbt_os_mutex_acquire(unit->mutex);
740 number_of_variables = vector_get_size(unit->runner->variables);
742 for(i = 0; i < number_of_variables; i++)
744 variable = vector_get_at(unit->runner->variables, i);
746 if(!strcmp(variable->name, name))
757 vector_erase_at(unit->runner->variables, i);
759 WARN3("environment variable %s not found %s %s", name, line, filepos);
764 WARN3("%s is an not environment variable use unset metacommand to delete it %s %s", name, line, filepos);
766 WARN3("%s environment variable not found %s %s", name, line, filepos);
769 xbt_os_mutex_release(unit->mutex);
773 else if(!strncmp(line,"setenv ", strlen("setenv ")))
776 char name[MAX_PATH + 1] = {0};
779 p = line + strlen("setenv ");
781 val = strchr(p, '=');
795 ERROR2("indefinite variable value %s %s", line, filepos);
796 unit_handle_failure(unit);
801 strncpy(name, p, (val - p -1));
803 /* test if the variable is already registred */
805 xbt_os_mutex_acquire(unit->mutex);
807 vector_rewind(unit->runner->variables);
809 while((variable = vector_get(unit->runner->variables)))
812 if(!strcmp(variable->name, name))
819 vector_move_next(unit->runner->variables);
822 /* if the variable is already registred, update its value;
823 * otherwise register it.
830 variable->val = strdup(val);
831 setenv(variable->name, variable->val, 1);
834 WARN3("%s variable already exists %s %s", name, line, filepos);
838 variable = variable_new(name, val);
841 vector_push_back(unit->runner->variables, variable);
843 setenv(variable->name, variable->val, 0);
846 xbt_os_mutex_release(unit->mutex);
850 else if(!strncmp(line,"unset ", strlen("unset ")))
853 int number_of_variables;
858 char* name = line + strlen("unset ");
860 xbt_os_mutex_acquire(unit->mutex);
862 number_of_variables = vector_get_size(unit->runner->variables);
864 for(i = 0; i < number_of_variables; i++)
866 variable = vector_get_at(unit->runner->variables, i);
868 if(!strcmp(variable->name, name))
880 vector_erase_at(unit->runner->variables, i);
882 WARN3("variable %s not found %s %s", name, line, filepos);
886 WARN3("%s is an environment variable use unsetenv metacommand to delete it %s %s", name, line, filepos);
890 WARN3("%s is an error variable : you are not allowed to delete it %s %s", name, line, filepos);
892 xbt_os_mutex_release(unit->mutex);
897 /* may be a variable */
899 char name[MAX_PATH + 1] = {0};
901 val = strchr(line, '=');
914 ERROR2("indefinite variable value %s %s", line, filepos);
915 unit_handle_failure(unit);
919 /* assume it's a varibale */
920 strncpy(name, line, (val - line -1));
922 xbt_os_mutex_acquire(unit->mutex);
924 /* test if the variable is already registred */
926 vector_rewind(unit->runner->variables);
928 while((variable = vector_get(unit->runner->variables)))
931 if(!strcmp(variable->name, name))
937 vector_move_next(unit->runner->variables);
940 /* if the variable is already registred, update its value;
941 * otherwise register it.
946 variable->val = strdup(val);
949 vector_push_back(unit->runner->variables,variable_new(name, val));
951 xbt_os_mutex_release(unit->mutex);
956 ERROR2("%s: Malformed metacommand: %s",filepos,line);
957 ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
960 unit_handle_failure(unit);
972 unit_handle_failure(unit_t unit)
975 if(!want_keep_going_unit)
977 unit_t root = unit->root ? unit->root : unit;
979 if(!root->interrupted)
981 /* the unit interrupted (exit for the loop) */
982 root->interrupted = 1;
984 /* release the unit */
985 xbt_os_sem_release(root->sem);
988 /* if the --keep-going option is not specified */
993 /* request an global interruption by the runner */
996 /* release the runner */
997 xbt_os_sem_release(units_sem);
1004 unit_run(unit_t unit, xbt_os_mutex_t mutex)
1008 unit->mutex = mutex;
1010 unit->sem = xbt_os_sem_init(0);
1012 /* start the unit */
1013 unit->thread = xbt_os_thread_create("", unit_start, unit);
1016 /* the unit is interrupted by the runner before its starting
1017 * in this case the unit semaphore is NULL take care of that
1018 * in the function unit_free()
1020 unit->interrupted = 1;
1026 unit_interrupt(unit_t unit)
1028 /* interrupt the loop */
1029 unit->interrupted = 1;
1030 xbt_os_sem_release(unit->sem);
1034 display_title(const char* description)
1038 int len = strlen(description);
1042 for (i = 1; i < 79; i++)
1048 sprintf(title + 40 - (len + 4)/2, "[ %s ]",description);
1049 title[40 + (len + 5 ) / 2] = '=';
1051 printf("\n%s\n",title);
1055 unit_verbose(unit_t unit)
1062 char title[MAX_PATH + 1] = {0};
1064 int number_of_tests = 0; /* number of tests of a unit contained by this unit */
1065 int number_of_failed_tests = 0; /* number of failed test of a unit contained by this unit */
1066 int number_of_successeded_tests = 0; /* number of successeded tests of a unit contained by this unit */
1067 int number_of_interrupted_tests = 0; /* number of interrupted tests of a unit contained by this unit */
1069 int number_of_tests_of_suite = 0; /* number of tests of a suite contained by this unit */
1070 int number_of_interrupted_tests_of_suite = 0; /* number of interrupted tests of a suite contained by this unit */
1071 int number_of_failed_tests_of_suite = 0; /* number of failed tests of a suite contained by this unit */
1072 int number_of_successeded_tests_of_suite = 0; /* number of successeded tests of a suite contained by this */
1074 int number_of_units = 0; /* number of units contained by a suite */
1075 int number_of_failed_units = 0; /* number of failed units contained by a suite */
1076 int number_of_successeded_units = 0; /* number of successeded units contained by a suite */
1077 int number_of_interrupted_units = 0; /* number of interrupted units contained by a suite */
1079 int total_of_tests = 0; /* total of the tests contained by this unit */
1080 int total_of_failed_tests = 0; /* total of failed tests contained by this unit */
1081 int total_of_successeded_tests = 0; /* total of successeded tests contained by this unit */
1082 int total_of_interrupted_tests = 0; /* total of interrupted tests contained by this unit */
1084 int total_of_units = 0; /* total of units contained by this unit */
1085 int total_of_failed_units = 0; /* total of failed units contained by this unit */
1086 int total_of_successeded_units = 0; /* total of successeded units contained by this unit */
1087 int total_of_interrupted_units = 0; /* total of interrutped units contained by this unit */
1089 int total_of_suites = 0; /* total of suites contained by this unit */
1090 int total_of_failed_suites = 0; /* total of failed suites contained by this unit */
1091 int total_of_successeded_suites = 0; /* total of successeded suites contained by this unit */
1092 int total_of_interrupted_suites = 0; /* total of interrupted suites contained by this unit */
1095 if(unit->description)
1096 strcpy(title, unit->description);
1098 sprintf(title, "file : %s",unit->fstream->name);
1100 if(unit->interrupted)
1101 strcat(title, " (interrupted)");
1103 display_title(title);
1105 number_of_tests = vector_get_size(unit->commands);
1109 for(i = 0; i < number_of_tests; i++)
1111 command = vector_get_at(unit->commands, i);
1113 if(command->status == cs_interrupted)
1114 number_of_interrupted_tests++;
1115 else if(command->status == cs_failed)
1116 number_of_failed_tests++;
1117 else if(command->status == cs_successeded)
1118 number_of_successeded_tests++;
1124 asprintf(&p," Test(s): .........................................................................");
1130 if(number_of_failed_tests > 0)
1131 printf(".. failed\n");
1132 else if(number_of_interrupted_tests > 0)
1133 printf("interrupt\n");
1135 printf(".... ..ok\n");
1138 for(i = 0; i < number_of_tests; i++)
1140 command = vector_get_at(unit->commands, i);
1142 printf(" %s: %s [%s]\n",
1143 command->status == cs_interrupted ? "INTR "
1144 : command->status == cs_failed ? "FAILED"
1145 : command->status == cs_successeded ? "PASS "
1147 command->context->command_line,
1148 command->context->line);
1150 if(want_detail_summary)
1151 command_display_status(command);
1155 printf(" =====================================================================%s\n",
1156 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
1158 printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
1159 ((1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0),
1160 number_of_tests, number_of_successeded_tests);
1162 if(number_of_failed_tests > 0)
1163 printf(", %d failed", number_of_failed_tests);
1165 if(number_of_interrupted_tests > 0)
1166 printf(", %d interrupted)", number_of_interrupted_tests);
1170 total_of_tests = number_of_tests;
1171 total_of_failed_tests = number_of_failed_tests;
1172 total_of_interrupted_tests = number_of_interrupted_tests;
1173 total_of_successeded_tests = number_of_successeded_tests;
1180 total_of_failed_units = total_of_interrupted_units = total_of_successeded_units = 0;
1182 number_of_failed_units = number_of_successeded_units = number_of_interrupted_units = 0;
1184 number_of_units = vector_get_size(unit->includes);
1186 for(i = 0; i < number_of_units ; i++)
1188 include = vector_get_at(unit->includes, i);
1190 number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
1192 number_of_tests = vector_get_size(include->commands);
1194 for(j = 0; j < number_of_tests; j++)
1196 command = vector_get_at(include->commands, j);
1198 if(command->status == cs_interrupted)
1199 number_of_interrupted_tests++;
1200 else if(command->status == cs_failed)
1201 number_of_failed_tests++;
1202 else if(command->status == cs_successeded)
1203 number_of_successeded_tests++;
1206 asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
1213 if(number_of_failed_tests > 0)
1215 total_of_failed_units++;
1216 printf(".. failed\n");
1218 else if(number_of_interrupted_tests > 0)
1220 total_of_interrupted_units++;
1221 printf("interrupt\n");
1225 total_of_successeded_units++;
1226 printf(".... ..ok\n");
1229 if(want_detail_summary)
1232 for(j = 0; j < vector_get_size(include->commands); j++)
1234 command = vector_get_at(include->commands, j);
1236 printf(" %s: %s [%s]\n",
1237 command->status == cs_interrupted ? "INTR "
1238 : command->status == cs_failed ? "FAILED"
1239 : command->status == cs_successeded ? "PASS "
1241 command->context->command_line,
1242 command->context->line);
1244 command_display_status(command);
1250 printf(" =====================================================================%s\n",
1251 number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
1254 printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
1255 (number_of_tests ? (1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0 : 100.0),
1256 number_of_tests, number_of_successeded_tests);
1258 if(number_of_failed_tests > 0)
1259 printf(", %d failed", number_of_failed_tests);
1261 if(number_of_interrupted_tests > 0)
1262 printf(", %d interrupted)", number_of_interrupted_tests);
1267 total_of_tests += number_of_tests;
1268 total_of_failed_tests += number_of_failed_tests;
1269 total_of_interrupted_tests += number_of_interrupted_tests;
1270 total_of_successeded_tests += number_of_successeded_tests;
1275 total_of_units = number_of_units;
1277 total_of_failed_suites = total_of_successeded_suites = total_of_interrupted_suites = 0;
1279 total_of_suites = vector_get_size(unit->suites);
1281 for(k = 0; k < total_of_suites; k++)
1283 suite = vector_get_at(unit->suites, k);
1285 display_title(suite->description);
1287 number_of_tests_of_suite = number_of_interrupted_tests_of_suite = number_of_failed_tests_of_suite = number_of_successeded_tests_of_suite = 0;
1289 number_of_interrupted_units = number_of_failed_units = number_of_successeded_units = 0;
1291 number_of_units = vector_get_size(suite->includes);
1293 for(i = 0; i < number_of_units; i++)
1295 number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
1297 number_of_tests = vector_get_size(include->commands);
1299 for(j = 0; j < vector_get_size(include->commands); j++)
1301 command = vector_get_at(include->commands, j);
1303 if(command->status == cs_interrupted)
1304 number_of_interrupted_tests++;
1305 else if(command->status == cs_failed)
1306 number_of_failed_tests++;
1307 else if(command->status == cs_successeded)
1308 number_of_successeded_tests++;
1313 include = vector_get_at(suite->includes, i);
1314 asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
1320 if(number_of_failed_tests > 0)
1322 number_of_failed_units++;
1323 printf(".. failed\n");
1325 else if(number_of_interrupted_tests > 0)
1327 number_of_interrupted_units++;
1328 printf("interrupt\n");
1332 number_of_successeded_units++;
1333 printf(".... ..ok\n");
1336 number_of_interrupted_tests_of_suite += number_of_interrupted_tests;
1337 number_of_failed_tests_of_suite += number_of_failed_tests;
1338 number_of_successeded_tests_of_suite += number_of_successeded_tests;
1340 number_of_tests_of_suite += number_of_tests;
1342 total_of_tests += number_of_tests;
1343 total_of_failed_tests += number_of_failed_tests;
1344 total_of_interrupted_tests += number_of_interrupted_tests;
1345 total_of_successeded_tests += number_of_successeded_tests;
1347 if(want_detail_summary)
1349 for(j = 0; j < vector_get_size(include->commands); j++)
1351 command = vector_get_at(include->commands, j);
1353 printf(" %s: %s [%s]\n",
1354 command->status == cs_interrupted ? "INTR "
1355 : command->status == cs_failed ? "FAILED"
1356 : command->status == cs_successeded ? "PASS "
1358 command->context->command_line,
1359 command->context->line);
1361 command_display_status(command);
1372 printf(" =====================================================================%s\n",
1373 number_of_failed_tests_of_suite ? "== FAILED": number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");
1375 if(number_of_failed_tests_of_suite > 0)
1376 total_of_failed_suites++;
1377 else if(number_of_interrupted_tests_of_suite)
1378 total_of_interrupted_suites++;
1380 total_of_successeded_suites++;
1382 total_of_failed_units += number_of_failed_units;
1383 total_of_interrupted_units += number_of_interrupted_units;
1384 total_of_successeded_units += number_of_successeded_units;
1386 total_of_units += number_of_units;
1388 printf(" Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok",
1389 (number_of_units ? (1-((double)number_of_failed_units + (double)number_of_interrupted_units)/(double)number_of_units)*100.0 : 100.0),
1390 number_of_units, number_of_successeded_units);
1392 if(number_of_failed_units > 0)
1393 printf(", %d failed", number_of_failed_units);
1395 if(number_of_interrupted_units > 0)
1396 printf(", %d interrupted)", number_of_interrupted_units);
1400 printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
1401 (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),
1402 number_of_tests_of_suite, number_of_successeded_tests_of_suite);
1404 if(number_of_failed_tests_of_suite > 0)
1405 printf(", %d failed", number_of_failed_tests_of_suite);
1407 if(number_of_interrupted_tests_of_suite > 0)
1408 printf(", %d interrupted)", number_of_interrupted_tests_of_suite);
1413 printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
1414 (total_of_suites ? (1-((double)total_of_failed_suites + (double)total_of_interrupted_suites)/(double)total_of_suites)*100.0 : 100.0),
1415 total_of_suites, total_of_successeded_suites);
1417 if(total_of_failed_suites > 0)
1418 printf(", %d failed", total_of_failed_suites);
1420 if(total_of_interrupted_suites > 0)
1421 printf(", %d interrupted)", total_of_interrupted_suites);
1425 printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",
1426 (total_of_units ? (1-((double)total_of_failed_units + (double)total_of_interrupted_units)/(double)total_of_units)*100.0 : 100.0),
1427 total_of_units, total_of_successeded_units);
1429 if(total_of_failed_units > 0)
1430 printf(", %d failed", total_of_failed_units);
1432 if(total_of_interrupted_units > 0)
1433 printf(", %d interrupted)", total_of_interrupted_units);
1437 printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
1438 (total_of_tests ? (1-((double)total_of_failed_tests + (double)total_of_interrupted_tests)/(double)total_of_tests)*100.0 : 100.0),
1439 total_of_tests, total_of_successeded_tests);
1441 if(total_of_failed_tests > 0)
1442 printf(", %d failed", total_of_failed_tests);
1444 if(total_of_interrupted_tests > 0)
1445 printf(", %d interrupted)", total_of_interrupted_tests);
1450 if(unit->interrupted)
1451 unit->runner->total_of_interrupted_units++;
1452 else if(total_of_failed_tests > 0)
1453 unit->runner->total_of_failed_units++;
1455 unit->runner->total_of_successeded_units++;
1458 unit->runner->total_of_tests += total_of_tests;
1459 unit->runner->total_of_failed_tests += total_of_failed_tests;
1460 unit->runner->total_of_successeded_tests += total_of_successeded_tests;
1461 unit->runner->total_of_interrupted_tests += total_of_interrupted_tests;
1464 unit->runner->total_of_units += total_of_units + 1;
1465 unit->runner->total_of_successeded_units += total_of_successeded_units;
1466 unit->runner->total_of_failed_units += total_of_failed_units;
1467 unit->runner->total_of_interrupted_units += total_of_interrupted_units;
1470 unit->runner->total_of_suites += total_of_suites;
1471 unit->runner->total_of_successeded_suites += total_of_successeded_suites;
1472 unit->runner->total_of_failed_suites += total_of_failed_suites;
1473 unit->runner->total_of_interrupted_suites += total_of_interrupted_suites;
1483 unit_handle_include(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, const char* description)
1486 char* prev_directory = NULL;
1487 fstream_t fstream = NULL;
1488 struct stat buffer = {0};
1490 if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
1492 /* the file is in the current directory */
1494 fstream = fstream_new(getcwd(NULL, 0), file_name);
1495 fstream_open(fstream);
1497 /* the file to include is not in the current directory, check if it is in a include directory */
1500 prev_directory = getcwd(NULL, 0);
1502 vector_rewind(include_dirs);
1504 while((dir = vector_get(include_dirs)))
1508 if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
1510 fstream = fstream_new(dir->name, file_name);
1511 fstream_open(fstream);
1516 vector_move_next(include_dirs);
1519 chdir(prev_directory);
1520 free(prev_directory);
1525 /* the file to include is not found handle the failure */
1528 exit_code = EINCLUDENOTFOUND;
1529 ERROR1("Include file %s not found",file_name);
1530 unit_handle_failure(unit);
1535 if(!unit->running_suite)
1536 {/* it's the unit of a suite */
1537 unit_t include = unit_new(unit->runner,unit->root, unit, fstream);
1539 include->mutex = unit->root->mutex;
1542 include->description = strdup(description);
1544 vector_push_back(unit->includes, include);
1546 fstream_parse(fstream, include, mutex);
1549 {/* it's a include */
1550 unit_t owner = vector_get_back(unit->suites);
1551 unit_t include = unit_new(unit->runner,unit->root, owner, fstream);
1553 include->mutex = unit->root->mutex;
1556 include->description = strdup(description);
1558 vector_push_back(owner->includes, include);
1560 fstream_parse(fstream, include, mutex);
1566 unit_handle_suite(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* description)
1568 if(unit->running_suite)
1570 exit_code = ESYNTAX;
1571 unit_handle_failure(unit);
1575 unit_t suite = unit_new(unit->runner, unit->root, unit, NULL);
1576 suite->is_suite = 1;
1577 suite->description = strdup(description);
1578 vector_push_back(unit->suites, suite);
1579 unit->running_suite = 1;
1584 unit_reset(unit_t unit)
1586 fseek(unit->fstream->stream,0L, SEEK_SET);
1588 unit->number_of_commands = 0;