#include <command.h>
#include <context.h>
#include <fstream.h>
-
-
+#include <variable.h>
+#include <str_replace.h>
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
+static void
+replace_variables(unit_t unit, char** line)
+{
+ variable_t variable;
+ char name[MAX_PATH + 1] = {0};
+
+ /* check if some commands have setted some environment variables */
+ /* TODO */
+
+ /*printf("repalce all the variables of the line %s\n", *line);*/
+
+
+ xbt_os_mutex_acquire(unit->mutex);
+
+ vector_rewind(unit->runner->variables);
+
+ while((variable = vector_get(unit->runner->variables)))
+ {
+ sprintf(name, "$%s", variable->name);
+ /*printf("try to replace all the variable %s\n",name);*/
+ str_replace_all(line, name, variable->val);
+
+ vector_move_next(unit->runner->variables);
+ memset(name, 0, MAX_PATH + 1);
+ }
+
+ xbt_os_mutex_release(unit->mutex);
+
+ /*printf("line after the variables replacement %s\n",*line);*/
+
+}
/* the unit thread start routine */
static void*
unit_start(void* p);
unit_t
-unit_new(runner_t runner, suite_t owner, fstream_t fstream)
+unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream)
{
unit_t unit = xbt_new0(s_unit_t, 1);
unit->sem = NULL;
unit->commands = vector_new(DEFAULT_COMMANDS_CAPACITY, (fn_finalize_t)command_free);
+ unit->includes = vector_new(DEFAULT_INCLUDES, (fn_finalize_t)unit_free);
unit->thread = NULL;
unit->number_of_failed_commands = 0;
unit->number_of_successeded_commands = 0;
unit->number_of_terminated_commands = 0;
+ unit->number_of_waiting_commands = 0;
unit->interrupted = 0;
unit->failed = 0;
unit->successeded = 0;
unit->owner = owner;
+
+ unit->root = root ? root : unit;
+
+
unit->number = 0;
- unit->suites = vector_new(DEFAULT_COMMANDS_CAPACITY, (fn_finalize_t)suite_free);
+ unit->suites = vector_new(DEFAULT_SUITES_CAPACITY, (fn_finalize_t)unit_free);
unit->owner = owner;
unit->running_suite = 0;
+ unit->is_suite = 0;
+ unit->description = NULL;
return unit;
}
-void
+/*void
unit_add_suite(unit_t unit, suite_t suite)
{
vector_push_back(unit->suites, suite);
-}
+}*/
int
unit_free(void** unitptr)
vector_free(&((*__unitptr)->commands));
+ vector_free(&((*__unitptr)->includes));
+
vector_free(&((*__unitptr)->suites));
/* if the unit is interrupted during its run, the semaphore is NULL */
if((*__unitptr)->sem)
xbt_os_sem_destroy((*__unitptr)->sem);
-
+ if((*__unitptr)->description)
+ free((*__unitptr)->description);
+
free((*__unitptr)->suites);
free(*__unitptr);
xbt_os_thread_t thread;
xbt_os_mutex_t mutex;
- context_t context;
- int i;
+ /*context_t context;*/
+ int i, j;
unit_t unit = (unit_t)p;
+ unit_t include;
xbt_os_mutex_acquire(unit->mutex);
unit->runner->number_of_runned_units++;
xbt_os_sem_acquire(jobs_sem);
mutex = xbt_os_mutex_init();
- context = context_new();
+ /*context = context_new();*/
if(want_dry_run)
INFO1("checking unit %s...",unit->fstream->name);
/* parse the file */
- unit_parse(unit, context, mutex, unit->fstream->name, unit->fstream->stream);
+ /*unit_parse(unit, context, mutex, unit->fstream->name, unit->fstream->stream);*/
+
+ fstream_parse(unit->fstream, unit, mutex);
+
/* if the unit is not interrupted and not failed the unit, all the file is parsed
* so all the command are launched
*/
+
+
if(!unit->interrupted)
{
unit->parsed = 1;
* so the unit release the semaphore itself
*/
if(!unit->released && (unit->number_of_started_commands == (unit->number_of_failed_commands + unit->number_of_interrupted_commands + unit->number_of_successeded_commands)))
+ {
+ /*INFO1("the unit %s is released", unit->fstream->name);*/
xbt_os_sem_release(unit->sem);
+ }
+ else
+ {
+
+ INFO1("the unit %s is not released", unit->fstream->name);
+ INFO1("number of started commands %d", unit->number_of_started_commands);
+ INFO1("number of failed commands %d", unit->number_of_failed_commands);
+ INFO1("number of interrupted commands %d", unit->number_of_interrupted_commands);
+ INFO1("number of successeded commands %d", unit->number_of_successeded_commands);
+ INFO1("number of waiting commands %d", unit->number_of_waiting_commands);
+
+
+ if(unit->number_of_waiting_commands)
+ {
+ command_t command;
+ int i, j;
+
+ for(i = 0; i < vector_get_size(unit->includes) ; i++)
+ {
+ include = vector_get_at(unit->includes, i);
+
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ if(command->status == cs_in_progress)
+ {
+ INFO2("the command %s PID %d is in process", command->context->command_line, command->pid);
+
+ if(command->writer->done)
+ INFO2("the writer of the command %s PID %d done", command->context->command_line, command->pid);
+ else
+ INFO2("the writer of the command %s PID %d doesn't done", command->context->command_line, command->pid);
+ }
+ }
+
+ }
+ }
+ }
}
/* wait the end of all the commands or a command failure or an interruption */
-
-
xbt_os_sem_acquire(unit->sem);
+
if(unit->interrupted)
{
command_t command;
-
+
/* interrupt all the running commands of the unit */
- for(i = 0; i < unit->number_of_commands; i++)
+ for(i = 0; i < vector_get_size(unit->commands); i++)
{
- /*command = unit->commands[i];*/
command = vector_get_at(unit->commands, i);
if(command->status == cs_in_progress)
- /*command_interrupt(unit->commands[i]);*/
command_interrupt(command);
}
+
+ for(i = 0; i < vector_get_size(unit->includes); i++)
+ {
+ include = vector_get_at(unit->includes, i);
+
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ if(command->status == cs_in_progress)
+ command_interrupt(command);
+ }
+ }
+
}
-
/* wait the end of the threads */
- for(i = 0; i < unit->number_of_commands; i++)
+ for(i = 0; i < vector_get_size(unit->commands); i++)
{
- /*thread = unit->commands[i]->thread;*/
-
command_t command = vector_get_at(unit->commands, i);
thread = command->thread;
xbt_os_thread_join(thread,NULL);
}
- context_free(&context);
-
+ for(i = 0; i < vector_get_size(unit->includes); i++)
+ {
+ include = vector_get_at(unit->includes, i);
+
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command_t command = vector_get_at(include->commands, j);
+ thread = command->thread;
+
+ if(thread)
+ xbt_os_thread_join(thread,NULL);
+ }
+ }
+
+ /*context_free(&context);*/
+
xbt_os_mutex_destroy(mutex);
+
xbt_os_mutex_acquire(unit->mutex);
/* increment the number of ended units */
/* first release the mutex */
xbt_os_mutex_release(unit->mutex);
+
xbt_os_sem_release(units_sem);
}
else
xbt_os_mutex_release(unit->mutex);
-
+
/* release the jobs semaphore, then the next unit can start */
xbt_os_sem_release(jobs_sem);
unit_handle_failure(unit);
break;
}
+ else if(unit->running_suite)
+ {
+ /* TODO */
+ }
+
if(context->command_line)
{
xbt_strbuff_free(buff);
}
+
+
void
unit_handle_line(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char * filepos, char *line)
{
+ char* line2;
/* Search end */
xbt_str_rtrim(line+2,"\n");
- switch (line[0])
+ line2 = strdup(line);
+
+ replace_variables(unit, &line2);
+
+ switch (line2[0])
{
case '#':
break;
case '$':
case '&':
- context->async = (line[0] == '&');
+ context->async = (line2[0] == '&');
/* further trim useless chars which are significant for in/output */
- xbt_str_rtrim(line+2," \t");
+ xbt_str_rtrim(line2+2," \t");
/* Deal with CD commands here, not in rctx */
- if (!strncmp("cd ",line+2,3))
+ if(!strncmp("cd ",line2 + 2, 3))
{
- char *dir=line+4;
-
- if (context->command_line)
+ /*char *dir=line2+4; */
+ char* dir = strdup(line2 + 4);
+
+ if(context->command_line)
{
if(!want_dry_run)
{
VERB1("Saw cd '%s'",dir);
- /*if(want_dry_run)
- {
- unit->number_of_successeded_commands++;
- }*/
+
if(!want_dry_run)
{
+
if(chdir(dir))
{
ERROR2("Chdir to %s failed: %s",dir,strerror(errno));
exit_code = ECHDIR;
unit_handle_failure(unit);
}
+
+
}
break;
} /* else, pushline */
else
{
- unit_pushline(unit, context, mutex, filepos, line[0], line+2 /* pass '$ ' stuff*/);
+ unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
break;
}
case '<':
case '>':
case '!':
- unit_pushline(unit, context, mutex, filepos, line[0], line+2 /* pass '$ ' stuff*/);
+ unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
break;
case 'p':
if(!want_dry_run)
- INFO2("[%s] %s",filepos,line+2);
+ INFO2("[%s] %s",filepos,line2+2);
break;
case 'P':
if(!want_dry_run)
- CRITICAL2("[%s] %s",filepos,line+2);
+ CRITICAL2("[%s] %s",filepos,line2+2);
+ break;
+
+ case 'D':
+ if(unit->description)
+ WARN2("description already specified %s %s", filepos, line2);
+ else
+ unit->description = strdup(line2 + 2);
break;
default:
- ERROR2("[%s] Syntax error: %s",filepos, line);
+ ERROR2("[%s] Syntax error: %s",filepos, line2);
ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
exit_code = ESYNTAX;
unit_handle_failure(unit);
break;
}
+
+ free(line2);
}
void
VERB1("[%s] (ignore output of next command)", filepos);
}
- else if(!strncmp(line,"include", strlen("include")))
+ else if(!strncmp(line,"include ", strlen("include ")))
{
- unit_handle_include(unit, context, mutex, line + strlen("include "));
+ char* p1;
+ char* p2;
+
+ p1 = line + strlen("include");
+
+ while(*p1 == ' ' || *p1 == '\t')
+ p1++;
+
+
+ if(p1[0] == '\0')
+ {
+
+ exit_code = ESYNTAX;
+ ERROR1("include file not specified %s ", filepos);
+ unit_handle_failure(unit);
+ }
+ else
+ {
+ char file_name[MAX_PATH + 1] = {0};
+
+ /*INFO1("p1 is %s",p1);*/
+
+ p2 = p1;
+
+ while(*p2 != '\0' && *p2 != ' ' && *p2 != '\t')
+ {
+ /*INFO1("p2 is %s",p2);*/
+ p2++;
+
+ }
+ /*INFO1("p2 is %s",p2);*/
+
+ strncpy(file_name, p1, p2 - p1);
+
+ /*INFO1("filename is %s", file_name);*/
+
+ if(p2[0] != '\0')
+ while(*p2 == ' ' || *p2 == '\t')
+ p2++;
+
+ unit_handle_include(unit, context, mutex, file_name, p2[0] != '\0' ? p2 : NULL);
+
+ }
}
-
- else if(!strncmp(line,"suite", strlen("suite")))
+ else if(!strncmp(line,"suite ", strlen("suite ")))
{
unit_handle_suite(unit, context, mutex, line + strlen("suite "));
}
- else
+ else if(!strncmp(line,"unsetenv ", strlen("unsetenv ")))
+ {
+ int i;
+ int number_of_variables;
+ int exists = 0;
+ int env;
+ variable_t variable;
+ char* name = line + strlen("unsetenv ");
+
+ xbt_os_mutex_acquire(unit->mutex);
+
+ number_of_variables = vector_get_size(unit->runner->variables);
+
+ for(i = 0; i < number_of_variables; i++)
+ {
+ variable = vector_get_at(unit->runner->variables, i);
+
+ if(!strcmp(variable->name, name))
+ {
+ env = variable->env;
+ exists = 1;
+ break;
+ }
+ }
+
+ if(env)
+ {
+ if(exists)
+ vector_erase_at(unit->runner->variables, i);
+ else
+ WARN3("environment variable %s not found %s %s", name, line, filepos);
+ }
+ else
+ {
+ if(exists)
+ WARN3("%s is an not environment variable use unset metacommand to delete it %s %s", name, line, filepos);
+ else
+ WARN3("%s environment variable not found %s %s", name, line, filepos);
+ }
+
+ xbt_os_mutex_release(unit->mutex);
+
+
+ }
+ else if(!strncmp(line,"setenv ", strlen("setenv ")))
+ {
+ char* val;
+ char name[MAX_PATH + 1] = {0};
+ char* p;
+
+ p = line + strlen("setenv ");
+
+ val = strchr(p, '=');
+
+ if(val)
+ {
+ variable_t variable;
+ int exists = 0;
+ int env = 0;
+ val++;
+
+ /* syntax error */
+ if(val[0] == '\0')
+ {
+
+ exit_code = ESYNTAX;
+ ERROR2("indefinite variable value %s %s", line, filepos);
+ unit_handle_failure(unit);
+ }
+
+
+
+ strncpy(name, p, (val - p -1));
+
+ /* test if the variable is already registred */
+
+ xbt_os_mutex_acquire(unit->mutex);
+
+ vector_rewind(unit->runner->variables);
+
+ while((variable = vector_get(unit->runner->variables)))
+ {
+
+ if(!strcmp(variable->name, name))
+ {
+ variable->env = 1;
+ exists = 1;
+ break;
+ }
+
+ vector_move_next(unit->runner->variables);
+ }
+
+ /* if the variable is already registred, update its value;
+ * otherwise register it.
+ */
+ if(exists)
+ {
+ if(env)
+ {
+ free(variable->val);
+ variable->val = strdup(val);
+ setenv(variable->name, variable->val, 1);
+ }
+ else
+ WARN3("%s variable already exists %s %s", name, line, filepos);
+ }
+ else
+ {
+ variable = variable_new(name, val);
+ variable->env = 1;
+
+ vector_push_back(unit->runner->variables, variable);
+
+ setenv(variable->name, variable->val, 0);
+ }
+
+ xbt_os_mutex_release(unit->mutex);
+
+ }
+ }
+ else if(!strncmp(line,"unset ", strlen("unset ")))
{
- ERROR2("%s: Malformed metacommand: %s",filepos,line);
- ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- return;
+ int i;
+ int number_of_variables;
+ int exists = 0;
+ int env;
+ int err;
+ variable_t variable;
+ char* name = line + strlen("unset ");
+
+ xbt_os_mutex_acquire(unit->mutex);
+
+ number_of_variables = vector_get_size(unit->runner->variables);
+
+ for(i = 0; i < number_of_variables; i++)
+ {
+ variable = vector_get_at(unit->runner->variables, i);
+
+ if(!strcmp(variable->name, name))
+ {
+ env = variable->env;
+ err = variable->err;
+ exists = 1;
+ break;
+ }
+ }
+
+ if(!env)
+ {
+ if(exists)
+ vector_erase_at(unit->runner->variables, i);
+ else
+ WARN3("variable %s not found %s %s", name, line, filepos);
+ }
+ else if(env)
+ {
+ WARN3("%s is an environment variable use unsetenv metacommand to delete it %s %s", name, line, filepos);
+ }
+ else
+ {
+ WARN3("%s is an error variable : you are not allowed to delete it %s %s", name, line, filepos);
+ }
+ xbt_os_mutex_release(unit->mutex);
+
}
+ else
+ {
+ /* may be a variable */
+ char* val;
+ char name[MAX_PATH + 1] = {0};
+
+ val = strchr(line, '=');
+
+ if(val)
+ {
+ variable_t variable;
+ int exists = 0;
+ val++;
+
+ /* syntax error */
+ if(val[0] == '\0')
+ {
+
+ exit_code = ESYNTAX;
+ ERROR2("indefinite variable value %s %s", line, filepos);
+ unit_handle_failure(unit);
+ }
+
+
+ /* assume it's a varibale */
+ strncpy(name, line, (val - line -1));
+
+ xbt_os_mutex_acquire(unit->mutex);
+
+ /* test if the variable is already registred */
+
+ vector_rewind(unit->runner->variables);
+
+ while((variable = vector_get(unit->runner->variables)))
+ {
+
+ if(!strcmp(variable->name, name))
+ {
+ exists = 1;
+ break;
+ }
+
+ vector_move_next(unit->runner->variables);
+ }
+
+ /* if the variable is already registred, update its value;
+ * otherwise register it.
+ */
+ if(exists)
+ {
+ free(variable->val);
+ variable->val = strdup(val);
+ }
+ else
+ vector_push_back(unit->runner->variables,variable_new(name, val));
+
+ xbt_os_mutex_release(unit->mutex);
+
+ }
+ else
+ {
+ ERROR2("%s: Malformed metacommand: %s",filepos,line);
+ ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
+
+ exit_code = ESYNTAX;
+ unit_handle_failure(unit);
+ return;
+ }
+ }
+
break;
}
void
unit_handle_failure(unit_t unit)
{
+
if(!want_keep_going_unit)
{
- if(!unit->interrupted)
+ unit_t root = unit->root ? unit->root : unit;
+
+ if(!root->interrupted)
{
/* the unit interrupted (exit for the loop) */
- unit->interrupted = 1;
+ root->interrupted = 1;
/* release the unit */
- xbt_os_sem_release(unit->sem);
+ xbt_os_sem_release(root->sem);
}
/* if the --keep-going option is not specified */
xbt_os_sem_release(unit->sem);
}
+void
+display_title(const char* description)
+{
+ int i;
+ char title[80];
+ int len = strlen(description);
+
+ title[0]=' ';
+
+ for (i = 1; i < 79; i++)
+ title[i]='=';
+
+ title[i++]='\n';
+ title[79]='\0';
+
+ sprintf(title + 40 - (len + 4)/2, "[ %s ]",description);
+ title[40 + (len + 5 ) / 2] = '=';
+
+ printf("\n%s\n",title);
+}
+
void
unit_verbose(unit_t unit)
{
- int i, test_count;
+ int i, j, k;
command_t command;
-
- printf("\nUnit : %s (%s)\n", unit->fstream->name, unit->fstream->directory);
- printf("Status informations :");
-
- if(unit->parsed && unit->number_of_successeded_commands == unit->number_of_started_commands)
- printf(" - (success)");
+ unit_t include;
+ unit_t suite;
+ char* p;
+ char title[MAX_PATH + 1] = {0};
+
+ int number_of_tests = 0; /* number of tests of a unit contained by this unit */
+ int number_of_failed_tests = 0; /* number of failed test of a unit contained by this unit */
+ int number_of_successeded_tests = 0; /* number of successeded tests of a unit contained by this unit */
+ int number_of_interrupted_tests = 0; /* number of interrupted tests of a unit contained by this unit */
+
+ int number_of_tests_of_suite = 0; /* number of tests of a suite contained by this unit */
+ int number_of_interrupted_tests_of_suite = 0; /* number of interrupted tests of a suite contained by this unit */
+ int number_of_failed_tests_of_suite = 0; /* number of failed tests of a suite contained by this unit */
+ int number_of_successeded_tests_of_suite = 0; /* number of successeded tests of a suite contained by this */
+
+ int number_of_units = 0; /* number of units contained by a suite */
+ int number_of_failed_units = 0; /* number of failed units contained by a suite */
+ int number_of_successeded_units = 0; /* number of successeded units contained by a suite */
+ int number_of_interrupted_units = 0; /* number of interrupted units contained by a suite */
+
+ int total_of_tests = 0; /* total of the tests contained by this unit */
+ int total_of_failed_tests = 0; /* total of failed tests contained by this unit */
+ int total_of_successeded_tests = 0; /* total of successeded tests contained by this unit */
+ int total_of_interrupted_tests = 0; /* total of interrupted tests contained by this unit */
+
+ int total_of_units = 0; /* total of units contained by this unit */
+ int total_of_failed_units = 0; /* total of failed units contained by this unit */
+ int total_of_successeded_units = 0; /* total of successeded units contained by this unit */
+ int total_of_interrupted_units = 0; /* total of interrutped units contained by this unit */
+
+ int total_of_suites = 0; /* total of suites contained by this unit */
+ int total_of_failed_suites = 0; /* total of failed suites contained by this unit */
+ int total_of_successeded_suites = 0; /* total of successeded suites contained by this unit */
+ int total_of_interrupted_suites = 0; /* total of interrupted suites contained by this unit */
+
+
+ if(unit->description)
+ strcpy(title, unit->description);
else
+ sprintf(title, "file : %s",unit->fstream->name);
+
+ if(unit->interrupted)
+ strcat(title, " (interrupted)");
+
+ display_title(title);
+
+ number_of_tests = vector_get_size(unit->commands);
+
+
+ /* tests */
+ for(i = 0; i < number_of_tests; i++)
{
- if(unit->interrupted)
- printf(" - (interruped)");
- else
- printf(" - (failed)");
+ command = vector_get_at(unit->commands, i);
+
+ if(command->status == cs_interrupted)
+ number_of_interrupted_tests++;
+ else if(command->status == cs_failed)
+ number_of_failed_tests++;
+ else if(command->status == cs_successeded)
+ number_of_successeded_tests++;
+
}
- printf("\n");
-
- printf(" number of commands : %d\n", unit->number_of_commands);
- printf(" number of runned commands : %d\n", unit->number_of_started_commands);
- printf(" number of successeded commands : %d\n", unit->number_of_successeded_commands);
- printf(" number of failed commands : %d\n", unit->number_of_failed_commands);
- printf(" number of interrupted commands : %d\n", unit->number_of_interrupted_commands);
+ if(number_of_tests)
+ {
+ asprintf(&p," Test(s): .........................................................................");
+
+ p[70] = '\0';
+ printf("%s", p);
+ free(p);
+
+ if(number_of_failed_tests > 0)
+ printf(".. failed\n");
+ else if(number_of_interrupted_tests > 0)
+ printf("interrupt\n");
+ else
+ printf(".... ..ok\n");
+
+
+ for(i = 0; i < number_of_tests; i++)
+ {
+ command = vector_get_at(unit->commands, i);
+
+ printf(" %s: %s [%s]\n",
+ command->status == cs_interrupted ? "INTR "
+ : command->status == cs_failed ? "FAILED"
+ : command->status == cs_successeded ? "PASS "
+ : "UNKNWN",
+ command->context->command_line,
+ command->context->line);
+
+ if(want_detail_summary)
+ command_display_status(command);
+
+ }
+
+ printf(" =====================================================================%s\n",
+ number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
+
+ printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
+ ((1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0),
+ number_of_tests, number_of_successeded_tests);
+
+ if(number_of_failed_tests > 0)
+ printf(", %d failed", number_of_failed_tests);
+
+ if(number_of_interrupted_tests > 0)
+ printf(", %d interrupted)", number_of_interrupted_tests);
+
+ printf(")\n\n");
+
+ total_of_tests = number_of_tests;
+ total_of_failed_tests = number_of_failed_tests;
+ total_of_interrupted_tests = number_of_interrupted_tests;
+ total_of_successeded_tests = number_of_successeded_tests;
+ }
- test_count = unit->number_of_commands;
- for(i = 0; i < test_count; i++)
+ /* includes */
+
+ total_of_failed_units = total_of_interrupted_units = total_of_successeded_units = 0;
+
+ number_of_failed_units = number_of_successeded_units = number_of_interrupted_units = 0;
+
+ number_of_units = vector_get_size(unit->includes);
+
+ for(i = 0; i < number_of_units ; i++)
{
- command = vector_get_at(unit->commands, i);
+ include = vector_get_at(unit->includes, i);
+
+ number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
+
+ number_of_tests = vector_get_size(include->commands);
+
+ for(j = 0; j < number_of_tests; j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ if(command->status == cs_interrupted)
+ number_of_interrupted_tests++;
+ else if(command->status == cs_failed)
+ number_of_failed_tests++;
+ else if(command->status == cs_successeded)
+ number_of_successeded_tests++;
+ }
+
+ asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
+
+ p[70] = '\0';
+ printf("%s", p);
+ free(p);
+
+
+ if(number_of_failed_tests > 0)
+ {
+ total_of_failed_units++;
+ printf(".. failed\n");
+ }
+ else if(number_of_interrupted_tests > 0)
+ {
+ total_of_interrupted_units++;
+ printf("interrupt\n");
+ }
+ else
+ {
+ total_of_successeded_units++;
+ printf(".... ..ok\n");
+ }
+
+ if(want_detail_summary)
+ {
+
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ printf(" %s: %s [%s]\n",
+ command->status == cs_interrupted ? "INTR "
+ : command->status == cs_failed ? "FAILED"
+ : command->status == cs_successeded ? "PASS "
+ : "UNKNWN",
+ command->context->command_line,
+ command->context->line);
+
+ command_display_status(command);
+ }
+
+
+ }
- /*command_display_status(unit->commands[i]);*/
- command_display_status(command);
+ printf(" =====================================================================%s\n",
+ number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
+
+
+ printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
+ (number_of_tests ? (1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0 : 100.0),
+ number_of_tests, number_of_successeded_tests);
+
+ if(number_of_failed_tests > 0)
+ printf(", %d failed", number_of_failed_tests);
+
+ if(number_of_interrupted_tests > 0)
+ printf(", %d interrupted)", number_of_interrupted_tests);
+
+ printf(")\n\n");
+
+
+ total_of_tests += number_of_tests;
+ total_of_failed_tests += number_of_failed_tests;
+ total_of_interrupted_tests += number_of_interrupted_tests;
+ total_of_successeded_tests += number_of_successeded_tests;
+ }
+
+ /* suites */
+
+ total_of_units = number_of_units;
+
+ total_of_failed_suites = total_of_successeded_suites = total_of_interrupted_suites = 0;
+
+ total_of_suites = vector_get_size(unit->suites);
+
+ for(k = 0; k < total_of_suites; k++)
+ {
+ suite = vector_get_at(unit->suites, k);
+
+ display_title(suite->description);
+
+ number_of_tests_of_suite = number_of_interrupted_tests_of_suite = number_of_failed_tests_of_suite = number_of_successeded_tests_of_suite = 0;
+
+ number_of_interrupted_units = number_of_failed_units = number_of_successeded_units = 0;
+
+ number_of_units = vector_get_size(suite->includes);
+
+ for(i = 0; i < number_of_units; i++)
+ {
+ number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
+
+ number_of_tests = vector_get_size(include->commands);
+
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ if(command->status == cs_interrupted)
+ number_of_interrupted_tests++;
+ else if(command->status == cs_failed)
+ number_of_failed_tests++;
+ else if(command->status == cs_successeded)
+ number_of_successeded_tests++;
+
+ }
+
+
+ include = vector_get_at(suite->includes, i);
+ asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
+
+ p[70] = '\0';
+ printf("%s", p);
+ free(p);
+
+ if(number_of_failed_tests > 0)
+ {
+ number_of_failed_units++;
+ printf(".. failed\n");
+ }
+ else if(number_of_interrupted_tests > 0)
+ {
+ number_of_interrupted_units++;
+ printf("interrupt\n");
+ }
+ else
+ {
+ number_of_successeded_units++;
+ printf(".... ..ok\n");
+ }
+
+ number_of_interrupted_tests_of_suite += number_of_interrupted_tests;
+ number_of_failed_tests_of_suite += number_of_failed_tests;
+ number_of_successeded_tests_of_suite += number_of_successeded_tests;
+
+ number_of_tests_of_suite += number_of_tests;
+
+ total_of_tests += number_of_tests;
+ total_of_failed_tests += number_of_failed_tests;
+ total_of_interrupted_tests += number_of_interrupted_tests;
+ total_of_successeded_tests += number_of_successeded_tests;
+
+ if(want_detail_summary)
+ {
+ for(j = 0; j < vector_get_size(include->commands); j++)
+ {
+ command = vector_get_at(include->commands, j);
+
+ printf(" %s: %s [%s]\n",
+ command->status == cs_interrupted ? "INTR "
+ : command->status == cs_failed ? "FAILED"
+ : command->status == cs_successeded ? "PASS "
+ : "UNKNWN",
+ command->context->command_line,
+ command->context->line);
+
+ command_display_status(command);
+
+ }
+
+
+ }
+
+ }
+
+
+
+ printf(" =====================================================================%s\n",
+ number_of_failed_tests_of_suite ? "== FAILED": number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");
+
+ if(number_of_failed_tests_of_suite > 0)
+ total_of_failed_suites++;
+ else if(number_of_interrupted_tests_of_suite)
+ total_of_interrupted_suites++;
+ else
+ total_of_successeded_suites++;
+
+ total_of_failed_units += number_of_failed_units;
+ total_of_interrupted_units += number_of_interrupted_units;
+ total_of_successeded_units += number_of_successeded_units;
+
+ total_of_units += number_of_units;
+
+ printf(" Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok",
+ (number_of_units ? (1-((double)number_of_failed_units + (double)number_of_interrupted_units)/(double)number_of_units)*100.0 : 100.0),
+ number_of_units, number_of_successeded_units);
+
+ if(number_of_failed_units > 0)
+ printf(", %d failed", number_of_failed_units);
+
+ if(number_of_interrupted_units > 0)
+ printf(", %d interrupted)", number_of_interrupted_units);
+
+ printf(")\n");
+
+ printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
+ (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),
+ number_of_tests_of_suite, number_of_successeded_tests_of_suite);
+
+ if(number_of_failed_tests_of_suite > 0)
+ printf(", %d failed", number_of_failed_tests_of_suite);
+
+ if(number_of_interrupted_tests_of_suite > 0)
+ printf(", %d interrupted)", number_of_interrupted_tests_of_suite);
+
+ printf(")\n\n");
}
+
+ printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
+ (total_of_suites ? (1-((double)total_of_failed_suites + (double)total_of_interrupted_suites)/(double)total_of_suites)*100.0 : 100.0),
+ total_of_suites, total_of_successeded_suites);
+
+ if(total_of_failed_suites > 0)
+ printf(", %d failed", total_of_failed_suites);
+
+ if(total_of_interrupted_suites > 0)
+ printf(", %d interrupted)", total_of_interrupted_suites);
+
+ printf(")\n");
+
+ printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",
+ (total_of_units ? (1-((double)total_of_failed_units + (double)total_of_interrupted_units)/(double)total_of_units)*100.0 : 100.0),
+ total_of_units, total_of_successeded_units);
+
+ if(total_of_failed_units > 0)
+ printf(", %d failed", total_of_failed_units);
+
+ if(total_of_interrupted_units > 0)
+ printf(", %d interrupted)", total_of_interrupted_units);
+
+ printf(")\n");
+
+ printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
+ (total_of_tests ? (1-((double)total_of_failed_tests + (double)total_of_interrupted_tests)/(double)total_of_tests)*100.0 : 100.0),
+ total_of_tests, total_of_successeded_tests);
+
+ if(total_of_failed_tests > 0)
+ printf(", %d failed", total_of_failed_tests);
+
+ if(total_of_interrupted_tests > 0)
+ printf(", %d interrupted)", total_of_interrupted_tests);
+
+ printf(")\n\n");
+
+
+ if(unit->interrupted)
+ unit->runner->total_of_interrupted_units++;
+ else if(total_of_failed_tests > 0)
+ unit->runner->total_of_failed_units++;
+ else
+ unit->runner->total_of_successeded_units++;
+
+
+ unit->runner->total_of_tests += total_of_tests;
+ unit->runner->total_of_failed_tests += total_of_failed_tests;
+ unit->runner->total_of_successeded_tests += total_of_successeded_tests;
+ unit->runner->total_of_interrupted_tests += total_of_interrupted_tests;
+
+
+ unit->runner->total_of_units += total_of_units + 1;
+ unit->runner->total_of_successeded_units += total_of_successeded_units;
+ unit->runner->total_of_failed_units += total_of_failed_units;
+ unit->runner->total_of_interrupted_units += total_of_interrupted_units;
+
+
+ unit->runner->total_of_suites += total_of_suites;
+ unit->runner->total_of_successeded_suites += total_of_successeded_suites;
+ unit->runner->total_of_failed_suites += total_of_failed_suites;
+ unit->runner->total_of_interrupted_suites += total_of_interrupted_suites;
+
+
+
+}
+
-}
void
-unit_handle_include(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name)
+unit_handle_include(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, const char* description)
{
- directory_t include;
+ directory_t dir;
char* prev_directory = NULL;
fstream_t fstream = NULL;
struct stat buffer = {0};
-
if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
{
- INFO1("the file stream %s is in the current directory", file_name);
+ /* the file is in the current directory */
fstream = fstream_new(getcwd(NULL, 0), file_name);
fstream_open(fstream);
{
prev_directory = getcwd(NULL, 0);
- vector_rewind(includes);
+ vector_rewind(include_dirs);
- while((include = vector_get(includes)))
+ while((dir = vector_get(include_dirs)))
{
- chdir(include->name);
+ chdir(dir->name);
if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
{
- fstream = fstream_new(include->name, file_name);
+ fstream = fstream_new(dir->name, file_name);
fstream_open(fstream);
break;
}
- vector_move_next(includes);
+ vector_move_next(include_dirs);
}
chdir(prev_directory);
}
else
{
- /* parse the include file */
-
- /*unit_t __unit = unit_new(unit->runner, NULL, fstream);*/
- unit->parsing_include_file = 1;
- /* add the unit to the list of the runned units */
+ if(!unit->running_suite)
+ {/* it's the unit of a suite */
+ unit_t include = unit_new(unit->runner,unit->root, unit, fstream);
+
+ include->mutex = unit->root->mutex;
- /*xbt_os_mutex_acquire(unit->mutex);
- vector_push_back(__unit->runner->units->items, __unit);
- xbt_os_mutex_release(unit->mutex);*/
+ if(description)
+ include->description = strdup(description);
+ vector_push_back(unit->includes, include);
- if(want_dry_run)
- INFO2("checking unit %s including in %s...",fstream->name, unit->fstream->name);
+ fstream_parse(fstream, include, mutex);
+ }
+ else
+ {/* it's a include */
+ unit_t owner = vector_get_back(unit->suites);
+ unit_t include = unit_new(unit->runner,unit->root, owner, fstream);
+
+ include->mutex = unit->root->mutex;
+
+ if(description)
+ include->description = strdup(description);
- unit_parse(unit, context_new(), mutex, fstream->name, fstream->stream);
+ vector_push_back(owner->includes, include);
- fstream_free((void**)&fstream);
- unit->parsing_include_file = 0;
+ fstream_parse(fstream, include, mutex);
+ }
}
}
void
unit_handle_suite(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* description)
{
- suite_t suite = suite_new(unit, description);
- unit_add_suite(unit, suite);
- unit->running_suite = 1;
+ if(unit->running_suite)
+ {
+ exit_code = ESYNTAX;
+ unit_handle_failure(unit);
+ }
+ else
+ {
+ unit_t suite = unit_new(unit->runner, unit->root, unit, NULL);
+ suite->is_suite = 1;
+ suite->description = strdup(description);
+ vector_push_back(unit->suites, suite);
+ unit->running_suite = 1;
+ }
}
int