tests: cover ibus connection capacity recovery
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
enum
|
||||
{
|
||||
Maxconnections = 16,
|
||||
Calltimeout = 4000,
|
||||
Starttimeout = 8000,
|
||||
Stoptimeout = 3000,
|
||||
@@ -626,6 +627,67 @@ closebus(DBusConnection **conn, Siglog *log)
|
||||
*conn = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
overflowrejected(char *address)
|
||||
{
|
||||
DBusConnection *conn;
|
||||
DBusError err;
|
||||
struct pollfd pfd;
|
||||
int fd, n, ok, timeout;
|
||||
int64_t deadline;
|
||||
|
||||
dbus_error_init(&err);
|
||||
conn = dbus_connection_open_private(address, &err);
|
||||
if(conn == NULL){
|
||||
if(!dbus_error_is_set(&err)){
|
||||
dbus_error_free(&err);
|
||||
return fail("overflow connection failed without a D-Bus error");
|
||||
}
|
||||
dbus_error_free(&err);
|
||||
return 1;
|
||||
}
|
||||
dbus_error_free(&err);
|
||||
dbus_connection_set_exit_on_disconnect(conn, FALSE);
|
||||
if(!dbus_connection_get_unix_fd(conn, &fd)){
|
||||
dbus_connection_close(conn);
|
||||
dbus_connection_unref(conn);
|
||||
return fail("overflow connection has no Unix descriptor");
|
||||
}
|
||||
ok = 0;
|
||||
deadline = nowms() + Calltimeout;
|
||||
for(;;){
|
||||
if(!dbus_connection_get_is_connected(conn)){
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
timeout = leftms(deadline);
|
||||
if(timeout == 0){
|
||||
fail("overflow IBus connection was not rejected");
|
||||
break;
|
||||
}
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
n = poll(&pfd, 1, timeout);
|
||||
if(n < 0 && errno == EINTR)
|
||||
continue;
|
||||
if(n < 0){
|
||||
fail("poll overflow IBus connection: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if(n == 0)
|
||||
continue;
|
||||
if(pfd.revents & POLLNVAL){
|
||||
fail("overflow IBus descriptor became invalid");
|
||||
break;
|
||||
}
|
||||
dbus_connection_read_write_dispatch(conn, 0);
|
||||
}
|
||||
dbus_connection_close(conn);
|
||||
dbus_connection_unref(conn);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static DBusMessage*
|
||||
method(char *path, char *iface, char *member)
|
||||
{
|
||||
@@ -642,9 +704,11 @@ static DBusMessage*
|
||||
sendcall(DBusConnection *conn, DBusMessage *m)
|
||||
{
|
||||
DBusMessage *reply;
|
||||
DBusError err;
|
||||
DBusPendingCall *pending;
|
||||
char member[64], path[128];
|
||||
const char *s;
|
||||
int timeout;
|
||||
int64_t deadline;
|
||||
|
||||
if(m == NULL)
|
||||
return NULL;
|
||||
@@ -652,21 +716,39 @@ sendcall(DBusConnection *conn, DBusMessage *m)
|
||||
snprintf(member, sizeof member, "%s", s != NULL ? s : "method");
|
||||
s = dbus_message_get_path(m);
|
||||
snprintf(path, sizeof path, "%s", s != NULL ? s : "path");
|
||||
dbus_error_init(&err);
|
||||
reply = dbus_connection_send_with_reply_and_block(conn, m,
|
||||
Calltimeout, &err);
|
||||
dbus_message_unref(m);
|
||||
if(reply == NULL){
|
||||
fail("%s on %s: %s: %s", member, path,
|
||||
err.name != NULL ? err.name : "D-Bus error",
|
||||
err.message != NULL ? err.message : "no reply");
|
||||
dbus_error_free(&err);
|
||||
pending = NULL;
|
||||
if(!dbus_connection_send_with_reply(conn, m, &pending, Calltimeout) ||
|
||||
pending == NULL){
|
||||
dbus_message_unref(m);
|
||||
fail("queue %s on %s: out of memory", member, path);
|
||||
return NULL;
|
||||
}
|
||||
dbus_message_unref(m);
|
||||
deadline = nowms() + Calltimeout;
|
||||
while(!dbus_pending_call_get_completed(pending)){
|
||||
timeout = leftms(deadline);
|
||||
if(timeout == 0){
|
||||
fail("timed out waiting for %s on %s", member, path);
|
||||
goto fail;
|
||||
}
|
||||
if(!dbus_connection_read_write_dispatch(conn, timeout)){
|
||||
fail("connection closed waiting for %s on %s", member, path);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
reply = dbus_pending_call_steal_reply(pending);
|
||||
dbus_pending_call_unref(pending);
|
||||
if(reply == NULL){
|
||||
fail("%s on %s completed without a reply", member, path);
|
||||
return NULL;
|
||||
}
|
||||
dbus_error_free(&err);
|
||||
while(dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
|
||||
dbus_connection_dispatch(conn);
|
||||
return reply;
|
||||
fail:
|
||||
dbus_pending_call_cancel(pending);
|
||||
dbus_pending_call_unref(pending);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -930,6 +1012,67 @@ expectkey(DBusConnection *conn, Siglog *log, char *path,
|
||||
text[0] != '\0', where);
|
||||
}
|
||||
|
||||
static int
|
||||
runconnectioncapacity(Daemon *d)
|
||||
{
|
||||
DBusConnection *conn[Maxconnections];
|
||||
Siglog logs[Maxconnections];
|
||||
char names[Maxconnections][32];
|
||||
char paths[Maxconnections][96];
|
||||
int i, ok;
|
||||
|
||||
for(i = 0; i < Maxconnections; i++)
|
||||
conn[i] = NULL;
|
||||
memset(logs, 0, sizeof logs);
|
||||
ok = 0;
|
||||
for(i = 0; i < Maxconnections; i++){
|
||||
conn[i] = openbus(d->address, &logs[i]);
|
||||
if(conn[i] == NULL || !hello(conn[i], names[i], sizeof names[i]) ||
|
||||
!createcontext(conn[i], paths[i], sizeof paths[i]) ||
|
||||
!emptycall(conn[i], &logs[i], paths[i], "FocusIn") ||
|
||||
!nosignal(&logs[i], "connection capacity FocusIn") ||
|
||||
!expectkey(conn[i], &logs[i], paths[i], 0xffe1, 0, 0, "",
|
||||
"connection capacity key"))
|
||||
goto out;
|
||||
}
|
||||
if(!overflowrejected(d->address))
|
||||
goto out;
|
||||
for(i = 0; i < Maxconnections; i++)
|
||||
if(!expectkey(conn[i], &logs[i], paths[i], 0xffe1, 0, 0, "",
|
||||
"accepted connection after rejection"))
|
||||
goto out;
|
||||
closebus(&conn[Maxconnections-1], &logs[Maxconnections-1]);
|
||||
if(!expectkey(conn[0], &logs[0], paths[0], 0xffe1, 0, 0, "",
|
||||
"connection close barrier"))
|
||||
goto out;
|
||||
conn[Maxconnections-1] = openbus(d->address,
|
||||
&logs[Maxconnections-1]);
|
||||
if(conn[Maxconnections-1] == NULL ||
|
||||
!hello(conn[Maxconnections-1], names[Maxconnections-1],
|
||||
sizeof names[Maxconnections-1]) ||
|
||||
!createcontext(conn[Maxconnections-1], paths[Maxconnections-1],
|
||||
sizeof paths[Maxconnections-1]) ||
|
||||
!emptycall(conn[Maxconnections-1], &logs[Maxconnections-1],
|
||||
paths[Maxconnections-1], "FocusIn") ||
|
||||
!nosignal(&logs[Maxconnections-1], "recovered connection FocusIn") ||
|
||||
!expectkey(conn[Maxconnections-1], &logs[Maxconnections-1],
|
||||
paths[Maxconnections-1], 'n', Ctrlmask, 1, "",
|
||||
"recovered connection select Japanese") ||
|
||||
!expectkey(conn[Maxconnections-1], &logs[Maxconnections-1],
|
||||
paths[Maxconnections-1], 'k', 0, 1, "k",
|
||||
"recovered connection key"))
|
||||
goto out;
|
||||
for(i = 0; i < Maxconnections-1; i++)
|
||||
if(!expectkey(conn[i], &logs[i], paths[i], 0xffe1, 0, 0, "",
|
||||
"accepted connection after recovery"))
|
||||
goto out;
|
||||
ok = 1;
|
||||
out:
|
||||
for(i = 0; i < Maxconnections; i++)
|
||||
closebus(&conn[i], &logs[i]);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
runlifecycle(Daemon *d)
|
||||
{
|
||||
@@ -1060,6 +1203,8 @@ main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
ok = startdaemon(&daemon, argv[1], argv[2]);
|
||||
if(ok)
|
||||
ok = runconnectioncapacity(&daemon);
|
||||
if(ok)
|
||||
ok = runlifecycle(&daemon);
|
||||
if(!ok)
|
||||
@@ -1068,6 +1213,6 @@ main(int argc, char **argv)
|
||||
ok = 0;
|
||||
if(!ok)
|
||||
return 1;
|
||||
printf("ibus live lifecycle: ok\n");
|
||||
printf("ibus live lifecycle and connection capacity: ok\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user