test: one Xvfb launcher and one daemon for the live tests
The XIM test carried its own Xvfb and daemon spawner, its own child struct, log files and process-group teardown, and the GTK test a second Xvfb launcher, because live.c's startdaemon always unset DISPLAY. Live now carries the display its own startxvfb reports, startdaemon passes it on, and both tests use the shared pair: 300 lines fewer, one place that knows how a child is started, watched, and stopped.
This commit is contained in:
82
tests/live.c
82
tests/live.c
@@ -240,6 +240,81 @@ childfds(int fd)
|
||||
return dup2(fd, STDOUT_FILENO) >= 0 && dup2(fd, STDERR_FILENO) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A private X server for the tests that need one; its display goes in
|
||||
* Live, so the daemon and the clients started after it share it.
|
||||
*/
|
||||
int
|
||||
startxvfb(Live *l, Daemon *d, char *program)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
char fdarg[16], line[32];
|
||||
int errpipe[2], n, pipefd[2];
|
||||
int64_t deadline;
|
||||
pid_t pid;
|
||||
ssize_t nr;
|
||||
|
||||
if(pipe2(pipefd, O_CLOEXEC) < 0)
|
||||
return fail("Xvfb display pipe: %s", strerror(errno));
|
||||
if(pipe2(errpipe, O_CLOEXEC|O_NONBLOCK) < 0){
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
return fail("pipe2: %s", strerror(errno));
|
||||
}
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
close(errpipe[0]);
|
||||
close(errpipe[1]);
|
||||
return fail("fork Xvfb: %s", strerror(errno));
|
||||
}
|
||||
if(pid == 0){
|
||||
close(pipefd[0]);
|
||||
close(errpipe[0]);
|
||||
n = fcntl(pipefd[1], F_GETFD);
|
||||
if(n < 0 || fcntl(pipefd[1], F_SETFD, n & ~FD_CLOEXEC) < 0 ||
|
||||
!childfds(errpipe[1]))
|
||||
_exit(126);
|
||||
snprintf(fdarg, sizeof fdarg, "%d", pipefd[1]);
|
||||
execlp(program, program, "-displayfd", fdarg, "-screen", "0",
|
||||
"1024x768x24", "-nolisten", "tcp", "-noreset", (char*)0);
|
||||
_exit(127);
|
||||
}
|
||||
close(pipefd[1]);
|
||||
close(errpipe[1]);
|
||||
d->pid = pid;
|
||||
d->errfd = errpipe[0];
|
||||
pfd.fd = pipefd[0];
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
deadline = nowms() + Starttimeout;
|
||||
n = 0;
|
||||
while(n + 1 < (int)sizeof line){
|
||||
pfd.revents = 0;
|
||||
if(poll(&pfd, 1, leftms(deadline)) <= 0)
|
||||
break;
|
||||
nr = read(pipefd[0], line + n, sizeof line - n - 1);
|
||||
if(nr < 0 && errno == EINTR)
|
||||
continue;
|
||||
if(nr <= 0)
|
||||
break;
|
||||
n += nr;
|
||||
line[n] = '\0';
|
||||
if(strchr(line, '\n') != NULL)
|
||||
break;
|
||||
}
|
||||
close(pipefd[0]);
|
||||
if(n == 0 || strchr(line, '\n') == NULL)
|
||||
return fail("Xvfb did not report a private display");
|
||||
line[strcspn(line, "\r\n")] = '\0';
|
||||
if(strspn(line, "0123456789") != strlen(line))
|
||||
return fail("invalid Xvfb display number %s", line);
|
||||
if(snprintf(l->display, sizeof l->display, ":%s", line)
|
||||
>= (int)sizeof l->display)
|
||||
return fail("Xvfb display number is too long");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
startdaemon(Live *l, Daemon *d, char *program, char *arg)
|
||||
{
|
||||
@@ -268,7 +343,10 @@ startdaemon(Live *l, Daemon *d, char *program, char *arg)
|
||||
}
|
||||
if(setenv("XDG_RUNTIME_DIR", l->runtime, 1) < 0 ||
|
||||
setenv("XDG_CONFIG_HOME", l->config, 1) < 0 ||
|
||||
setenv("HOME", l->home, 1) < 0 || unsetenv("DISPLAY") < 0 ||
|
||||
setenv("HOME", l->home, 1) < 0 ||
|
||||
(l->display[0] != '\0' ?
|
||||
setenv("DISPLAY", l->display, 1) :
|
||||
unsetenv("DISPLAY")) < 0 ||
|
||||
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 ||
|
||||
unsetenv("IBUS_ADDRESS") < 0 ||
|
||||
unsetenv("IBUS_ADDRESS_FILE") < 0){
|
||||
@@ -393,7 +471,7 @@ stopdaemon(Daemon *d)
|
||||
}
|
||||
/* plan9port turns a caught termination note into exit status 1. */
|
||||
if(reaped && !((WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM) ||
|
||||
(WIFEXITED(status) && WEXITSTATUS(status) == 1)))
|
||||
(WIFEXITED(status) && WEXITSTATUS(status) <= 1)))
|
||||
ok = fail("%s exited with unexpected wait status %#x", d->name,
|
||||
status);
|
||||
readerrors(d);
|
||||
|
||||
Reference in New Issue
Block a user