]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
test-utils-glib: Add failable functions to connect to a bus
authorSimon McVittie <smcv@collabora.com>
Thu, 6 Jul 2017 14:57:18 +0000 (15:57 +0100)
committerSimon McVittie <smcv@collabora.com>
Mon, 6 Nov 2017 16:41:05 +0000 (16:41 +0000)
Instead of calling g_test_skip() internally, raise a distinctive error
and let the caller handle it.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101354

test/test-utils-glib.c
test/test-utils-glib.h
test/uid-permissions.c

index 9dc58b97613e7d6f2ade4e3d3c67168764da10f1..a7543a9d9abf60dc361dc4e8059eb0145994f372 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <glib.h>
 #include <glib/gstdio.h>
+#include <gio/gio.h>
 
 #include <dbus/dbus.h>
 
@@ -318,28 +319,53 @@ test_get_dbus_daemon (const gchar *config_file,
 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;
 
index 800a53283f0ee9b8ad97b704b6f897c7e40de588..bebd5dd66d2896793bca108dc1424158da3944c3 100644 (file)
@@ -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);
 
index 19a9aa46eb42d61eb024af9daeb3d1dc67166004..75bbb13fb82f3249f55d6ac1ac60cd43d3771de8 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "test-utils-glib.h"
 
+#include <gio/gio.h>
+
 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);
 }