add setrlimit to test run
[libc-test] / common / t.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <sys/time.h>
9 #include <sys/resource.h>
10 #include <unistd.h>
11 #include "test.h"
12
13 #define B(f)
14 #define T(f) void f();
15 #include "tests.h"
16 #undef T
17
18 static int failed;
19 static const char *name;
20
21 static int slow;
22 static int verbose;
23 static int count;
24 static int nfailed;
25
26 static void errtimer() { error("use *_timer in benchmarks only\n"); }
27 void start_timer() { errtimer(); }
28 void stop_timer() { errtimer(); }
29 void reset_timer() { errtimer(); }
30
31 void error__(const char *n, int l, const char *s, ...) {
32         va_list ap;
33
34         if (failed == 0 && nfailed == 0)
35                 dprintf(1, "FAIL\n");
36         failed = 1;
37         dprintf(1, " ERROR %s %s:%d: ", name, n, l);
38         va_start(ap, s);
39         vdprintf(1, s, ap);
40         va_end(ap);
41 }
42
43 static void setrl(int r, long lim) {
44         struct rlimit rl;
45
46         if (getrlimit(r, &rl))
47                 error("getrlimit %d: %s\n", r, strerror(errno));
48         rl.rlim_cur = lim;
49         if (setrlimit(r, &rl))
50                 error("setrlimit %d: %s\n", r, strerror(errno));
51 }
52
53 static void run(const char *n, void (*f)()) {
54         pid_t pid;
55         int s;
56
57         count++;
58         failed = 0;
59         name = n;
60         if (verbose)
61                 dprintf(1, "running %s:\n", name);
62
63         pid = fork();
64         if (pid == 0) {
65                 /* run test in a child process */
66                 setrl(RLIMIT_CORE, 1<<24);
67                 setrl(RLIMIT_STACK, 1<<16);
68                 setrl(RLIMIT_CPU, 2);
69                 f();
70                 exit(failed);
71         }
72
73         if (pid == -1)
74                 error("fork failed: %s\n", strerror(errno));
75         else {
76                 if (waitpid(pid, &s, 0) == -1)
77                         error("waitpid failed: %s\n", strerror(errno));
78                 else if (!WIFEXITED(s))
79                         error("abnormal exit: %s\n", WIFSIGNALED(s) ? strsignal(WTERMSIG(s)) : "(unknown)");
80                 else
81                         failed = !!WEXITSTATUS(s);
82         }
83
84         if (failed) {
85                 nfailed++;
86                 dprintf(1, "FAILED %s\n", name);
87         } else if (verbose)
88                 dprintf(1, "PASSED %s\n", name);
89 }
90
91 static int summary() {
92         if (nfailed)
93                 dprintf(1, "FAIL (%d out of %d tests)\n", nfailed, count);
94         else
95                 dprintf(1, "ok (%d tests)\n", count);
96         return !!nfailed;
97 }
98
99 static void usage() {
100         dprintf(1, "usage: ./t [-vs]\n");
101         exit(1);
102 }
103
104 int main(int argc, char *argv[]) {
105         int c;
106
107         while((c = getopt(argc, argv, "vs")) != -1)
108                 switch(c) {
109                 case 'v':
110                         verbose = 1;
111                         break;
112                 case 's':
113                         slow = 1; /* TODO */
114                         break;
115                 default:
116                         usage();
117                 }
118         if (optind != argc)
119                 usage();
120
121 #define T(t) run(#t, t);
122 #include "tests.h"
123         return summary();
124 }