xref: /dragonfly/contrib/lvm2/dist/test/harness.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /*	$NetBSD: harness.c,v 1.1.1.1 2009/12/02 00:25:58 haad Exp $	*/
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino #include <fcntl.h>
4*86d7f5d3SJohn Marino #include <string.h>
5*86d7f5d3SJohn Marino #include <stdio.h>
6*86d7f5d3SJohn Marino #include <sys/socket.h>
7*86d7f5d3SJohn Marino #include <sys/wait.h>
8*86d7f5d3SJohn Marino #include <unistd.h>
9*86d7f5d3SJohn Marino #include <stdlib.h>
10*86d7f5d3SJohn Marino 
11*86d7f5d3SJohn Marino pid_t pid;
12*86d7f5d3SJohn Marino int fds[2];
13*86d7f5d3SJohn Marino int *status;
14*86d7f5d3SJohn Marino int nfailed = 0;
15*86d7f5d3SJohn Marino int nskipped = 0;
16*86d7f5d3SJohn Marino int npassed = 0;
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino char *readbuf = NULL;
19*86d7f5d3SJohn Marino int readbuf_sz = 0, readbuf_used = 0;
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino int die = 0;
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino #define PASSED 0
24*86d7f5d3SJohn Marino #define SKIPPED 1
25*86d7f5d3SJohn Marino #define FAILED 2
26*86d7f5d3SJohn Marino 
handler(int s)27*86d7f5d3SJohn Marino void handler( int s ) {
28*86d7f5d3SJohn Marino 	signal( s, SIG_DFL );
29*86d7f5d3SJohn Marino 	kill( pid, s );
30*86d7f5d3SJohn Marino 	die = s;
31*86d7f5d3SJohn Marino }
32*86d7f5d3SJohn Marino 
dump()33*86d7f5d3SJohn Marino void dump() {
34*86d7f5d3SJohn Marino 	write(1, readbuf, readbuf_used);
35*86d7f5d3SJohn Marino }
36*86d7f5d3SJohn Marino 
clear()37*86d7f5d3SJohn Marino void clear() {
38*86d7f5d3SJohn Marino 	readbuf_used = 0;
39*86d7f5d3SJohn Marino }
40*86d7f5d3SJohn Marino 
drain()41*86d7f5d3SJohn Marino void drain() {
42*86d7f5d3SJohn Marino 	int sz;
43*86d7f5d3SJohn Marino 	char buf[2048];
44*86d7f5d3SJohn Marino 	while (1) {
45*86d7f5d3SJohn Marino 		sz = read(fds[1], buf, 2048);
46*86d7f5d3SJohn Marino 		if (sz <= 0)
47*86d7f5d3SJohn Marino 			return;
48*86d7f5d3SJohn Marino 		if (readbuf_used + sz >= readbuf_sz) {
49*86d7f5d3SJohn Marino 			readbuf_sz = readbuf_sz ? 2 * readbuf_sz : 4096;
50*86d7f5d3SJohn Marino 			readbuf = realloc(readbuf, readbuf_sz);
51*86d7f5d3SJohn Marino 		}
52*86d7f5d3SJohn Marino 		if (!readbuf)
53*86d7f5d3SJohn Marino 			exit(205);
54*86d7f5d3SJohn Marino 		memcpy(readbuf + readbuf_used, buf, sz);
55*86d7f5d3SJohn Marino 		readbuf_used += sz;
56*86d7f5d3SJohn Marino 	}
57*86d7f5d3SJohn Marino }
58*86d7f5d3SJohn Marino 
passed(int i,char * f)59*86d7f5d3SJohn Marino void passed(int i, char *f) {
60*86d7f5d3SJohn Marino 	++ npassed;
61*86d7f5d3SJohn Marino 	status[i] = PASSED;
62*86d7f5d3SJohn Marino 	printf("passed.\n");
63*86d7f5d3SJohn Marino }
64*86d7f5d3SJohn Marino 
skipped(int i,char * f)65*86d7f5d3SJohn Marino void skipped(int i, char *f) {
66*86d7f5d3SJohn Marino 	++ nskipped;
67*86d7f5d3SJohn Marino 	status[i] = SKIPPED;
68*86d7f5d3SJohn Marino 	printf("skipped.\n");
69*86d7f5d3SJohn Marino }
70*86d7f5d3SJohn Marino 
failed(int i,char * f,int st)71*86d7f5d3SJohn Marino void failed(int i, char *f, int st) {
72*86d7f5d3SJohn Marino 	++ nfailed;
73*86d7f5d3SJohn Marino 	status[i] = FAILED;
74*86d7f5d3SJohn Marino 	if(die == 2) {
75*86d7f5d3SJohn Marino 		printf("interrupted.\n");
76*86d7f5d3SJohn Marino 		return;
77*86d7f5d3SJohn Marino 	}
78*86d7f5d3SJohn Marino 	printf("FAILED.\n");
79*86d7f5d3SJohn Marino 	printf("-- FAILED %s ------------------------------------\n", f);
80*86d7f5d3SJohn Marino 	dump();
81*86d7f5d3SJohn Marino 	printf("-- FAILED %s (end) ------------------------------\n", f);
82*86d7f5d3SJohn Marino }
83*86d7f5d3SJohn Marino 
run(int i,char * f)84*86d7f5d3SJohn Marino void run(int i, char *f) {
85*86d7f5d3SJohn Marino 	pid = fork();
86*86d7f5d3SJohn Marino 	if (pid < 0) {
87*86d7f5d3SJohn Marino 		perror("Fork failed.");
88*86d7f5d3SJohn Marino 		exit(201);
89*86d7f5d3SJohn Marino 	} else if (pid == 0) {
90*86d7f5d3SJohn Marino 		close(0);
91*86d7f5d3SJohn Marino 		dup2(fds[0], 1);
92*86d7f5d3SJohn Marino 		dup2(fds[0], 2);
93*86d7f5d3SJohn Marino 		execlp("bash", "bash", f, NULL);
94*86d7f5d3SJohn Marino 		perror("execlp");
95*86d7f5d3SJohn Marino 		fflush(stderr);
96*86d7f5d3SJohn Marino 		_exit(202);
97*86d7f5d3SJohn Marino 	} else {
98*86d7f5d3SJohn Marino 		char buf[128];
99*86d7f5d3SJohn Marino 		snprintf(buf, 128, "%s ...", f);
100*86d7f5d3SJohn Marino 		buf[127] = 0;
101*86d7f5d3SJohn Marino 		printf("Running %-40s ", buf);
102*86d7f5d3SJohn Marino 		fflush(stdout);
103*86d7f5d3SJohn Marino 		int st, w;
104*86d7f5d3SJohn Marino 		while ((w = waitpid(pid, &st, WNOHANG)) == 0) {
105*86d7f5d3SJohn Marino 			drain();
106*86d7f5d3SJohn Marino 			usleep(20000);
107*86d7f5d3SJohn Marino 		}
108*86d7f5d3SJohn Marino 		if (w != pid) {
109*86d7f5d3SJohn Marino 			perror("waitpid");
110*86d7f5d3SJohn Marino 			exit(206);
111*86d7f5d3SJohn Marino 		}
112*86d7f5d3SJohn Marino 		drain();
113*86d7f5d3SJohn Marino 		if (WIFEXITED(st)) {
114*86d7f5d3SJohn Marino 			if (WEXITSTATUS(st) == 0) {
115*86d7f5d3SJohn Marino 				passed(i, f);
116*86d7f5d3SJohn Marino 			} else if (WEXITSTATUS(st) == 200) {
117*86d7f5d3SJohn Marino 				skipped(i, f);
118*86d7f5d3SJohn Marino 			} else {
119*86d7f5d3SJohn Marino 				failed(i, f, st);
120*86d7f5d3SJohn Marino 			}
121*86d7f5d3SJohn Marino 		} else {
122*86d7f5d3SJohn Marino 			failed(i, f, st);
123*86d7f5d3SJohn Marino 		}
124*86d7f5d3SJohn Marino 		clear();
125*86d7f5d3SJohn Marino 	}
126*86d7f5d3SJohn Marino }
127*86d7f5d3SJohn Marino 
main(int argc,char ** argv)128*86d7f5d3SJohn Marino int main(int argc, char **argv) {
129*86d7f5d3SJohn Marino 	int i;
130*86d7f5d3SJohn Marino 	status = alloca(sizeof(int)*argc);
131*86d7f5d3SJohn Marino 
132*86d7f5d3SJohn Marino 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds)) {
133*86d7f5d3SJohn Marino 		perror("socketpair");
134*86d7f5d3SJohn Marino 		return 201;
135*86d7f5d3SJohn Marino 	}
136*86d7f5d3SJohn Marino 
137*86d7f5d3SJohn Marino         if ( fcntl( fds[1], F_SETFL, O_NONBLOCK ) == -1 ) {
138*86d7f5d3SJohn Marino 		perror("fcntl on socket");
139*86d7f5d3SJohn Marino 		return 202;
140*86d7f5d3SJohn Marino 	}
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino 	/* set up signal handlers */
143*86d7f5d3SJohn Marino         for (i = 0; i <= 32; ++i) {
144*86d7f5d3SJohn Marino             if (i == SIGCHLD || i == SIGWINCH || i == SIGURG)
145*86d7f5d3SJohn Marino                 continue;
146*86d7f5d3SJohn Marino             signal(i, handler);
147*86d7f5d3SJohn Marino         }
148*86d7f5d3SJohn Marino 
149*86d7f5d3SJohn Marino 	/* run the tests */
150*86d7f5d3SJohn Marino 	for (i = 1; i < argc; ++ i) {
151*86d7f5d3SJohn Marino 		run(i, argv[i]);
152*86d7f5d3SJohn Marino 		if (die)
153*86d7f5d3SJohn Marino 			break;
154*86d7f5d3SJohn Marino 	}
155*86d7f5d3SJohn Marino 
156*86d7f5d3SJohn Marino 	printf("\n## %d tests: %d OK, %d failed, %d skipped\n",
157*86d7f5d3SJohn Marino 	       npassed + nfailed + nskipped, npassed, nfailed, nskipped);
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino 	/* print out a summary */
160*86d7f5d3SJohn Marino 	if (nfailed || nskipped) {
161*86d7f5d3SJohn Marino 		for (i = 1; i < argc; ++ i) {
162*86d7f5d3SJohn Marino 			switch (status[i]) {
163*86d7f5d3SJohn Marino 			case FAILED:
164*86d7f5d3SJohn Marino 				printf("FAILED: %s\n", argv[i]);
165*86d7f5d3SJohn Marino 				break;
166*86d7f5d3SJohn Marino 			case SKIPPED:
167*86d7f5d3SJohn Marino 				printf("skipped: %s\n", argv[i]);
168*86d7f5d3SJohn Marino 				break;
169*86d7f5d3SJohn Marino 			}
170*86d7f5d3SJohn Marino 		}
171*86d7f5d3SJohn Marino 		printf("\n");
172*86d7f5d3SJohn Marino 		return nfailed > 0 || die;
173*86d7f5d3SJohn Marino 	}
174*86d7f5d3SJohn Marino 	return !die;
175*86d7f5d3SJohn Marino }
176