Exemple #1
0
static void library_enter(MuLogger* _self, const char* path, MuLibrary* library)
{
    XmlLogger* self = (XmlLogger*) _self;

    if (library)
    {
        fprintf(self->out, INDENT_LIBRARY "<library file=\"%s\" name=\"%s\">\n",
                basename_pure(path), mu_library_name(library));
    }
    else
    {
        fprintf(self->out, INDENT_LIBRARY "<library file=\"%s\">\n", basename_pure(path));
    }
}
Exemple #2
0
static void test_log(MuLogger* _self, MuLogEvent* event)
{
    XmlLogger* self = (XmlLogger*) _self;
    const char* level_str = "unknown";

    switch (event->level)
    {
        case MU_LEVEL_WARNING:
            level_str = "warning"; break;
        case MU_LEVEL_INFO:
            level_str = "info"; break;
        case MU_LEVEL_VERBOSE:
            level_str = "verbose"; break;
        case MU_LEVEL_DEBUG:
            level_str = "debug"; break;
        case MU_LEVEL_TRACE:
            level_str = "trace"; break;
    }
    fprintf(self->out, INDENT_TEST INDENT "<event level=\"%s\"", level_str);

    fprintf(self->out, " stage=\"%s\"", mu_test_stage_to_string(event->stage));
    
    if (event->file)
        fprintf(self->out, " file=\"%s\"", basename_pure(event->file));
    if (event->line)
        fprintf(self->out, " line=\"%u\"", event->line);

    fprintf(self->out, ">");
    fprintf(self->out, "<![CDATA[%s]]>", event->message);
    fprintf(self->out, "</event>\n");
}
Exemple #3
0
// Opens a library and returns a handle
static struct MuLibrary*
sh_open (struct MuLoader* self, const char* path, MuError** err)
{
    ShLibrary* library = NULL;
    Process handle;
    array* tests = NULL;
    char* line = NULL;
    char* dot = NULL;
    unsigned int len;
    struct stat statbuf;

    /* As a sanity check, make sure the file is actually valid */
    if (stat(path, &statbuf) != 0)
    {
        MU_RAISE_GOTO(error, err, MU_ERROR_LOAD_LIBRARY, "%s: %s",
                      path, strerror(errno));
    }

    if (!S_ISREG(statbuf.st_mode))
    {
        MU_RAISE_GOTO(error, err, MU_ERROR_LOAD_LIBRARY, "%s: not a file",
                      path);
    }

    library = calloc(1, sizeof(ShLibrary));

    library->base.loader = self;
    library->path = strdup(path);
    library->name = strdup(basename_pure(path));

    dot = strrchr(library->name, '.');
    if (dot)
    {
        *dot = '\0';
    }

    mu_sh_exec(&handle, path, "mu_enum_test_functions >& ${MU_CMD_OUT}");

    while ((len = process_channel_read_line(&handle, 4, &line)))
    {
        ShTest* test = calloc(1, sizeof(ShTest));
        char* div1, *div2;

        line[len-1] = '\0';
        div1 = strchr(line, '_');
        div2 = strchr(div1+1, '_');

        if (div1 && div2)
        {
            test->base.loader = self;
            test->base.library = (MuLibrary*) library;
            test->function = strdup(line);

            *div1 = *div2 = '\0';

            test->suite = strdup(div1+1);
            test->name = strdup(div2+1);

            tests = array_append(tests, test);
        }

        free(line);
    }

    process_close(&handle);

    library->tests = (ShTest**) tests;

error:

    return (MuLibrary*) library;
}
Exemple #4
0
MuLibrary*
cloader_open(MuLoader* _self, const char* path, MuError** _err)
{
	CLibrary* library = xmalloc(sizeof (CLibrary));
    MuError* err = NULL;
    void (*stub_hook)(MuEntryInfo*** es);
    char *last_dot;

    if (!library)
    {
        MU_RAISE_GOTO(error, _err, MU_ERROR_MEMORY, "Out of memory");
    }

    library->base.loader = _self;
	library->tests = NULL;
	library->fixture_setups = NULL;
    library->fixture_teardowns = NULL;
	library->library_setup = NULL;
    library->library_teardown = NULL;
    library->library_construct = NULL;
    library->library_destruct = NULL;
	library->path = strdup(path);
    library->name = NULL;
	library->dlhandle = mu_dlopen(library->path, RTLD_NOW);

    if (!library->dlhandle)
    {
        MU_RAISE_GOTO(error, _err, MU_ERROR_LOAD_LIBRARY, "%s", dlerror());
    }

    if ((stub_hook = dlsym(library->dlhandle, "__mu_stub_hook")))
    {
        int i;
        MuEntryInfo** entries;

        stub_hook(&entries);

        for (i = 0; entries[i]; i++)
        {
            if (!add(entries[i], library, &err))
            {
                MU_RERAISE_GOTO(error, _err, err);
            }
        }
    }
#ifdef HAVE_LIBELF
    else if (!cloader_scan(_self, library, &err))
    {
        MU_RERAISE_GOTO(error, _err, err);
    }
#else
    else
    {
        MU_RAISE_GOTO(error, _err, MU_ERROR_LOAD_LIBRARY, 
                      "Library did not contain a loading stub "
                      "and reflection is unavailable");
    }
#endif

    /* If an explicit library name was not available, create one */
    if (!library->name)
    {
        library->name = strdup(basename_pure(path));
        if (!library->name)
        {
            MU_RAISE_GOTO(error, _err, MU_ERROR_MEMORY, "Out of memory");
        }
        last_dot = strrchr(library->name, '.');
        if (last_dot)
        {
            *last_dot = '\0';
        }
    }

    return (MuLibrary*) library;

error:
    
    if (library)
    {
        cloader_close(_self, (MuLibrary*) library);
    }

    return NULL;
}
Exemple #5
0
static void test_leave(MuLogger* _self, 
                       MuTest* test, MuTestResult* summary)
{
    XmlLogger* self = (XmlLogger*) _self;
    const char* stage;
    FILE* out = self->out;
    bool result = summary->status == summary->expected;
    const char* result_str;

    if (summary->status == MU_STATUS_DEBUG)
    {
        result_str = "debug";
    }
    else if (result)
    {
        switch (summary->status)
        {		
        case MU_STATUS_SUCCESS:
            result_str = "pass";
            break;
        case MU_STATUS_SKIPPED:
            result_str = "skip";
            break;
        default:
            result_str = "xfail";
            break;
        }
    }
    else
    {
        switch (summary->status)
        {		
        case MU_STATUS_SUCCESS:
            result_str = "xpass";
            break;
        case MU_STATUS_SKIPPED:
            result_str = "skip";
            break;
        default:
            result_str = "fail";
            break;
        }
    }
        
    if (summary->status == MU_STATUS_SUCCESS)
	{
        fprintf(out, INDENT_TEST INDENT "<result status=\"%s\"/>\n", result_str);
    }
    else
    {
        stage = mu_test_stage_to_string(summary->stage);
        
        if (summary->reason)
        {
            fprintf(out, INDENT_TEST INDENT "<result status=\"%s\" stage=\"%s\"", result_str, stage);
            if (summary->file)
                fprintf(out, " file=\"%s\"", basename_pure(summary->file));
            if (summary->line)
                fprintf(out, " line=\"%i\"", summary->line);

            fprintf(out, ">");
            fprintf(out, "<![CDATA[%s]]>", summary->reason);
            fprintf(out, "</result>\n");
        }
        else
        {
            fprintf(out, INDENT_TEST INDENT "<result status=\"fail\" stage=\"%s\"", stage);
            if (summary->file)
                fprintf(out, " file=\"%s\"", basename_pure(summary->file));
            if (summary->line)
                fprintf(out, " line=\"%i\"", summary->line);
            fprintf(out, "/>\n");
        }
	}

    if (summary->backtrace)
    {
        MuBacktrace* frame;
        fprintf(out, INDENT_TEST INDENT "<backtrace>\n");
        for (frame = summary->backtrace; frame; frame = frame->up)
        {
            fprintf(out, INDENT_TEST INDENT INDENT "<frame");
            if (frame->file_name)
            {
                fprintf(out, " binary_file=\"%s\"", frame->file_name);
            }
            if (frame->func_name)
            {
                fprintf(out, " function=\"%s\"", frame->func_name);
            }
            if (frame->func_addr)
            {
                fprintf(out, " func_addr=\"%lx\"", frame->func_addr);
            }
            if (frame->return_addr)
            {
                fprintf(out, " return_addr=\"%lx\"", frame->return_addr);
            }
            fprintf(out, "/>\n");
        }
        fprintf(out, INDENT_TEST "  </backtrace>\n");
    }

    fprintf(out, INDENT_TEST "</test>\n");
}