runtest.c 2.38 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);
        exit(EXIT_FAILURE);
    }

    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;

    size_t index;
    void * dlhandle;

    dlhandle = dlopen("./cclass.test", 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");
    
    *_count += *count;

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

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

        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", dirent->d_name + strlen(dirent->d_name) - 5)) {
            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 0;
}

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