|
nsz |
54c268 |
#include <stdlib.h>
|
|
nsz |
9087bf |
#include <stdio.h>
|
|
nsz |
9087bf |
#include <stdarg.h>
|
|
nsz |
54c268 |
#include <string.h>
|
|
nsz |
54c268 |
#include <errno.h>
|
|
nsz |
54c268 |
#include <sys/types.h>
|
|
nsz |
54c268 |
#include <sys/wait.h>
|
|
nsz |
5348e7 |
#include <sys/time.h>
|
|
nsz |
5348e7 |
#include <sys/resource.h>
|
|
nsz |
54c268 |
#include <unistd.h>
|
|
nsz |
7308b3 |
#include "test.h"
|
|
nsz |
7308b3 |
|
|
nsz |
7d87d3 |
#define B(f)
|
|
nsz |
7d87d3 |
#define T(f) void f();
|
|
nsz |
7d87d3 |
#include "tests.h"
|
|
nsz |
7308b3 |
#undef T
|
|
nsz |
7308b3 |
|
|
nsz |
9087bf |
static int failed;
|
|
nsz |
9087bf |
static const char *name;
|
|
nsz |
7308b3 |
|
|
nsz |
3a7270 |
static int slow;
|
|
nsz |
7308b3 |
static int verbose;
|
|
nsz |
7308b3 |
static int count;
|
|
nsz |
7308b3 |
static int nfailed;
|
|
nsz |
7308b3 |
|
|
nsz |
a520c1 |
static void errtimer() { error("use *_timer in benchmarks only\n"); }
|
|
nsz |
a520c1 |
void start_timer() { errtimer(); }
|
|
nsz |
a520c1 |
void stop_timer() { errtimer(); }
|
|
nsz |
a520c1 |
void reset_timer() { errtimer(); }
|
|
nsz |
a520c1 |
|
|
nsz |
9087bf |
void error__(const char *n, int l, const char *s, ...) {
|
|
nsz |
9087bf |
va_list ap;
|
|
nsz |
9087bf |
|
|
nsz |
1b83d1 |
if (failed == 0 && nfailed == 0)
|
|
nsz |
5348e7 |
dprintf(1, "FAIL\n");
|
|
nsz |
9087bf |
failed = 1;
|
|
nsz |
1b83d1 |
dprintf(1, " ERROR %s %s:%d: ", name, n, l);
|
|
nsz |
9087bf |
va_start(ap, s);
|
|
nsz |
1b83d1 |
vdprintf(1, s, ap);
|
|
nsz |
9087bf |
va_end(ap);
|
|
nsz |
9087bf |
}
|
|
nsz |
9087bf |
|
|
nsz |
5348e7 |
static void setrl(int r, long lim) {
|
|
nsz |
5348e7 |
struct rlimit rl;
|
|
nsz |
5348e7 |
|
|
nsz |
5348e7 |
if (getrlimit(r, &rl))
|
|
nsz |
5348e7 |
error("getrlimit %d: %s\n", r, strerror(errno));
|
|
nsz |
5348e7 |
rl.rlim_cur = lim;
|
|
nsz |
5348e7 |
if (setrlimit(r, &rl))
|
|
nsz |
5348e7 |
error("setrlimit %d: %s\n", r, strerror(errno));
|
|
nsz |
5348e7 |
}
|
|
nsz |
5348e7 |
|
|
nsz |
7308b3 |
static void run(const char *n, void (*f)()) {
|
|
nsz |
54c268 |
pid_t pid;
|
|
nsz |
9087bf |
int s;
|
|
nsz |
54c268 |
|
|
nsz |
7308b3 |
count++;
|
|
nsz |
9087bf |
failed = 0;
|
|
nsz |
9087bf |
name = n;
|
|
nsz |
7308b3 |
if (verbose)
|
|
nsz |
1b83d1 |
dprintf(1, "running %s:\n", name);
|
|
nsz |
54c268 |
|
|
nsz |
54c268 |
pid = fork();
|
|
nsz |
54c268 |
if (pid == 0) {
|
|
nsz |
54c268 |
/* run test in a child process */
|
|
nsz |
5348e7 |
setrl(RLIMIT_CORE, 1<<24);
|
|
nsz |
5348e7 |
setrl(RLIMIT_STACK, 1<<16);
|
|
nsz |
5348e7 |
setrl(RLIMIT_CPU, 2);
|
|
nsz |
54c268 |
f();
|
|
nsz |
9087bf |
exit(failed);
|
|
nsz |
54c268 |
}
|
|
nsz |
54c268 |
|
|
nsz |
54c268 |
if (pid == -1)
|
|
nsz |
54c268 |
error("fork failed: %s\n", strerror(errno));
|
|
nsz |
54c268 |
else {
|
|
nsz |
9087bf |
if (waitpid(pid, &s, 0) == -1)
|
|
nsz |
54c268 |
error("waitpid failed: %s\n", strerror(errno));
|
|
nsz |
9087bf |
else if (!WIFEXITED(s))
|
|
nsz |
9087bf |
error("abnormal exit: %s\n", WIFSIGNALED(s) ? strsignal(WTERMSIG(s)) : "(unknown)");
|
|
nsz |
54c268 |
else
|
|
nsz |
9087bf |
failed = !!WEXITSTATUS(s);
|
|
nsz |
54c268 |
}
|
|
nsz |
54c268 |
|
|
nsz |
9087bf |
if (failed) {
|
|
nsz |
7308b3 |
nfailed++;
|
|
nsz |
1b83d1 |
dprintf(1, "FAILED %s\n", name);
|
|
nsz |
7308b3 |
} else if (verbose)
|
|
nsz |
1b83d1 |
dprintf(1, "PASSED %s\n", name);
|
|
nsz |
7308b3 |
}
|
|
nsz |
7308b3 |
|
|
nsz |
7308b3 |
static int summary() {
|
|
nsz |
8f27a3 |
if (nfailed)
|
|
nsz |
1b83d1 |
dprintf(1, "FAIL (%d out of %d tests)\n", nfailed, count);
|
|
nsz |
8f27a3 |
else
|
|
nsz |
1b83d1 |
dprintf(1, "ok (%d tests)\n", count);
|
|
nsz |
7308b3 |
return !!nfailed;
|
|
nsz |
7308b3 |
}
|
|
nsz |
7308b3 |
|
|
nsz |
3a7270 |
static void usage() {
|
|
nsz |
1b83d1 |
dprintf(1, "usage: ./t [-vs]\n");
|
|
nsz |
3a7270 |
exit(1);
|
|
nsz |
3a7270 |
}
|
|
nsz |
3a7270 |
|
|
nsz |
3a7270 |
int main(int argc, char *argv[]) {
|
|
nsz |
3a7270 |
int c;
|
|
nsz |
3a7270 |
|
|
nsz |
3a7270 |
while((c = getopt(argc, argv, "vs")) != -1)
|
|
nsz |
3a7270 |
switch(c) {
|
|
nsz |
3a7270 |
case 'v':
|
|
nsz |
3a7270 |
verbose = 1;
|
|
nsz |
3a7270 |
break;
|
|
nsz |
3a7270 |
case 's':
|
|
nsz |
3a7270 |
slow = 1; /* TODO */
|
|
nsz |
3a7270 |
break;
|
|
nsz |
3a7270 |
default:
|
|
nsz |
3a7270 |
usage();
|
|
nsz |
3a7270 |
}
|
|
nsz |
3a7270 |
if (optind != argc)
|
|
nsz |
3a7270 |
usage();
|
|
nsz |
3a7270 |
|
|
nsz |
7308b3 |
#define T(t) run(#t, t);
|
|
nsz |
7d87d3 |
#include "tests.h"
|
|
nsz |
7308b3 |
return summary();
|
|
nsz |
7308b3 |
}
|