1 /* integration tests */
9 #include <sys/socket.h>
11 #include <netinet/ip.h>
12 #include <arpa/inet.h>
19 static void testsrv(char*, char*, int);
20 static void forksrv(int*, int*);
21 static int copy(int, int, int);
22 static int diff(char*, int);
23 static int diallocal(int);
24 static void cleanup(int sig
);
33 {"sh-tests/allow-underscore.commands", "sh-tests/allow-underscore.expected"},
34 {"sh-tests/delete_ready.commands", "sh-tests/delete_ready.expected"},
35 {"sh-tests/multi-tube.commands", "sh-tests/multi-tube.expected"},
36 {"sh-tests/no_negative_delays.commands", "sh-tests/no_negative_delays.expected"},
37 {"sh-tests/omit-time-left.commands", "sh-tests/omit-time-left.expected"},
38 {"sh-tests/pause-tube.commands", "sh-tests/pause-tube.expected"},
39 {"sh-tests/small_delay.commands", "sh-tests/small_delay.expected"},
40 {"sh-tests/too-big.commands", "sh-tests/too-big.expected"},
41 {"sh-tests/ttr-large.commands", "sh-tests/ttr-large.expected"},
42 {"sh-tests/zero_delay.commands", "sh-tests/zero_delay.expected"},
54 for (i
= 0; ts
[i
].cmd
; i
++) {
55 testsrv(ts
[i
].cmd
, ts
[i
].exp
, 4096);
56 testsrv(ts
[i
].cmd
, ts
[i
].exp
, 1);
62 testsrv(char *cmd
, char *exp
, int bufsiz
)
64 int diffst
, srvst
, port
= 0, cfd
, tfd
, diffpid
;
65 struct sigaction sa
= {};
67 job_data_size_limit
= 10;
71 forksrv(&port
, &srvpid
);
72 if (port
== -1 || srvpid
== -1) {
73 puts("forksrv failed");
77 // Fail if this test takes more than 10 seconds.
78 // If we have trouble installing the timeout,
79 // just proceed anyway.
80 sa
.sa_handler
= cleanup
;
81 sigaction(SIGALRM
, &sa
, 0);
84 cfd
= diallocal(port
);
91 tfd
= open(cmd
, O_RDONLY
, 0);
98 if (copy(cfd
, tfd
, bufsiz
) == -1) {
104 diffpid
= diff(exp
, cfd
);
111 waitpid(diffpid
, &diffst
, 0);
113 // wait until after diff has finished to kill srvpid
115 waitpid(srvpid
, &srvst
, 0);
116 printf("srv status %d, signal %d\n", WEXITSTATUS(srvst
), WTERMSIG(srvst
));
117 assertf(WIFSIGNALED(srvst
) && WTERMSIG(srvst
) == 9, "srv status");
119 printf("diff status %d\n", diffst
);
120 assertf(diffst
== 0, "diff status");
125 forksrv(int *port
, int *pid
)
129 struct sockaddr_in addr
;
131 s
.sock
.fd
= make_server_socket("127.0.0.1", "0");
132 if (s
.sock
.fd
== -1) return;
135 r
= getsockname(s
.sock
.fd
, (struct sockaddr
*)&addr
, (socklen_t
*)&len
);
136 if (r
== -1 || len
> sizeof(addr
)) return;
138 *port
= addr
.sin_port
;
141 if (*pid
!= 0) return;
147 srv(&s
); /* does not return */
148 exit(1); /* satisfy the compiler */
153 diff(char *f0
, int fd
)
158 if (pid
!= 0) return pid
;
165 execlp("diff", "diff", f0
, "-", (char*)0);
172 copy(int dst
, int src
, int bs
)
178 r
= read(src
, buf
, sizeof buf
);
179 if (r
== -1) return -1;
182 for (w
= 0; w
< r
; w
+= c
) {
183 c
= write(dst
, buf
+w
, r
-w
);
184 if (c
== -1) return -1;
195 struct sockaddr_in addr
= {};
197 addr
.sin_family
= AF_INET
;
198 addr
.sin_port
= port
;
199 r
= inet_aton("127.0.0.1", &addr
.sin_addr
);
205 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
210 r
= connect(fd
, (struct sockaddr
*)&addr
, sizeof addr
);