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 | #include <unistd.h> |
23 | #include <string.h> |
24 | |
25 | #include "gdbus-tests.h" |
26 | |
27 | /* all tests rely on a shared mainloop */ |
28 | static GMainLoop *loop = NULL; |
29 | |
30 | /* ---------------------------------------------------------------------------------------------------- */ |
31 | |
32 | static void |
33 | proxy_new_cb (GObject *source_object, |
34 | GAsyncResult *res, |
35 | gpointer user_data) |
36 | { |
37 | GDBusProxy **ret = user_data; |
38 | GError *error; |
39 | |
40 | error = NULL; |
41 | *ret = g_dbus_proxy_new_finish (res, error: &error); |
42 | g_assert_no_error (error); |
43 | g_assert (ret != NULL); |
44 | |
45 | g_main_loop_quit (loop); |
46 | } |
47 | |
48 | static void |
49 | test_proxy_well_known_name (void) |
50 | { |
51 | GDBusProxy *p; |
52 | GDBusProxy *p2; |
53 | GDBusProxy *ap; |
54 | GDBusProxy *ap2; |
55 | GDBusConnection *c; |
56 | GError *error; |
57 | gchar *name_owner; |
58 | gchar **property_names; |
59 | GVariant *variant; |
60 | GVariant *result; |
61 | |
62 | session_bus_up (); |
63 | |
64 | error = NULL; |
65 | c = g_bus_get_sync (bus_type: G_BUS_TYPE_SESSION, NULL, error: &error); |
66 | g_assert_no_error (error); |
67 | g_assert (c != NULL); |
68 | |
69 | error = NULL; |
70 | p = g_dbus_proxy_new_sync (connection: c, |
71 | flags: G_DBUS_PROXY_FLAGS_NONE, |
72 | NULL, /* GDBusInterfaceInfo* */ |
73 | name: "com.example.TestService" , /* name */ |
74 | object_path: "/com/example/TestObject" , /* object path */ |
75 | interface_name: "com.example.Frob" , /* interface name */ |
76 | NULL, /* GCancellable */ |
77 | error: &error); |
78 | g_assert_no_error (error); |
79 | |
80 | /* we shouldn't have a name owner nor any cached properties */ |
81 | g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL); |
82 | g_assert (g_dbus_proxy_get_cached_property_names (p) == NULL); |
83 | |
84 | /* also for async: we shouldn't have a name owner nor any cached properties */ |
85 | g_dbus_proxy_new (connection: c, |
86 | flags: G_DBUS_PROXY_FLAGS_NONE, |
87 | NULL, /* GDBusInterfaceInfo* */ |
88 | name: "com.example.TestService" , /* name */ |
89 | object_path: "/com/example/TestObject" , /* object path */ |
90 | interface_name: "com.example.Frob" , /* interface name */ |
91 | NULL, /* GCancellable */ |
92 | callback: (GAsyncReadyCallback) proxy_new_cb, |
93 | user_data: &ap); |
94 | g_main_loop_run (loop); |
95 | g_assert_cmpstr (g_dbus_proxy_get_name_owner (ap), ==, NULL); |
96 | g_assert (g_dbus_proxy_get_cached_property_names (ap) == NULL); |
97 | |
98 | /* this is safe; testserver will exit once the bus goes away */ |
99 | g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver" , NULL), NULL)); |
100 | |
101 | /* check that we get the notify::g-name-owner signal */ |
102 | _g_assert_property_notify (p, "g-name-owner" ); |
103 | |
104 | /* Now we should have a name owner as well as properties */ |
105 | name_owner = g_dbus_proxy_get_name_owner (proxy: p); |
106 | property_names = g_dbus_proxy_get_cached_property_names (proxy: p); |
107 | g_assert (g_dbus_is_unique_name (name_owner)); |
108 | g_assert (property_names != NULL && g_strv_length (property_names) > 0); |
109 | g_free (mem: name_owner); |
110 | g_strfreev (str_array: property_names); |
111 | |
112 | /* if we create another proxy with the service being available, check that |
113 | * it has a name owner and properties |
114 | */ |
115 | error = NULL; |
116 | p2 = g_dbus_proxy_new_sync (connection: c, |
117 | flags: G_DBUS_PROXY_FLAGS_NONE, |
118 | NULL, /* GDBusInterfaceInfo* */ |
119 | name: "com.example.TestService" , /* name */ |
120 | object_path: "/com/example/TestObject" , /* object path */ |
121 | interface_name: "com.example.Frob" , /* interface name */ |
122 | NULL, /* GCancellable */ |
123 | error: &error); |
124 | g_assert_no_error (error); |
125 | name_owner = g_dbus_proxy_get_name_owner (proxy: p2); |
126 | property_names = g_dbus_proxy_get_cached_property_names (proxy: p2); |
127 | g_assert (g_dbus_is_unique_name (name_owner)); |
128 | g_assert (property_names != NULL && g_strv_length (property_names) > 0); |
129 | g_free (mem: name_owner); |
130 | g_strfreev (str_array: property_names); |
131 | |
132 | /* also for async: we should have a name owner and cached properties */ |
133 | g_dbus_proxy_new (connection: c, |
134 | flags: G_DBUS_PROXY_FLAGS_NONE, |
135 | NULL, /* GDBusInterfaceInfo* */ |
136 | name: "com.example.TestService" , /* name */ |
137 | object_path: "/com/example/TestObject" , /* object path */ |
138 | interface_name: "com.example.Frob" , /* interface name */ |
139 | NULL, /* GCancellable */ |
140 | callback: (GAsyncReadyCallback) proxy_new_cb, |
141 | user_data: &ap2); |
142 | g_main_loop_run (loop); |
143 | name_owner = g_dbus_proxy_get_name_owner (proxy: ap2); |
144 | property_names = g_dbus_proxy_get_cached_property_names (proxy: ap2); |
145 | g_assert (g_dbus_is_unique_name (name_owner)); |
146 | g_assert (property_names != NULL && g_strv_length (property_names) > 0); |
147 | g_free (mem: name_owner); |
148 | g_strfreev (str_array: property_names); |
149 | |
150 | /* Check property value is the initial value */ |
151 | variant = g_dbus_proxy_get_cached_property (proxy: p, property_name: "y" ); |
152 | g_assert (variant != NULL); |
153 | g_assert_cmpint (g_variant_get_byte (variant), ==, 1); |
154 | g_variant_unref (value: variant); |
155 | variant = g_dbus_proxy_get_cached_property (proxy: p2, property_name: "y" ); |
156 | g_assert (variant != NULL); |
157 | g_assert_cmpint (g_variant_get_byte (variant), ==, 1); |
158 | g_variant_unref (value: variant); |
159 | variant = g_dbus_proxy_get_cached_property (proxy: ap, property_name: "y" ); |
160 | g_assert (variant != NULL); |
161 | g_assert_cmpint (g_variant_get_byte (variant), ==, 1); |
162 | g_variant_unref (value: variant); |
163 | variant = g_dbus_proxy_get_cached_property (proxy: ap2, property_name: "y" ); |
164 | g_assert (variant != NULL); |
165 | g_assert_cmpint (g_variant_get_byte (variant), ==, 1); |
166 | g_variant_unref (value: variant); |
167 | |
168 | /* Check that properties are updated on both p and p2 */ |
169 | result = g_dbus_proxy_call_sync (proxy: p, |
170 | method_name: "FrobSetProperty" , |
171 | parameters: g_variant_new (format_string: "(sv)" , |
172 | "y" , |
173 | g_variant_new_byte (value: 42)), |
174 | flags: G_DBUS_CALL_FLAGS_NONE, |
175 | timeout_msec: -1, |
176 | NULL, |
177 | error: &error); |
178 | g_assert_no_error (error); |
179 | g_assert (result != NULL); |
180 | g_assert_cmpstr (g_variant_get_type_string (result), ==, "()" ); |
181 | g_variant_unref (value: result); |
182 | _g_assert_signal_received (p, "g-properties-changed" ); |
183 | variant = g_dbus_proxy_get_cached_property (proxy: p, property_name: "y" ); |
184 | g_assert (variant != NULL); |
185 | g_assert_cmpint (g_variant_get_byte (variant), ==, 42); |
186 | g_variant_unref (value: variant); |
187 | variant = g_dbus_proxy_get_cached_property (proxy: p2, property_name: "y" ); |
188 | g_assert (variant != NULL); |
189 | g_assert_cmpint (g_variant_get_byte (variant), ==, 42); |
190 | g_variant_unref (value: variant); |
191 | variant = g_dbus_proxy_get_cached_property (proxy: ap, property_name: "y" ); |
192 | g_assert (variant != NULL); |
193 | g_assert_cmpint (g_variant_get_byte (variant), ==, 42); |
194 | g_variant_unref (value: variant); |
195 | variant = g_dbus_proxy_get_cached_property (proxy: ap2, property_name: "y" ); |
196 | g_assert (variant != NULL); |
197 | g_assert_cmpint (g_variant_get_byte (variant), ==, 42); |
198 | g_variant_unref (value: variant); |
199 | |
200 | /* Nuke the service and check that we get the signal and then don't |
201 | * have a name owner nor any cached properties |
202 | */ |
203 | result = g_dbus_proxy_call_sync (proxy: p, |
204 | method_name: "Quit" , |
205 | NULL, |
206 | flags: G_DBUS_CALL_FLAGS_NONE, |
207 | timeout_msec: -1, |
208 | NULL, |
209 | error: &error); |
210 | g_assert_no_error (error); |
211 | g_assert (result != NULL); |
212 | g_assert_cmpstr (g_variant_get_type_string (result), ==, "()" ); |
213 | g_variant_unref (value: result); |
214 | /* and wait... */ |
215 | _g_assert_property_notify (p, "g-name-owner" ); |
216 | /* now we shouldn't have a name owner nor any cached properties */ |
217 | g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL); |
218 | g_assert (g_dbus_proxy_get_cached_property_names (p) == NULL); |
219 | g_assert (g_dbus_proxy_get_cached_property (p, "y" ) == NULL); |
220 | |
221 | /* now bring back the server and wait for the proxy to be updated.. now |
222 | * the 'y' property should be back at 1... |
223 | */ |
224 | /* this is safe; testserver will exit once the bus goes away */ |
225 | g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver" , NULL), NULL)); |
226 | |
227 | /* check that we get the notify::g-name-owner signal */ |
228 | _g_assert_property_notify (p, "g-name-owner" ); |
229 | /* Now we should have a name owner as well as properties */ |
230 | name_owner = g_dbus_proxy_get_name_owner (proxy: p); |
231 | property_names = g_dbus_proxy_get_cached_property_names (proxy: p); |
232 | g_assert (g_dbus_is_unique_name (name_owner)); |
233 | g_assert (property_names != NULL && g_strv_length (property_names) > 0); |
234 | g_free (mem: name_owner); |
235 | g_strfreev (str_array: property_names); |
236 | /* and finally check the 'y' property */ |
237 | variant = g_dbus_proxy_get_cached_property (proxy: p, property_name: "y" ); |
238 | g_assert (variant != NULL); |
239 | g_assert_cmpint (g_variant_get_byte (variant), ==, 1); |
240 | g_variant_unref (value: variant); |
241 | |
242 | g_object_unref (object: p2); |
243 | g_object_unref (object: p); |
244 | g_object_unref (object: ap2); |
245 | g_object_unref (object: ap); |
246 | |
247 | g_object_unref (object: c); |
248 | |
249 | /* tear down bus */ |
250 | session_bus_down (); |
251 | } |
252 | |
253 | /* ---------------------------------------------------------------------------------------------------- */ |
254 | |
255 | int |
256 | main (int argc, |
257 | char *argv[]) |
258 | { |
259 | gint ret; |
260 | |
261 | g_test_init (argc: &argc, argv: &argv, NULL); |
262 | |
263 | /* all the tests rely on a shared main loop */ |
264 | loop = g_main_loop_new (NULL, FALSE); |
265 | |
266 | g_test_dbus_unset (); |
267 | |
268 | g_test_add_func (testpath: "/gdbus/proxy-well-known-name" , test_func: test_proxy_well_known_name); |
269 | |
270 | ret = g_test_run(); |
271 | return ret; |
272 | } |
273 | |