7 #include <sys/socket.h>
9 #include <netinet/ip.h>
10 #include <arpa/inet.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
);
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"},
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);
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;
69 forksrv(&port
, &srvpid
);
70 if (port
== -1 || srvpid
== -1) {
71 puts("forksrv failed");
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);
82 cfd
= diallocal(port
);
89 tfd
= open(cmd
, O_RDONLY
, 0);
96 if (copy(cfd
, tfd
, bufsiz
) == -1) {
102 diffpid
= diff(exp
, cfd
);
109 waitpid(diffpid
, &diffst
, 0);
111 // wait until after diff has finished to kill srvpid
113 waitpid(srvpid
, &srvst
, 0);
114 assertf(WIFSIGNALED(srvst
) && WTERMSIG(srvst
) == 9,
115 "status %d, signal %d",
119 assertf(diffst
== 0, "was %d", diffst
);
124 forksrv(int *port
, int *pid
)
128 struct sockaddr_in addr
;
130 s
.sock
.fd
= make_server_socket("127.0.0.1", "0");
131 if (s
.sock
.fd
== -1) return;
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
;
140 if (*pid
!= 0) return;
146 srv(&s
); /* does not return */
147 exit(1); /* satisfy the compiler */
152 diff(char *f0
, int fd
)
157 if (pid
!= 0) return pid
;
164 execlp("diff", "diff", f0
, "-", (char*)0);
171 copy(int dst
, int src
, int bs
)
177 r
= read(src
, buf
, sizeof buf
);
178 if (r
== -1) return -1;
181 for (w
= 0; w
< r
; w
+= c
) {
182 c
= write(dst
, buf
+w
, r
-w
);
183 if (c
== -1) return -1;
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
);
204 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
209 r
= connect(fd
, (struct sockaddr
*)&addr
, sizeof addr
);