summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2013-12-20 12:09:28 +0100
committerDaniel Mack <zonque@gmail.com>2013-12-20 20:56:23 +0100
commit7c022ca1022e1bef1bb16d3314238380095a4d62 (patch)
tree87a6338eedee690e1b39e0113f95f3b33add4eff /test
parente480fb1d4ab40a053c2e0be39455008d1632f5e3 (diff)
downloadkdbus-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.c326
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 }
};