From a6f83d73e59cc2ab0353ff3edf38d27185852581 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 18 Apr 2012 13:47:51 -0400 Subject: [PATCH] Revert "Add GTestDBus object" This reverts commit 1b5f70b5b035019ba28da6a5db6eff8122e17ae7. --- docs/reference/gio/gio-docs.xml | 4 - docs/reference/gio/gio-sections.txt | 18 - docs/reference/gio/gio.types | 2 - gio/Makefile.am | 2 - gio/gio.h | 1 - gio/gio.symbols | 10 - gio/gioenums.h | 15 - gio/giotypes.h | 2 - gio/gtestdbus.c | 650 ------------------------ gio/gtestdbus.h | 82 --- gio/tests/actions.c | 2 + gio/tests/gapplication.c | 23 +- gio/tests/gdbus-auth.c | 5 + gio/tests/gdbus-bz627724.c | 6 +- gio/tests/gdbus-connection-loss.c | 13 +- gio/tests/gdbus-connection-slow.c | 7 +- gio/tests/gdbus-connection.c | 20 +- gio/tests/gdbus-exit-on-close.c | 12 +- gio/tests/gdbus-export.c | 13 +- gio/tests/gdbus-introspection.c | 11 +- gio/tests/gdbus-names.c | 13 +- gio/tests/gdbus-peer.c | 2 + gio/tests/gdbus-proxy-threads.c | 10 +- gio/tests/gdbus-proxy-well-known-name.c | 11 +- gio/tests/gdbus-proxy.c | 11 +- gio/tests/gdbus-sessionbus.c | 325 +++++++++++- gio/tests/gdbus-sessionbus.h | 12 +- gio/tests/gdbus-test-codegen.c | 11 + gio/tests/gdbus-threading.c | 11 + gio/tests/gmenumodel.c | 3 + 30 files changed, 469 insertions(+), 838 deletions(-) delete mode 100644 gio/gtestdbus.c delete mode 100644 gio/gtestdbus.h diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml index a1e8c6c73..83afa7004 100644 --- a/docs/reference/gio/gio-docs.xml +++ b/docs/reference/gio/gio-docs.xml @@ -230,10 +230,6 @@ - - GIO Testing - - diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index ef51521f5..39265ed2f 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -3870,21 +3870,3 @@ g_resource_flags_get_type g_resource_lookup_flags_get_type g_resource_error_quark - -
-gtestdbus -GTestDBus -GTestDBus -GTestDBusFlags -g_test_dbus_new -g_test_dbus_get_flags -g_test_dbus_get_bus_address -g_test_dbus_add_service_dir -g_test_dbus_up -g_test_dbus_stop -g_test_dbus_down -g_test_dbus_unset - -g_test_dbus_get_type -g_test_dbus_flags_get_type -
diff --git a/docs/reference/gio/gio.types b/docs/reference/gio/gio.types index 9eec8a99a..ac0689312 100644 --- a/docs/reference/gio/gio.types +++ b/docs/reference/gio/gio.types @@ -133,5 +133,3 @@ g_menu_attribute_iter_get_type g_menu_link_iter_get_type g_menu_get_type g_menu_item_get_type -g_test_dbus_get_type -g_test_dbus_flags_get_type diff --git a/gio/Makefile.am b/gio/Makefile.am index 91981cbbf..cb30475f7 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -65,7 +65,6 @@ gdbus_headers = \ gdbusobjectmanager.h \ gdbusobjectmanagerclient.h \ gdbusobjectmanagerserver.h \ - gtestdbus.h \ $(NULL) gdbus_sources = \ @@ -96,7 +95,6 @@ gdbus_sources = \ gdbusobjectmanagerclient.h gdbusobjectmanagerclient.c \ gdbusobjectmanagerserver.h gdbusobjectmanagerserver.c \ gdbus-tests.h gdbus-tests.c \ - gtestdbus.h gtestdbus.c \ $(NULL) settings_headers = \ diff --git a/gio/gio.h b/gio/gio.h index 3fb914d20..c8afdf5a1 100644 --- a/gio/gio.h +++ b/gio/gio.h @@ -124,7 +124,6 @@ #include #include #include -#include #include #include #include diff --git a/gio/gio.symbols b/gio/gio.symbols index cb4bdca56..9cb3ff5df 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -1721,13 +1721,3 @@ g_resolver_lookup_records g_resolver_lookup_records_async g_resolver_lookup_records_finish g_resolver_record_type_get_type -g_test_dbus_add_service_dir -g_test_dbus_flags_get_type -g_test_dbus_get_bus_address -g_test_dbus_get_flags -g_test_dbus_get_type -g_test_dbus_new -g_test_dbus_down -g_test_dbus_stop -g_test_dbus_up -g_test_dbus_unset diff --git a/gio/gioenums.h b/gio/gioenums.h index 71a881e67..cc19d3c51 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -1640,21 +1640,6 @@ typedef enum { G_SOCKET_CLIENT_COMPLETE } GSocketClientEvent; -/** - * GTestDBusFlags: - * @G_TEST_DBUS_NONE: No flags. - * - * Flags to define future #GTestDBus behaviour. - * - * Since: 2.34 - */ -typedef enum { - G_TEST_DBUS_NONE = 0, - - /* FIXME: Must have a value, otherwise mkenum generate GEnum instead of GFlags */ - G_TEST_DBUS_FOO = (1 << 0), -} GTestDBusFlags; - G_END_DECLS #endif /* __GIO_ENUMS_H__ */ diff --git a/gio/giotypes.h b/gio/giotypes.h index 876d856cd..a3abecc6f 100644 --- a/gio/giotypes.h +++ b/gio/giotypes.h @@ -465,8 +465,6 @@ typedef GType (*GDBusProxyTypeFunc) (GDBusObjectManagerClient *manager, const gchar *interface_name, gpointer user_data); -typedef struct _GTestDBus GTestDBus; - G_END_DECLS #endif /* __GIO_TYPES_H__ */ diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c deleted file mode 100644 index e45092711..000000000 --- a/gio/gtestdbus.c +++ /dev/null @@ -1,650 +0,0 @@ -/* GIO testing utilities - * - * Copyright (C) 2008-2010 Red Hat, Inc. - * Copyright (C) 2012 Collabora Ltd. - * - * 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 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, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: David Zeuthen - * Xavier Claessens - */ - -#include "config.h" - -#include -#include -#include - -#include - -#include "gdbus-tests.h" -#include "gdbusconnection.h" -#include "gdbusprivate.h" -#include "gfile.h" -#include "gioenumtypes.h" -#include "gtestdbus.h" - -#include "glibintl.h" - -/* -------------------------------------------------------------------------- */ -/* Utilities to cleanup the mess in the case unit test process crash */ - -#define ADD_PID_FORMAT "add pid %d\n" -#define REMOVE_PID_FORMAT "remove pid %d\n" - -static void -watch_parent (gint fd) -{ - GIOChannel *channel; - GPollFD fds[1]; - GArray *pids_to_kill; - - channel = g_io_channel_unix_new (fd); - - fds[0].fd = fd; - fds[0].events = G_IO_HUP | G_IO_IN; - fds[0].revents = 0; - - pids_to_kill = g_array_new (FALSE, FALSE, sizeof (guint)); - - do - { - gint num_events; - gchar *command = NULL; - guint pid; - guint n; - GError *error = NULL; - - num_events = g_poll (fds, 1, -1); - if (num_events == 0) - continue; - - if (fds[0].revents == G_IO_HUP) - { - /* Parent quit, cleanup the mess and exit */ - for (n = 0; n < pids_to_kill->len; n++) - { - pid = g_array_index (pids_to_kill, guint, n); - g_print ("cleaning up pid %d\n", pid); - kill (pid, SIGTERM); - } - - g_array_unref (pids_to_kill); - g_io_channel_shutdown (channel, FALSE, &error); - g_assert_no_error (error); - g_io_channel_unref (channel); - - exit (0); - } - - /* Read the command from the input */ - g_io_channel_read_line (channel, &command, NULL, NULL, &error); - g_assert_no_error (error); - - /* Check for known commands */ - if (sscanf (command, ADD_PID_FORMAT, &pid) == 1) - { - g_array_append_val (pids_to_kill, pid); - } - else if (sscanf (command, REMOVE_PID_FORMAT, &pid) == 1) - { - for (n = 0; n < pids_to_kill->len; n++) - { - if (g_array_index (pids_to_kill, guint, n) == pid) - { - g_array_remove_index (pids_to_kill, n); - pid = 0; - break; - } - } - if (pid != 0) - { - g_warning ("unknown pid %d to remove", pid); - } - } - else - { - g_warning ("unknown command from parent '%s'", command); - } - - g_free (command); - } - while (TRUE); -} - -static GIOChannel * -watcher_init (void) -{ - static gsize started = 0; - static GIOChannel *channel = NULL; - - if (g_once_init_enter (&started)) - { - gint pipe_fds[2]; - - /* fork a child to clean up when we are killed */ - if (pipe (pipe_fds) != 0) - { - g_warning ("pipe() failed: %m"); - g_assert_not_reached (); - } - - switch (fork ()) - { - case -1: - g_warning ("fork() failed: %m"); - g_assert_not_reached (); - break; - - case 0: - /* child */ - close (pipe_fds[1]); - watch_parent (pipe_fds[0]); - break; - - default: - /* parent */ - close (pipe_fds[0]); - channel = g_io_channel_unix_new (pipe_fds[1]); - } - - g_once_init_leave (&started, 1); - } - - return channel; -} - -static void -watcher_send_command (const gchar *command) -{ - GIOChannel *channel; - GError *error = NULL; - - channel = watcher_init (); - - g_io_channel_write_chars (channel, command, -1, NULL, &error); - g_assert_no_error (error); - - g_io_channel_flush (channel, &error); - g_assert_no_error (error); -} - -/* This could be interesting to expose in public API */ -static void -_g_test_watcher_add_pid (GPid pid) -{ - gchar *command; - - command = g_strdup_printf (ADD_PID_FORMAT, (guint) pid); - watcher_send_command (command); - g_free (command); -} - -static void -_g_test_watcher_remove_pid (GPid pid) -{ - gchar *command; - - command = g_strdup_printf (REMOVE_PID_FORMAT, (guint) pid); - watcher_send_command (command); - g_free (command); -} - -/* -------------------------------------------------------------------------- */ -/* GTestDBus object implementation */ - -/** - * SECTION:gtestdbus - * @short_description: D-Bus testing helper - * @include: gio/gio.h - * - * Helper to test D-Bus code wihtout messing up with user' session bus. - * - * Since: 2.34 - */ - -typedef struct _GTestDBusClass GTestDBusClass; -typedef struct _GTestDBusPrivate GTestDBusPrivate; - -/** - * GTestDBus: - * - * The #GTestDBus structure contains only private data and - * should only be accessed using the provided API. - * - * Since: 2.34 - */ -struct _GTestDBus { - GObject parent; - - GTestDBusPrivate *priv; -}; - -/** - * GTestDBusClass: - * - * Class structure for #GTestDBus. - * - * Since: 2.34 - */ -struct _GTestDBusClass { - GObjectClass parent_class; -}; - -struct _GTestDBusPrivate -{ - GTestDBusFlags flags; - GPtrArray *service_dirs; - GPid bus_pid; - gchar *bus_address; - gboolean up; -}; - -enum -{ - PROP_0, - PROP_FLAGS, -}; - -G_DEFINE_TYPE (GTestDBus, g_test_dbus, G_TYPE_OBJECT) - -static void -g_test_dbus_init (GTestDBus *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), G_TYPE_TEST_DBUS, - GTestDBusPrivate); - - self->priv->service_dirs = g_ptr_array_new_with_free_func (g_free); -} - -static void -g_test_dbus_dispose (GObject *object) -{ - GTestDBus *self = (GTestDBus *) object; - - if (self->priv->up) - g_test_dbus_down (self); - - G_OBJECT_CLASS (g_test_dbus_parent_class)->dispose (object); -} - -static void -g_test_dbus_finalize (GObject *object) -{ - GTestDBus *self = (GTestDBus *) object; - - g_ptr_array_unref (self->priv->service_dirs); - g_free (self->priv->bus_address); - - G_OBJECT_CLASS (g_test_dbus_parent_class)->finalize (object); -} - -static void -g_test_dbus_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GTestDBus *self = (GTestDBus *) object; - - switch (property_id) - { - case PROP_FLAGS: - g_value_set_flags (value, g_test_dbus_get_flags (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -g_test_dbus_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GTestDBus *self = (GTestDBus *) object; - - switch (property_id) - { - case PROP_FLAGS: - self->priv->flags = g_value_get_flags (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -g_test_dbus_class_init (GTestDBusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = g_test_dbus_dispose; - object_class->finalize = g_test_dbus_finalize; - object_class->get_property = g_test_dbus_get_property; - object_class->set_property = g_test_dbus_set_property; - - g_type_class_add_private (object_class, sizeof (GTestDBusPrivate)); - - /** - * GTestDBus:flags: - * - * #GTestDBusFlags specifying the behaviour of the dbus session - * - * Since: 2.34 - */ - g_object_class_install_property (object_class, PROP_FLAGS, - g_param_spec_flags ("flags", - P_("dbus session flags"), - P_("Flags specifying the behaviour of the dbus session"), - G_TYPE_TEST_DBUS_FLAGS, G_TEST_DBUS_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - -} - -static GFile * -write_config_file (GTestDBus *self) -{ - GString *contents; - GFile *file; - GFileIOStream *iostream; - guint i; - GError *error = NULL; - - file = g_file_new_tmp ("g-test-dbus-XXXXXX", &iostream, &error); - g_assert_no_error (error); - g_object_unref (iostream); - - contents = g_string_new (NULL); - g_string_append (contents, - "\n" - " session\n" - " unix:tmpdir=/tmp\n"); - - for (i = 0; i < self->priv->service_dirs->len; i++) - { - const gchar *path = g_ptr_array_index (self->priv->service_dirs, i); - - g_string_append_printf (contents, - " %s\n", path); - } - - g_string_append (contents, - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"); - - g_file_replace_contents (file, contents->str, contents->len, - NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); - g_assert_no_error (error); - - g_string_free (contents, TRUE); - - return file; -} - -static void -start_daemon (GTestDBus *self) -{ - gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL}; - GFile *file; - gchar *config_path; - gchar *config_arg; - gint stdout_fd; - GIOChannel *channel; - gsize termpos; - GError *error = NULL; - - /* Write config file and set its path in argv */ - file = write_config_file (self); - config_path = g_file_get_path (file); - config_arg = g_strdup_printf ("--config-file=%s", config_path); - argv[2] = config_arg; - - /* Spawn dbus-daemon */ - g_spawn_async_with_pipes (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, - NULL, - &self->priv->bus_pid, - NULL, - &stdout_fd, - NULL, - &error); - g_assert_no_error (error); - - _g_test_watcher_add_pid (self->priv->bus_pid); - - /* Read bus address from daemon' stdout */ - channel = g_io_channel_unix_new (stdout_fd); - g_io_channel_read_line (channel, &self->priv->bus_address, NULL, - &termpos, &error); - g_assert_no_error (error); - self->priv->bus_address[termpos] = '\0'; - - /* start dbus-monitor */ - if (g_getenv ("G_DBUS_MONITOR") != NULL) - { - gchar *command; - - command = g_strdup_printf ("dbus-monitor --address %s", - self->priv->bus_address); - g_spawn_command_line_async (command, NULL); - g_free (command); - - usleep (500 * 1000); - } - - /* Cleanup */ - g_io_channel_shutdown (channel, FALSE, &error); - g_assert_no_error (error); - g_io_channel_unref (channel); - - g_file_delete (file, NULL, &error); - g_assert_no_error (error); - g_object_unref (file); - - g_free (config_path); - g_free (config_arg); -} - -static void -stop_daemon (GTestDBus *self) -{ - kill (self->priv->bus_pid, SIGTERM); - _g_test_watcher_remove_pid (self->priv->bus_pid); - self->priv->bus_pid = 0; - - g_free (self->priv->bus_address); - self->priv->bus_address = NULL; -} - -/** - * g_test_dbus_new: - * @flags: a #GTestDBusFlags - * - * Create a new #GTestDBus object. - * - * Returns: (transfer full): a new #GTestDBus. - */ -GTestDBus * -g_test_dbus_new (GTestDBusFlags flags) -{ - return g_object_new (G_TYPE_TEST_DBUS, - "flags", flags, - NULL); -} - -/** - * g_test_dbus_get_flags: - * @self: a #GTestDBus - * - * Returns: the value of #GTestDBus:flags property - */ -GTestDBusFlags -g_test_dbus_get_flags (GTestDBus *self) -{ - g_return_val_if_fail (G_IS_TEST_DBUS (self), G_TEST_DBUS_NONE); - - return self->priv->flags; -} - -/** - * g_test_dbus_get_bus_address: - * @self: a #GTestDBus - * - * Get the address on which dbus-daemon is running. if g_test_dbus_up() has not - * been called yet, %NULL is returned. This can be used with - * g_dbus_connection_new_for_address() - * - * Returns: the address of the bus, or %NULL. - */ -const gchar * -g_test_dbus_get_bus_address (GTestDBus *self) -{ - g_return_val_if_fail (G_IS_TEST_DBUS (self), NULL); - - return self->priv->bus_address; -} - -/** - * g_test_dbus_add_service_dir: - * @self: a #GTestDBus - * @path: path to a directory containing .service files - * - * Add a path where dbus-daemon will lookup for .services files. This can't be - * called after g_test_dbus_up(). - */ -void -g_test_dbus_add_service_dir (GTestDBus *self, - const gchar *path) -{ - g_return_if_fail (G_IS_TEST_DBUS (self)); - g_return_if_fail (self->priv->bus_address == NULL); - - g_ptr_array_add (self->priv->service_dirs, g_strdup (path)); -} - -/** - * g_test_dbus_up: - * @self: a #GTestDBus - * - * Start a dbus-daemon instance and set DBUS_SESSION_BUS_ADDRESS. After this - * call, it is safe for unit tests to start sending messages on the session bug. - * - * If this function is called from setup callback of g_test_add(), - * g_test_dbus_down() must be called in its teardown callback. - * - * If this function is called from unit test's main(), then g_test_dbus_down() - * must be called after g_test_run(). - */ -void -g_test_dbus_up (GTestDBus *self) -{ - g_return_if_fail (G_IS_TEST_DBUS (self)); - g_return_if_fail (self->priv->bus_address == NULL); - g_return_if_fail (!self->priv->up); - - start_daemon (self); - - g_setenv ("DBUS_SESSION_BUS_ADDRESS", self->priv->bus_address, TRUE); - self->priv->up = TRUE; -} - - -/** - * g_test_dbus_stop: - * @self: a #GTestDBus - * - * Stop the session bus started by g_test_dbus_up(). - * - * Unlike g_test_dbus_down(), this won't verify the #GDBusConnection - * singleton returned by g_bus_get() or g_bus_get_sync() is destroyed. Unit - * tests wanting to verify behaviour after the session bus has been stopped - * can use this function but should still call g_test_dbus_down() when done. - */ -void -g_test_dbus_stop (GTestDBus *self) -{ - g_return_if_fail (G_IS_TEST_DBUS (self)); - g_return_if_fail (self->priv->bus_address != NULL); - - stop_daemon (self); -} - -/** - * g_test_dbus_down: - * @self: a #GTestDBus - * - * Stop the session bus started by g_test_dbus_up(). - * - * This will wait for the singleton returned by g_bus_get() or g_bus_get_sync() - * is destroyed. This is done to ensure that the next unit test won't get a - * leaked singleton from this test. - */ -void -g_test_dbus_down (GTestDBus *self) -{ - GDBusConnection *connection; - - g_return_if_fail (G_IS_TEST_DBUS (self)); - g_return_if_fail (self->priv->up); - - connection = _g_bus_get_singleton_if_exists (G_BUS_TYPE_SESSION); - if (connection != NULL) - g_dbus_connection_set_exit_on_close (connection, FALSE); - - if (self->priv->bus_address != NULL) - stop_daemon (self); - - if (connection != NULL) - { - _g_object_wait_for_single_ref (connection); - g_object_unref (connection); - } - - g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); - self->priv->up = FALSE; -} - -/** - * g_test_dbus_unset: - * - * Unset DISPLAY and DBUS_SESSION_BUS_ADDRESS env variables to ensure the test - * won't use user's session bus. - * - * This is useful for unit tests that want to verify behaviour when no session - * bus is running. It is not necessary to call this if unit test already calls - * g_test_dbus_up() before acquiring the session bus. - */ -void -g_test_dbus_unset (void) -{ - g_unsetenv ("DISPLAY"); - g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); -} diff --git a/gio/gtestdbus.h b/gio/gtestdbus.h deleted file mode 100644 index 9970555c1..000000000 --- a/gio/gtestdbus.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GIO testing utilities - * - * Copyright (C) 2008-2010 Red Hat, Inc. - * Copyright (C) 2012 Collabora Ltd. - * - * 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 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, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: David Zeuthen - * Xavier Claessens - */ - -#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __G_TEST_DBUS_H__ -#define __G_TEST_DBUS_H__ - -#include - -G_BEGIN_DECLS - -#define G_TYPE_TEST_DBUS \ - (g_test_dbus_get_type ()) -#define G_TEST_DBUS(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_TEST_DBUS, \ - GTestDbus)) -#define G_TEST_DBUS_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_TEST_DBUS, \ - GTestDBusClass)) -#define G_IS_TEST_DBUS(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_TEST_DBUS)) -#define G_IS_TEST_DBUS_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_TEST_DBUS)) -#define G_TEST_DBUS_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_TEST_DBUS, \ - GTestDBusClass)) - -GLIB_AVAILABLE_IN_2_34 -GType g_test_dbus_get_type (void) G_GNUC_CONST; - -GLIB_AVAILABLE_IN_2_34 -GTestDBus * g_test_dbus_new (GTestDBusFlags flags); - -GLIB_AVAILABLE_IN_2_34 -GTestDBusFlags g_test_dbus_get_flags (GTestDBus *self); - -GLIB_AVAILABLE_IN_2_34 -const gchar * g_test_dbus_get_bus_address (GTestDBus *self); - -GLIB_AVAILABLE_IN_2_34 -void g_test_dbus_add_service_dir (GTestDBus *self, - const gchar *path); - -GLIB_AVAILABLE_IN_2_34 -void g_test_dbus_up (GTestDBus *self); - -GLIB_AVAILABLE_IN_2_34 -void g_test_dbus_stop (GTestDBus *self); - -GLIB_AVAILABLE_IN_2_34 -void g_test_dbus_down (GTestDBus *self); - -GLIB_AVAILABLE_IN_2_34 -void g_test_dbus_unset (void); - -G_END_DECLS - -#endif /* __G_TEST_DBUS_H__ */ diff --git a/gio/tests/actions.c b/gio/tests/actions.c index f82515cc3..148f656c6 100644 --- a/gio/tests/actions.c +++ b/gio/tests/actions.c @@ -712,6 +712,8 @@ main (int argc, char **argv) g_type_init (); g_test_init (&argc, &argv, NULL); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + g_test_add_func ("/actions/basic", test_basic); g_test_add_func ("/actions/simplegroup", test_simple_group); g_test_add_func ("/actions/stateful", test_stateful); diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c index 4dc239f52..a1faa5c60 100644 --- a/gio/tests/gapplication.c +++ b/gio/tests/gapplication.c @@ -116,8 +116,11 @@ basic (void) g_main_loop_run (main_loop); - g_object_unref (c); session_bus_down (); + _g_object_wait_for_single_ref_do (c); + g_object_unref (c); + + g_assert (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL) == NULL); } @@ -249,11 +252,14 @@ properties (void) g_application_quit (G_APPLICATION (app)); - g_object_unref (c); g_object_unref (app); g_free (id); session_bus_down (); + _g_object_wait_for_single_ref (c); + g_object_unref (c); + + g_assert (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL) == NULL); } static void @@ -351,11 +357,15 @@ test_quit (void) g_signal_connect (app, "activate", G_CALLBACK (quit_activate), NULL); g_application_run (app, 1, argv); g_object_unref (app); - g_object_unref (c); g_assert (quit_activated); session_bus_down (); + + _g_object_wait_for_single_ref (c); + g_object_unref (c); + + g_assert (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL) == NULL); } static void @@ -413,7 +423,12 @@ main (int argc, char **argv) g_test_init (&argc, &argv, NULL); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address + * that we can bring up and down using session_bus_up() and + * session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gapplication/no-dbus", test_nodbus); g_test_add_func ("/gapplication/basic", basic); diff --git a/gio/tests/gdbus-auth.c b/gio/tests/gdbus-auth.c index 737770e8d..3b24b092e 100644 --- a/gio/tests/gdbus-auth.c +++ b/gio/tests/gdbus-auth.c @@ -269,6 +269,11 @@ main (int argc, g_type_init (); g_test_init (&argc, &argv, NULL); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); session_bus_up (); g_test_add_func ("/gdbus/auth/client/EXTERNAL", auth_client_external); diff --git a/gio/tests/gdbus-bz627724.c b/gio/tests/gdbus-bz627724.c index b9ea9c97f..03d196e53 100644 --- a/gio/tests/gdbus-bz627724.c +++ b/gio/tests/gdbus-bz627724.c @@ -83,7 +83,11 @@ main (int argc, g_type_init (); g_test_init (&argc, &argv, NULL); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/bz627724", test_bz627724); return g_test_run(); diff --git a/gio/tests/gdbus-connection-loss.c b/gio/tests/gdbus-connection-loss.c index 504383e9e..3fdd36740 100644 --- a/gio/tests/gdbus-connection-loss.c +++ b/gio/tests/gdbus-connection-loss.c @@ -54,7 +54,7 @@ static gboolean on_timeout (gpointer user_data) { /* tear down bus */ - session_bus_stop (); + session_bus_down (); return FALSE; /* remove source */ } @@ -119,8 +119,19 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + /* this is safe; testserver will exit once the bus goes away */ g_assert (g_spawn_command_line_async (SRCDIR "/gdbus-testserver.py", NULL)); diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c index c9f4411fc..39a9eb8d8 100644 --- a/gio/tests/gdbus-connection-slow.c +++ b/gio/tests/gdbus-connection-slow.c @@ -105,6 +105,7 @@ test_connection_flush (void) } g_dbus_connection_signal_unsubscribe (connection, signal_handler_id); + _g_object_wait_for_single_ref (connection); g_object_unref (connection); session_bus_down (); @@ -201,7 +202,11 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/connection/flush", test_connection_flush); g_test_add_func ("/gdbus/connection/large_message", test_connection_large_message); diff --git a/gio/tests/gdbus-connection.c b/gio/tests/gdbus-connection.c index 10e458594..94c4d9d4c 100644 --- a/gio/tests/gdbus-connection.c +++ b/gio/tests/gdbus-connection.c @@ -267,14 +267,12 @@ test_connection_life_cycle (void) */ g_assert (!g_dbus_connection_is_closed (c)); g_dbus_connection_set_exit_on_close (c, FALSE); - session_bus_stop (); + session_bus_down (); _g_assert_signal_received (c, "closed"); g_assert (g_dbus_connection_is_closed (c)); _g_object_wait_for_single_ref (c); g_object_unref (c); - - session_bus_down (); } /* ---------------------------------------------------------------------------------------------------- */ @@ -471,7 +469,7 @@ test_connection_send (void) * Check that we get an error when sending to a connection that is disconnected. */ g_dbus_connection_set_exit_on_close (c, FALSE); - session_bus_stop (); + session_bus_down (); _g_assert_signal_received (c, "closed"); g_assert (g_dbus_connection_is_closed (c)); @@ -490,8 +488,6 @@ test_connection_send (void) _g_object_wait_for_single_ref (c); g_object_unref (c); - - session_bus_down (); } /* ---------------------------------------------------------------------------------------------------- */ @@ -709,6 +705,10 @@ test_connection_signals (void) g_dbus_connection_signal_unsubscribe (c1, s3); g_dbus_connection_signal_unsubscribe (c1, s1b); + _g_object_wait_for_single_ref (c1); + _g_object_wait_for_single_ref (c2); + _g_object_wait_for_single_ref (c3); + g_object_unref (c1); g_object_unref (c2); g_object_unref (c3); @@ -992,6 +992,7 @@ test_connection_filter (void) g_dbus_connection_remove_filter (c, filter_id); + _g_object_wait_for_single_ref (c); g_object_unref (c); g_object_unref (m); @@ -1045,6 +1046,7 @@ test_connection_basic (void) g_free (name); g_free (guid); + _g_object_wait_for_single_ref (connection); g_object_unref (connection); session_bus_down (); @@ -1062,7 +1064,11 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/connection/basic", test_connection_basic); g_test_add_func ("/gdbus/connection/life-cycle", test_connection_life_cycle); diff --git a/gio/tests/gdbus-exit-on-close.c b/gio/tests/gdbus-exit-on-close.c index f97e5dac0..14d3a8cb6 100644 --- a/gio/tests/gdbus-exit-on-close.c +++ b/gio/tests/gdbus-exit-on-close.c @@ -117,7 +117,11 @@ test_exit_on_close (gconstpointer test_data) /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); if (g_test_verbose ()) silence = 0; @@ -169,16 +173,12 @@ test_exit_on_close (gconstpointer test_data) } else { - session_bus_stop (); + session_bus_down (); } g_main_loop_run (loop); /* this is only reached when we turn off exit-on-close */ g_main_loop_unref (loop); - g_object_unref (c); - - session_bus_down (); - exit (0); } diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c index e015ed913..21e9fda65 100644 --- a/gio/tests/gdbus-export.c +++ b/gio/tests/gdbus-export.c @@ -1341,7 +1341,7 @@ test_object_registration (void) /* To prevent from exiting and attaching a D-Bus tool like D-Feet; uncomment: */ #if 0 - g_debug ("Point D-feet or other tool at: %s", g_test_dbus_get_temporary_address()); + g_debug ("Point D-feet or other tool at: %s", session_bus_get_temporary_address()); g_main_loop_run (loop); #endif @@ -1537,8 +1537,19 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + g_test_add_func ("/gdbus/object-registration", test_object_registration); g_test_add_func ("/gdbus/registered-interfaces", test_registered_interfaces); diff --git a/gio/tests/gdbus-introspection.c b/gio/tests/gdbus-introspection.c index 0afeb7a86..8a3fed2f1 100644 --- a/gio/tests/gdbus-introspection.c +++ b/gio/tests/gdbus-introspection.c @@ -110,6 +110,11 @@ test_introspection_parser (void) session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, @@ -309,7 +314,11 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/introspection-parser", test_introspection_parser); g_test_add_func ("/gdbus/introspection-generate", test_generate); diff --git a/gio/tests/gdbus-names.c b/gio/tests/gdbus-names.c index 54bb05984..4af7ecbfa 100644 --- a/gio/tests/gdbus-names.c +++ b/gio/tests/gdbus-names.c @@ -462,7 +462,7 @@ test_bus_own_name (void) * */ data.expect_null_connection = TRUE; - session_bus_stop (); + session_bus_down (); while (data.num_lost != 2) g_main_loop_run (loop); g_assert_cmpint (data.num_acquired, ==, 2); @@ -473,8 +473,6 @@ test_bus_own_name (void) _g_object_wait_for_single_ref (c); g_object_unref (c); g_object_unref (c2); - - session_bus_down (); } /* ---------------------------------------------------------------------------------------------------- */ @@ -698,7 +696,7 @@ test_bus_watch_name (void) * Nuke the bus and check that the name vanishes and is lost. */ data.expect_null_connection = TRUE; - session_bus_stop (); + session_bus_down (); g_main_loop_run (loop); g_assert_cmpint (data.num_lost, ==, 1); g_assert_cmpint (data.num_vanished, ==, 2); @@ -709,7 +707,6 @@ test_bus_watch_name (void) g_bus_unown_name (owner_id); g_assert_cmpint (data.num_free_func, ==, 2); - session_bus_down (); } /* ---------------------------------------------------------------------------------------------------- */ @@ -775,7 +772,11 @@ main (int argc, loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/validate-names", test_validate_names); g_test_add_func ("/gdbus/bus-own-name", test_bus_own_name); diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index 934ebda32..926010ab7 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -1804,6 +1804,8 @@ main (int argc, g_type_init (); g_test_init (&argc, &argv, NULL); + g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); + introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL); g_assert (introspection_data != NULL); test_interface_introspection_data = introspection_data->interfaces[0]; diff --git a/gio/tests/gdbus-proxy-threads.c b/gio/tests/gdbus-proxy-threads.c index 69047e2f7..325c68b1e 100644 --- a/gio/tests/gdbus-proxy-threads.c +++ b/gio/tests/gdbus-proxy-threads.c @@ -205,6 +205,11 @@ test_proxy (void) session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + loop = g_main_loop_new (NULL, TRUE); connection = g_bus_get_sync (G_BUS_TYPE_SESSION, @@ -235,11 +240,12 @@ int main (int argc, char *argv[]) { + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + g_type_init (); g_test_init (&argc, &argv, NULL); - g_test_dbus_unset (); - g_test_add_func ("/gdbus/proxy/vs-threads", test_proxy); return g_test_run(); diff --git a/gio/tests/gdbus-proxy-well-known-name.c b/gio/tests/gdbus-proxy-well-known-name.c index b2d204d17..a599ef6c5 100644 --- a/gio/tests/gdbus-proxy-well-known-name.c +++ b/gio/tests/gdbus-proxy-well-known-name.c @@ -63,6 +63,11 @@ test_proxy_well_known_name (void) session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + error = NULL; c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); g_assert_no_error (error); @@ -265,7 +270,11 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/proxy-well-known-name", test_proxy_well_known_name); diff --git a/gio/tests/gdbus-proxy.c b/gio/tests/gdbus-proxy.c index cdaa2ba28..ba750ff6a 100644 --- a/gio/tests/gdbus-proxy.c +++ b/gio/tests/gdbus-proxy.c @@ -741,6 +741,11 @@ test_proxy (void) session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, @@ -889,7 +894,11 @@ main (int argc, /* all the tests rely on a shared main loop */ loop = g_main_loop_new (NULL, FALSE); - g_test_dbus_unset (); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); g_test_add_func ("/gdbus/proxy", test_proxy); g_test_add_func ("/gdbus/proxy/no-properties", test_no_properties); diff --git a/gio/tests/gdbus-sessionbus.c b/gio/tests/gdbus-sessionbus.c index 68c4449cd..f39583cd4 100644 --- a/gio/tests/gdbus-sessionbus.c +++ b/gio/tests/gdbus-sessionbus.c @@ -1,6 +1,6 @@ /* GLib testing framework examples and tests * - * Copyright (C) 2012 Collabora Ltd. + * Copyright (C) 2008-2010 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 @@ -17,33 +17,328 @@ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * - * Author: Xavier Claessens + * Author: David Zeuthen */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + #include "gdbus-sessionbus.h" -static GTestDBus *singleton = NULL; +/* ---------------------------------------------------------------------------------------------------- */ +/* Utilities for bringing up and tearing down session message bus instances */ -void -session_bus_up (void) +static void +watch_parent (gint fd) { - g_assert (singleton == NULL); - singleton = g_test_dbus_new (G_TEST_DBUS_NONE); - g_test_dbus_up (singleton); + GPollFD fds[1]; + gint num_events; + gchar buf[512]; + gssize bytes_read; + GArray *buses_to_kill_array; + + fds[0].fd = fd; + fds[0].events = G_IO_HUP | G_IO_IN; + fds[0].revents = 0; + + buses_to_kill_array = g_array_new (FALSE, TRUE, sizeof (guint)); + + do + { + guint pid; + guint n; + + num_events = g_poll (fds, 1, -1); + if (num_events == 0) + continue; + + if (fds[0].revents == G_IO_HUP) + { + for (n = 0; n < buses_to_kill_array->len; n++) + { + pid = g_array_index (buses_to_kill_array, guint, n); + g_print ("cleaning up bus with pid %d\n", pid); + kill (pid, SIGTERM); + } + g_array_free (buses_to_kill_array, TRUE); + exit (0); + } + + //g_debug ("data from parent"); + + memset (buf, '\0', sizeof buf); + again: + bytes_read = read (fds[0].fd, buf, sizeof buf); + if (bytes_read < 0 && (errno == EAGAIN || errno == EINTR)) + goto again; + + if (sscanf (buf, "add %d\n", &pid) == 1) + { + g_array_append_val (buses_to_kill_array, pid); + } + else if (sscanf (buf, "remove %d\n", &pid) == 1) + { + for (n = 0; n < buses_to_kill_array->len; n++) + { + if (g_array_index (buses_to_kill_array, guint, n) == pid) + { + g_array_remove_index (buses_to_kill_array, n); + pid = 0; + break; + } + } + if (pid != 0) + { + g_warning ("unknown pid %d to remove", pid); + } + } + else + { + g_warning ("unknown command from parent '%s'", buf); + } + } + while (TRUE); + +} + +static GHashTable *session_bus_address_to_pid = NULL; +static gint pipe_fds[2]; + +const gchar * +session_bus_up_with_address (const gchar *given_address) +{ + gchar *address; + int stdout_fd; + GError *error; + gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL}; + GPid pid; + gchar buf[512]; + ssize_t bytes_read; + gchar *config_file_name; + gint config_file_fd; + GString *config_file_contents; + + address = NULL; + error = NULL; + config_file_name = NULL; + config_file_fd = -1; + argv[2] = NULL; + + config_file_fd = g_file_open_tmp ("g-dbus-tests-XXXXXX", + &config_file_name, + &error); + if (config_file_fd < 0) + { + g_warning ("Error creating temporary config file: %s", error->message); + g_error_free (error); + goto out; + } + + config_file_contents = g_string_new (NULL); + g_string_append (config_file_contents, "\n"); + g_string_append (config_file_contents, " session\n"); + g_string_append_printf (config_file_contents, " %s\n", given_address); + g_string_append (config_file_contents, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"); + g_string_append (config_file_contents, "\n"); + + if (write (config_file_fd, config_file_contents->str, config_file_contents->len) != (gssize) config_file_contents->len) + { + g_warning ("Error writing %d bytes to config file: %m", (gint) config_file_contents->len); + g_string_free (config_file_contents, TRUE); + goto out; + } + g_string_free (config_file_contents, TRUE); + + argv[2] = g_strdup_printf ("--config-file=%s", config_file_name); + + if (session_bus_address_to_pid == NULL) + { + /* keep a mapping from session bus address to the pid */ + session_bus_address_to_pid = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + /* fork a child to clean up session buses when we are killed */ + if (pipe (pipe_fds) != 0) + { + g_warning ("pipe() failed: %m"); + g_assert_not_reached (); + } + switch (fork ()) + { + case -1: + g_warning ("fork() failed: %m"); + g_assert_not_reached (); + break; + + case 0: + /* child */ + close (pipe_fds[1]); + watch_parent (pipe_fds[0]); + break; + + default: + /* parent */ + close (pipe_fds[0]); + break; + } + + //atexit (cleanup_session_buses); + /* TODO: need to handle the cases where we crash */ + } + else + { + /* check if we already have a bus running for this address */ + if (g_hash_table_lookup (session_bus_address_to_pid, given_address) != NULL) + { + g_warning ("Already have a bus instance for the given address %s", given_address); + goto out; + } + } + + if (!g_spawn_async_with_pipes (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + &pid, + NULL, + &stdout_fd, + NULL, + &error)) + { + g_warning ("Error spawning dbus-daemon: %s", error->message); + g_error_free (error); + goto out; + } + + memset (buf, '\0', sizeof buf); + again: + bytes_read = read (stdout_fd, buf, sizeof buf); + if (bytes_read < 0 && (errno == EAGAIN || errno == EINTR)) + goto again; + close (stdout_fd); + + if (bytes_read == 0 || bytes_read == sizeof buf) + { + g_warning ("Error reading address from dbus daemon, %d bytes read", (gint) bytes_read); + kill (SIGTERM, pid); + goto out; + } + + address = g_strdup (buf); + g_strstrip (address); + + /* write the pid to the child so it can kill it when we die */ + g_snprintf (buf, sizeof buf, "add %d\n", (guint) pid); + write (pipe_fds[1], buf, strlen (buf)); + + /* start dbus-monitor */ + if (g_getenv ("G_DBUS_MONITOR") != NULL) + { + g_spawn_command_line_async ("dbus-monitor --session", NULL); + usleep (500 * 1000); + } + + g_hash_table_insert (session_bus_address_to_pid, address, GUINT_TO_POINTER (pid)); + + out: + if (config_file_fd > 0) + { + if (close (config_file_fd) != 0) + { + g_warning ("Error closing fd for config file %s: %m", config_file_name); + } + g_assert (config_file_name != NULL); + if (unlink (config_file_name) != 0) + { + g_warning ("Error unlinking config file %s: %m", config_file_name); + } + } + g_free (argv[2]); + g_free (config_file_name); + return address; } void -session_bus_stop (void) +session_bus_down_with_address (const gchar *address) { - g_assert (singleton != NULL); - g_test_dbus_stop (singleton); + gpointer value; + GPid pid; + gchar buf[512]; + + g_assert (address != NULL); + g_assert (session_bus_address_to_pid != NULL); + + value = g_hash_table_lookup (session_bus_address_to_pid, address); + g_assert (value != NULL); + + pid = GPOINTER_TO_UINT (g_hash_table_lookup (session_bus_address_to_pid, address)); + + kill (pid, SIGTERM); + + /* write the pid to the child so it won't kill it when we die */ + g_snprintf (buf, sizeof buf, "remove %d\n", (guint) pid); + write (pipe_fds[1], buf, strlen (buf)); + + g_hash_table_remove (session_bus_address_to_pid, address); +} + +static gchar *temporary_address = NULL; +static gchar *temporary_address_used_by_bus = NULL; + +const gchar * +session_bus_get_temporary_address (void) +{ + if (temporary_address == NULL) + { + temporary_address = g_strdup_printf ("unix:path=/tmp/g-dbus-tests-pid-%d", getpid ()); + } + + return temporary_address; +} + +const gchar * +session_bus_up (void) +{ + if (temporary_address_used_by_bus != NULL) + { + g_warning ("There is already a session bus up"); + goto out; + } + + temporary_address_used_by_bus = g_strdup (session_bus_up_with_address (session_bus_get_temporary_address ())); + + out: + return temporary_address_used_by_bus; } void session_bus_down (void) { - g_assert (singleton != NULL); - g_test_dbus_down (singleton); - g_clear_object (&singleton); + if (temporary_address_used_by_bus == NULL) + { + g_warning ("There is not a session bus up"); + } + else + { + session_bus_down_with_address (temporary_address_used_by_bus); + g_free (temporary_address_used_by_bus); + temporary_address_used_by_bus = NULL; + } } - diff --git a/gio/tests/gdbus-sessionbus.h b/gio/tests/gdbus-sessionbus.h index 7ef3abd6d..e107e0664 100644 --- a/gio/tests/gdbus-sessionbus.h +++ b/gio/tests/gdbus-sessionbus.h @@ -1,6 +1,6 @@ /* GLib testing framework examples and tests * - * Copyright (C) 2012 Collabora Ltd. + * Copyright (C) 2008-2009 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 @@ -17,7 +17,7 @@ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * - * Author: Xavier Claessens + * Author: David Zeuthen */ #ifndef __SESSION_BUS_H__ @@ -27,9 +27,11 @@ G_BEGIN_DECLS -void session_bus_up (void); -void session_bus_stop (void); -void session_bus_down (void); +const gchar *session_bus_up_with_address (const gchar *given_address); +void session_bus_down_with_address (const gchar *address); +const gchar *session_bus_get_temporary_address (void); +const gchar *session_bus_up (void); +void session_bus_down (void); G_END_DECLS diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c index 5eb175f7c..363aa853a 100644 --- a/gio/tests/gdbus-test-codegen.c +++ b/gio/tests/gdbus-test-codegen.c @@ -2299,8 +2299,19 @@ main (int argc, g_type_init (); g_test_init (&argc, &argv, NULL); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + g_test_add_func ("/gdbus/codegen/annotations", test_annotations); g_test_add_func ("/gdbus/codegen/interface_stability", test_interface_stability); g_test_add_func ("/gdbus/codegen/object-manager", test_object_manager); diff --git a/gio/tests/gdbus-threading.c b/gio/tests/gdbus-threading.c index c1fc97e46..b46af0be9 100644 --- a/gio/tests/gdbus-threading.c +++ b/gio/tests/gdbus-threading.c @@ -585,8 +585,19 @@ main (int argc, g_type_init (); g_test_init (&argc, &argv, NULL); + /* all the tests use a session bus with a well-known address that we can bring up and down + * using session_bus_up() and session_bus_down(). + */ + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + session_bus_up (); + /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return + * until one can connect to the bus but that's not how things work right now + */ + usleep (500 * 1000); + /* this is safe; testserver will exit once the bus goes away */ g_assert (g_spawn_command_line_async (SRCDIR "/gdbus-testserver.py", NULL)); diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c index c882c4924..3d8cefaec 100644 --- a/gio/tests/gmenumodel.c +++ b/gio/tests/gmenumodel.c @@ -1027,6 +1027,9 @@ main (int argc, char **argv) g_test_init (&argc, &argv, NULL); g_type_init (); + g_unsetenv ("DISPLAY"); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + session_bus_up (); g_test_add_func ("/gmenu/equality", test_equality);