#include #include #include #include #include #include #include int test_selector(const struct dirent *ep) { return fnmatch("*_tests", ep->d_name, 0) == 0; } int run_tests_file(char *filename) { if(access(filename, R_OK | X_OK) == 0) { return system(filename); } return -1; } int main(int argc, char *argv[]) { int entcount = 0; int rc = 0; int i = 0; int ntests = 0; char *testsdir = NULL; char *valgrind = getenv("VALGRIND"); struct dirent **namelist = NULL; struct dirent *ep = NULL; if(argc > 1) { testsdir = argv[1]; } if(!testsdir) { testsdir = getenv("TESTS"); } if(!testsdir) { testsdir = "./tests"; } entcount = scandir((const char *)testsdir, &namelist, test_selector, alphasort); check(entcount > -1, "Failed to scan tests dir"); for(i = 0; i < entcount; i++) { ep = namelist[i]; check(ep, "Dirent is missing."); char filename[256]; rc = sprintf(filename, "%s/%s", testsdir, ep->d_name); check(rc > -1, "Failed to build filename."); debug("Found filename '%s'", filename); free(ep); if(valgrind) { char command[1024]; rc = sprintf(command, "%s %s", valgrind, filename); check(rc > -1, "Failed to build command with valgrind."); rc = run_tests_file(command); } else { rc = run_tests_file(filename); } if(rc > 0) { debug("Skipping '%s'", filename); continue; } ntests++; if(rc == 0) { printf("%s PASS\n", filename); continue; } printf("ERROR in test %s", filename); if(access("tests/tests.log", R_OK) == 0) { printf(": here's tests/tests.log\n"); printf("------\n"); rc = system("tail tests/tests.log"); } else { printf("\n"); } goto error; } printf("------\n"); printf("Total of %d test file%s run.\n", ntests, ntests > 1 ? "s" : ""); if(namelist) { free(namelist); } return 0; error: if(namelist) { free(namelist); } return rc != 0 ? rc : 1; }