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
30 typedef struct
31 {
32 GMainLoop *loop;
33 gboolean timed_out;
34 } PropertyNotifyData;
35
36 static void
on_property_notify(GObject * object,GParamSpec * pspec,gpointer user_data)37 on_property_notify (GObject *object,
38 GParamSpec *pspec,
39 gpointer user_data)
40 {
41 PropertyNotifyData *data = user_data;
42 g_main_loop_quit (data->loop);
43 }
44
45 static gboolean
on_property_notify_timeout(gpointer user_data)46 on_property_notify_timeout (gpointer user_data)
47 {
48 PropertyNotifyData *data = user_data;
49 data->timed_out = TRUE;
50 g_main_loop_quit (data->loop);
51 return TRUE;
52 }
53
54 gboolean
_g_assert_property_notify_run(gpointer object,const gchar * property_name)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 (g_main_context_get_thread_default (), FALSE);
64 data.timed_out = FALSE;
65 s = g_strdup_printf ("notify::%s", property_name);
66 handler_id = g_signal_connect (object,
67 s,
68 G_CALLBACK (on_property_notify),
69 &data);
70 g_free (s);
71 timeout_id = g_timeout_add_seconds (30,
72 on_property_notify_timeout,
73 &data);
74 g_main_loop_run (data.loop);
75 g_signal_handler_disconnect (object, handler_id);
76 g_source_remove (timeout_id);
77 g_main_loop_unref (data.loop);
78
79 return data.timed_out;
80 }
81
82 static gboolean
_give_up(gpointer data)83 _give_up (gpointer data)
84 {
85 g_error ("%s", (const gchar *) data);
86 g_return_val_if_reached (TRUE);
87 }
88
89 void
ensure_gdbus_testserver_up(void)90 ensure_gdbus_testserver_up (void)
91 {
92 guint id;
93 gchar *name_owner;
94 GDBusConnection *connection;
95 GDBusProxy *proxy;
96 GError *error = NULL;
97
98 connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
99 NULL,
100 &error);
101
102 g_assert_no_error (error);
103 error = NULL;
104
105 proxy = g_dbus_proxy_new_sync (connection,
106 G_DBUS_PROXY_FLAGS_NONE,
107 NULL, /* GDBusInterfaceInfo */
108 "com.example.TestService", /* name */
109 "/com/example/TestObject", /* object path */
110 "com.example.Frob", /* interface */
111 NULL, /* GCancellable */
112 &error);
113 g_assert_no_error (error);
114
115 id = g_timeout_add_seconds (60, _give_up,
116 "waited more than ~ 60s for gdbus-testserver to take its bus name");
117
118 while (TRUE)
119 {
120 name_owner = g_dbus_proxy_get_name_owner (proxy);
121
122 if (name_owner != NULL)
123 break;
124
125 g_main_context_iteration (NULL, TRUE);
126 }
127
128 g_source_remove (id);
129 g_free (name_owner);
130 g_object_unref (proxy);
131 g_object_unref (connection);
132 }
133
134 /* ---------------------------------------------------------------------------------------------------- */
135
136 typedef struct
137 {
138 GMainLoop *loop;
139 gboolean timed_out;
140 } SignalReceivedData;
141
142 static void
on_signal_received(gpointer user_data)143 on_signal_received (gpointer user_data)
144 {
145 SignalReceivedData *data = user_data;
146 g_main_loop_quit (data->loop);
147 }
148
149 static gboolean
on_signal_received_timeout(gpointer user_data)150 on_signal_received_timeout (gpointer user_data)
151 {
152 SignalReceivedData *data = user_data;
153 data->timed_out = TRUE;
154 g_main_loop_quit (data->loop);
155 return TRUE;
156 }
157
158 gboolean
_g_assert_signal_received_run(gpointer object,const gchar * signal_name)159 _g_assert_signal_received_run (gpointer object,
160 const gchar *signal_name)
161 {
162 gulong handler_id;
163 guint timeout_id;
164 SignalReceivedData data;
165
166 data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
167 data.timed_out = FALSE;
168 handler_id = g_signal_connect_swapped (object,
169 signal_name,
170 G_CALLBACK (on_signal_received),
171 &data);
172 timeout_id = g_timeout_add_seconds (30,
173 on_signal_received_timeout,
174 &data);
175 g_main_loop_run (data.loop);
176 g_signal_handler_disconnect (object, handler_id);
177 g_source_remove (timeout_id);
178 g_main_loop_unref (data.loop);
179
180 return data.timed_out;
181 }
182
183 /* ---------------------------------------------------------------------------------------------------- */
184
185 GDBusConnection *
_g_bus_get_priv(GBusType bus_type,GCancellable * cancellable,GError ** error)186 _g_bus_get_priv (GBusType bus_type,
187 GCancellable *cancellable,
188 GError **error)
189 {
190 gchar *address;
191 GDBusConnection *ret;
192
193 ret = NULL;
194
195 address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
196 if (address == NULL)
197 goto out;
198
199 ret = g_dbus_connection_new_for_address_sync (address,
200 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
201 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
202 NULL, /* GDBusAuthObserver */
203 cancellable,
204 error);
205 g_free (address);
206
207 out:
208 return ret;
209 }
210
211 /* ---------------------------------------------------------------------------------------------------- */
212