document the new binlog stats
[beanstalkd.git] / integ-test.c
blob95dd492b2af68c6604defa5eeb7a66d7258dd358
1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <signal.h>
6 #include <sys/stat.h>
7 #include <sys/socket.h>
8 #include <netdb.h>
9 #include <netinet/ip.h>
10 #include <arpa/inet.h>
11 #include <fcntl.h>
12 #include <sys/wait.h>
13 #include <errno.h>
14 #include "ct/ct.h"
15 #include "dat.h"
17 static void testsrv(char*, char*, int);
18 static void forksrv(int*, int*);
19 static int copy(int, int, int);
20 static int diff(char*, int);
21 static int diallocal(int);
22 static void cleanup(int sig);
24 typedef struct T T;
25 struct T {
26 char *cmd;
27 char *exp;
30 static T ts[] = {
31 {"sh-tests/allow-underscore.commands", "sh-tests/allow-underscore.expected"},
32 {"sh-tests/delete_ready.commands", "sh-tests/delete_ready.expected"},
33 {"sh-tests/multi-tube.commands", "sh-tests/multi-tube.expected"},
34 {"sh-tests/no_negative_delays.commands", "sh-tests/no_negative_delays.expected"},
35 {"sh-tests/omit-time-left.commands", "sh-tests/omit-time-left.expected"},
36 {"sh-tests/pause-tube.commands", "sh-tests/pause-tube.expected"},
37 {"sh-tests/small_delay.commands", "sh-tests/small_delay.expected"},
38 {"sh-tests/too-big.commands", "sh-tests/too-big.expected"},
39 {"sh-tests/ttr-large.commands", "sh-tests/ttr-large.expected"},
40 {"sh-tests/zero_delay.commands", "sh-tests/zero_delay.expected"},
41 {},
44 static int srvpid;
47 void
48 cttestsrv()
50 int i;
52 for (i = 0; ts[i].cmd; i++) {
53 testsrv(ts[i].cmd, ts[i].exp, 4096);
54 testsrv(ts[i].cmd, ts[i].exp, 1);
59 static void
60 testsrv(char *cmd, char *exp, int bufsiz)
62 int diffst, srvst, port = 0, cfd, tfd, diffpid;
63 struct sigaction sa = {};
65 job_data_size_limit = 10;
67 progname = cmd;
68 puts(cmd);
69 forksrv(&port, &srvpid);
70 if (port == -1 || srvpid == -1) {
71 puts("forksrv failed");
72 exit(1);
75 // Fail if this test takes more than 10 seconds.
76 // If we have trouble installing the timeout,
77 // just proceed anyway.
78 sa.sa_handler = cleanup;
79 sigaction(SIGALRM, &sa, 0);
80 alarm(10);
82 cfd = diallocal(port);
83 if (cfd == -1) {
84 twarn("diallocal");
85 kill(srvpid, 9);
86 exit(1);
89 tfd = open(cmd, O_RDONLY, 0);
90 if (tfd == -1) {
91 twarn("open");
92 kill(srvpid, 9);
93 exit(1);
96 if (copy(cfd, tfd, bufsiz) == -1) {
97 twarn("copy");
98 kill(srvpid, 9);
99 exit(1);
102 diffpid = diff(exp, cfd);
103 if (diffpid == -1) {
104 twarn("diff");
105 kill(srvpid, 9);
106 exit(1);
109 waitpid(diffpid, &diffst, 0);
111 // wait until after diff has finished to kill srvpid
112 kill(srvpid, 9);
113 waitpid(srvpid, &srvst, 0);
114 assertf(WIFSIGNALED(srvst) && WTERMSIG(srvst) == 9,
115 "status %d, signal %d",
116 WEXITSTATUS(srvst),
117 WTERMSIG(srvst));
119 assertf(diffst == 0, "was %d", diffst);
123 static void
124 forksrv(int *port, int *pid)
126 int r, len;
127 Srv s = {};
128 struct sockaddr_in addr;
130 s.sock.fd = make_server_socket("127.0.0.1", "0");
131 if (s.sock.fd == -1) return;
133 len = sizeof(addr);
134 r = getsockname(s.sock.fd, (struct sockaddr*)&addr, (socklen_t*)&len);
135 if (r == -1 || len > sizeof(addr)) return;
137 *port = addr.sin_port;
139 *pid = fork();
140 if (*pid != 0) return;
142 /* now in child */
144 prot_init();
146 srv(&s); /* does not return */
147 exit(1); /* satisfy the compiler */
151 static int
152 diff(char *f0, int fd)
154 int pid;
156 pid = fork();
157 if (pid != 0) return pid;
159 /* now in child */
161 dup2(fd, 0);
162 close(fd);
164 execlp("diff", "diff", f0, "-", (char*)0);
165 /* not reached */
166 exit(1);
170 static int
171 copy(int dst, int src, int bs)
173 char buf[bs];
174 int r, w, c;
176 for (;;) {
177 r = read(src, buf, sizeof buf);
178 if (r == -1) return -1;
179 if (r == 0) break;
181 for (w = 0; w < r; w += c) {
182 c = write(dst, buf+w, r-w);
183 if (c == -1) return -1;
186 return 0;
190 static int
191 diallocal(int port)
193 int r, fd;
194 struct sockaddr_in addr = {};
196 addr.sin_family = AF_INET;
197 addr.sin_port = port;
198 r = inet_aton("127.0.0.1", &addr.sin_addr);
199 if (!r) {
200 errno = EINVAL;
201 return -1;
204 fd = socket(PF_INET, SOCK_STREAM, 0);
205 if (fd == -1) {
206 return -1;
209 r = connect(fd, (struct sockaddr*)&addr, sizeof addr);
210 if (r == -1) {
211 return -1;
214 return fd;
218 static void
219 cleanup(int sig)
221 puts("timed out");
222 if (srvpid > 0) {
223 kill(srvpid, 9);
225 exit(1);