runtest.c 2.87 KB
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>

#include "runtest.h"

#define TEST_OK_CHAR		'.'
#define TEST_FAILED_CHAR	'F'
#define TEST_ERROR_CHAR		'E'


const char results[3] = {
    TEST_OK_CHAR,
    TEST_FAILED_CHAR,
    TEST_ERROR_CHAR
};


void *
load_symbol(void * dlhandle, const char * const symbol)
{
    void * sym = dlsym(dlhandle, symbol);
    char * error;

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
    }

    return sym;
}

void
runtests(
        const char * const filename,
        size_t * _count,
        size_t * failures,
        size_t * errors)
{
    size_t * count;
    testfunc * tests;
    const char * const testname;
    //char * const * funcnames;
    char testfile[NAME_MAX+3] = "./";

    strcat(testfile, filename);

    void (*setUp)()    = NULL;
    void (*tearDown)() = NULL;

    size_t index;
    void * dlhandle;

    dlhandle = dlopen(testfile, RTLD_LAZY);
    if (!dlhandle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    * (void **) (&count)    = load_symbol(dlhandle, "count");
    * (void **) (&tests)    = load_symbol(dlhandle, "tests");
    * (void **) (&testname) = load_symbol(dlhandle, "testname");
    // * (void **) (&funcnames) = load_symbol(dlhandle, "funcnames");

    * (void **) (&setUp)    = load_symbol(dlhandle, "setUp");
    * (void **) (&tearDown) = load_symbol(dlhandle, "tearDown");
    
    if (NULL == count || NULL == tests || NULL == testname) {
        *errors = TEST_ERROR;
        return;
    }

    *_count += *count;

    printf("running tests for %s\n", testname);

    for (index=0; index<*count; index++) {
        int result;

        if (NULL != setUp) {
            setUp();
        }

        result = tests[index]();

        if (NULL != setUp) {
            tearDown();
        }

        switch (result) {
            case TEST_FAILED: (*failures)++; break;
            case TEST_ERROR:  (*errors)++; break;
        }

        putchar(results[result]);

        if (79 == index%80) {
            putchar('\n');
        }

        fflush(stdout);
    }
    puts("\n");

    dlclose(dlhandle);
}

int
main(int argc, char * argv[])
{
    size_t count      = 0;
    size_t errors     = 0;
    size_t failures   = 0;
    size_t assertions = 0;

    DIR *  dir;
    struct dirent * dirent;

    dir = opendir(".");

    dirent = readdir(dir);
    while (dirent) {
        if (0 == strcmp("Test.la", dirent->d_name + strlen(dirent->d_name) - 7)) {
            runtests(dirent->d_name, &count, &failures, &errors);
        }

        dirent = readdir(dir);
    }
    closedir(dir);

    printf("running %lu tests: %lu - OK, %lu - FAILED, %lu - ERRORS\n",
            count,
            count - errors - failures,
            failures,
            errors);

    return failures + errors;
}

// vim: set et ts=4 sw=4: