mirror of
https://github.com/systemd/systemd.git
synced 2024-10-28 11:55:44 +03:00
test: add tests for destroy callback of asynchronous netlink call
This commit is contained in:
parent
545bab1f0a
commit
0d0f02cd15
@ -5,6 +5,7 @@
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ether-addr-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing.h"
|
||||
@ -177,8 +178,9 @@ static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata)
|
||||
|
||||
assert_se(rtnl);
|
||||
assert_se(m);
|
||||
assert_se(userdata);
|
||||
|
||||
log_info("got link info about %s", ifname);
|
||||
log_info("%s: got link info about %s", __func__, ifname);
|
||||
free(ifname);
|
||||
|
||||
assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0);
|
||||
@ -212,21 +214,6 @@ static void test_event_loop(int ifindex) {
|
||||
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||
}
|
||||
|
||||
static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
int *counter = userdata;
|
||||
int r;
|
||||
|
||||
(*counter)--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
|
||||
log_info_errno(r, "%d left in pipe. got reply: %m", *counter);
|
||||
|
||||
assert_se(r >= 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_async(int ifindex) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||
@ -248,6 +235,116 @@ static void test_async(int ifindex) {
|
||||
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||
}
|
||||
|
||||
struct test_async_object {
|
||||
unsigned n_ref;
|
||||
char *ifname;
|
||||
};
|
||||
|
||||
static struct test_async_object *test_async_object_free(struct test_async_object *t) {
|
||||
assert(t);
|
||||
|
||||
free(t->ifname);
|
||||
return mfree(t);
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct test_async_object, test_async_object, test_async_object_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct test_async_object *, test_async_object_unref);
|
||||
|
||||
static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
struct test_async_object *t = userdata;
|
||||
const char *data;
|
||||
|
||||
assert_se(rtnl);
|
||||
assert_se(m);
|
||||
assert_se(userdata);
|
||||
|
||||
log_info("%s: got link info about %s", __func__, t->ifname);
|
||||
|
||||
assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0);
|
||||
assert_se(streq(data, "lo"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_async_object_destroy(void *userdata) {
|
||||
struct test_async_object *t = userdata;
|
||||
|
||||
assert(userdata);
|
||||
|
||||
log_info("%s: n_ref=%u", __func__, t->n_ref);
|
||||
test_async_object_unref(t);
|
||||
}
|
||||
|
||||
static void test_async_destroy_callback(int ifindex) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||
_cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL;
|
||||
uint32_t serial;
|
||||
char *ifname;
|
||||
|
||||
assert_se(t = new(struct test_async_object, 1));
|
||||
assert_se(ifname = strdup("lo"));
|
||||
*t = (struct test_async_object) {
|
||||
.n_ref = 1,
|
||||
.ifname = ifname,
|
||||
};
|
||||
|
||||
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||
|
||||
/* destroy callback is called after processing message */
|
||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
||||
|
||||
assert_se(t->n_ref == 1);
|
||||
assert_se(test_async_object_ref(t));
|
||||
assert_se(t->n_ref == 2);
|
||||
|
||||
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||
assert_se(sd_netlink_process(rtnl, &r) == 1);
|
||||
assert_se(t->n_ref == 1);
|
||||
|
||||
assert_se(!sd_netlink_message_unref(m));
|
||||
|
||||
/* destroy callback is called when asynchronous call is cancelled */
|
||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
||||
|
||||
assert_se(t->n_ref == 1);
|
||||
assert_se(test_async_object_ref(t));
|
||||
assert_se(t->n_ref == 2);
|
||||
|
||||
assert_se(sd_netlink_call_async_cancel(rtnl, serial) >= 0);
|
||||
assert_se(t->n_ref == 1);
|
||||
|
||||
assert_se(!sd_netlink_message_unref(m));
|
||||
|
||||
/* destroy callback is also called by sd_netlink_unref() */
|
||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
||||
|
||||
assert_se(t->n_ref == 1);
|
||||
assert_se(test_async_object_ref(t));
|
||||
assert_se(t->n_ref == 2);
|
||||
|
||||
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||
assert_se(t->n_ref == 1);
|
||||
}
|
||||
|
||||
static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
int *counter = userdata;
|
||||
int r;
|
||||
|
||||
(*counter)--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
|
||||
log_info_errno(r, "%d left in pipe. got reply: %m", *counter);
|
||||
|
||||
assert_se(r >= 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_pipe(int ifindex) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL;
|
||||
@ -366,31 +463,25 @@ int main(void) {
|
||||
uint16_t type;
|
||||
|
||||
test_match();
|
||||
|
||||
test_multiple();
|
||||
|
||||
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||
assert_se(rtnl);
|
||||
|
||||
test_route(rtnl);
|
||||
|
||||
test_message(rtnl);
|
||||
|
||||
test_container(rtnl);
|
||||
|
||||
if_loopback = (int) if_nametoindex("lo");
|
||||
assert_se(if_loopback > 0);
|
||||
|
||||
test_async(if_loopback);
|
||||
|
||||
test_async_destroy_callback(if_loopback);
|
||||
test_pipe(if_loopback);
|
||||
|
||||
test_event_loop(if_loopback);
|
||||
|
||||
test_link_configure(rtnl, if_loopback);
|
||||
|
||||
test_get_addresses(rtnl);
|
||||
|
||||
test_message_link_bridge(rtnl);
|
||||
|
||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
|
||||
|
Loading…
Reference in New Issue
Block a user