1/* GLib testing framework examples and tests
2 *
3 * Copyright (C) 2008-2010 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: David Zeuthen <davidz@redhat.com>
19 */
20
21#include <gio/gio.h>
22#ifndef _MSC_VER
23#include <unistd.h>
24#endif
25
26#include "gdbus-tests.h"
27
28/* ---------------------------------------------------------------------------------------------------- */
29
30typedef struct
31{
32 GMainLoop *loop;
33 gboolean timed_out;
34} PropertyNotifyData;
35
36static void
37on_property_notify (GObject *object,
38 GParamSpec *pspec,
39 gpointer user_data)
40{
41 PropertyNotifyData *data = user_data;
42 g_main_loop_quit (loop: data->loop);
43}
44
45static gboolean
46on_property_notify_timeout (gpointer user_data)
47{
48 PropertyNotifyData *data = user_data;
49 data->timed_out = TRUE;
50 g_main_loop_quit (loop: data->loop);
51 return G_SOURCE_CONTINUE;
52}
53
54gboolean
55_g_assert_property_notify_run (gpointer object,
56 const gchar *property_name)
57{
58 gchar *s;
59 gulong handler_id;
60 guint timeout_id;
61 PropertyNotifyData data;
62
63 data.loop = g_main_loop_new (context: g_main_context_get_thread_default (), FALSE);
64 data.timed_out = FALSE;
65 s = g_strdup_printf (format: "notify::%s", property_name);
66 handler_id = g_signal_connect (object,
67 s,
68 G_CALLBACK (on_property_notify),
69 &data);
70 g_free (mem: s);
71 timeout_id = g_timeout_add_seconds (interval: 30,
72 function: on_property_notify_timeout,
73 data: &data);
74 g_main_loop_run (loop: data.loop);
75 g_signal_handler_disconnect (instance: object, handler_id);
76 g_source_remove (tag: timeout_id);
77 g_main_loop_unref (loop: data.loop);
78
79 return data.timed_out;
80}
81
82static gboolean
83_give_up (gpointer data)
84{
85 g_error ("%s", (const gchar *) data);
86 g_return_val_if_reached (G_SOURCE_CONTINUE);
87}
88
89typedef struct
90{
91 GMainContext *context;
92 gboolean name_appeared;
93 gboolean unwatch_complete;
94} WatchData;
95
96static void
97name_appeared_cb (GDBusConnection *connection,
98 const gchar *name,
99 const gchar *name_owner,
100 gpointer user_data)
101{
102 WatchData *data = user_data;
103
104 g_assert (name_owner != NULL);
105 data->name_appeared = TRUE;
106 g_main_context_wakeup (context: data->context);
107}
108
109static void
110watch_free_cb (gpointer user_data)
111{
112 WatchData *data = user_data;
113
114 data->unwatch_complete = TRUE;
115 g_main_context_wakeup (context: data->context);
116}
117
118void
119ensure_gdbus_testserver_up (GDBusConnection *connection,
120 GMainContext *context)
121{
122 GSource *timeout_source = NULL;
123 guint watch_id;
124 WatchData data = { context, FALSE, FALSE };
125
126 g_main_context_push_thread_default (context);
127
128 watch_id = g_bus_watch_name_on_connection (connection,
129 name: "com.example.TestService",
130 flags: G_BUS_NAME_WATCHER_FLAGS_NONE,
131 name_appeared_handler: name_appeared_cb,
132 NULL,
133 user_data: &data,
134 user_data_free_func: watch_free_cb);
135
136 timeout_source = g_timeout_source_new_seconds (interval: 60);
137 g_source_set_callback (source: timeout_source, func: _give_up,
138 data: "waited more than ~ 60s for gdbus-testserver to take its bus name",
139 NULL);
140 g_source_attach (source: timeout_source, context);
141
142 while (!data.name_appeared)
143 g_main_context_iteration (context, TRUE);
144
145 g_bus_unwatch_name (watcher_id: watch_id);
146 watch_id = 0;
147
148 while (!data.unwatch_complete)
149 g_main_context_iteration (context, TRUE);
150
151 g_source_destroy (source: timeout_source);
152 g_source_unref (source: timeout_source);
153
154 g_main_context_pop_thread_default (context);
155}
156
157/* ---------------------------------------------------------------------------------------------------- */
158
159typedef struct
160{
161 GMainLoop *loop;
162 gboolean timed_out;
163} SignalReceivedData;
164
165static void
166on_signal_received (gpointer user_data)
167{
168 SignalReceivedData *data = user_data;
169 g_main_loop_quit (loop: data->loop);
170}
171
172static gboolean
173on_signal_received_timeout (gpointer user_data)
174{
175 SignalReceivedData *data = user_data;
176 data->timed_out = TRUE;
177 g_main_loop_quit (loop: data->loop);
178 return G_SOURCE_CONTINUE;
179}
180
181gboolean
182_g_assert_signal_received_run (gpointer object,
183 const gchar *signal_name)
184{
185 gulong handler_id;
186 guint timeout_id;
187 SignalReceivedData data;
188
189 data.loop = g_main_loop_new (context: g_main_context_get_thread_default (), FALSE);
190 data.timed_out = FALSE;
191 handler_id = g_signal_connect_swapped (object,
192 signal_name,
193 G_CALLBACK (on_signal_received),
194 &data);
195 timeout_id = g_timeout_add_seconds (interval: 30,
196 function: on_signal_received_timeout,
197 data: &data);
198 g_main_loop_run (loop: data.loop);
199 g_signal_handler_disconnect (instance: object, handler_id);
200 g_source_remove (tag: timeout_id);
201 g_main_loop_unref (loop: data.loop);
202
203 return data.timed_out;
204}
205
206/* ---------------------------------------------------------------------------------------------------- */
207
208GDBusConnection *
209_g_bus_get_priv (GBusType bus_type,
210 GCancellable *cancellable,
211 GError **error)
212{
213 gchar *address;
214 GDBusConnection *ret;
215
216 ret = NULL;
217
218 address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
219 if (address == NULL)
220 goto out;
221
222 ret = g_dbus_connection_new_for_address_sync (address,
223 flags: G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
224 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
225 NULL, /* GDBusAuthObserver */
226 cancellable,
227 error);
228 g_free (mem: address);
229
230 out:
231 return ret;
232}
233
234/* ---------------------------------------------------------------------------------------------------- */
235

source code of gtk/subprojects/glib/gio/tests/gdbus-tests.c