mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
404d5d40e0
If the whole set of tests takes more than 5 seconds, the failure timeout from the first test could still trigger, causing an incorrect failure. Ensure the timeout is removed at the end of each test.i This will hopefully fix the CI failure seen here: https://gitlab.gnome.org/pwithnall/glib/-/jobs/1879558. ``` 204/266 glib:gio / gdbus-auth FAIL 9.21 s (killed by signal 5 SIGTRAP) … ok 1 /gdbus/auth/client/EXTERNAL Bail out! GLib-GIO-FATAL-ERROR: Timeout waiting for client ``` Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
315 lines
8.5 KiB
C
315 lines
8.5 KiB
C
/* GLib testing framework examples and tests
|
|
*
|
|
* Copyright (C) 2008-2013 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General
|
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: David Zeuthen <davidz@redhat.com>
|
|
*/
|
|
|
|
#include <locale.h>
|
|
#include <gio/gio.h>
|
|
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "gdbus-tests.h"
|
|
|
|
#ifdef G_OS_UNIX
|
|
#include <gio/gunixconnection.h>
|
|
#include <gio/gnetworkingprivate.h>
|
|
#include <gio/gunixsocketaddress.h>
|
|
#include <gio/gunixfdlist.h>
|
|
#endif
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
static gboolean
|
|
server_on_allow_mechanism (GDBusAuthObserver *observer,
|
|
const gchar *mechanism,
|
|
gpointer user_data)
|
|
{
|
|
const gchar *allowed_mechanism = user_data;
|
|
if (allowed_mechanism == NULL || g_strcmp0 (mechanism, allowed_mechanism) == 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/* pass NULL to allow any mechanism */
|
|
static GDBusServer *
|
|
server_new_for_mechanism (const gchar *allowed_mechanism)
|
|
{
|
|
gchar *addr;
|
|
gchar *guid;
|
|
GDBusServer *server;
|
|
GDBusAuthObserver *auth_observer;
|
|
GError *error;
|
|
GDBusServerFlags flags;
|
|
|
|
guid = g_dbus_generate_guid ();
|
|
|
|
#ifdef G_OS_UNIX
|
|
if (g_unix_socket_address_abstract_names_supported ())
|
|
{
|
|
addr = g_strdup ("unix:tmpdir=/tmp/gdbus-test-");
|
|
}
|
|
else
|
|
{
|
|
gchar *tmpdir;
|
|
tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
|
|
addr = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
|
|
g_free (tmpdir);
|
|
}
|
|
#else
|
|
addr = g_strdup ("nonce-tcp:");
|
|
#endif
|
|
|
|
auth_observer = g_dbus_auth_observer_new ();
|
|
|
|
flags = G_DBUS_SERVER_FLAGS_NONE;
|
|
if (g_strcmp0 (allowed_mechanism, "ANONYMOUS") == 0)
|
|
flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
|
|
|
|
error = NULL;
|
|
server = g_dbus_server_new_sync (addr,
|
|
flags,
|
|
guid,
|
|
auth_observer,
|
|
NULL, /* cancellable */
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (server != NULL);
|
|
|
|
g_signal_connect (auth_observer,
|
|
"allow-mechanism",
|
|
G_CALLBACK (server_on_allow_mechanism),
|
|
(gpointer) allowed_mechanism);
|
|
|
|
g_free (addr);
|
|
g_free (guid);
|
|
g_object_unref (auth_observer);
|
|
|
|
return server;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
static gboolean
|
|
test_auth_on_new_connection (GDBusServer *server,
|
|
GDBusConnection *connection,
|
|
gpointer user_data)
|
|
{
|
|
GMainLoop *loop = user_data;
|
|
g_main_loop_quit (loop);
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
test_auth_on_timeout (gpointer user_data)
|
|
{
|
|
g_error ("Timeout waiting for client");
|
|
g_assert_not_reached ();
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
const gchar *address;
|
|
const gchar *allowed_client_mechanism;
|
|
const gchar *allowed_server_mechanism;
|
|
} TestAuthData;
|
|
|
|
static gpointer
|
|
test_auth_client_thread_func (gpointer user_data)
|
|
{
|
|
TestAuthData *data = user_data;
|
|
GDBusConnection *c = NULL;
|
|
GError *error = NULL;
|
|
GDBusAuthObserver *auth_observer = NULL;
|
|
|
|
auth_observer = g_dbus_auth_observer_new ();
|
|
|
|
g_signal_connect (auth_observer,
|
|
"allow-mechanism",
|
|
G_CALLBACK (server_on_allow_mechanism),
|
|
(gpointer) data->allowed_client_mechanism);
|
|
|
|
c = g_dbus_connection_new_for_address_sync (data->address,
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
auth_observer,
|
|
NULL, /* GCancellable */
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (c != NULL);
|
|
g_clear_object (&c);
|
|
g_clear_object (&auth_observer);
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
test_auth_mechanism (const gchar *allowed_client_mechanism,
|
|
const gchar *allowed_server_mechanism)
|
|
{
|
|
GDBusServer *server;
|
|
GMainLoop *loop;
|
|
GThread *client_thread;
|
|
TestAuthData data;
|
|
guint timeout_id;
|
|
|
|
server = server_new_for_mechanism (allowed_server_mechanism);
|
|
|
|
loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
g_signal_connect (server,
|
|
"new-connection",
|
|
G_CALLBACK (test_auth_on_new_connection),
|
|
loop);
|
|
|
|
timeout_id = g_timeout_add_seconds (5, test_auth_on_timeout, NULL);
|
|
|
|
data.allowed_client_mechanism = allowed_client_mechanism;
|
|
data.allowed_server_mechanism = allowed_server_mechanism;
|
|
data.address = g_dbus_server_get_client_address (server);
|
|
|
|
/* run the D-Bus client in a thread */
|
|
client_thread = g_thread_new ("gdbus-client-thread",
|
|
test_auth_client_thread_func,
|
|
&data);
|
|
|
|
g_dbus_server_start (server);
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
g_dbus_server_stop (server);
|
|
|
|
g_thread_join (client_thread);
|
|
g_source_remove (timeout_id);
|
|
|
|
while (g_main_context_iteration (NULL, FALSE));
|
|
g_main_loop_unref (loop);
|
|
|
|
g_object_unref (server);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
static void
|
|
auth_client_external (void)
|
|
{
|
|
test_auth_mechanism ("EXTERNAL", NULL);
|
|
}
|
|
|
|
static void
|
|
auth_client_dbus_cookie_sha1 (void)
|
|
{
|
|
test_auth_mechanism ("DBUS_COOKIE_SHA1", NULL);
|
|
}
|
|
|
|
static void
|
|
auth_server_anonymous (void)
|
|
{
|
|
test_auth_mechanism (NULL, "ANONYMOUS");
|
|
}
|
|
|
|
static void
|
|
auth_server_external (void)
|
|
{
|
|
test_auth_mechanism (NULL, "EXTERNAL");
|
|
}
|
|
|
|
static void
|
|
auth_server_dbus_cookie_sha1 (void)
|
|
{
|
|
test_auth_mechanism (NULL, "DBUS_COOKIE_SHA1");
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
static gchar *temp_dbus_keyrings_dir = NULL;
|
|
|
|
static void
|
|
temp_dbus_keyrings_setup (void)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
g_assert (temp_dbus_keyrings_dir == NULL);
|
|
temp_dbus_keyrings_dir = g_dir_make_tmp ("gdbus-test-dbus-keyrings-XXXXXX", &error);
|
|
g_assert_no_error (error);
|
|
g_assert (temp_dbus_keyrings_dir != NULL);
|
|
g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR", temp_dbus_keyrings_dir, TRUE);
|
|
g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION", "1", TRUE);
|
|
}
|
|
|
|
static void
|
|
temp_dbus_keyrings_teardown (void)
|
|
{
|
|
GDir *dir;
|
|
GError *error = NULL;
|
|
const gchar *name;
|
|
|
|
g_assert (temp_dbus_keyrings_dir != NULL);
|
|
|
|
dir = g_dir_open (temp_dbus_keyrings_dir, 0, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (dir != NULL);
|
|
while ((name = g_dir_read_name (dir)) != NULL)
|
|
{
|
|
gchar *path = g_build_filename (temp_dbus_keyrings_dir, name, NULL);
|
|
g_assert (unlink (path) == 0);
|
|
g_free (path);
|
|
}
|
|
g_dir_close (dir);
|
|
g_assert (rmdir (temp_dbus_keyrings_dir) == 0);
|
|
|
|
g_free (temp_dbus_keyrings_dir);
|
|
temp_dbus_keyrings_dir = NULL;
|
|
g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR");
|
|
g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION");
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
int
|
|
main (int argc,
|
|
char *argv[])
|
|
{
|
|
gint ret;
|
|
|
|
setlocale (LC_ALL, "C");
|
|
|
|
temp_dbus_keyrings_setup ();
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
g_test_add_func ("/gdbus/auth/client/EXTERNAL", auth_client_external);
|
|
g_test_add_func ("/gdbus/auth/client/DBUS_COOKIE_SHA1", auth_client_dbus_cookie_sha1);
|
|
g_test_add_func ("/gdbus/auth/server/ANONYMOUS", auth_server_anonymous);
|
|
g_test_add_func ("/gdbus/auth/server/EXTERNAL", auth_server_external);
|
|
g_test_add_func ("/gdbus/auth/server/DBUS_COOKIE_SHA1", auth_server_dbus_cookie_sha1);
|
|
|
|
/* TODO: we currently don't have tests for
|
|
*
|
|
* - DBUS_COOKIE_SHA1 timeouts (and clock changes etc)
|
|
* - interoperability with libdbus-1 implementations of authentication methods (both client and server)
|
|
*/
|
|
|
|
ret = g_test_run();
|
|
|
|
temp_dbus_keyrings_teardown ();
|
|
|
|
return ret;
|
|
}
|