Migrate various tests to new assertion macros (#39691)

Split out of #39608
This commit is contained in:
Daan De Meyer
2025-11-12 16:17:38 +01:00
committed by GitHub
9 changed files with 732 additions and 796 deletions

View File

@@ -45,13 +45,13 @@ static int object_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_
return 0;
}
static int server_init(sd_bus **ret_bus) {
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
static int server_init(sd_bus **ret) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *unique, *desc;
sd_id128_t id;
int r;
assert_se(ret_bus);
assert(ret);
r = sd_bus_open_user_with_description(&bus, "my bus!");
if (r < 0)
@@ -65,8 +65,8 @@ static int server_init(sd_bus **ret_bus) {
if (r < 0)
return log_error_errno(r, "Failed to get unique name: %m");
assert_se(sd_bus_get_description(bus, &desc) >= 0);
assert_se(streq(desc, "my bus!"));
ASSERT_OK(sd_bus_get_description(bus, &desc));
ASSERT_STREQ(desc, "my bus!");
log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
log_info("Unique ID: %s", unique);
@@ -94,12 +94,11 @@ static int server_init(sd_bus **ret_bus) {
bus_match_dump(stdout, &bus->match_callbacks, 0);
*ret_bus = TAKE_PTR(bus);
*ret = TAKE_PTR(bus);
return 0;
}
static int server(sd_bus *_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = ASSERT_PTR(_bus);
static int server(sd_bus *bus) {
bool client1_gone = false, client2_gone = false;
int r;
@@ -250,7 +249,7 @@ static void* client1(void *p) {
goto finish;
}
assert_se(streq(hello, "hello"));
ASSERT_STREQ(hello, "hello");
if (pipe2(pp, O_CLOEXEC|O_NONBLOCK) < 0) {
r = log_error_errno(errno, "Failed to allocate pipe: %m");
@@ -494,44 +493,30 @@ finish:
return INT_TO_PTR(r);
}
int main(int argc, char *argv[]) {
TEST(chat) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
pthread_t c1, c2;
sd_bus *bus;
void *p;
int q, r;
int r;
test_setup_logging(LOG_INFO);
r = server_init(&bus);
if (r < 0)
return log_tests_skipped("Failed to connect to bus");
return (void) log_tests_skipped_errno(r, "Failed to connect to bus: %m");
log_info("Initialized...");
r = pthread_create(&c1, NULL, client1, bus);
if (r != 0)
return EXIT_FAILURE;
r = pthread_create(&c2, NULL, client2, bus);
if (r != 0)
return EXIT_FAILURE;
ASSERT_OK(-pthread_create(&c1, NULL, client1, NULL));
ASSERT_OK(-pthread_create(&c2, NULL, client2, NULL));
r = server(bus);
q = pthread_join(c1, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
q = pthread_join(c2, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
if (r < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
ASSERT_OK(-pthread_join(c1, &p));
ASSERT_OK(PTR_TO_INT(p));
ASSERT_OK(-pthread_join(c2, &p));
ASSERT_OK(PTR_TO_INT(p));
ASSERT_OK(r);
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@@ -23,13 +23,10 @@ static int something_handler(sd_bus_message *m, void *userdata, sd_bus_error *re
struct context *c = userdata;
const char *s;
char *n = NULL;
int r;
r = sd_bus_message_read(m, "s", &s);
assert_se(r > 0);
ASSERT_OK_POSITIVE(sd_bus_message_read(m, "s", &s));
n = strjoin("<<<", s, ">>>");
assert_se(n);
ASSERT_NOT_NULL(n = strjoin("<<<", s, ">>>"));
free(c->something);
c->something = n;
@@ -37,36 +34,31 @@ static int something_handler(sd_bus_message *m, void *userdata, sd_bus_error *re
log_info("AlterSomething() called, got %s, returning %s", s, n);
/* This should fail, since the return type doesn't match */
assert_se(sd_bus_reply_method_return(m, "u", 4711) == -ENOMSG);
ASSERT_ERROR(sd_bus_reply_method_return(m, "u", 4711), ENOMSG);
r = sd_bus_reply_method_return(m, "s", n);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, "s", n));
return 1;
}
static int exit_handler(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
struct context *c = userdata;
int r;
c->quit = true;
log_info("Exit called");
r = sd_bus_reply_method_return(m, "");
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, ""));
return 1;
}
static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error) {
struct context *c = userdata;
int r;
log_info("property get for %s called, returning \"%s\".", property, c->something);
r = sd_bus_message_append(reply, "s", c->something);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_append(reply, "s", c->something));
return 1;
}
@@ -75,15 +67,12 @@ static int set_handler(sd_bus *bus, const char *path, const char *interface, con
struct context *c = userdata;
const char *s;
char *n;
int r;
log_info("property set for %s called", property);
r = sd_bus_message_read(value, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(value, "s", &s));
n = strdup(s);
assert_se(n);
ASSERT_NOT_NULL(n = strdup(s));
free(c->something);
c->something = n;
@@ -94,87 +83,67 @@ static int set_handler(sd_bus *bus, const char *path, const char *interface, con
static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error) {
_cleanup_free_ char *s = NULL;
const char *x;
int r;
assert_se(asprintf(&s, "object %p, path %s", userdata, path) >= 0);
r = sd_bus_message_append(reply, "s", s);
assert_se(r >= 0);
ASSERT_OK(asprintf(&s, "object %p, path %s", userdata, path));
ASSERT_OK(sd_bus_message_append(reply, "s", s));
assert_se(x = startswith(path, "/value/"));
ASSERT_NOT_NULL(x = startswith(path, "/value/"));
assert_se(PTR_TO_UINT(userdata) == 30);
ASSERT_EQ(PTR_TO_UINT(userdata), 30U);
return 1;
}
static int notify_test(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", "Value", NULL));
assert_se(sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", "Value", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
static int notify_test2(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_properties_changed_strv(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", NULL));
assert_se(sd_bus_emit_properties_changed_strv(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
static int emit_interfaces_added(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_interfaces_added(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL));
assert_se(sd_bus_emit_interfaces_added(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
static int emit_interfaces_removed(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL));
assert_se(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
static int emit_object_added(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a/x"));
assert_se(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
static int emit_object_with_manager_added(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
assert_se(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a") >= 0);
ASSERT_OK(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a"));
return ASSERT_SE_NONNEG(sd_bus_reply_method_return(m, NULL));
return ASSERT_OK(sd_bus_reply_method_return(m, NULL));
}
static int emit_object_removed(sd_bus_message *m, void *userdata, sd_bus_error *reterr_error) {
int r;
ASSERT_OK(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), "/value/a/x"));
assert_se(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
return 1;
}
@@ -210,7 +179,7 @@ static const sd_bus_vtable vtable2[] = {
static int enumerator_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *reterr_error) {
if (object_path_startswith("/value", path))
assert_se(*nodes = strv_new("/value/c", "/value/b", "/value/a"));
ASSERT_NOT_NULL(*nodes = strv_new("/value/c", "/value/b", "/value/a"));
return 1;
}
@@ -218,7 +187,7 @@ static int enumerator_callback(sd_bus *bus, const char *path, void *userdata, ch
static int enumerator2_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *reterr_error) {
if (object_path_startswith("/value/a", path))
assert_se(*nodes = strv_new("/value/a/z", "/value/a/x", "/value/a/y"));
ASSERT_NOT_NULL(*nodes = strv_new("/value/a/z", "/value/a/x", "/value/a/y"));
return 1;
}
@@ -230,9 +199,9 @@ static int enumerator3_callback(sd_bus *bus, const char *path, void *userdata, c
return 1;
for (unsigned i = 10; i < 20; i++)
assert_se(strv_extendf(&v, "/value/b/%u", i) >= 0);
ASSERT_OK(strv_extendf(&v, "/value/b/%u", i));
for (unsigned i = 29; i >= 20; i--)
assert_se(strv_extendf(&v, "/value/b/%u", i) >= 0);
ASSERT_OK(strv_extendf(&v, "/value/b/%u", i));
*nodes = TAKE_PTR(v);
return 1;
@@ -246,22 +215,22 @@ static void* server(void *p) {
c->quit = false;
assert_se(sd_id128_randomize(&id) >= 0);
ASSERT_OK(sd_id128_randomize(&id));
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
assert_se(sd_bus_set_server(bus, 1, id) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_fd(bus, c->fds[0], c->fds[0]));
ASSERT_OK(sd_bus_set_server(bus, 1, id));
assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test", vtable, c) >= 0);
assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test2", vtable, c) >= 0);
assert_se(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL) >= 0);
assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/a", enumerator2_callback, NULL) >= 0);
assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/b", enumerator3_callback, NULL) >= 0);
assert_se(sd_bus_add_object_manager(bus, NULL, "/value") >= 0);
assert_se(sd_bus_add_object_manager(bus, NULL, "/value/a") >= 0);
ASSERT_OK(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test", vtable, c));
ASSERT_OK(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test2", vtable, c));
ASSERT_OK(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)));
ASSERT_OK(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL));
ASSERT_OK(sd_bus_add_node_enumerator(bus, NULL, "/value/a", enumerator2_callback, NULL));
ASSERT_OK(sd_bus_add_node_enumerator(bus, NULL, "/value/b", enumerator3_callback, NULL));
ASSERT_OK(sd_bus_add_object_manager(bus, NULL, "/value"));
ASSERT_OK(sd_bus_add_object_manager(bus, NULL, "/value/a"));
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_start(bus));
log_error("Entering event loop on server");
@@ -304,178 +273,147 @@ static int client(struct context *c) {
const char *s;
int r;
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_fd(bus, c->fds[1], c->fds[1]));
ASSERT_OK(sd_bus_start(bus));
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "NoOperation", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "NoOperation", &error, NULL, NULL));
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "s", "hallo");
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "s", "hallo"));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
assert_se(streq(s, "<<<hallo>>>"));
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
ASSERT_STREQ(s, "<<<hallo>>>");
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, "");
assert_se(r < 0);
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
ASSERT_FAIL(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, ""));
ASSERT_TRUE(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
sd_bus_error_free(&error);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, NULL); /* NULL and "" are equivalent */
assert_se(r < 0);
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
ASSERT_FAIL(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, NULL)); /* NULL and "" are equivalent */
ASSERT_TRUE(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
sd_bus_error_free(&error);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "as", 1, "hallo");
assert_se(r < 0);
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS));
ASSERT_FAIL(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "as", 1, "hallo"));
ASSERT_TRUE(sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS));
sd_bus_error_free(&error);
r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
assert_se(r >= 0);
ASSERT_OK(sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s"));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
assert_se(streq(s, "<<<hallo>>>"));
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
ASSERT_STREQ(s, "<<<hallo>>>");
reply = sd_bus_message_unref(reply);
r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, "s", "test");
assert_se(r >= 0);
ASSERT_OK(sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, "s", "test"));
r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
assert_se(r >= 0);
ASSERT_OK(sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s"));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
assert_se(streq(s, "test"));
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
ASSERT_STREQ(s, "test");
reply = sd_bus_message_unref(reply);
r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticIntegerProperty", &error, "u", 815);
assert_se(r >= 0);
ASSERT_OK(sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticIntegerProperty", &error, "u", 815));
assert_se(c->automatic_integer_property == 815);
ASSERT_EQ(c->automatic_integer_property, 815U);
r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticStringProperty", &error, "s", "Du Dödel, Du!");
assert_se(r >= 0);
ASSERT_OK(sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticStringProperty", &error, "s", "Du Dödel, Du!"));
assert_se(streq(c->automatic_string_property, "Du Dödel, Du!"));
ASSERT_STREQ(c->automatic_string_property, "Du Dödel, Du!");
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, ""));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL); /* NULL and "" are equivalent */
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL)); /* NULL and "" are equivalent */
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
reply = sd_bus_message_unref(reply);
r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/value/xuzz", "org.freedesktop.systemd.ValueTest", "Value", &error, &reply, "s");
assert_se(r >= 0);
ASSERT_OK(sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/value/xuzz", "org.freedesktop.systemd.ValueTest", "Value", &error, &reply, "s"));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
log_info("read %s", s);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
assert_se(lines = strv_split_newlines(s));
assert_se(strv_contains(lines, " <node name=\"x\"/>"));
assert_se(strv_contains(lines, " <node name=\"y\"/>"));
assert_se(strv_contains(lines, " <node name=\"z\"/>"));
ASSERT_NOT_NULL(lines = strv_split_newlines(s));
ASSERT_TRUE(strv_contains(lines, " <node name=\"x\"/>"));
ASSERT_TRUE(strv_contains(lines, " <node name=\"y\"/>"));
ASSERT_TRUE(strv_contains(lines, " <node name=\"z\"/>"));
lines = strv_free(lines);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/b", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/b", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL));
r = sd_bus_message_read(reply, "s", &s);
assert_se(r >= 0);
ASSERT_OK(sd_bus_message_read(reply, "s", &s));
fputs(s, stdout);
assert_se(lines = strv_split_newlines(s));
ASSERT_NOT_NULL(lines = strv_split_newlines(s));
for (unsigned i = 10; i < 30; i++) {
_cleanup_free_ char *n = NULL;
assert_se(asprintf(&n, " <node name=\"%u\"/>", i) >= 0);
assert_se(strv_contains(lines, n));
ASSERT_OK(asprintf(&n, " <node name=\"%u\"/>", i));
ASSERT_TRUE(strv_contains(lines, n));
}
lines = strv_free(lines);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", NULL));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "org.freedesktop.systemd.ValueTest2");
assert_se(r < 0);
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_INTERFACE));
ASSERT_FAIL(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "org.freedesktop.systemd.ValueTest2"));
ASSERT_TRUE(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_INTERFACE));
sd_bus_error_free(&error);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, NULL);
assert_se(r < 0);
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
ASSERT_FAIL(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, NULL));
ASSERT_TRUE(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
sd_bus_error_free(&error);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, NULL));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
/* Check that /value/b does not have ObjectManager interface but /value/a does */
assert_se(sd_bus_message_rewind(reply, 1) > 0);
assert_se(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{oa{sa{sv}}}") > 0);
ASSERT_OK_POSITIVE(sd_bus_message_rewind(reply, 1));
ASSERT_OK_POSITIVE(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{oa{sa{sv}}}"));
unsigned path_count = 0;
while (ASSERT_SE_NONNEG(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "oa{sa{sv}}")) > 0) {
while (ASSERT_OK(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "oa{sa{sv}}")) > 0) {
const char *path = NULL;
assert_se(sd_bus_message_read_basic(reply, 'o', &path) > 0);
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 'o', &path));
/* Check if the enumerated path is sorted. */
switch (path_count) {
@@ -498,154 +436,140 @@ static int client(struct context *c) {
/* Check that there is no object manager interface here */
bool found_object_manager_interface = false;
assert_se(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}") > 0);
while (ASSERT_SE_NONNEG(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
ASSERT_OK_POSITIVE(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}"));
while (ASSERT_OK(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
const char *interface_name = NULL;
assert_se(sd_bus_message_read_basic(reply, 's', &interface_name) > 0);
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 's', &interface_name));
if (streq(interface_name, "org.freedesktop.DBus.ObjectManager"))
found_object_manager_interface = true;
assert_se(sd_bus_message_skip(reply, "a{sv}") >= 0);
assert_se(sd_bus_message_exit_container(reply) >= 0);
ASSERT_OK(sd_bus_message_skip(reply, "a{sv}"));
ASSERT_OK(sd_bus_message_exit_container(reply));
}
assert_se(sd_bus_message_exit_container(reply) >= 0);
ASSERT_OK(sd_bus_message_exit_container(reply));
assert_se(found_object_manager_interface == streq(path, "/value/a"));
ASSERT_EQ(found_object_manager_interface, streq(path, "/value/a"));
assert_se(sd_bus_message_exit_container(reply) >= 0);
ASSERT_OK(sd_bus_message_exit_container(reply));
}
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest2", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest2", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesAdded", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesAdded", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesRemoved", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesRemoved", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectAdded", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectAdded", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
/* Check if /value/a/x does not have org.freedesktop.DBus.ObjectManager */
assert_se(sd_bus_message_rewind(reply, 1) >= 0);
ASSERT_OK(sd_bus_message_rewind(reply, 1));
const char* should_be_value_a_x = NULL;
assert_se(sd_bus_message_read_basic(reply, 'o', &should_be_value_a_x) > 0);
assert_se(streq(should_be_value_a_x, "/value/a/x"));
assert_se(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}") > 0);
while (ASSERT_SE_NONNEG(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 'o', &should_be_value_a_x));
ASSERT_STREQ(should_be_value_a_x, "/value/a/x");
ASSERT_OK_POSITIVE(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}"));
while (ASSERT_OK(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
const char* interface_name = NULL;
assert_se(sd_bus_message_read_basic(reply, 's', &interface_name) > 0);
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 's', &interface_name));
assert(!streq(interface_name, "org.freedesktop.DBus.ObjectManager"));
ASSERT_FALSE(streq(interface_name, "org.freedesktop.DBus.ObjectManager"));
assert_se(sd_bus_message_skip(reply, "a{sv}") >= 0);
ASSERT_OK(sd_bus_message_skip(reply, "a{sv}"));
assert_se(sd_bus_message_exit_container(reply) >= 0);
ASSERT_OK(sd_bus_message_exit_container(reply));
}
reply = sd_bus_message_unref(reply);
assert_se(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectWithManagerAdded", &error, NULL, NULL) >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectWithManagerAdded", &error, NULL, NULL));
assert_se(sd_bus_process(bus, &reply) > 0);
ASSERT_OK_POSITIVE(sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
/* Check if /value/a has org.freedesktop.DBus.ObjectManager */
assert_se(sd_bus_message_rewind(reply, 1) >= 0);
ASSERT_OK(sd_bus_message_rewind(reply, 1));
const char* should_be_value_a = NULL;
bool found_object_manager = false;
assert_se(sd_bus_message_read_basic(reply, 'o', &should_be_value_a) > 0);
assert_se(streq(should_be_value_a, "/value/a"));
assert_se(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}") > 0);
while (ASSERT_SE_NONNEG(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 'o', &should_be_value_a));
ASSERT_STREQ(should_be_value_a, "/value/a");
ASSERT_OK_POSITIVE(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sa{sv}}"));
while (ASSERT_OK(sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sa{sv}")) > 0) {
const char* interface_name = NULL;
assert_se(sd_bus_message_read_basic(reply, 's', &interface_name));
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 's', &interface_name));
if (streq(interface_name, "org.freedesktop.DBus.ObjectManager")) {
found_object_manager = true;
break;
}
assert_se(sd_bus_message_skip(reply, "a{sv}") >= 0);
ASSERT_OK(sd_bus_message_skip(reply, "a{sv}"));
assert_se(sd_bus_message_exit_container(reply) >= 0);
ASSERT_OK(sd_bus_message_exit_container(reply));
}
assert_se(found_object_manager);
ASSERT_TRUE(found_object_manager);
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectRemoved", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectRemoved", &error, NULL, NULL));
r = sd_bus_process(bus, &reply);
assert_se(r > 0);
ASSERT_OK_POSITIVE(r = sd_bus_process(bus, &reply));
assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
ASSERT_OK_POSITIVE(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
sd_bus_message_dump(reply, stdout, SD_BUS_MESSAGE_DUMP_WITH_HEADER);
/* Check if /value/a/x does not have org.freedesktop.DBus.ObjectManager */
assert_se(sd_bus_message_rewind(reply, 1) >= 0);
ASSERT_OK(sd_bus_message_rewind(reply, 1));
should_be_value_a_x = NULL;
assert_se(sd_bus_message_read_basic(reply, 'o', &should_be_value_a_x) > 0);
assert_se(streq(should_be_value_a_x, "/value/a/x"));
assert_se(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s") > 0);
ASSERT_OK_POSITIVE(sd_bus_message_read_basic(reply, 'o', &should_be_value_a_x));
ASSERT_STREQ(should_be_value_a_x, "/value/a/x");
ASSERT_OK_POSITIVE(sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s"));
const char* deleted_interface_name = NULL;
while (ASSERT_SE_NONNEG(sd_bus_message_read_basic(reply, 's', &deleted_interface_name)) > 0) {
assert(!streq(deleted_interface_name, "org.freedesktop.DBus.ObjectManager"));
}
assert_se(sd_bus_message_exit_container(reply) >= 0);
while (ASSERT_OK(sd_bus_message_read_basic(reply, 's', &deleted_interface_name)))
ASSERT_FALSE(streq(deleted_interface_name, "org.freedesktop.DBus.ObjectManager"));
ASSERT_OK(sd_bus_message_exit_container(reply));
reply = sd_bus_message_unref(reply);
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Exit", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Exit", &error, NULL, NULL));
sd_bus_flush(bus);
@@ -661,9 +585,9 @@ int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG);
c.automatic_integer_property = 4711;
assert_se(c.automatic_string_property = strdup("dudeldu"));
ASSERT_NOT_NULL(c.automatic_string_property = strdup("dudeldu"));
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds));
r = pthread_create(&s, NULL, server, &c);
if (r != 0)

View File

@@ -14,8 +14,8 @@
#include "user-util.h"
static bool gid_list_contained(const gid_t *a, size_t n, const gid_t *b, size_t m) {
assert_se(a || n == 0);
assert_se(b || m == 0);
ASSERT_TRUE(a || n == 0);
ASSERT_TRUE(b || m == 0);
/* Checks if every entry in a[] is also in b[] */
@@ -46,77 +46,70 @@ static void* server(void *p) {
sd_id128_t id;
int r;
assert_se(sd_id128_randomize(&id) >= 0);
ASSERT_OK(sd_id128_randomize(&id));
fd = accept4(listen_fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK);
assert_se(fd >= 0);
ASSERT_OK_ERRNO(fd = accept4(listen_fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK));
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_fd(bus, fd, fd) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_fd(bus, fd, fd));
TAKE_FD(fd);
assert_se(sd_bus_set_server(bus, true, id) >= 0);
assert_se(sd_bus_negotiate_creds(bus, 1, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_SUPPLEMENTARY_GIDS) >= 0);
assert_se(sd_bus_start(bus) >= 0);
assert_se(sd_bus_get_owner_creds(bus, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_SUPPLEMENTARY_GIDS, &c) >= 0);
ASSERT_OK(sd_bus_set_server(bus, true, id));
ASSERT_OK(sd_bus_negotiate_creds(bus, 1, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_SUPPLEMENTARY_GIDS));
ASSERT_OK(sd_bus_start(bus));
ASSERT_OK(sd_bus_get_owner_creds(bus, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_SUPPLEMENTARY_GIDS, &c));
bus_creds_dump(c, /* f= */ NULL, /* terse= */ false);
uid_t u;
assert_se(sd_bus_creds_get_euid(c, &u) >= 0);
assert_se(u == getuid());
ASSERT_OK(sd_bus_creds_get_euid(c, &u));
ASSERT_EQ(u, getuid());
gid_t g;
assert_se(sd_bus_creds_get_egid(c, &g) >= 0);
assert_se(g == getgid());
ASSERT_OK(sd_bus_creds_get_egid(c, &g));
ASSERT_EQ(g, getgid());
pid_t pid;
assert_se(sd_bus_creds_get_pid(c, &pid) >= 0);
assert_se(pid == getpid_cached());
ASSERT_OK(sd_bus_creds_get_pid(c, &pid));
ASSERT_EQ(pid, getpid_cached());
int pidfd = -EBADF;
if (sd_bus_creds_get_pidfd_dup(c, &pidfd) >= 0) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
assert_se(pidref_set_pidfd_take(&pidref, pidfd) >= 0);
assert_se(pidref_is_self(&pidref));
ASSERT_OK(pidref_set_pidfd_take(&pidref, pidfd));
ASSERT_TRUE(pidref_is_self(&pidref));
}
const gid_t *gl = NULL;
int n;
n = sd_bus_creds_get_supplementary_gids(c, &gl);
int n = sd_bus_creds_get_supplementary_gids(c, &gl);
if (n >= 0) {
_cleanup_free_ gid_t *gg = NULL;
r = getgroups_alloc(&gg);
assert_se(r >= 0);
assert_se(gid_list_same(gl, n, gg, r));
ASSERT_OK(r = getgroups_alloc(&gg));
ASSERT_TRUE(gid_list_same(gl, n, gg, r));
}
const char *comm;
assert_se(sd_bus_creds_get_comm(c, &comm) >= 0);
assert_se(pid_get_comm(0, &our_comm) >= 0);
assert_se(streq_ptr(comm, our_comm));
ASSERT_OK(sd_bus_creds_get_comm(c, &comm));
ASSERT_OK(pid_get_comm(0, &our_comm));
ASSERT_STREQ(comm, our_comm);
const char *description;
assert_se(sd_bus_creds_get_description(c, &description) >= 0);
assert_se(streq_ptr(description, "wuffwuff"));
ASSERT_OK(sd_bus_creds_get_description(c, &description));
ASSERT_STREQ(description, "wuffwuff");
for (;;) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
r = sd_bus_process(bus, &m);
assert_se(r >= 0);
ASSERT_OK(r = sd_bus_process(bus, &m));
if (r == 0) {
assert_se(sd_bus_wait(bus, UINT64_MAX) >= 0);
ASSERT_OK(sd_bus_wait(bus, UINT64_MAX));
continue;
}
if (m && sd_bus_message_is_method_call(m, "foo.foo", "Foo") > 0) {
assert_se(sd_bus_reply_method_return(m, "s", "bar") >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, "s", "bar"));
break;
}
}
@@ -129,15 +122,15 @@ static void* client(void *p) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
const char *z;
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_description(bus, "wuffwuff") >= 0);
assert_se(sd_bus_set_address(bus, p) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_description(bus, "wuffwuff"));
ASSERT_OK(sd_bus_set_address(bus, p));
ASSERT_OK(sd_bus_start(bus));
assert_se(sd_bus_call_method(bus, "foo.foo", "/foo", "foo.foo", "Foo", NULL, &reply, "s", "foo") >= 0);
ASSERT_OK(sd_bus_call_method(bus, "foo.foo", "/foo", "foo.foo", "Foo", NULL, &reply, "s", "foo"));
assert_se(sd_bus_message_read(reply, "s", &z) >= 0);
assert_se(streq_ptr(z, "bar"));
ASSERT_OK(sd_bus_message_read(reply, "s", &z));
ASSERT_STREQ(z, "bar");
return NULL;
}
@@ -151,27 +144,24 @@ TEST(description) {
socklen_t salen;
pthread_t s, c;
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
assert_se(fd >= 0);
assert_se(bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path)) >= 0); /* force auto-bind */
assert_se(listen(fd, 1) >= 0);
ASSERT_OK_ERRNO(fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0));
ASSERT_OK_ERRNO(bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path))); /* force auto-bind */
ASSERT_OK_ERRNO(listen(fd, 1));
salen = sizeof(sa);
assert_se(getsockname(fd, &sa.sa, &salen) >= 0);
assert_se(salen >= offsetof(struct sockaddr_un, sun_path));
assert_se(sa.un.sun_path[0] == 0);
ASSERT_OK_ERRNO(getsockname(fd, &sa.sa, &salen));
ASSERT_GE(salen, offsetof(struct sockaddr_un, sun_path));
ASSERT_EQ(sa.un.sun_path[0], 0);
assert_se(asprintf(&a, "unix:abstract=%s", sa.un.sun_path + 1) >= 0);
ASSERT_OK(asprintf(&a, "unix:abstract=%s", sa.un.sun_path + 1));
assert_se(pthread_create(&s, NULL, server, INT_TO_PTR(fd)) == 0);
ASSERT_OK(-pthread_create(&s, NULL, server, INT_TO_PTR(fd)));
TAKE_FD(fd);
assert_se(pthread_create(&c, NULL, client, a) == 0);
ASSERT_OK(-pthread_create(&c, NULL, client, a));
assert_se(pthread_join(s, NULL) == 0);
assert_se(pthread_join(c, NULL) == 0);
ASSERT_OK(-pthread_join(s, NULL));
ASSERT_OK(-pthread_join(c, NULL));
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@@ -5,7 +5,6 @@
#include "sd-bus.h"
#include "bus-error.h"
#include "log.h"
#include "memory-util.h"
#include "string-util.h"
@@ -27,14 +26,14 @@ static int _server(struct context *c) {
bool quit = false;
int r;
assert_se(sd_id128_randomize(&id) >= 0);
ASSERT_OK(sd_id128_randomize(&id));
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
assert_se(sd_bus_set_server(bus, 1, id) >= 0);
assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_fd(bus, c->fds[0], c->fds[0]));
ASSERT_OK(sd_bus_set_server(bus, 1, id));
ASSERT_OK(sd_bus_set_anonymous(bus, c->server_anonymous_auth));
ASSERT_OK(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds));
ASSERT_OK(sd_bus_start(bus));
while (!quit) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
@@ -44,9 +43,7 @@ static int _server(struct context *c) {
return log_error_errno(r, "Failed to process requests: %m");
if (r == 0) {
r = sd_bus_wait(bus, UINT64_MAX);
if (r < 0)
return log_error_errno(r, "Failed to wait: %m");
ASSERT_OK(sd_bus_wait(bus, UINT64_MAX));
continue;
}
@@ -57,29 +54,21 @@ static int _server(struct context *c) {
if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
(c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
ASSERT_EQ(sd_bus_can_send(bus, 'h') >= 1,
c->server_negotiate_unix_fds && c->client_negotiate_unix_fds);
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
return log_error_errno(r, "Failed to allocate return: %m");
ASSERT_OK(sd_bus_message_new_method_return(m, &reply));
quit = true;
} else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
r = sd_bus_message_new_method_error(
} else if (sd_bus_message_is_method_call(m, NULL, NULL))
ASSERT_OK(sd_bus_message_new_method_error(
m,
&reply,
&SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
if (r < 0)
return log_error_errno(r, "Failed to allocate return: %m");
}
&SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")));
if (reply) {
r = sd_bus_send(bus, reply, NULL);
if (r < 0)
return log_error_errno(r, "Failed to send reply: %m");
}
if (reply)
ASSERT_OK(sd_bus_send(bus, reply, NULL));
}
return 0;
@@ -93,29 +82,22 @@ static int client(struct context *c) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_fd(bus, c->fds[1], c->fds[1]));
ASSERT_OK(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds));
ASSERT_OK(sd_bus_set_anonymous(bus, c->client_anonymous_auth));
ASSERT_OK(sd_bus_start(bus));
r = sd_bus_message_new_method_call(
ASSERT_OK(sd_bus_message_new_method_call(
bus,
&m,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"Exit");
if (r < 0)
return log_error_errno(r, "Failed to allocate method call: %m");
"Exit"));
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
return 0;
return sd_bus_call(bus, m, 0, &error, &reply);
}
static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds,
@@ -128,7 +110,7 @@ static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_f
zero(c);
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds));
c.client_negotiate_unix_fds = client_negotiate_unix_fds;
c.server_negotiate_unix_fds = server_negotiate_unix_fds;
@@ -155,30 +137,15 @@ static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_f
}
int main(int argc, char *argv[]) {
int r;
test_setup_logging(LOG_DEBUG);
r = test_one(true, true, false, false);
assert_se(r >= 0);
r = test_one(true, false, false, false);
assert_se(r >= 0);
r = test_one(false, true, false, false);
assert_se(r >= 0);
r = test_one(false, false, false, false);
assert_se(r >= 0);
r = test_one(true, true, true, true);
assert_se(r >= 0);
r = test_one(true, true, false, true);
assert_se(r >= 0);
r = test_one(true, true, true, false);
assert_se(r == -EPERM);
ASSERT_OK(test_one(true, true, false, false));
ASSERT_OK(test_one(true, false, false, false));
ASSERT_OK(test_one(false, true, false, false));
ASSERT_OK(test_one(false, false, false, false));
ASSERT_OK(test_one(true, true, true, true));
ASSERT_OK(test_one(true, true, false, true));
ASSERT_ERROR(test_one(true, true, true, false), EPERM);
return EXIT_SUCCESS;
}

View File

@@ -24,14 +24,14 @@
static int method_foobar(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Got Foobar() call.");
assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0) >= 0);
ASSERT_OK(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0));
return sd_bus_reply_method_return(m, NULL);
}
static int method_exit(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Got Exit() call");
assert_se(sd_bus_reply_method_return(m, NULL) >= 0);
ASSERT_OK(sd_bus_reply_method_return(m, NULL));
/* Simulate D-Bus going away to test the bus_exit_now() path with exit_on_disconnect set */
bus_enter_closing(sd_bus_message_get_bus(m));
return 0;
@@ -56,37 +56,37 @@ static void* thread_server(void *p) {
/* Let's play some games, by slowly creating the socket directory, and renaming it in the middle */
usleep_safe(100 * USEC_PER_MSEC);
assert_se(mkdir_parents(path, 0755) >= 0);
ASSERT_OK(mkdir_parents(path, 0755));
usleep_safe(100 * USEC_PER_MSEC);
assert_se(path_extract_directory(path, &d) >= 0);
assert_se(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()) >= 0);
assert_se(rename(d, suffixed) >= 0);
ASSERT_OK(path_extract_directory(path, &d));
ASSERT_OK(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()));
ASSERT_OK_ERRNO(rename(d, suffixed));
usleep_safe(100 * USEC_PER_MSEC);
assert_se(asprintf(&suffixed2, "%s.%" PRIx64, d, random_u64()) >= 0);
assert_se(symlink(suffixed2, d) >= 0);
ASSERT_OK(asprintf(&suffixed2, "%s.%" PRIx64, d, random_u64()));
ASSERT_OK_ERRNO(symlink(suffixed2, d));
usleep_safe(100 * USEC_PER_MSEC);
assert_se(path_extract_filename(suffixed, &suffixed_basename) >= 0);
assert_se(symlink(suffixed_basename, suffixed2) >= 0);
ASSERT_OK(path_extract_filename(suffixed, &suffixed_basename));
ASSERT_OK_ERRNO(symlink(suffixed_basename, suffixed2));
usleep_safe(100 * USEC_PER_MSEC);
socklen_t sa_len;
r = sockaddr_un_set_path(&u.un, path);
assert_se(r >= 0);
ASSERT_OK(r);
sa_len = r;
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
assert_se(fd >= 0);
ASSERT_OK_ERRNO(fd);
assert_se(bind(fd, &u.sa, sa_len) >= 0);
ASSERT_OK_ERRNO(bind(fd, &u.sa, sa_len));
usleep_safe(100 * USEC_PER_MSEC);
assert_se(listen(fd, SOMAXCONN_DELUXE) >= 0);
ASSERT_OK_ERRNO(listen(fd, SOMAXCONN_DELUXE));
usleep_safe(100 * USEC_PER_MSEC);
assert_se(touch(path) >= 0);
ASSERT_OK(touch(path));
usleep_safe(100 * USEC_PER_MSEC);
log_debug("Initialized server");
@@ -97,31 +97,31 @@ static void* thread_server(void *p) {
sd_id128_t id;
int bus_fd, code;
assert_se(sd_id128_randomize(&id) >= 0);
ASSERT_OK(sd_id128_randomize(&id));
assert_se(sd_event_new(&event) >= 0);
ASSERT_OK(sd_event_new(&event));
bus_fd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
assert_se(bus_fd >= 0);
ASSERT_OK_ERRNO(bus_fd);
log_debug("Accepted server connection");
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_exit_on_disconnect(bus, true) >= 0);
assert_se(sd_bus_set_description(bus, "server") >= 0);
assert_se(sd_bus_set_fd(bus, bus_fd, bus_fd) >= 0);
assert_se(sd_bus_set_server(bus, true, id) >= 0);
/* assert_se(sd_bus_set_anonymous(bus, true) >= 0); */
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_exit_on_disconnect(bus, true));
ASSERT_OK(sd_bus_set_description(bus, "server"));
ASSERT_OK(sd_bus_set_fd(bus, bus_fd, bus_fd));
ASSERT_OK(sd_bus_set_server(bus, true, id));
/* ASSERT_OK(sd_bus_set_anonymous(bus, true)); */
assert_se(sd_bus_attach_event(bus, event, 0) >= 0);
ASSERT_OK(sd_bus_attach_event(bus, event, 0));
assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "foo.TestInterface", vtable, NULL) >= 0);
ASSERT_OK(sd_bus_add_object_vtable(bus, NULL, "/foo", "foo.TestInterface", vtable, NULL));
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_start(bus));
assert_se(sd_event_loop(event) >= 0);
ASSERT_OK(sd_event_loop(event));
assert_se(sd_event_get_exit_code(event, &code) >= 0);
ASSERT_OK(sd_event_get_exit_code(event, &code));
if (code > 0)
break;
@@ -136,20 +136,18 @@ static void* thread_client1(void *p) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *path = p, *t;
int r;
log_debug("Initializing client1");
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_description(bus, "client1") >= 0);
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_description(bus, "client1"));
t = strjoina("unix:path=", path);
assert_se(sd_bus_set_address(bus, t) >= 0);
assert_se(sd_bus_set_watch_bind(bus, true) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_set_address(bus, t));
ASSERT_OK(sd_bus_set_watch_bind(bus, true));
ASSERT_OK(sd_bus_start(bus));
r = sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Foobar", &error, NULL, NULL);
assert_se(r >= 0);
ASSERT_OK(sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Foobar", &error, NULL, NULL));
log_debug("Client1 done");
@@ -157,8 +155,8 @@ static void* thread_client1(void *p) {
}
static int client2_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
assert_se(sd_bus_message_is_method_error(m, NULL) == 0);
assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0) >= 0);
ASSERT_OK_ZERO(sd_bus_message_is_method_error(m, NULL));
ASSERT_OK(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0));
return 0;
}
@@ -169,19 +167,19 @@ static void* thread_client2(void *p) {
log_debug("Initializing client2");
assert_se(sd_event_new(&event) >= 0);
assert_se(sd_bus_new(&bus) >= 0);
assert_se(sd_bus_set_description(bus, "client2") >= 0);
ASSERT_OK(sd_event_new(&event));
ASSERT_OK(sd_bus_new(&bus));
ASSERT_OK(sd_bus_set_description(bus, "client2"));
t = strjoina("unix:path=", path);
assert_se(sd_bus_set_address(bus, t) >= 0);
assert_se(sd_bus_set_watch_bind(bus, true) >= 0);
assert_se(sd_bus_attach_event(bus, event, 0) >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_set_address(bus, t));
ASSERT_OK(sd_bus_set_watch_bind(bus, true));
ASSERT_OK(sd_bus_attach_event(bus, event, 0));
ASSERT_OK(sd_bus_start(bus));
assert_se(sd_bus_call_method_async(bus, NULL, "foo.bar", "/foo", "foo.TestInterface", "Foobar", client2_callback, NULL, NULL) >= 0);
ASSERT_OK(sd_bus_call_method_async(bus, NULL, "foo.bar", "/foo", "foo.TestInterface", "Foobar", client2_callback, NULL, NULL));
assert_se(sd_event_loop(event) >= 0);
ASSERT_OK(sd_event_loop(event));
log_debug("Client2 done");
@@ -192,15 +190,15 @@ static void request_exit(const char *path) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
const char *t;
assert_se(sd_bus_new(&bus) >= 0);
ASSERT_OK(sd_bus_new(&bus));
t = strjoina("unix:path=", path);
assert_se(sd_bus_set_address(bus, t) >= 0);
assert_se(sd_bus_set_watch_bind(bus, true) >= 0);
assert_se(sd_bus_set_description(bus, "request-exit") >= 0);
assert_se(sd_bus_start(bus) >= 0);
ASSERT_OK(sd_bus_set_address(bus, t));
ASSERT_OK(sd_bus_set_watch_bind(bus, true));
ASSERT_OK(sd_bus_set_description(bus, "request-exit"));
ASSERT_OK(sd_bus_start(bus));
assert_se(sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Exit", NULL, NULL, NULL) >= 0);
ASSERT_OK(sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Exit", NULL, NULL, NULL));
}
int main(int argc, char *argv[]) {
@@ -212,20 +210,20 @@ int main(int argc, char *argv[]) {
/* We use /dev/shm here rather than /tmp, since some weird distros might set up /tmp as some weird fs that
* doesn't support inotify properly. */
assert_se(mkdtemp_malloc("/dev/shm/systemd-watch-bind-XXXXXX", &d) >= 0);
ASSERT_OK(mkdtemp_malloc("/dev/shm/systemd-watch-bind-XXXXXX", &d));
path = strjoina(d, "/this/is/a/socket");
assert_se(pthread_create(&server, NULL, thread_server, path) == 0);
assert_se(pthread_create(&client1, NULL, thread_client1, path) == 0);
assert_se(pthread_create(&client2, NULL, thread_client2, path) == 0);
ASSERT_OK(-pthread_create(&server, NULL, thread_server, path));
ASSERT_OK(-pthread_create(&client1, NULL, thread_client1, path));
ASSERT_OK(-pthread_create(&client2, NULL, thread_client2, path));
assert_se(pthread_join(client1, NULL) == 0);
assert_se(pthread_join(client2, NULL) == 0);
ASSERT_OK(-pthread_join(client1, NULL));
ASSERT_OK(-pthread_join(client2, NULL));
request_exit(path);
assert_se(pthread_join(server, NULL) == 0);
ASSERT_OK(-pthread_join(server, NULL));
return 0;
}

View File

@@ -41,18 +41,18 @@ static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userda
log_info("got IO on %c", PTR_TO_INT(userdata));
if (userdata == INT_TO_PTR('a')) {
assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
assert_se(!got_a);
ASSERT_OK(sd_event_source_set_enabled(s, SD_EVENT_OFF));
ASSERT_FALSE(got_a);
got_a = true;
} else if (userdata == INT_TO_PTR('b')) {
assert_se(!got_b);
ASSERT_FALSE(got_b);
got_b = true;
} else if (userdata == INT_TO_PTR('d')) {
got_d++;
if (got_d < 2)
assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
ASSERT_OK(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT));
else
assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
ASSERT_OK(sd_event_source_set_enabled(s, SD_EVENT_OFF));
} else
assert_not_reached();
@@ -61,19 +61,19 @@ static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userda
static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
assert_se(s);
assert_se(si);
ASSERT_NOT_NULL(s);
ASSERT_NOT_NULL(si);
assert_se(si->si_uid == getuid());
assert_se(si->si_signo == SIGCHLD);
assert_se(si->si_code == CLD_EXITED);
assert_se(si->si_status == 78);
ASSERT_EQ(si->si_uid, getuid());
ASSERT_EQ(si->si_signo, SIGCHLD);
ASSERT_EQ(si->si_code, CLD_EXITED);
ASSERT_EQ(si->si_status, 78);
log_info("got child on %c", PTR_TO_INT(userdata));
assert_se(userdata == INT_TO_PTR('f'));
ASSERT_PTR_EQ(userdata, INT_TO_PTR('f'));
assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
ASSERT_OK(sd_event_exit(sd_event_source_get_event(s), 0));
sd_event_source_unref(s);
return 1;
@@ -84,36 +84,35 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si,
pid_t pid;
siginfo_t plain_si;
assert_se(s);
assert_se(si);
ASSERT_NOT_NULL(s);
ASSERT_NOT_NULL(si);
log_info("got signal on %c", PTR_TO_INT(userdata));
assert_se(userdata == INT_TO_PTR('e'));
ASSERT_PTR_EQ(userdata, INT_TO_PTR('e'));
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGUSR2) >= 0);
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGUSR2));
pid = fork();
assert_se(pid >= 0);
ASSERT_OK_ERRNO(pid = fork());
if (pid == 0) {
sigset_t ss;
assert_se(sigemptyset(&ss) >= 0);
assert_se(sigaddset(&ss, SIGUSR2) >= 0);
ASSERT_OK_ERRNO(sigemptyset(&ss));
ASSERT_OK_ERRNO(sigaddset(&ss, SIGUSR2));
zero(plain_si);
assert_se(sigwaitinfo(&ss, &plain_si) >= 0);
ASSERT_OK_ERRNO(sigwaitinfo(&ss, &plain_si));
assert_se(plain_si.si_signo == SIGUSR2);
assert_se(plain_si.si_value.sival_int == 4711);
ASSERT_EQ(plain_si.si_signo, SIGUSR2);
ASSERT_EQ(plain_si.si_value.sival_int, 4711);
_exit(78);
}
assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
assert_se(sd_event_source_set_child_process_own(p, true) >= 0);
ASSERT_OK(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')));
ASSERT_OK(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT));
ASSERT_OK(sd_event_source_set_child_process_own(p, true));
/* We can't use structured initialization here, since the structure contains various unions and these
* fields lie in overlapping (carefully aligned) unions that LLVM is allergic to allow assignments
@@ -125,7 +124,7 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si,
plain_si.si_uid = getuid();
plain_si.si_value.sival_int = 4711;
assert_se(sd_event_source_send_child_signal(p, SIGUSR2, &plain_si, 0) >= 0);
ASSERT_OK(sd_event_source_send_child_signal(p, SIGUSR2, &plain_si, 0));
sd_event_source_unref(s);
@@ -135,16 +134,16 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si,
static int defer_handler(sd_event_source *s, void *userdata) {
sd_event_source *p = NULL;
assert_se(s);
ASSERT_NOT_NULL(s);
log_info("got defer on %c", PTR_TO_INT(userdata));
assert_se(userdata == INT_TO_PTR('d'));
ASSERT_PTR_EQ(userdata, INT_TO_PTR('d'));
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGUSR1) >= 0);
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGUSR1));
assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0);
assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
ASSERT_OK(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')));
ASSERT_OK(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT));
raise(SIGUSR1);
sd_event_source_unref(s);
@@ -162,10 +161,10 @@ static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
if (do_quit) {
sd_event_source *p;
assert_se(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')) >= 0);
assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
ASSERT_OK(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')));
ASSERT_OK(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT));
} else {
assert_se(!got_c);
ASSERT_FALSE(got_c);
got_c = true;
}
} else
@@ -203,84 +202,92 @@ TEST(basic) {
uint64_t event_now;
int64_t priority;
assert_se(pipe(a) >= 0);
assert_se(pipe(b) >= 0);
assert_se(pipe(d) >= 0);
assert_se(pipe(k) >= 0);
ASSERT_OK_ERRNO(pipe(a));
ASSERT_OK_ERRNO(pipe(b));
ASSERT_OK_ERRNO(pipe(d));
ASSERT_OK_ERRNO(pipe(k));
assert_se(sd_event_default(&e) >= 0);
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0);
ASSERT_OK(sd_event_default(&e));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_MONOTONIC, &event_now));
assert_se(sd_event_set_watchdog(e, true) >= 0);
ASSERT_OK(sd_event_set_watchdog(e, true));
/* Test whether we cleanly can destroy an io event source from its own handler */
got_unref = false;
assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
assert_se(write(k[1], &ch, 1) == 1);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(got_unref);
ASSERT_OK(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL));
ASSERT_OK_EQ_ERRNO(write(k[1], &ch, 1), 1);
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
ASSERT_TRUE(got_unref);
got_a = false, got_b = false, got_c = false, got_d = 0;
/* Add a oneshot handler, trigger it, reenable it, and trigger it again. */
assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
assert_se(write(d[1], &ch, 1) >= 0);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(got_d == 1);
assert_se(write(d[1], &ch, 1) >= 0);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(got_d == 2);
ASSERT_OK(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')));
ASSERT_OK(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT));
ASSERT_OK_ERRNO(write(d[1], &ch, 1));
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
ASSERT_EQ(got_d, 1U);
ASSERT_OK_ERRNO(write(d[1], &ch, 1));
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
ASSERT_EQ(got_d, 2U);
assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
ASSERT_OK(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')));
ASSERT_OK(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')));
do_quit = false;
assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
ASSERT_OK(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')));
ASSERT_OK(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')));
assert_se(sd_event_source_set_priority(x, 99) >= 0);
assert_se(sd_event_source_get_priority(x, &priority) >= 0);
assert_se(priority == 99);
assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
assert_se(sd_event_source_set_priority(z, 50) >= 0);
assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
ASSERT_OK(sd_event_source_set_priority(x, 99));
ASSERT_OK(sd_event_source_get_priority(x, &priority));
ASSERT_EQ(priority, 99);
ASSERT_OK(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT));
ASSERT_OK(sd_event_source_set_prepare(x, prepare_handler));
ASSERT_OK(sd_event_source_set_priority(z, 50));
ASSERT_OK(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT));
ASSERT_OK(sd_event_source_set_prepare(z, prepare_handler));
/* Test for floating event sources */
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+1) >= 0);
assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+1));
ASSERT_OK(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL));
assert_se(write(a[1], &ch, 1) >= 0);
assert_se(write(b[1], &ch, 1) >= 0);
ASSERT_OK_ERRNO(write(a[1], &ch, 1));
ASSERT_OK_ERRNO(write(b[1], &ch, 1));
assert_se(!got_a && !got_b && !got_c);
ASSERT_FALSE(got_a);
ASSERT_FALSE(got_b);
ASSERT_FALSE(got_c);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
assert_se(!got_a && got_b && !got_c);
ASSERT_FALSE(got_a);
ASSERT_TRUE(got_b);
ASSERT_FALSE(got_c);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
assert_se(!got_a && got_b && got_c);
ASSERT_FALSE(got_a);
ASSERT_TRUE(got_b);
ASSERT_TRUE(got_c);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
ASSERT_OK_POSITIVE(sd_event_run(e, UINT64_MAX));
assert_se(got_a && got_b && got_c);
ASSERT_TRUE(got_a);
ASSERT_TRUE(got_b);
ASSERT_TRUE(got_c);
sd_event_source_unref(x);
sd_event_source_unref(y);
do_quit = true;
assert_se(sd_event_add_post(e, NULL, post_handler, NULL) >= 0);
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0);
assert_se(sd_event_source_set_time(z, event_now + 200 * USEC_PER_MSEC) >= 0);
assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
ASSERT_OK(sd_event_add_post(e, NULL, post_handler, NULL));
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_MONOTONIC, &event_now));
ASSERT_OK(sd_event_source_set_time(z, event_now + 200 * USEC_PER_MSEC));
ASSERT_OK(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT));
assert_se(sd_event_loop(e) >= 0);
assert_se(got_post);
assert_se(got_exit);
ASSERT_OK(sd_event_loop(e));
ASSERT_TRUE(got_post);
ASSERT_TRUE(got_exit);
sd_event_source_unref(z);
sd_event_source_unref(q);
@@ -299,24 +306,24 @@ TEST(sd_event_now) {
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
uint64_t event_now;
assert_se(sd_event_new(&e) >= 0);
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) > 0);
assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) > 0);
assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
ASSERT_OK(sd_event_new(&e));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_MONOTONIC, &event_now));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_REALTIME, &event_now));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_BOOTTIME, &event_now));
ASSERT_OK_POSITIVE(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now));
ASSERT_ERROR(sd_event_now(e, -1, &event_now), EOPNOTSUPP);
ASSERT_ERROR(sd_event_now(e, 900 /* arbitrary big number */, &event_now), EOPNOTSUPP);
assert_se(sd_event_run(e, 0) == 0);
ASSERT_OK_ZERO(sd_event_run(e, 0));
assert_se(sd_event_now(e, CLOCK_MONOTONIC, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_REALTIME, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_BOOTTIME, &event_now) == 0);
assert_se(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now) == 0);
assert_se(sd_event_now(e, -1, &event_now) == -EOPNOTSUPP);
assert_se(sd_event_now(e, 900 /* arbitrary big number */, &event_now) == -EOPNOTSUPP);
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_MONOTONIC, &event_now));
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_REALTIME, &event_now));
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_REALTIME_ALARM, &event_now));
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_BOOTTIME, &event_now));
ASSERT_OK_ZERO(sd_event_now(e, CLOCK_BOOTTIME_ALARM, &event_now));
ASSERT_ERROR(sd_event_now(e, -1, &event_now), EOPNOTSUPP);
ASSERT_ERROR(sd_event_now(e, 900 /* arbitrary big number */, &event_now), EOPNOTSUPP);
}
static int last_rtqueue_sigval = 0;
@@ -332,43 +339,43 @@ TEST(rtqueue) {
sd_event_source *u = NULL, *v = NULL, *s = NULL;
sd_event *e = NULL;
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+2, SIGRTMIN+3, SIGUSR2) >= 0);
assert_se(sd_event_add_signal(e, &u, SIGRTMIN+2, rtqueue_handler, NULL) >= 0);
assert_se(sd_event_add_signal(e, &v, SIGRTMIN+3, rtqueue_handler, NULL) >= 0);
assert_se(sd_event_add_signal(e, &s, SIGUSR2, rtqueue_handler, NULL) >= 0);
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+2, SIGRTMIN+3, SIGUSR2));
ASSERT_OK(sd_event_add_signal(e, &u, SIGRTMIN+2, rtqueue_handler, NULL));
ASSERT_OK(sd_event_add_signal(e, &v, SIGRTMIN+3, rtqueue_handler, NULL));
ASSERT_OK(sd_event_add_signal(e, &s, SIGUSR2, rtqueue_handler, NULL));
assert_se(sd_event_source_set_priority(v, -10) >= 0);
ASSERT_OK(sd_event_source_set_priority(v, -10));
assert_se(sigqueue(getpid_cached(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }) >= 0);
assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }) >= 0);
assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 3 }) >= 0);
assert_se(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }) >= 0);
assert_se(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 5 }) >= 0);
ASSERT_OK_ERRNO(sigqueue(getpid_cached(), SIGRTMIN+2, (union sigval) { .sival_int = 1 }));
ASSERT_OK_ERRNO(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 2 }));
ASSERT_OK_ERRNO(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 3 }));
ASSERT_OK_ERRNO(sigqueue(getpid_cached(), SIGRTMIN+3, (union sigval) { .sival_int = 4 }));
ASSERT_OK_ERRNO(sigqueue(getpid_cached(), SIGUSR2, (union sigval) { .sival_int = 5 }));
assert_se(n_rtqueue == 0);
assert_se(last_rtqueue_sigval == 0);
ASSERT_EQ(n_rtqueue, 0);
ASSERT_EQ(last_rtqueue_sigval, 0);
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(n_rtqueue == 1);
assert_se(last_rtqueue_sigval == 2); /* first SIGRTMIN+3 */
ASSERT_OK_EQ(sd_event_run(e, UINT64_MAX), 1);
ASSERT_EQ(n_rtqueue, 1);
ASSERT_EQ(last_rtqueue_sigval, 2); /* first SIGRTMIN+3 */
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(n_rtqueue == 2);
assert_se(last_rtqueue_sigval == 4); /* second SIGRTMIN+3 */
ASSERT_OK_EQ(sd_event_run(e, UINT64_MAX), 1);
ASSERT_EQ(n_rtqueue, 2);
ASSERT_EQ(last_rtqueue_sigval, 4); /* second SIGRTMIN+3 */
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(n_rtqueue == 3);
assert_se(last_rtqueue_sigval == 3); /* first SIGUSR2 */
ASSERT_OK_EQ(sd_event_run(e, UINT64_MAX), 1);
ASSERT_EQ(n_rtqueue, 3);
ASSERT_EQ(last_rtqueue_sigval, 3); /* first SIGUSR2 */
assert_se(sd_event_run(e, UINT64_MAX) >= 1);
assert_se(n_rtqueue == 4);
assert_se(last_rtqueue_sigval == 1); /* SIGRTMIN+2 */
ASSERT_OK_EQ(sd_event_run(e, UINT64_MAX), 1);
ASSERT_EQ(n_rtqueue, 4);
ASSERT_EQ(last_rtqueue_sigval, 1); /* SIGRTMIN+2 */
assert_se(sd_event_run(e, 0) == 0); /* the other SIGUSR2 is dropped, because the first one was still queued */
assert_se(n_rtqueue == 4);
assert_se(last_rtqueue_sigval == 1);
ASSERT_OK_ZERO(sd_event_run(e, 0)); /* the other SIGUSR2 is dropped, because the first one was still queued */
ASSERT_EQ(n_rtqueue, 4);
ASSERT_EQ(last_rtqueue_sigval, 1);
sd_event_source_unref(u);
sd_event_source_unref(v);
@@ -390,8 +397,8 @@ struct inotify_context {
static void maybe_exit(sd_event_source *s, struct inotify_context *c) {
unsigned n;
assert_se(s);
assert_se(c);
ASSERT_NOT_NULL(s);
ASSERT_NOT_NULL(c);
if (!c->delete_self_handler_called)
return;
@@ -415,31 +422,31 @@ static int inotify_handler(sd_event_source *s, const struct inotify_event *ev, v
const char *path, *description;
unsigned bit, n;
assert_se(sd_event_source_get_inotify_path(s, &path) >= 0);
ASSERT_OK(sd_event_source_get_inotify_path(s, &path));
assert_se(sd_event_source_get_description(s, &description) >= 0);
assert_se(safe_atou(description, &n) >= 0);
ASSERT_OK(sd_event_source_get_description(s, &description));
ASSERT_OK(safe_atou(description, &n));
assert_se(n <= 3);
ASSERT_LE(n, 3U);
bit = 1U << n;
if (ev->mask & IN_Q_OVERFLOW) {
log_info("inotify-handler for %s <%s>: overflow", path, description);
c->create_overflow |= bit;
} else if (ev->mask & IN_CREATE) {
assert_se(path_equal_or_inode_same(path, c->path, 0));
ASSERT_TRUE(path_equal_or_inode_same(path, c->path, 0));
if (streq(ev->name, "sub"))
log_debug("inotify-handler for %s <%s>: create on %s", path, description, ev->name);
else {
unsigned i;
assert_se(safe_atou(ev->name, &i) >= 0);
assert_se(i < c->n_create_events);
ASSERT_OK(safe_atou(ev->name, &i));
ASSERT_LT(i, c->n_create_events);
c->create_called[i] |= bit;
}
} else if (ev->mask & IN_DELETE) {
log_info("inotify-handler for %s <%s>: delete of %s", path, description, ev->name);
assert_se(streq(ev->name, "sub"));
ASSERT_STREQ(ev->name, "sub");
} else
assert_not_reached();
@@ -451,7 +458,7 @@ static int delete_self_handler(sd_event_source *s, const struct inotify_event *e
struct inotify_context *c = ASSERT_PTR(userdata);
const char *path;
assert_se(sd_event_source_get_inotify_path(s, &path) >= 0);
ASSERT_OK(sd_event_source_get_inotify_path(s, &path));
if (ev->mask & IN_Q_OVERFLOW) {
log_info("delete-self-handler for %s: overflow", path);
@@ -480,46 +487,46 @@ static void test_inotify_one(unsigned n_create_events) {
log_info("/* %s(%u) */", __func__, n_create_events);
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
assert_se(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p) >= 0);
ASSERT_OK(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p));
context.path = p;
assert_se(sd_event_add_inotify(e, &a, p, IN_CREATE|IN_ONLYDIR, inotify_handler, &context) >= 0);
assert_se(sd_event_add_inotify(e, &b, p, IN_CREATE|IN_DELETE|IN_DONT_FOLLOW, inotify_handler, &context) >= 0);
assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_IDLE) >= 0);
assert_se(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_NORMAL) >= 0);
assert_se(sd_event_add_inotify(e, &c, p, IN_CREATE|IN_DELETE|IN_EXCL_UNLINK, inotify_handler, &context) >= 0);
assert_se(sd_event_source_set_priority(c, SD_EVENT_PRIORITY_IDLE) >= 0);
ASSERT_OK(sd_event_add_inotify(e, &a, p, IN_CREATE|IN_ONLYDIR, inotify_handler, &context));
ASSERT_OK(sd_event_add_inotify(e, &b, p, IN_CREATE|IN_DELETE|IN_DONT_FOLLOW, inotify_handler, &context));
ASSERT_OK(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_IDLE));
ASSERT_OK(sd_event_source_set_priority(b, SD_EVENT_PRIORITY_NORMAL));
ASSERT_OK(sd_event_add_inotify(e, &c, p, IN_CREATE|IN_DELETE|IN_EXCL_UNLINK, inotify_handler, &context));
ASSERT_OK(sd_event_source_set_priority(c, SD_EVENT_PRIORITY_IDLE));
assert_se(sd_event_source_set_description(a, "0") >= 0);
assert_se(sd_event_source_set_description(b, "1") >= 0);
assert_se(sd_event_source_set_description(c, "2") >= 0);
ASSERT_OK(sd_event_source_set_description(a, "0"));
ASSERT_OK(sd_event_source_set_description(b, "1"));
ASSERT_OK(sd_event_source_set_description(c, "2"));
assert_se(sd_event_source_get_inotify_path(a, &pp) >= 0);
assert_se(path_equal_or_inode_same(pp, p, 0));
assert_se(sd_event_source_get_inotify_path(b, &pp) >= 0);
assert_se(path_equal_or_inode_same(pp, p, 0));
assert_se(sd_event_source_get_inotify_path(b, &pp) >= 0);
assert_se(path_equal_or_inode_same(pp, p, 0));
ASSERT_OK(sd_event_source_get_inotify_path(a, &pp));
ASSERT_TRUE(path_equal_or_inode_same(pp, p, 0));
ASSERT_OK(sd_event_source_get_inotify_path(b, &pp));
ASSERT_TRUE(path_equal_or_inode_same(pp, p, 0));
ASSERT_OK(sd_event_source_get_inotify_path(b, &pp));
ASSERT_TRUE(path_equal_or_inode_same(pp, p, 0));
q = strjoina(p, "/sub");
assert_se(touch(q) >= 0);
assert_se(sd_event_add_inotify(e, &d, q, IN_DELETE_SELF, delete_self_handler, &context) >= 0);
ASSERT_OK(touch(q));
ASSERT_OK(sd_event_add_inotify(e, &d, q, IN_DELETE_SELF, delete_self_handler, &context));
for (i = 0; i < n_create_events; i++) {
char buf[DECIMAL_STR_MAX(unsigned)+1];
_cleanup_free_ char *z = NULL;
xsprintf(buf, "%u", i);
assert_se(z = path_join(p, buf));
ASSERT_NOT_NULL(z = path_join(p, buf));
assert_se(touch(z) >= 0);
ASSERT_OK(touch(z));
}
assert_se(unlink(q) >= 0);
ASSERT_OK_ERRNO(unlink(q));
assert_se(sd_event_loop(e) >= 0);
ASSERT_OK(sd_event_loop(e));
sd_event_source_unref(a);
sd_event_source_unref(b);
@@ -535,19 +542,19 @@ TEST(inotify) {
}
static int pidfd_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
assert_se(s);
assert_se(si);
ASSERT_NOT_NULL(s);
ASSERT_NOT_NULL(si);
assert_se(si->si_uid == getuid());
assert_se(si->si_signo == SIGCHLD);
assert_se(si->si_code == CLD_EXITED);
assert_se(si->si_status == 66);
ASSERT_EQ(si->si_uid, getuid());
ASSERT_EQ(si->si_signo, SIGCHLD);
ASSERT_EQ(si->si_code, CLD_EXITED);
ASSERT_EQ(si->si_status, 66);
log_info("got pidfd on %c", PTR_TO_INT(userdata));
assert_se(userdata == INT_TO_PTR('p'));
ASSERT_PTR_EQ(userdata, INT_TO_PTR('p'));
assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
ASSERT_OK(sd_event_exit(sd_event_source_get_event(s), 0));
sd_event_source_unref(s);
return 0;
@@ -559,40 +566,36 @@ TEST(pidfd) {
int pidfd;
pid_t pid, pid2;
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
ASSERT_OK(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD));
pid = fork();
ASSERT_OK_ERRNO(pid = fork());
if (pid == 0)
/* child */
_exit(66);
assert_se(pid > 1);
ASSERT_OK(pidfd = pidfd_open(pid, 0));
pid2 = fork();
ASSERT_OK_ERRNO(pid2 = fork());
if (pid2 == 0)
freeze();
assert_se(pid > 2);
assert_se(sd_event_default(&e) >= 0);
assert_se(sd_event_add_child_pidfd(e, &s, pidfd, WEXITED, pidfd_handler, INT_TO_PTR('p')) >= 0);
assert_se(sd_event_source_set_child_pidfd_own(s, true) >= 0);
ASSERT_OK(sd_event_default(&e));
ASSERT_OK(sd_event_add_child_pidfd(e, &s, pidfd, WEXITED, pidfd_handler, INT_TO_PTR('p')));
ASSERT_OK(sd_event_source_set_child_pidfd_own(s, true));
/* This one should never trigger, since our second child lives forever */
assert_se(sd_event_add_child(e, &t, pid2, WEXITED, pidfd_handler, INT_TO_PTR('q')) >= 0);
assert_se(sd_event_source_set_child_process_own(t, true) >= 0);
ASSERT_OK(sd_event_add_child(e, &t, pid2, WEXITED, pidfd_handler, INT_TO_PTR('q')));
ASSERT_OK(sd_event_source_set_child_process_own(t, true));
assert_se(sd_event_loop(e) >= 0);
ASSERT_OK(sd_event_loop(e));
/* Child should still be alive */
assert_se(kill(pid2, 0) >= 0);
ASSERT_OK_ERRNO(kill(pid2, 0));
t = sd_event_source_unref(t);
/* Child should now be dead, since we dropped the ref */
assert_se(kill(pid2, 0) < 0 && errno == ESRCH);
ASSERT_ERROR_ERRNO(kill(pid2, 0), ESRCH);
sd_event_unref(e);
}
@@ -632,73 +635,74 @@ TEST(ratelimit) {
uint64_t interval;
unsigned count, burst;
assert_se(sd_event_default(&e) >= 0);
assert_se(pipe2(p, O_CLOEXEC|O_NONBLOCK) >= 0);
ASSERT_OK(sd_event_default(&e));
ASSERT_OK_ERRNO(pipe2(p, O_CLOEXEC|O_NONBLOCK));
assert_se(sd_event_add_io(e, &s, p[0], EPOLLIN, ratelimit_io_handler, &count) >= 0);
assert_se(sd_event_source_set_description(s, "test-ratelimit-io") >= 0);
assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5) >= 0);
assert_se(sd_event_source_get_ratelimit(s, &interval, &burst) >= 0);
assert_se(interval == 1 * USEC_PER_SEC && burst == 5);
ASSERT_OK(sd_event_add_io(e, &s, p[0], EPOLLIN, ratelimit_io_handler, &count));
ASSERT_OK(sd_event_source_set_description(s, "test-ratelimit-io"));
ASSERT_OK(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5));
ASSERT_OK(sd_event_source_get_ratelimit(s, &interval, &burst));
ASSERT_EQ(interval, 1 * USEC_PER_SEC);
ASSERT_EQ(burst, 5U);
assert_se(write(p[1], "1", 1) == 1);
ASSERT_OK_EQ_ERRNO(write(p[1], "1", 1), 1);
count = 0;
for (unsigned i = 0; i < 10; i++) {
log_debug("slow loop iteration %u", i);
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
assert_se(usleep_safe(250 * USEC_PER_MSEC) >= 0);
ASSERT_OK(sd_event_run(e, UINT64_MAX));
ASSERT_OK(usleep_safe(250 * USEC_PER_MSEC));
}
assert_se(sd_event_source_is_ratelimited(s) == 0);
assert_se(count == 10);
ASSERT_OK_ZERO(sd_event_source_is_ratelimited(s));
ASSERT_EQ(count, 10U);
log_info("ratelimit_io_handler: called %u times, event source not ratelimited", count);
assert_se(sd_event_source_set_ratelimit(s, 0, 0) >= 0);
assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5) >= 0);
ASSERT_OK(sd_event_source_set_ratelimit(s, 0, 0));
ASSERT_OK(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5));
count = 0;
for (unsigned i = 0; i < 10; i++) {
log_debug("fast event loop iteration %u", i);
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
assert_se(usleep_safe(10) >= 0);
ASSERT_OK(sd_event_run(e, UINT64_MAX));
ASSERT_OK(usleep_safe(10));
}
log_info("ratelimit_io_handler: called %u times, event source got ratelimited", count);
assert_se(count < 10);
ASSERT_LT(count, 10U);
s = sd_event_source_unref(s);
safe_close_pair(p);
count = 0;
assert_se(sd_event_add_time_relative(e, &s, CLOCK_MONOTONIC, 1000, 1, ratelimit_time_handler, &count) >= 0);
assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) == 0);
ASSERT_OK(sd_event_add_time_relative(e, &s, CLOCK_MONOTONIC, 1000, 1, ratelimit_time_handler, &count));
ASSERT_OK_ZERO(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10));
do {
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
ASSERT_OK(sd_event_run(e, UINT64_MAX));
} while (!sd_event_source_is_ratelimited(s));
log_info("ratelimit_time_handler: called %u times, event source got ratelimited", count);
assert_se(count == 10);
ASSERT_EQ(count, 10U);
/* In order to get rid of active rate limit client needs to disable it explicitly */
assert_se(sd_event_source_set_ratelimit(s, 0, 0) >= 0);
assert_se(!sd_event_source_is_ratelimited(s));
ASSERT_OK(sd_event_source_set_ratelimit(s, 0, 0));
ASSERT_OK_ZERO(sd_event_source_is_ratelimited(s));
assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) >= 0);
ASSERT_OK(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10));
/* Set callback that will be invoked when we leave rate limited state. */
assert_se(sd_event_source_set_ratelimit_expire_callback(s, ratelimit_expired) >= 0);
ASSERT_OK(sd_event_source_set_ratelimit_expire_callback(s, ratelimit_expired));
do {
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
ASSERT_OK(sd_event_run(e, UINT64_MAX));
} while (!sd_event_source_is_ratelimited(s));
log_info("ratelimit_time_handler: called 10 more times, event source got ratelimited");
assert_se(count == 20);
ASSERT_EQ(count, 20U);
/* Dispatch the event loop once more and check that ratelimit expiration callback got called */
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
assert_se(expired == 0);
ASSERT_OK(sd_event_run(e, UINT64_MAX));
ASSERT_EQ(expired, 0);
}
TEST(simple_timeout) {
@@ -707,29 +711,29 @@ TEST(simple_timeout) {
some_time = random_u64_range(2 * USEC_PER_SEC);
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
assert_se(sd_event_prepare(e) == 0);
ASSERT_OK_ZERO(sd_event_prepare(e));
f = now(CLOCK_MONOTONIC);
assert_se(sd_event_wait(e, some_time) >= 0);
ASSERT_OK(sd_event_wait(e, some_time));
t = now(CLOCK_MONOTONIC);
/* The event loop may sleep longer than the specified time (timer accuracy, scheduling latencies, …),
* but never shorter. Let's check that. */
assert_se(t >= usec_add(f, some_time));
ASSERT_GE(t, usec_add(f, some_time));
}
static int inotify_self_destroy_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) {
sd_event_source **p = userdata;
assert_se(ev);
assert_se(p);
assert_se(*p == s);
ASSERT_NOT_NULL(ev);
ASSERT_NOT_NULL(p);
ASSERT_PTR_EQ(*p, s);
assert_se(FLAGS_SET(ev->mask, IN_ATTRIB));
ASSERT_TRUE(FLAGS_SET(ev->mask, IN_ATTRIB));
assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
ASSERT_OK(sd_event_exit(sd_event_source_get_event(s), 0));
*p = sd_event_source_unref(*p); /* here's what we actually intend to test: we destroy the event
* source from inside the event source handler */
@@ -744,14 +748,13 @@ TEST(inotify_self_destroy) {
/* Tests that destroying an inotify event source from its own handler is safe */
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
fd = mkostemp_safe(path);
assert_se(fd >= 0);
assert_se(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s) >= 0);
ASSERT_OK(fd = mkostemp_safe(path));
ASSERT_OK(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s));
fd = safe_close(fd);
assert_se(unlink(path) >= 0); /* This will trigger IN_ATTRIB because link count goes to zero */
assert_se(sd_event_loop(e) >= 0);
ASSERT_OK_ERRNO(unlink(path)); /* This will trigger IN_ATTRIB because link count goes to zero */
ASSERT_OK(sd_event_loop(e));
}
struct inotify_process_buffered_data_context {
@@ -763,10 +766,10 @@ static int inotify_process_buffered_data_handler(sd_event_source *s, const struc
struct inotify_process_buffered_data_context *c = ASSERT_PTR(userdata);
const char *description;
assert_se(sd_event_source_get_description(s, &description) >= 0);
ASSERT_OK(sd_event_source_get_description(s, &description));
assert_se(c->i < 2);
assert_se(streq(c->path[c->i], description));
ASSERT_LT(c->i, 2U);
ASSERT_STREQ(c->path[c->i], description);
c->i++;
return 1;
@@ -780,30 +783,30 @@ TEST(inotify_process_buffered_data) {
/* For issue #23826 */
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
assert_se(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p) >= 0);
assert_se(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &q) >= 0);
ASSERT_OK(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &p));
ASSERT_OK(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &q));
struct inotify_process_buffered_data_context context = {
.path = { p, q },
};
assert_se(sd_event_add_inotify(e, &a, p, IN_CREATE, inotify_process_buffered_data_handler, &context) >= 0);
assert_se(sd_event_add_inotify(e, &b, q, IN_CREATE, inotify_process_buffered_data_handler, &context) >= 0);
ASSERT_OK(sd_event_add_inotify(e, &a, p, IN_CREATE, inotify_process_buffered_data_handler, &context));
ASSERT_OK(sd_event_add_inotify(e, &b, q, IN_CREATE, inotify_process_buffered_data_handler, &context));
assert_se(z = path_join(p, "aaa"));
assert_se(touch(z) >= 0);
ASSERT_NOT_NULL(z = path_join(p, "aaa"));
ASSERT_OK(touch(z));
z = mfree(z);
assert_se(z = path_join(q, "bbb"));
assert_se(touch(z) >= 0);
ASSERT_NOT_NULL(z = path_join(q, "bbb"));
ASSERT_OK(touch(z));
z = mfree(z);
assert_se(sd_event_run(e, 10 * USEC_PER_SEC) > 0);
assert_se(sd_event_prepare(e) > 0); /* issue #23826: this was 0. */
assert_se(sd_event_dispatch(e) > 0);
assert_se(sd_event_prepare(e) == 0);
assert_se(sd_event_wait(e, 0) == 0);
ASSERT_OK_POSITIVE(sd_event_run(e, 10 * USEC_PER_SEC));
ASSERT_OK_POSITIVE(sd_event_prepare(e)); /* issue #23826: this was 0. */
ASSERT_OK_POSITIVE(sd_event_dispatch(e));
ASSERT_OK_ZERO(sd_event_prepare(e));
ASSERT_OK_ZERO(sd_event_wait(e, 0));
}
static int inotify_handler_issue_38265(sd_event_source *s, const struct inotify_event *event, void *userdata) {
@@ -844,19 +847,19 @@ TEST(fork) {
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
int r;
assert_se(sd_event_default(&e) >= 0);
assert_se(sd_event_prepare(e) == 0);
ASSERT_OK(sd_event_default(&e));
ASSERT_OK_ZERO(sd_event_prepare(e));
/* Check that after a fork the cleanup functions return NULL */
r = safe_fork("(bus-fork-test)", FORK_WAIT|FORK_LOG, NULL);
if (r == 0) {
assert_se(e);
assert_se(sd_event_ref(e) == NULL);
assert_se(sd_event_unref(e) == NULL);
ASSERT_NOT_NULL(e);
ASSERT_NULL(sd_event_ref(e));
ASSERT_NULL(sd_event_unref(e));
_exit(EXIT_SUCCESS);
}
assert_se(r >= 0);
ASSERT_OK(r);
}
TEST(sd_event_source_set_io_fd) {
@@ -864,23 +867,23 @@ TEST(sd_event_source_set_io_fd) {
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
_cleanup_close_pair_ int pfd_a[2] = EBADF_PAIR, pfd_b[2] = EBADF_PAIR;
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
assert_se(pipe2(pfd_a, O_CLOEXEC) >= 0);
assert_se(pipe2(pfd_b, O_CLOEXEC) >= 0);
ASSERT_OK_ERRNO(pipe2(pfd_a, O_CLOEXEC));
ASSERT_OK_ERRNO(pipe2(pfd_b, O_CLOEXEC));
assert_se(sd_event_add_io(e, &s, pfd_a[0], EPOLLIN, NULL, INT_TO_PTR(-ENOANO)) >= 0);
assert_se(sd_event_source_set_io_fd_own(s, true) >= 0);
ASSERT_OK(sd_event_add_io(e, &s, pfd_a[0], EPOLLIN, NULL, INT_TO_PTR(-ENOANO)));
ASSERT_OK(sd_event_source_set_io_fd_own(s, true));
TAKE_FD(pfd_a[0]);
assert_se(sd_event_source_set_io_fd(s, pfd_b[0]) >= 0);
ASSERT_OK(sd_event_source_set_io_fd(s, pfd_b[0]));
TAKE_FD(pfd_b[0]);
}
static int hup_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
unsigned *c = userdata;
assert_se(revents == EPOLLHUP);
ASSERT_EQ(revents, (uint32_t) EPOLLHUP);
(*c)++;
return 0;
@@ -894,47 +897,42 @@ TEST(leave_ratelimit) {
unsigned c = 0;
int r;
assert_se(sd_event_default(&e) >= 0);
ASSERT_OK(sd_event_default(&e));
/* Create an event source that will continuously fire by creating a pipe whose write side is closed,
* and which hence will only see EOF and constant EPOLLHUP */
assert_se(pipe2(pfd, O_CLOEXEC) >= 0);
assert_se(sd_event_add_io(e, &s, pfd[0], EPOLLIN, hup_callback, &c) >= 0);
assert_se(sd_event_source_set_io_fd_own(s, true) >= 0);
assert_se(sd_event_source_set_ratelimit(s, 5*USEC_PER_MINUTE, 5) >= 0);
ASSERT_OK_ERRNO(pipe2(pfd, O_CLOEXEC));
ASSERT_OK(sd_event_add_io(e, &s, pfd[0], EPOLLIN, hup_callback, &c));
ASSERT_OK(sd_event_source_set_io_fd_own(s, true));
ASSERT_OK(sd_event_source_set_ratelimit(s, 5*USEC_PER_MINUTE, 5));
pfd[0] = -EBADF;
pfd[1] = safe_close(pfd[1]); /* Trigger continuous EOF */
for (;;) {
r = sd_event_prepare(e);
assert_se(r >= 0);
ASSERT_OK(r = sd_event_prepare(e));
if (r == 0) {
r = sd_event_wait(e, UINT64_MAX);
assert_se(r > 0);
}
if (r == 0)
ASSERT_OK_POSITIVE(sd_event_wait(e, UINT64_MAX));
r = sd_event_dispatch(e);
assert_se(r > 0);
ASSERT_OK_POSITIVE(sd_event_dispatch(e));
r = sd_event_source_is_ratelimited(s);
assert_se(r >= 0);
ASSERT_OK(r = sd_event_source_is_ratelimited(s));
if (c < 5)
/* First four dispatches should just work */
assert_se(!r);
ASSERT_FALSE(r);
else if (c == 5) {
/* The fifth dispatch should still work, but we now expect the ratelimit to be hit subsequently */
if (!expect_ratelimit) {
assert_se(!r);
assert_se(sd_event_source_leave_ratelimit(s) == 0); /* this should be a NOP, and return 0 hence */
ASSERT_FALSE(r);
ASSERT_OK_ZERO(sd_event_source_leave_ratelimit(s)); /* this should be a NOP, and return 0 hence */
expect_ratelimit = true;
} else {
/* We expected the ratelimit, let's leave it manually, and verify it */
assert_se(r);
assert_se(sd_event_source_leave_ratelimit(s) > 0); /* we are ratelimited, hence should return > 0 */
assert_se(sd_event_source_is_ratelimited(s) == 0);
ASSERT_TRUE(r);
ASSERT_OK_POSITIVE(sd_event_source_leave_ratelimit(s)); /* we are ratelimited, hence should return > 0 */
ASSERT_OK_ZERO(sd_event_source_is_ratelimited(s));
manually_left_ratelimit = true;
}
@@ -945,7 +943,7 @@ TEST(leave_ratelimit) {
}
/* Verify we definitely hit the ratelimit and left it manually again */
assert_se(manually_left_ratelimit);
ASSERT_TRUE(manually_left_ratelimit);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@@ -175,7 +175,12 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
unsigned long long: "%llu")
#ifdef __COVERITY__
# define ASSERT_OK(expr) __coverity_check__((expr) >= 0)
# define ASSERT_OK(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result >= 0); \
_result; \
})
#else
# define ASSERT_OK(expr) \
({ \
@@ -183,6 +188,7 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_result < 0) \
log_test_failed("Expected \"%s\" to succeed, but got error: %"PRIiMAX"/%s", \
#expr, (intmax_t) _result, ERRNO_NAME(_result)); \
_result; \
})
#endif
@@ -190,7 +196,8 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
# define ASSERT_OK_OR(expr, ...) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result >= 0 || IN_SET(_result, 0, __VA_ARGS__) \
__coverity_check__(_result >= 0 || IN_SET(_result, 0, __VA_ARGS__); \
_result; \
})
#else
# define ASSERT_OK_OR(expr, ...) \
@@ -199,12 +206,18 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_result < 0 && !IN_SET(_result, 0, __VA_ARGS__)) \
log_test_failed("\"%s\" failed with unexpected error: %"PRIiMAX"/%s", \
#expr, (intmax_t) _result, ERRNO_NAME(_result)); \
_result; \
})
#endif
/* For functions that return a boolean on success and a negative errno on failure. */
#ifdef __COVERITY__
# define ASSERT_OK_POSITIVE(expr) __coverity_check__((expr) > 0)
# define ASSERT_OK_POSITIVE(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result > 0); \
_result; \
})
#else
# define ASSERT_OK_POSITIVE(expr) \
({ \
@@ -214,11 +227,17 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
#expr, (intmax_t) _result, ERRNO_NAME(_result)); \
if (_result == 0) \
log_test_failed("Expected \"%s\" to be positive, but it is zero.", #expr); \
_result; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_OK_ZERO(expr) __coverity_check__((expr) == 0)
# define ASSERT_OK_ZERO(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result == 0); \
_result; \
})
#else
# define ASSERT_OK_ZERO(expr) \
({ \
@@ -229,11 +248,18 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_result != 0) \
log_test_failed("Expected \"%s\" to be zero, but it is %"PRIiMAX".", \
#expr, (intmax_t) _result); \
_result; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_OK_EQ(expr1, expr2) __coverity_check__((expr1) == (expr2))
# define ASSERT_OK_EQ(expr1, expr2) \
({ \
typeof(expr1) _expr1 = (expr1); \
typeof(expr2) _expr2 = (expr2); \
__coverity_check__(_expr1 == _expr2); \
_expr1; \
})
#else
# define ASSERT_OK_EQ(expr1, expr2) \
({ \
@@ -245,12 +271,18 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_expr1 != _expr2) \
log_test_failed("Expected \"%s == %s\", got %"PRIiMAX" != %"PRIiMAX, \
#expr1, #expr2, (intmax_t) _expr1, (intmax_t) _expr2); \
_expr1; \
})
#endif
/* For functions that return a boolean on success and set errno on failure. */
#ifdef __COVERITY__
# define ASSERT_OK_ERRNO(expr) __coverity_check__((expr) >= 0)
# define ASSERT_OK_ERRNO(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result >= 0); \
_result; \
})
#else
# define ASSERT_OK_ERRNO(expr) \
({ \
@@ -258,11 +290,17 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_result < 0) \
log_test_failed("Expected \"%s\" to succeed, but got errno: %d/%s", \
#expr, errno, ERRNO_NAME(errno)); \
_result; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_OK_ZERO_ERRNO(expr) __coverity_check__((expr) == 0)
# define ASSERT_OK_ZERO_ERRNO(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result == 0); \
_result; \
})
#else
# define ASSERT_OK_ZERO_ERRNO(expr) \
({ \
@@ -273,11 +311,18 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_result != 0) \
log_test_failed("Expected \"%s\" to be zero, but it is %"PRIiMAX".", \
#expr, (intmax_t) _result); \
_result; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_OK_EQ_ERRNO(expr1, expr2) __coverity_check__((expr1) == (expr2))
# define ASSERT_OK_EQ_ERRNO(expr1, expr2) \
({ \
typeof(expr1) _expr1 = (expr1); \
typeof(expr2) _expr2 = (expr2); \
__coverity_check__(_expr1 == _expr2); \
_expr1; \
})
#else
# define ASSERT_OK_EQ_ERRNO(expr1, expr2) \
({ \
@@ -289,22 +334,35 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
if (_expr1 != _expr2) \
log_test_failed("Expected \"%s == %s\", but %"PRIiMAX" != %"PRIiMAX, \
#expr1, #expr2, (intmax_t) _expr1, (intmax_t) _expr2); \
_expr1; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_FAIL(expr) __coverity_check__((expr) < 0)
# define ASSERT_FAIL(expr) \
({ \
typeof(expr) _result = (expr); \
__coverity_check__(_result < 0); \
_result; \
})
#else
# define ASSERT_FAIL(expr) \
({ \
typeof(expr) _result = (expr); \
if (_result >= 0) \
log_test_failed("Expected \"%s\" to fail, but it succeeded.", #expr); \
_result; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_ERROR(expr1, expr2) __coverity_check__((expr1) == -(expr2))
# define ASSERT_ERROR(expr1, expr2) \
({ \
int _expr1 = (expr1); \
int _expr2 = (expr2); \
__coverity_check__((_expr1) == -(_expr2)); \
_expr1; \
})
#else
# define ASSERT_ERROR(expr1, expr2) \
({ \
@@ -316,11 +374,18 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
else if (-_expr1 != _expr2) \
log_test_failed("Expected \"%s\" to fail with error %d/%s, but got %d/%s", \
#expr1, -_expr2, ERRNO_NAME(_expr2), _expr1, ERRNO_NAME(_expr1)); \
_expr1; \
})
#endif
#ifdef __COVERITY__
# define ASSERT_ERROR_ERRNO(expr1, expr2) __coverity_check__((expr1) < 0 && errno == (expr2))
# define ASSERT_ERROR_ERRNO(expr1, expr2) \
({ \
int _expr1 = (expr1); \
int _expr2 = (expr2); \
__coverity_check__(_expr1 < 0 && errno == _expr2); \
_expr1; \
})
#else
# define ASSERT_ERROR_ERRNO(expr1, expr2) \
({ \
@@ -332,6 +397,7 @@ _noreturn_ void log_test_failed_internal(const char *file, int line, const char
else if (errno != _expr2) \
log_test_failed("Expected \"%s\" to fail with errno %d/%s, but got %d/%s", \
#expr1, _expr2, ERRNO_NAME(_expr2), errno, ERRNO_NAME(errno)); \
_expr1; \
})
#endif

View File

@@ -26,8 +26,13 @@
#include "tests.h"
#include "tpm2-util.h"
#define ASSERT_DLOPEN(func, cond) \
cond ? ASSERT_OK(func()) : ASSERT_ERROR(func(), EOPNOTSUPP)
#define ASSERT_DLOPEN(func, cond) \
do { \
if (cond) \
ASSERT_OK(func()); \
else \
ASSERT_ERROR(func(), EOPNOTSUPP); \
} while (false)
static int run(int argc, char **argv) {
test_setup_logging(LOG_DEBUG);

View File

@@ -14,76 +14,80 @@ static void test_rm_rf_chmod_inner(void) {
const char *a, *b, *x, *y;
struct stat st;
assert_se(getuid() != 0);
ASSERT_NE(getuid(), 0U);
assert_se(mkdtemp_malloc("/tmp/test-rm-rf.XXXXXXX", &d) >= 0);
ASSERT_OK(mkdtemp_malloc("/tmp/test-rm-rf.XXXXXXX", &d));
a = strjoina(d, "/a");
b = strjoina(a, "/b");
x = strjoina(d, "/x");
y = strjoina(x, "/y");
assert_se(mkdir(x, 0700) >= 0);
assert_se(mknod(y, S_IFREG | 0600, 0) >= 0);
ASSERT_OK_ERRNO(mkdir(x, 0700));
ASSERT_OK_ERRNO(mknod(y, S_IFREG | 0600, 0));
assert_se(chmod(y, 0400) >= 0);
assert_se(chmod(x, 0500) >= 0);
assert_se(chmod(d, 0500) >= 0);
ASSERT_OK_ERRNO(chmod(y, 0400));
ASSERT_OK_ERRNO(chmod(x, 0500));
ASSERT_OK_ERRNO(chmod(d, 0500));
assert_se(rm_rf(d, REMOVE_PHYSICAL) == -EACCES);
ASSERT_ERROR(rm_rf(d, REMOVE_PHYSICAL), EACCES);
assert_se(access(d, F_OK) >= 0);
assert_se(access(x, F_OK) >= 0);
assert_se(access(y, F_OK) >= 0);
ASSERT_OK_ERRNO(access(d, F_OK));
ASSERT_OK_ERRNO(access(x, F_OK));
ASSERT_OK_ERRNO(access(y, F_OK));
assert_se(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD) >= 0);
ASSERT_OK(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD));
assert_se(access(d, F_OK) >= 0);
assert_se(access(x, F_OK) < 0 && errno == ENOENT);
assert_se(access(y, F_OK) < 0 && errno == ENOENT);
ASSERT_OK_ERRNO(access(d, F_OK));
ASSERT_ERROR_ERRNO(access(x, F_OK), ENOENT);
ASSERT_ERROR_ERRNO(access(y, F_OK), ENOENT);
assert_se(mkdir(a, 0700) >= 0);
assert_se(mkdir(b, 0700) >= 0);
assert_se(mkdir(x, 0700) >= 0);
assert_se(mknod(y, S_IFREG | 0600, 0) >= 0);
ASSERT_OK_ERRNO(mkdir(a, 0700));
ASSERT_OK_ERRNO(mkdir(b, 0700));
ASSERT_OK_ERRNO(mkdir(x, 0700));
ASSERT_OK_ERRNO(mknod(y, S_IFREG | 0600, 0));
assert_se(chmod(b, 0000) >= 0);
assert_se(chmod(a, 0000) >= 0);
assert_se(chmod(y, 0000) >= 0);
assert_se(chmod(x, 0000) >= 0);
assert_se(chmod(d, 0500) >= 0);
ASSERT_OK_ERRNO(chmod(b, 0000));
ASSERT_OK_ERRNO(chmod(a, 0000));
ASSERT_OK_ERRNO(chmod(y, 0000));
ASSERT_OK_ERRNO(chmod(x, 0000));
ASSERT_OK_ERRNO(chmod(d, 0500));
assert_se(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_CHMOD_RESTORE|REMOVE_ONLY_DIRECTORIES) == -ENOTEMPTY);
ASSERT_ERROR(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_CHMOD_RESTORE|REMOVE_ONLY_DIRECTORIES), ENOTEMPTY);
assert_se(access(a, F_OK) < 0 && errno == ENOENT);
assert_se(access(d, F_OK) >= 0);
assert_se(stat(d, &st) >= 0 && (st.st_mode & 07777) == 0500);
assert_se(access(x, F_OK) >= 0);
assert_se(stat(x, &st) >= 0 && (st.st_mode & 07777) == 0000);
assert_se(chmod(x, 0700) >= 0);
assert_se(access(y, F_OK) >= 0);
assert_se(stat(y, &st) >= 0 && (st.st_mode & 07777) == 0000);
ASSERT_ERROR_ERRNO(access(a, F_OK), ENOENT);
ASSERT_OK_ERRNO(access(d, F_OK));
ASSERT_OK_ERRNO(stat(d, &st));
ASSERT_EQ(st.st_mode & 07777, 0500U);
ASSERT_OK_ERRNO(access(x, F_OK));
ASSERT_OK_ERRNO(stat(x, &st));
ASSERT_EQ(st.st_mode & 07777, 0000U);
ASSERT_OK_ERRNO(chmod(x, 0700));
ASSERT_OK_ERRNO(access(y, F_OK));
ASSERT_OK_ERRNO(stat(y, &st));
ASSERT_EQ(st.st_mode & 07777, 0000U);
assert_se(chmod(y, 0000) >= 0);
assert_se(chmod(x, 0000) >= 0);
assert_se(chmod(d, 0000) >= 0);
ASSERT_OK_ERRNO(chmod(y, 0000));
ASSERT_OK_ERRNO(chmod(x, 0000));
ASSERT_OK_ERRNO(chmod(d, 0000));
assert_se(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_CHMOD_RESTORE) >= 0);
ASSERT_OK(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_CHMOD_RESTORE));
assert_se(stat(d, &st) >= 0 && (st.st_mode & 07777) == 0000);
assert_se(access(d, F_OK) >= 0);
assert_se(chmod(d, 0700) >= 0);
assert_se(access(x, F_OK) < 0 && errno == ENOENT);
ASSERT_OK_ERRNO(stat(d, &st));
ASSERT_EQ(st.st_mode & 07777, 0000U);
ASSERT_OK_ERRNO(access(d, F_OK));
ASSERT_OK_ERRNO(chmod(d, 0700));
ASSERT_ERROR_ERRNO(access(x, F_OK), ENOENT);
assert_se(mkdir(x, 0700) >= 0);
assert_se(mknod(y, S_IFREG | 0600, 0) >= 0);
ASSERT_OK_ERRNO(mkdir(x, 0700));
ASSERT_OK_ERRNO(mknod(y, S_IFREG | 0600, 0));
assert_se(chmod(y, 0000) >= 0);
assert_se(chmod(x, 0000) >= 0);
assert_se(chmod(d, 0000) >= 0);
ASSERT_OK_ERRNO(chmod(y, 0000));
ASSERT_OK_ERRNO(chmod(x, 0000));
ASSERT_OK_ERRNO(chmod(d, 0000));
assert_se(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_ROOT) >= 0);
ASSERT_OK(rm_rf(d, REMOVE_PHYSICAL|REMOVE_CHMOD|REMOVE_ROOT));
assert_se(access(d, F_OK) < 0 && errno == ENOENT);
ASSERT_ERROR_ERRNO(access(d, F_OK), ENOENT);
}
TEST(rm_rf_chmod) {
@@ -96,13 +100,12 @@ TEST(rm_rf_chmod) {
/* This test only works unpriv (as only then the access mask for the owning user matters),
* hence drop privs here */
r = safe_fork("(setresuid)", FORK_DEATHSIG_SIGTERM|FORK_WAIT, NULL);
assert_se(r >= 0);
ASSERT_OK(r = safe_fork("(setresuid)", FORK_DEATHSIG_SIGTERM|FORK_WAIT, NULL));
if (r == 0) {
/* child */
assert_se(setresuid(1, 1, 1) >= 0);
ASSERT_OK_ERRNO(setresuid(1, 1, 1));
test_rm_rf_chmod_inner();
_exit(EXIT_SUCCESS);