From e1b7b1ac161343b1ca708c95c7618ec98fe7babe Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 29 Oct 2019 16:05:55 +0000 Subject: [PATCH 1/4] gdbus-peer test: Improve diagnostics if g_rmdir fails Helps: GNOME/glib#1921 Signed-off-by: Simon McVittie --- gio/tests/gdbus-peer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index dc4176cf2..c51166ae7 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -313,7 +313,8 @@ teardown_test_address (void) /* Ensuring the rmdir succeeds also ensures any sockets created on the * filesystem are also deleted. */ - g_assert_cmpint (g_rmdir (tmpdir), ==, 0); + g_assert_cmpstr (g_rmdir (tmpdir) == 0 ? "OK" : g_strerror (errno), + ==, "OK"); g_clear_pointer (&tmpdir, g_free); } } From 7c2e4095f44c2580eb7113beb86e16d086205669 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 29 Oct 2019 16:14:16 +0000 Subject: [PATCH 2/4] gdbus-peer test: Stop GDBusServer before tearing down temporary directory Otherwise, since GNOME/glib!1193, the listening socket won't be deleted, and if we are not using abstract sockets (for example on *BSD), g_rmdir will fail with ENOTEMPTY. Fixes: 8e32b8e8 "gdbusserver: Delete socket and nonce file when stopping server" Resolves: GNOME/glib#1921 Signed-off-by: Simon McVittie --- gio/tests/gdbus-peer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index c51166ae7..bb6304151 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -1259,6 +1259,7 @@ dmp_thread_func (gpointer user_data) data->loop = g_main_loop_new (data->context, FALSE); g_main_loop_run (data->loop); + g_dbus_server_stop (data->server); g_main_context_pop_thread_default (data->context); g_free (guid); From bab277fd50a4d44e253a38cc964c50dd0902301f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 29 Oct 2019 16:18:32 +0000 Subject: [PATCH 3/4] gdbus-peer test: Use unix:dir address if exact format doesn't matter Previously, we used unix:tmpdir, except in tests that verify that a particular address type works (notably unix:dir). Now we use unix:dir most of the time, and unix:tmpdir gets its own test instead. This helps to ensure that the tests continue to work on non-Linux Unix kernels, where abstract sockets do not exist and so unix:tmpdir is equivalent to unix:dir, even in the common case where the developer has only tried the test on Linux. Signed-off-by: Simon McVittie --- gio/tests/gdbus-peer.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index bb6304151..7887ab917 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -273,14 +273,9 @@ setup_test_address (void) { if (is_unix) { - g_test_message ("Testing with unix:tmpdir address"); - if (g_unix_socket_address_abstract_names_supported ()) - tmp_address = g_strdup ("unix:tmpdir=/tmp/gdbus-test-"); - else - { - tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); - tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); - } + g_test_message ("Testing with unix:dir address"); + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:dir=%s", tmpdir); } else tmp_address = g_strdup ("nonce-tcp:"); @@ -288,11 +283,11 @@ setup_test_address (void) #ifdef G_OS_UNIX static void -setup_dir_test_address (void) +setup_tmpdir_test_address (void) { - g_test_message ("Testing with unix:dir address"); + g_test_message ("Testing with unix:tmpdir address"); tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); - tmp_address = g_strdup_printf ("unix:dir=%s", tmpdir); + tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); } static void @@ -1045,7 +1040,7 @@ test_peer (void) teardown_test_address (); #ifdef G_OS_UNIX - setup_dir_test_address (); + setup_tmpdir_test_address (); do_test_peer (); teardown_test_address (); From 2b1e706b2f0007982f4fe6a70734d4490e4093a3 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 29 Oct 2019 16:27:53 +0000 Subject: [PATCH 4/4] gdbus-server-auth test: Create temporary directory for Unix socket This avoids failure to listen on the given address on non-Linux Unix kernels, where abstract sockets do not exist and so unix:tmpdir is equivalent to unix:dir. To avoid bugs like this one recurring, run most of these tests using the unix:dir address type, where Linux is equivalent to other Unix kernels; just do one unix:tmpdir test, to check that we still interoperate with libdbus when using abstract sockets on Linux. Resolves: GNOME/glib#1920 Fixes: 9f962ebe "Add a test for GDBusServer authentication" Signed-off-by: Simon McVittie --- gio/tests/gdbus-server-auth.c | 88 ++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/gio/tests/gdbus-server-auth.c b/gio/tests/gdbus-server-auth.c index 6a72ba6c1..160c18b03 100644 --- a/gio/tests/gdbus-server-auth.c +++ b/gio/tests/gdbus-server-auth.c @@ -17,6 +17,9 @@ #include "config.h" +#include + +#include #include #ifdef HAVE_DBUS1 @@ -30,6 +33,7 @@ typedef enum INTEROP_FLAGS_SHA1 = (1 << 2), INTEROP_FLAGS_TCP = (1 << 3), INTEROP_FLAGS_LIBDBUS = (1 << 4), + INTEROP_FLAGS_ABSTRACT = (1 << 5), INTEROP_FLAGS_NONE = 0 } InteropFlags; @@ -245,18 +249,19 @@ assert_expected_uid_pid (InteropFlags flags, } static void -do_test_server_auth (const char *listenable_address, - InteropFlags flags) +do_test_server_auth (InteropFlags flags) { GError *error = NULL; - GDBusServer *server; - GDBusAuthObserver *observer; + gchar *tmpdir = NULL; + gchar *listenable_address = NULL; + GDBusServer *server = NULL; + GDBusAuthObserver *observer = NULL; GDBusServerFlags server_flags = G_DBUS_SERVER_FLAGS_RUN_IN_THREAD; - gchar *guid; + gchar *guid = NULL; const char *connectable_address; - GDBusConnection *client; + GDBusConnection *client = NULL; GAsyncResult *result = NULL; - GVariant *tuple; + GVariant *tuple = NULL; gint64 uid, pid; #ifdef HAVE_DBUS1 /* GNOME/glib#1831 seems to involve a race condition, so try a few times @@ -265,37 +270,47 @@ do_test_server_auth (const char *listenable_address, gsize n = 20; #endif - if (g_str_has_prefix (listenable_address, "tcp:") || - g_str_has_prefix (listenable_address, "nonce-tcp:")) - g_assert_cmpint (flags & INTEROP_FLAGS_TCP, !=, 0); + if (flags & INTEROP_FLAGS_TCP) + { + listenable_address = g_strdup ("tcp:host=127.0.0.1"); + } else - g_assert_cmpint (flags & INTEROP_FLAGS_TCP, ==, 0); + { +#ifdef G_OS_UNIX + gchar *escaped; + + tmpdir = g_dir_make_tmp ("gdbus-server-auth-XXXXXX", &error); + g_assert_no_error (error); + escaped = g_dbus_address_escape_value (tmpdir); + listenable_address = g_strdup_printf ("unix:%s=%s", + (flags & INTEROP_FLAGS_ABSTRACT) ? "tmpdir" : "dir", + escaped); + g_free (escaped); +#else + g_test_skip ("unix: addresses only work on Unix"); + goto out; +#endif + } g_test_message ("Testing GDBus server at %s / libdbus client, with flags: " "external:%s " "anonymous:%s " "sha1:%s " + "abstract:%s " "tcp:%s", listenable_address, (flags & INTEROP_FLAGS_EXTERNAL) ? "true" : "false", (flags & INTEROP_FLAGS_ANONYMOUS) ? "true" : "false", (flags & INTEROP_FLAGS_SHA1) ? "true" : "false", + (flags & INTEROP_FLAGS_ABSTRACT) ? "true" : "false", (flags & INTEROP_FLAGS_TCP) ? "true" : "false"); -#ifndef G_OS_UNIX - if (g_str_has_prefix (listenable_address, "unix:")) - { - g_test_skip ("unix: addresses only work on Unix"); - return; - } -#endif - #if !defined(G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED) \ && !defined(G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED) if (flags & INTEROP_FLAGS_EXTERNAL) { g_test_skip ("EXTERNAL authentication not implemented on this platform"); - return; + goto out; } #endif @@ -333,6 +348,7 @@ do_test_server_auth (const char *listenable_address, g_signal_connect (server, "new-connection", G_CALLBACK (new_connection_cb), NULL); g_dbus_server_start (server); connectable_address = g_dbus_server_get_client_address (server); + g_test_message ("Connectable address: %s", connectable_address); result = NULL; g_dbus_connection_new_for_address (connectable_address, @@ -425,52 +441,67 @@ do_test_server_auth (const char *listenable_address, g_test_skip ("Testing interop with libdbus not supported"); #endif /* !HAVE_DBUS1 */ - g_dbus_server_stop (server); +out: + if (server != NULL) + g_dbus_server_stop (server); + + if (tmpdir != NULL) + g_assert_cmpstr (g_rmdir (tmpdir) == 0 ? "OK" : g_strerror (errno), + ==, "OK"); + g_clear_object (&server); g_clear_object (&observer); g_free (guid); + g_free (listenable_address); + g_free (tmpdir); } static void test_server_auth (void) { - do_test_server_auth ("unix:tmpdir=/tmp/gdbus-test", INTEROP_FLAGS_NONE); + do_test_server_auth (INTEROP_FLAGS_NONE); +} + +static void +test_server_auth_abstract (void) +{ + do_test_server_auth (INTEROP_FLAGS_ABSTRACT); } static void test_server_auth_tcp (void) { - do_test_server_auth ("tcp:host=127.0.0.1", INTEROP_FLAGS_TCP); + do_test_server_auth (INTEROP_FLAGS_TCP); } static void test_server_auth_anonymous (void) { - do_test_server_auth ("unix:tmpdir=/tmp/gdbus-test", INTEROP_FLAGS_ANONYMOUS); + do_test_server_auth (INTEROP_FLAGS_ANONYMOUS); } static void test_server_auth_anonymous_tcp (void) { - do_test_server_auth ("tcp:host=127.0.0.1", INTEROP_FLAGS_ANONYMOUS | INTEROP_FLAGS_TCP); + do_test_server_auth (INTEROP_FLAGS_ANONYMOUS | INTEROP_FLAGS_TCP); } static void test_server_auth_external (void) { - do_test_server_auth ("unix:tmpdir=/tmp/gdbus-test", INTEROP_FLAGS_EXTERNAL); + do_test_server_auth (INTEROP_FLAGS_EXTERNAL); } static void test_server_auth_sha1 (void) { - do_test_server_auth ("unix:tmpdir=/tmp/gdbus-test", INTEROP_FLAGS_SHA1); + do_test_server_auth (INTEROP_FLAGS_SHA1); } static void test_server_auth_sha1_tcp (void) { - do_test_server_auth ("tcp:host=127.0.0.1", INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP); + do_test_server_auth (INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP); } int @@ -480,6 +511,7 @@ main (int argc, g_test_init (&argc, &argv, NULL); g_test_add_func ("/gdbus/server-auth", test_server_auth); + g_test_add_func ("/gdbus/server-auth/abstract", test_server_auth_abstract); g_test_add_func ("/gdbus/server-auth/tcp", test_server_auth_tcp); g_test_add_func ("/gdbus/server-auth/anonymous", test_server_auth_anonymous); g_test_add_func ("/gdbus/server-auth/anonymous/tcp", test_server_auth_anonymous_tcp);