#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include "testmore.h"
static int test_num = 0;
static int test_fails = 0;
static int test_cases = 0;
static const char *test_plan_file;
static int test_plan_line=0;
const char *test_directive = NULL;
const char *test_reason = NULL;
void test_skip(const char *reason, int how_many, int unless)
{
if (unless)
return;
int done;
for (done = 0; done < how_many; ++done)
test_ok(1, NULL, "skip", reason, __FILE__, __LINE__, NULL);
}
void test_bail_out(const char *reason, const char *file, unsigned line)
{
printf("BAIL OUT! (%s at line %u) %s\n", file, line, reason);
fflush(stdout);
exit(255);
}
void test_plan_skip_all(const char *reason)
{
if (test_num > test_cases)
{
test_skip(reason, test_cases - test_num, 0);
exit(test_fails > 255 ? 255 : test_fails);
}
}
static void test_plan_exit(void)
{
fflush(stdout);
if (!test_num)
{
if (test_cases)
{
fprintf(stderr, "%s:%u: warning: No tests run!\n", test_plan_file, test_plan_line);
}
else
{
fprintf(stderr, "%s:%u: error: Looks like your test died before it could "
"output anything.\n", test_plan_file, test_plan_line);
}
}
else {
if (test_fails)
{
fprintf(stderr, "%s:%u: error: Looks like you failed %d tests of %d.\n",
test_plan_file, test_plan_line, test_fails, test_cases);
}
if (test_num < test_cases)
{
fprintf(stderr, "%s:%u: warning: Looks like you planned %d tests but only ran %d.\n",
test_plan_file, test_plan_line, test_cases, test_num);
}
else if (test_num > test_cases)
{
fprintf(stderr, "%s:%u: warning: Looks like you planned %d tests but ran %d extra.\n",
test_plan_file, test_plan_line, test_cases, test_num - test_cases);
}
}
fflush(stderr);
test_num = 0;
test_fails = 0;
test_cases = 0;
}
void test_plan_tests(int count, const char *file, unsigned line)
{
#if 0
if (atexit(test_plan_exit) < 0)
{
fprintf(stderr, "failed to setup atexit handler: %s\n",
strerror(errno));
fflush(stderr);
exit(255);
}
#endif
if (test_cases)
{
fprintf(stderr,
"%s:%u: error: You tried to plan twice!\n",
file, line);
fflush(stderr);
exit(255);
}
else
{
if (!count)
{
fprintf(stderr, "%s:%u: warning: You said to run 0 tests! You've got to run "
"something.\n", file, line);
fflush(stderr);
exit(255);
}
test_plan_file=file;
test_plan_line=line;
test_cases = count;
fprintf(stderr, "%s:%u: note: 1..%d\n", file, line, test_cases);
fflush(stdout);
}
}
int
test_diag(const char *directive, const char *reason,
const char *file, unsigned line, const char *fmt, ...)
{
int is_todo = directive && !strcmp(directive, "TODO");
va_list args;
va_start(args, fmt);
if (is_todo)
{
fputs("# ", stdout);
if (fmt)
vprintf(fmt, args);
fputs("\n", stdout);
fflush(stdout);
}
else
{
fflush(stdout);
fputs("# ", stderr);
if (fmt)
vfprintf(stderr, fmt, args);
fputs("\n", stderr);
fflush(stderr);
}
va_end(args);
return 1;
}
int
test_ok(int passed, const char *description, const char *directive,
const char *reason, const char *file, unsigned line,
const char *fmt, ...)
{
int is_todo = !passed && directive && !strcmp(directive, "TODO");
int is_setup = directive && !is_todo && !strcmp(directive, "SETUP");
if (is_setup)
{
if (!passed)
{
fflush(stdout);
fprintf(stderr, "# SETUP not ok%s%s%s%s\n",
description ? " - " : "",
description ? description : "",
reason ? " - " : "",
reason ? reason : "");
}
}
else
{
if (!test_cases)
{
atexit(test_plan_exit);
fprintf(stderr, "You tried to run a test without a plan! "
"Gotta have a plan. at %s line %u\n", file, line);
fflush(stderr);
exit(255);
}
++test_num;
if (!passed && !is_todo) {
++test_fails;
}
#if 0
fprintf(stderr, "%s:%u: note: %sok %d%s%s%s%s%s%s\n", file, line, passed ? "" : "not ", test_num,
description ? " - " : "",
description ? description : "",
directive ? " # " : "",
directive ? directive : "",
reason ? " " : "",
reason ? reason : "");
#endif
}
if (passed)
fflush(stdout);
else
{
va_list args;
va_start(args, fmt);
if (is_todo)
{
#if 0
printf("%s:%d: warning: Failed (TODO) test\n", file, line);
if (fmt)
vprintf(fmt, args);
#endif
fflush(stdout);
}
else
{
fflush(stdout);
fprintf(stderr, "%s:%d: error: Failed test [%s]\n", file, line, description);
if (fmt)
vfprintf(stderr, fmt, args);
fflush(stderr);
}
va_end(args);
}
return passed;
}
const char *
sec_errstr(int err)
{
#if 1
static int bufnum = 0;
static char buf[2][20];
bufnum = bufnum ? 0 : 1;
sprintf(buf[bufnum], "0x%X", err);
return buf[bufnum];
#else
if (err >= errSecErrnoBase && err <= errSecErrnoLimit)
return strerror(err - 100000);
#ifdef MAC_OS_X_VERSION_10_4
extern const char *cssmErrorString(long);
return cssmErrorString(err);
#else
extern const char *_ZN8Security15cssmErrorStringEl(long);
return _ZN8Security15cssmErrorStringEl(err);
#endif
#endif
}
int run_one_test(struct one_test_s *test, int argc, char * const *argv)
{
struct timeval start, stop;
if(test->entry==NULL) {
printf("%s:%d: error: wtf?\n", __FILE__, __LINE__);
return -1;
}
gettimeofday(&start, NULL);
test->entry(argc, argv);
gettimeofday(&stop, NULL);
test->failed_tests=test_fails;
test_plan_exit();
test->duration=(unsigned int) (stop.tv_sec-start.tv_sec)*1000+(stop.tv_usec/1000)-(start.tv_usec/1000);
return test->failed_tests;
};