/* GLib testing framework examples and tests * * Copyright (C) 2008-2010 Red Hat, Inc. * * SPDX-License-Identifier: LGPL-2.1-or-later * * 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 . * * Author: David Zeuthen */ #include #ifndef _MSC_VER #include #endif #include "gdbus-tests.h" /* ---------------------------------------------------------------------------------------------------- */ typedef struct { GMainLoop *loop; gboolean timed_out; } PropertyNotifyData; static void on_property_notify (GObject *object, GParamSpec *pspec, gpointer user_data) { PropertyNotifyData *data = user_data; g_main_loop_quit (data->loop); } static gboolean on_property_notify_timeout (gpointer user_data) { PropertyNotifyData *data = user_data; data->timed_out = TRUE; g_main_loop_quit (data->loop); return G_SOURCE_CONTINUE; } gboolean _g_assert_property_notify_run (gpointer object, const gchar *property_name) { gchar *s; gulong handler_id; guint timeout_id; PropertyNotifyData data; data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); data.timed_out = FALSE; s = g_strdup_printf ("notify::%s", property_name); handler_id = g_signal_connect (object, s, G_CALLBACK (on_property_notify), &data); g_free (s); timeout_id = g_timeout_add_seconds (30, on_property_notify_timeout, &data); g_main_loop_run (data.loop); g_signal_handler_disconnect (object, handler_id); g_source_remove (timeout_id); g_main_loop_unref (data.loop); return data.timed_out; } static gboolean _give_up (gpointer data) { g_error ("%s", (const gchar *) data); g_return_val_if_reached (G_SOURCE_CONTINUE); } typedef struct { GMainContext *context; gboolean name_appeared; gboolean unwatch_complete; } WatchData; static void name_appeared_cb (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { WatchData *data = user_data; g_assert (name_owner != NULL); data->name_appeared = TRUE; g_main_context_wakeup (data->context); } static void watch_free_cb (gpointer user_data) { WatchData *data = user_data; data->unwatch_complete = TRUE; g_main_context_wakeup (data->context); } void ensure_gdbus_testserver_up (GDBusConnection *connection, GMainContext *context) { GSource *timeout_source = NULL; guint watch_id; WatchData data = { context, FALSE, FALSE }; g_main_context_push_thread_default (context); watch_id = g_bus_watch_name_on_connection (connection, "com.example.TestService", G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_cb, NULL, &data, watch_free_cb); timeout_source = g_timeout_source_new_seconds (60); g_source_set_callback (timeout_source, _give_up, "waited more than ~ 60s for gdbus-testserver to take its bus name", NULL); g_source_attach (timeout_source, context); while (!data.name_appeared) g_main_context_iteration (context, TRUE); g_bus_unwatch_name (watch_id); while (!data.unwatch_complete) g_main_context_iteration (context, TRUE); g_source_destroy (timeout_source); g_source_unref (timeout_source); g_main_context_pop_thread_default (context); } /* ---------------------------------------------------------------------------------------------------- */ typedef struct { GMainLoop *loop; gboolean timed_out; } SignalReceivedData; static void on_signal_received (gpointer user_data) { SignalReceivedData *data = user_data; g_main_loop_quit (data->loop); } static gboolean on_signal_received_timeout (gpointer user_data) { SignalReceivedData *data = user_data; data->timed_out = TRUE; g_main_loop_quit (data->loop); return G_SOURCE_CONTINUE; } gboolean _g_assert_signal_received_run (gpointer object, const gchar *signal_name) { gulong handler_id; guint timeout_id; SignalReceivedData data; data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); data.timed_out = FALSE; handler_id = g_signal_connect_swapped (object, signal_name, G_CALLBACK (on_signal_received), &data); timeout_id = g_timeout_add_seconds (30, on_signal_received_timeout, &data); g_main_loop_run (data.loop); g_signal_handler_disconnect (object, handler_id); g_source_remove (timeout_id); g_main_loop_unref (data.loop); return data.timed_out; } /* ---------------------------------------------------------------------------------------------------- */ GDBusConnection * _g_bus_get_priv (GBusType bus_type, GCancellable *cancellable, GError **error) { gchar *address; GDBusConnection *ret; ret = NULL; address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error); if (address == NULL) goto out; ret = g_dbus_connection_new_for_address_sync (address, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, NULL, /* GDBusAuthObserver */ cancellable, error); g_free (address); out: return ret; } /* ---------------------------------------------------------------------------------------------------- */