test: separate quick, live, and stress checks

This commit is contained in:
2026-08-14 23:13:32 +09:00
parent bfe83d0119
commit 516ec98a70
9 changed files with 469 additions and 2091 deletions

View File

@@ -27,6 +27,7 @@ enum
Calltimeout = 4000,
Starttimeout = 8000,
Stoptimeout = 3000,
Cappreedit = 1,
};
typedef struct Daemon Daemon;
@@ -141,11 +142,19 @@ waitsocket(Daemon *d, int notifyfd)
if(lstat(d->socket, &st) == 0 && S_ISSOCK(st.st_mode) &&
(st.st_mode & 0777) == 0600)
return 1;
if(waitpid(d->pid, &status, WNOHANG) == d->pid){
do
n = waitpid(d->pid, &status, WNOHANG);
while(n < 0 && errno == EINTR);
if(n == d->pid){
d->pid = -1;
readerrors(d);
return fail("daemon exited before creating IPC socket");
}
if(n < 0){
if(errno == ECHILD)
d->pid = -1;
return fail("wait for daemon startup: %s", strerror(errno));
}
timeout = leftms(deadline);
if(timeout == 0)
return fail("timed out waiting for protected IPC socket %s",
@@ -182,8 +191,10 @@ startdaemon(Daemon *d, char *program, char *mapdir)
d->pid = -1;
d->errfd = -1;
snprintf(d->root, sizeof d->root, "/tmp/strans-ipc.XXXXXX");
if(mkdtemp(d->root) == NULL)
if(mkdtemp(d->root) == NULL){
d->root[0] = '\0';
return fail("mkdtemp: %s", strerror(errno));
}
if(snprintf(d->runtime, sizeof d->runtime, "%s/runtime", d->root)
>= (int)sizeof d->runtime ||
snprintf(d->config, sizeof d->config, "%s/config", d->root)
@@ -236,10 +247,10 @@ startdaemon(Daemon *d, char *program, char *mapdir)
}
if(setenv("XDG_RUNTIME_DIR", d->runtime, 1) < 0 ||
setenv("XDG_CONFIG_HOME", d->config, 1) < 0 ||
setenv("HOME", d->home, 1) < 0 ||
setenv("DISPLAY", "invalid", 1) < 0 ||
setenv("HOME", d->home, 1) < 0 || unsetenv("DISPLAY") < 0 ||
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 ||
unsetenv("IBUS_ADDRESS") < 0){
unsetenv("IBUS_ADDRESS") < 0 ||
unsetenv("IBUS_ADDRESS_FILE") < 0){
dprintf(STDERR_FILENO, "set daemon environment: %s\n",
strerror(errno));
_exit(126);
@@ -323,6 +334,8 @@ killdaemon(Daemon *d, int *status)
if(n != d->pid){
fail("reap %ld after SIGKILL: %s", (long)d->pid,
n < 0 ? strerror(errno) : "wrong child");
if(n < 0 && errno == ECHILD)
d->pid = -1;
ok = 0;
}else
d->pid = -1;
@@ -614,6 +627,15 @@ sendreset(int fd, int want)
return ipcsend(fd, req, sizeof req) == 0;
}
static int
sendcap(int fd, int cap)
{
unsigned char req[Ipcreqsz];
ipcpackcap(req, cap);
return ipcsend(fd, req, sizeof req) == 0;
}
static int
expectresponse(int fd, int want, int eaten, char *commit, char *preedit,
char *where)
@@ -740,7 +762,25 @@ overflowrejected(char *path)
}
static int
runlistener(Daemon *d)
runsmoke(Daemon *d)
{
int client, ok;
client = connectuntil(d->socket, nowms() + Calltimeout);
if(client < 0)
return fail("connect client: %s", strerror(errno));
ok = sendcap(client, Cappreedit) &&
expectresponse(client, 1, 1, "", "", "negotiate preedit") &&
requestkey(client, 1, Mctrl, 'n', 1, "", "",
"select Japanese") &&
requestkey(client, 1, 0, 'k', 1, "", "k", "preedit") &&
requestreset(client, 1, 1, "", "reset");
close(client);
return ok;
}
static int
runcapacity(Daemon *d)
{
int client[Maxclients];
int i, ok;
@@ -753,17 +793,8 @@ runlistener(Daemon *d)
fail("connect first client: %s", strerror(errno));
goto out;
}
if(!requestkey(client[0], 1, Mctrl, 'n', 1, "", "", "select Japanese") ||
!requestkey(client[0], 1, 0, 'k', 1, "", "k", "GTK preedit") ||
!requestreset(client[0], 1, 1, "", "active reset"))
goto out;
if(!sendkey(client[0], 0, 0, 'k') ||
!sendkey(client[0], 1, 0, Kmodfirst)){
fail("send pipelined XIM/GTK requests: %s", strerror(errno));
goto out;
}
if(!expectresponse(client[0], 0, 1, "", "", "XIM framing") ||
!expectresponse(client[0], 1, 0, "", "k", "GTK after XIM framing"))
if(!requestkey(client[0], 1, Mctrl, 'n', 1, "", "",
"select Japanese"))
goto out;
for(i = 1; i < Maxclients; i++){
client[i] = connectuntil(d->socket, nowms() + Calltimeout);
@@ -799,21 +830,26 @@ int
main(int argc, char **argv)
{
Daemon daemon;
int ok;
char *program, *mapdir;
int capacity, ok;
if(argc != 3){
fprintf(stderr, "usage: ipc_live_test strans mapdir\n");
capacity = argc == 4 && strcmp(argv[1], "--capacity") == 0;
if((!capacity && argc != 3) || (capacity && argc != 4)){
fprintf(stderr,
"usage: ipc_live_test [--capacity] strans mapdir\n");
return 2;
}
ok = startdaemon(&daemon, argv[1], argv[2]);
program = argv[1+capacity];
mapdir = argv[2+capacity];
ok = startdaemon(&daemon, program, mapdir);
if(ok)
ok = runlistener(&daemon);
ok = capacity ? runcapacity(&daemon) : runsmoke(&daemon);
if(!ok)
showerrors(&daemon);
if(!stopdaemon(&daemon))
ok = 0;
if(!ok)
return 1;
printf("ipc live listener: ok\n");
printf("ipc %s: ok\n", capacity ? "connection capacity" : "live smoke");
return 0;
}