diff options
author | Daniel Mack <zonque@gmail.com> | 2013-12-20 12:09:28 +0100 |
---|---|---|
committer | Daniel Mack <zonque@gmail.com> | 2013-12-20 20:56:23 +0100 |
commit | 7c022ca1022e1bef1bb16d3314238380095a4d62 (patch) | |
tree | 87a6338eedee690e1b39e0113f95f3b33add4eff /test | |
parent | e480fb1d4ab40a053c2e0be39455008d1632f5e3 (diff) | |
download | kdbus-bus-7c022ca1022e1bef1bb16d3314238380095a4d62.tar.gz kdbus-bus-7c022ca1022e1bef1bb16d3314238380095a4d62.tar.bz2 kdbus-bus-7c022ca1022e1bef1bb16d3314238380095a4d62.zip |
test-kdbus: add tests for match logic
Diffstat (limited to 'test')
-rw-r--r-- | test/test-kdbus.c | 326 |
1 files changed, 314 insertions, 12 deletions
diff --git a/test/test-kdbus.c b/test/test-kdbus.c index d5f5eedcaa3..e6cdfd2cd91 100644 --- a/test/test-kdbus.c +++ b/test/test-kdbus.c @@ -478,7 +478,7 @@ static int check_monitor(struct kdbus_check_env *env) /* taking a name must fail */ name = "foo.bla.blaz"; - ret = upload_policy(env->conn->fd, name); + ret = upload_policy(conn->fd, name); ASSERT_RETURN(ret == 0); size = sizeof(*cmd_name) + strlen(name) + 1; @@ -672,6 +672,303 @@ static int check_conn_info(struct kdbus_check_env *env) return CHECK_OK; } +static int check_match_id_add(struct kdbus_check_env *env) +{ + struct { + struct kdbus_cmd_match cmd; + struct { + uint64_t size; + uint64_t type; + struct kdbus_notify_id_change chg; + } item; + } buf; + struct kdbus_conn *conn; + struct kdbus_item *item; + struct kdbus_msg *msg; + uint64_t off; + int ret; + + memset(&buf, 0, sizeof(buf)); + + buf.cmd.size = sizeof(buf); + buf.cmd.cookie = 0xdeafbeefdeaddead; + buf.item.size = sizeof(buf.item); + buf.item.type = KDBUS_ITEM_ID_ADD; + buf.item.chg.id = KDBUS_MATCH_ID_ANY; + + /* match on id add */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MATCH_ADD, &buf); + ASSERT_RETURN(ret == 0); + + /* create 2nd connection */ + conn = make_conn(env->buspath, 0); + ASSERT_RETURN(conn != NULL); + + /* 1st connection should have received a notification */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MSG_RECV, &off); + ASSERT_RETURN(ret == 0); + + msg = (struct kdbus_msg *)(env->conn->buf + off); + item = &msg->items[0]; + ASSERT_RETURN(item->type == KDBUS_ITEM_ID_ADD); + ASSERT_RETURN(item->id_change.id == conn->hello.id); + + free_conn(conn); + + return CHECK_OK; +} + +static int check_match_id_remove(struct kdbus_check_env *env) +{ + struct { + struct kdbus_cmd_match cmd; + struct { + uint64_t size; + uint64_t type; + struct kdbus_notify_id_change chg; + } item; + } buf; + struct kdbus_conn *conn; + struct kdbus_item *item; + struct kdbus_msg *msg; + uint64_t off; + size_t id; + int ret; + + /* create 2nd connection */ + conn = make_conn(env->buspath, 0); + id = conn->hello.id; + ASSERT_RETURN(conn != NULL); + + memset(&buf, 0, sizeof(buf)); + buf.cmd.size = sizeof(buf); + buf.cmd.cookie = 0xdeafbeefdeaddead; + buf.item.size = sizeof(buf.item); + buf.item.type = KDBUS_ITEM_ID_REMOVE; + buf.item.chg.id = id; + + /* register match on 2nd connection */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MATCH_ADD, &buf); + ASSERT_RETURN(ret == 0); + + /* remove 2nd connection again */ + free_conn(conn); + + /* 1st connection should have received a notification */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MSG_RECV, &off); + ASSERT_RETURN(ret == 0); + + msg = (struct kdbus_msg *)(env->conn->buf + off); + item = &msg->items[0]; + ASSERT_RETURN(item->type == KDBUS_ITEM_ID_REMOVE); + ASSERT_RETURN(item->id_change.id == id); + + return CHECK_OK; +} + +static int check_match_name_add(struct kdbus_check_env *env) +{ + struct { + struct kdbus_cmd_match cmd; + struct { + uint64_t size; + uint64_t type; + struct kdbus_notify_name_change chg; + char name[64]; + } item; + } buf; + struct kdbus_cmd_name *cmd_name; + struct kdbus_item *item; + struct kdbus_msg *msg; + uint64_t size, off; + char *name; + int ret; + + name = "foo.bla.blaz"; + ret = upload_policy(env->conn->fd, name); + ASSERT_RETURN(ret == 0); + + /* install the match rule */ + memset(&buf, 0, sizeof(buf)); + buf.cmd.size = sizeof(buf); + buf.item.size = sizeof(buf.item); + buf.item.type = KDBUS_ITEM_NAME_ADD; + buf.item.chg.old.id = KDBUS_MATCH_ID_ANY; + buf.item.chg.new.id = KDBUS_MATCH_ID_ANY; + strncpy(buf.item.name, name, sizeof(buf.item.name)); + + ret = ioctl(env->conn->fd, KDBUS_CMD_MATCH_ADD, &buf); + ASSERT_RETURN(ret == 0); + + /* acquire the name */ + size = sizeof(*cmd_name) + strlen(name) + 1; + cmd_name = alloca(size); + + memset(cmd_name, 0, size); + strcpy(cmd_name->name, name); + cmd_name->size = size; + cmd_name->flags = 0; + ret = ioctl(env->conn->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name); + ASSERT_RETURN(ret == 0); + + /* we should have received a notification */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MSG_RECV, &off); + ASSERT_RETURN(ret == 0); + + msg = (struct kdbus_msg *)(env->conn->buf + off); + item = &msg->items[0]; + ASSERT_RETURN(item->type == KDBUS_ITEM_NAME_ADD); + ASSERT_RETURN(item->name_change.old.id == 0); + ASSERT_RETURN(item->name_change.new.id == env->conn->hello.id); + ASSERT_RETURN(strcmp(item->name_change.name, name) == 0); + + return CHECK_OK; +} + +static int check_match_name_remove(struct kdbus_check_env *env) +{ + struct { + struct kdbus_cmd_match cmd; + struct { + uint64_t size; + uint64_t type; + struct kdbus_notify_name_change chg; + char name[64]; + } item; + } buf; + struct kdbus_cmd_name *cmd_name; + struct kdbus_item *item; + struct kdbus_msg *msg; + uint64_t size, off; + char *name; + int ret; + + name = "foo.bla.blaz"; + ret = upload_policy(env->conn->fd, name); + ASSERT_RETURN(ret == 0); + + /* acquire the name */ + size = sizeof(*cmd_name) + strlen(name) + 1; + cmd_name = alloca(size); + + memset(cmd_name, 0, size); + strcpy(cmd_name->name, name); + cmd_name->size = size; + cmd_name->flags = 0; + ret = ioctl(env->conn->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name); + ASSERT_RETURN(ret == 0); + + /* install the match rule */ + memset(&buf, 0, sizeof(buf)); + buf.cmd.size = sizeof(buf); + buf.item.size = sizeof(buf.item); + buf.item.type = KDBUS_ITEM_NAME_REMOVE; + buf.item.chg.old.id = KDBUS_MATCH_ID_ANY; + buf.item.chg.new.id = KDBUS_MATCH_ID_ANY; + strncpy(buf.item.name, name, sizeof(buf.item.name)); + + ret = ioctl(env->conn->fd, KDBUS_CMD_MATCH_ADD, &buf); + ASSERT_RETURN(ret == 0); + + /* release the name again */ + ret = ioctl(env->conn->fd, KDBUS_CMD_NAME_RELEASE, cmd_name); + ASSERT_RETURN(ret == 0); + + /* we should have received a notification */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MSG_RECV, &off); + ASSERT_RETURN(ret == 0); + + msg = (struct kdbus_msg *)(env->conn->buf + off); + item = &msg->items[0]; + ASSERT_RETURN(item->type == KDBUS_ITEM_NAME_REMOVE); + ASSERT_RETURN(item->name_change.old.id == env->conn->hello.id); + ASSERT_RETURN(item->name_change.new.id == 0); + ASSERT_RETURN(strcmp(item->name_change.name, name) == 0); + + return CHECK_OK; +} + +static int check_match_name_change(struct kdbus_check_env *env) +{ + struct { + struct kdbus_cmd_match cmd; + struct { + uint64_t size; + uint64_t type; + struct kdbus_notify_name_change chg; + char name[64]; + } item; + } buf; + struct kdbus_cmd_name *cmd_name; + struct kdbus_item *item; + struct kdbus_conn *conn; + struct kdbus_msg *msg; + uint64_t size, off; + char *name; + int ret; + + name = "foo.bla.blaz"; + ret = upload_policy(env->conn->fd, name); + ASSERT_RETURN(ret == 0); + + /* acquire the name */ + size = sizeof(*cmd_name) + strlen(name) + 1; + cmd_name = alloca(size); + + memset(cmd_name, 0, size); + strcpy(cmd_name->name, name); + cmd_name->size = size; + cmd_name->flags = KDBUS_NAME_ALLOW_REPLACEMENT; + ret = ioctl(env->conn->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name); + ASSERT_RETURN(ret == 0); + + /* install the match rule */ + memset(&buf, 0, sizeof(buf)); + buf.cmd.size = sizeof(buf); + buf.item.size = sizeof(buf.item); + buf.item.type = KDBUS_ITEM_NAME_CHANGE; + buf.item.chg.old.id = KDBUS_MATCH_ID_ANY; + buf.item.chg.new.id = KDBUS_MATCH_ID_ANY; + strncpy(buf.item.name, name, sizeof(buf.item.name)); + + ret = ioctl(env->conn->fd, KDBUS_CMD_MATCH_ADD, &buf); + ASSERT_RETURN(ret == 0); + + /* create a 2nd connection */ + conn = make_conn(env->buspath, 0); + ASSERT_RETURN(conn != NULL); + + /* allow the new connection to own the same name */ + ret = upload_policy(conn->fd, name); + ASSERT_RETURN(ret == 0); + + /* queue the 2nd connection as waiting owner */ + cmd_name->flags = KDBUS_NAME_QUEUE; + ret = ioctl(conn->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name); + ASSERT_RETURN(ret == 0); + ASSERT_RETURN(cmd_name->flags & KDBUS_NAME_IN_QUEUE); + + /* release name from 1st connection */ + cmd_name->flags = 0; + ret = ioctl(env->conn->fd, KDBUS_CMD_NAME_RELEASE, cmd_name); + ASSERT_RETURN(ret == 0); + + /* we should have received a notification */ + ret = ioctl(env->conn->fd, KDBUS_CMD_MSG_RECV, &off); + ASSERT_RETURN(ret == 0); + + msg = (struct kdbus_msg *)(env->conn->buf + off); + item = &msg->items[0]; + ASSERT_RETURN(item->type == KDBUS_ITEM_NAME_CHANGE); + ASSERT_RETURN(item->name_change.old.id == env->conn->hello.id); + ASSERT_RETURN(item->name_change.new.id == conn->hello.id); + ASSERT_RETURN(strcmp(item->name_change.name, name) == 0); + + free_conn(conn); + + return CHECK_OK; +} + static int check_msg_basic(struct kdbus_check_env *env) { struct kdbus_conn *conn; @@ -810,17 +1107,22 @@ void check_unprepare_env(const struct kdbus_check *c, struct kdbus_check_env *en } static const struct kdbus_check checks[] = { - { "bus make", check_busmake, 0 }, - { "hello", check_hello, CHECK_CREATE_BUS }, - { "byebye", check_byebye, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "monitor", check_monitor, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "name basics", check_name_basic, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "name conflict", check_name_conflict, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "name queue", check_name_queue, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "message basic", check_msg_basic, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "message free", check_msg_free, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "connection info", check_conn_info, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, - { "ns make", check_nsmake, 0 }, + { "bus make", check_busmake, 0 }, + { "hello", check_hello, CHECK_CREATE_BUS }, + { "byebye", check_byebye, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "monitor", check_monitor, CHECK_CREATE_BUS }, + { "name basics", check_name_basic, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "name conflict", check_name_conflict, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "name queue", check_name_queue, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "message basic", check_msg_basic, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "message free", check_msg_free, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "connection info", check_conn_info, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "match id add", check_match_id_add, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "match id remove", check_match_id_remove, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "match name add", check_match_name_add, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "match name remove", check_match_name_remove, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "match name change", check_match_name_change, CHECK_CREATE_BUS | CHECK_CREATE_CONN }, + { "ns make", check_nsmake, 0 }, { NULL, NULL, 0 } }; |