From 645962aadc2f919946030a1f7ea1d80ede0c804d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 6 Jul 2017 15:57:18 +0100 Subject: [PATCH] test-utils-glib: Add failable functions to connect to a bus Instead of calling g_test_skip() internally, raise a distinctive error and let the caller handle it. Signed-off-by: Simon McVittie --- test/test-utils-glib.c | 59 ++++++++++++++++++++++++++++++++++++-------------- test/test-utils-glib.h | 8 +++++-- test/uid-permissions.c | 16 ++++++++++---- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/test/test-utils-glib.c b/test/test-utils-glib.c index bb481952..6dfaf470 100644 --- a/test/test-utils-glib.c +++ b/test/test-utils-glib.c @@ -42,6 +42,7 @@ #include #include +#include #include @@ -319,27 +320,52 @@ DBusConnection * test_connect_to_bus (TestMainContext *ctx, const gchar *address) { + GError *error = NULL; + DBusConnection *conn = test_try_connect_to_bus (ctx, address, &error); + + g_assert_no_error (error); + g_assert (conn != NULL); + return conn; +} + +DBusConnection * +test_try_connect_to_bus (TestMainContext *ctx, + const gchar *address, + GError **gerror) +{ DBusConnection *conn; DBusError error = DBUS_ERROR_INIT; - dbus_bool_t ok; conn = dbus_connection_open_private (address, &error); - test_assert_no_error (&error); - g_assert (conn != NULL); - ok = dbus_bus_register (conn, &error); - test_assert_no_error (&error); - g_assert (ok); + if (conn == NULL) + goto fail; + + if (!dbus_bus_register (conn, &error)) + goto fail; + g_assert (dbus_bus_get_unique_name (conn) != NULL); test_connection_setup (ctx, conn); return conn; + +fail: + if (gerror != NULL) + *gerror = g_dbus_error_new_for_dbus_error (error.name, error.message); + + dbus_error_free (&error); + return FALSE; } +/* + * Raise G_IO_ERROR_NOT_SUPPORTED if the requested user is impossible. + * Do not mark the test as skipped: we might have more to test anyway. + */ DBusConnection * -test_connect_to_bus_as_user (TestMainContext *ctx, +test_try_connect_to_bus_as_user (TestMainContext *ctx, const char *address, - TestUser user) + TestUser user, + GError **error) { /* For now we only do tests like this on Linux, because I don't know how * safe this use of setresuid() is on other platforms */ @@ -352,7 +378,7 @@ test_connect_to_bus_as_user (TestMainContext *ctx, switch (user) { case TEST_USER_ME: - return test_connect_to_bus (ctx, address); + return test_try_connect_to_bus (ctx, address, error); case TEST_USER_ROOT: username = "root"; @@ -375,9 +401,9 @@ test_connect_to_bus_as_user (TestMainContext *ctx, if (ruid != 0 || euid != 0 || suid != 0) { - g_test_message ("not uid 0 (ruid=%ld euid=%ld suid=%ld)", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "not uid 0 (ruid=%ld euid=%ld suid=%ld)", (unsigned long) ruid, (unsigned long) euid, (unsigned long) suid); - g_test_skip ("not uid 0"); return NULL; } @@ -385,13 +411,13 @@ test_connect_to_bus_as_user (TestMainContext *ctx, if (pwd == NULL) { - g_test_message ("getpwnam(\"%s\"): %s", username, g_strerror (errno)); - g_test_skip ("not uid 0"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "getpwnam(\"%s\"): %s", username, g_strerror (errno)); return NULL; } /* Impersonate the desired user while we connect to the bus. - * This should work, because we're root. */ + * This should work, because we're root; so if it fails, we just crash. */ if (setresuid (pwd->pw_uid, pwd->pw_uid, 0) != 0) g_error ("setresuid(%ld, (same), 0): %s", (unsigned long) pwd->pw_uid, g_strerror (errno)); @@ -409,12 +435,13 @@ test_connect_to_bus_as_user (TestMainContext *ctx, switch (user) { case TEST_USER_ME: - return test_connect_to_bus (ctx, address); + return test_try_connect_to_bus (ctx, address, error); case TEST_USER_ROOT: case TEST_USER_MESSAGEBUS: case TEST_USER_OTHER: - g_test_skip ("setresuid() not available, or unsure about " + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "setresuid() not available, or unsure about " "credentials-passing semantics on this platform"); return NULL; diff --git a/test/test-utils-glib.h b/test/test-utils-glib.h index 52d66b91..200a5468 100644 --- a/test/test-utils-glib.h +++ b/test/test-utils-glib.h @@ -74,9 +74,13 @@ gchar *test_get_dbus_daemon (const gchar *config_file, DBusConnection *test_connect_to_bus (TestMainContext *ctx, const gchar *address); -DBusConnection *test_connect_to_bus_as_user (TestMainContext *ctx, +DBusConnection *test_try_connect_to_bus (TestMainContext *ctx, + const gchar *address, + GError **error); +DBusConnection *test_try_connect_to_bus_as_user (TestMainContext *ctx, const char *address, - TestUser user); + TestUser user, + GError **error); void test_kill_pid (GPid pid); diff --git a/test/uid-permissions.c b/test/uid-permissions.c index 0bef74ed..6bee3a0c 100644 --- a/test/uid-permissions.c +++ b/test/uid-permissions.c @@ -29,6 +29,8 @@ #include "test-utils-glib.h" +#include + typedef struct { gboolean skip; @@ -69,12 +71,18 @@ setup (Fixture *f, return; } - f->conn = test_connect_to_bus_as_user (f->ctx, address, - config ? config->user : TEST_USER_ME); + f->conn = test_try_connect_to_bus_as_user (f->ctx, address, + config ? config->user : TEST_USER_ME, &f->ge); - if (f->conn == NULL) - f->skip = TRUE; + if (f->conn == NULL && + g_error_matches (f->ge, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_test_skip (f->ge->message); + g_clear_error (&f->ge); + f->skip = TRUE; + } + g_assert_no_error (f->ge); g_free (address); } -- 2.13.3