Add some more cases to the app-id unit tests
[glib.git] / gio / tests / gdbus-names.c
blob90c9eb3a7c4ee61d4ed4c566338b57017796549d
1 /* GLib testing framework examples and tests
3 * Copyright (C) 2008-2010 Red Hat, Inc.
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 of the License, or (at your option) any later version.
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.
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/>.
18 * Author: David Zeuthen <davidz@redhat.com>
21 #include <gio/gio.h>
22 #include <unistd.h>
24 #include "gdbus-tests.h"
26 /* all tests rely on a shared mainloop */
27 static GMainLoop *loop;
29 /* ---------------------------------------------------------------------------------------------------- */
30 /* Test that g_bus_own_name() works correctly */
31 /* ---------------------------------------------------------------------------------------------------- */
33 typedef struct
35 GMainLoop *loop;
36 gboolean expect_null_connection;
37 guint num_bus_acquired;
38 guint num_acquired;
39 guint num_lost;
40 guint num_free_func;
41 } OwnNameData;
43 static void
44 own_name_data_free_func (OwnNameData *data)
46 data->num_free_func++;
47 g_main_loop_quit (loop);
50 static void
51 bus_acquired_handler (GDBusConnection *connection,
52 const gchar *name,
53 gpointer user_data)
55 OwnNameData *data = user_data;
56 g_dbus_connection_set_exit_on_close (connection, FALSE);
57 data->num_bus_acquired += 1;
58 g_main_loop_quit (loop);
61 static void
62 name_acquired_handler (GDBusConnection *connection,
63 const gchar *name,
64 gpointer user_data)
66 OwnNameData *data = user_data;
67 data->num_acquired += 1;
68 g_main_loop_quit (loop);
71 static void
72 name_lost_handler (GDBusConnection *connection,
73 const gchar *name,
74 gpointer user_data)
76 OwnNameData *data = user_data;
77 if (data->expect_null_connection)
79 g_assert (connection == NULL);
81 else
83 g_assert (connection != NULL);
84 g_dbus_connection_set_exit_on_close (connection, FALSE);
86 data->num_lost += 1;
87 g_main_loop_quit (loop);
90 static void
91 test_bus_own_name (void)
93 guint id;
94 guint id2;
95 OwnNameData data;
96 OwnNameData data2;
97 const gchar *name;
98 GDBusConnection *c;
99 GError *error;
100 gboolean name_has_owner_reply;
101 GDBusConnection *c2;
102 GVariant *result;
104 error = NULL;
105 name = "org.gtk.GDBus.Name1";
108 * First check that name_lost_handler() is invoked if there is no bus.
110 * Also make sure name_lost_handler() isn't invoked when unowning the name.
112 data.num_bus_acquired = 0;
113 data.num_free_func = 0;
114 data.num_acquired = 0;
115 data.num_lost = 0;
116 data.expect_null_connection = TRUE;
117 id = g_bus_own_name (G_BUS_TYPE_SESSION,
118 name,
119 G_BUS_NAME_OWNER_FLAGS_NONE,
120 bus_acquired_handler,
121 name_acquired_handler,
122 name_lost_handler,
123 &data,
124 (GDestroyNotify) own_name_data_free_func);
125 g_assert_cmpint (data.num_bus_acquired, ==, 0);
126 g_assert_cmpint (data.num_acquired, ==, 0);
127 g_assert_cmpint (data.num_lost, ==, 0);
128 g_main_loop_run (loop);
129 g_assert_cmpint (data.num_bus_acquired, ==, 0);
130 g_assert_cmpint (data.num_acquired, ==, 0);
131 g_assert_cmpint (data.num_lost, ==, 1);
132 g_bus_unown_name (id);
133 g_assert_cmpint (data.num_acquired, ==, 0);
134 g_assert_cmpint (data.num_lost, ==, 1);
135 g_assert_cmpint (data.num_free_func, ==, 1);
138 * Bring up a bus, then own a name and check bus_acquired_handler() then name_acquired_handler() is invoked.
140 session_bus_up ();
141 data.num_bus_acquired = 0;
142 data.num_acquired = 0;
143 data.num_lost = 0;
144 data.expect_null_connection = FALSE;
145 id = g_bus_own_name (G_BUS_TYPE_SESSION,
146 name,
147 G_BUS_NAME_OWNER_FLAGS_NONE,
148 bus_acquired_handler,
149 name_acquired_handler,
150 name_lost_handler,
151 &data,
152 (GDestroyNotify) own_name_data_free_func);
153 g_assert_cmpint (data.num_bus_acquired, ==, 0);
154 g_assert_cmpint (data.num_acquired, ==, 0);
155 g_assert_cmpint (data.num_lost, ==, 0);
156 g_main_loop_run (loop);
157 g_assert_cmpint (data.num_bus_acquired, ==, 1);
158 g_assert_cmpint (data.num_acquired, ==, 0);
159 g_assert_cmpint (data.num_lost, ==, 0);
160 g_main_loop_run (loop);
161 g_assert_cmpint (data.num_bus_acquired, ==, 1);
162 g_assert_cmpint (data.num_acquired, ==, 1);
163 g_assert_cmpint (data.num_lost, ==, 0);
166 * Check that the name was actually acquired.
168 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
169 g_assert (c != NULL);
170 g_assert (!g_dbus_connection_is_closed (c));
171 result = g_dbus_connection_call_sync (c,
172 "org.freedesktop.DBus", /* bus name */
173 "/org/freedesktop/DBus", /* object path */
174 "org.freedesktop.DBus", /* interface name */
175 "NameHasOwner", /* method name */
176 g_variant_new ("(s)", name),
177 G_VARIANT_TYPE ("(b)"),
178 G_DBUS_CALL_FLAGS_NONE,
180 NULL,
181 &error);
182 g_assert_no_error (error);
183 g_assert (result != NULL);
184 g_variant_get (result, "(b)", &name_has_owner_reply);
185 g_assert (name_has_owner_reply);
186 g_variant_unref (result);
189 * Stop owning the name - this should invoke our free func
191 g_bus_unown_name (id);
192 g_assert_cmpint (data.num_free_func, ==, 2);
195 * Check that the name was actually released.
197 result = g_dbus_connection_call_sync (c,
198 "org.freedesktop.DBus", /* bus name */
199 "/org/freedesktop/DBus", /* object path */
200 "org.freedesktop.DBus", /* interface name */
201 "NameHasOwner", /* method name */
202 g_variant_new ("(s)", name),
203 G_VARIANT_TYPE ("(b)"),
204 G_DBUS_CALL_FLAGS_NONE,
206 NULL,
207 &error);
208 g_assert_no_error (error);
209 g_assert (result != NULL);
210 g_variant_get (result, "(b)", &name_has_owner_reply);
211 g_assert (!name_has_owner_reply);
212 g_variant_unref (result);
214 /* Now try owning the name and then immediately decide to unown the name */
215 g_assert_cmpint (data.num_bus_acquired, ==, 1);
216 g_assert_cmpint (data.num_acquired, ==, 1);
217 g_assert_cmpint (data.num_lost, ==, 0);
218 g_assert_cmpint (data.num_free_func, ==, 2);
219 id = g_bus_own_name (G_BUS_TYPE_SESSION,
220 name,
221 G_BUS_NAME_OWNER_FLAGS_NONE,
222 bus_acquired_handler,
223 name_acquired_handler,
224 name_lost_handler,
225 &data,
226 (GDestroyNotify) own_name_data_free_func);
227 g_assert_cmpint (data.num_bus_acquired, ==, 1);
228 g_assert_cmpint (data.num_acquired, ==, 1);
229 g_assert_cmpint (data.num_lost, ==, 0);
230 g_assert_cmpint (data.num_free_func, ==, 2);
231 g_bus_unown_name (id);
232 g_assert_cmpint (data.num_bus_acquired, ==, 1);
233 g_assert_cmpint (data.num_acquired, ==, 1);
234 g_assert_cmpint (data.num_lost, ==, 0);
235 g_assert_cmpint (data.num_free_func, ==, 2);
236 g_main_loop_run (loop); /* the GDestroyNotify is called in idle because the bus is acquired in idle */
237 g_assert_cmpint (data.num_free_func, ==, 3);
240 * Own the name again.
242 data.num_bus_acquired = 0;
243 data.num_acquired = 0;
244 data.num_lost = 0;
245 data.expect_null_connection = FALSE;
246 id = g_bus_own_name_with_closures (G_BUS_TYPE_SESSION,
247 name,
248 G_BUS_NAME_OWNER_FLAGS_NONE,
249 g_cclosure_new (G_CALLBACK (bus_acquired_handler),
250 &data,
251 NULL),
252 g_cclosure_new (G_CALLBACK (name_acquired_handler),
253 &data,
254 NULL),
255 g_cclosure_new (G_CALLBACK (name_lost_handler),
256 &data,
257 (GClosureNotify) own_name_data_free_func));
258 g_assert_cmpint (data.num_bus_acquired, ==, 0);
259 g_assert_cmpint (data.num_acquired, ==, 0);
260 g_assert_cmpint (data.num_lost, ==, 0);
261 g_main_loop_run (loop);
262 g_assert_cmpint (data.num_bus_acquired, ==, 1);
263 g_assert_cmpint (data.num_acquired, ==, 0);
264 g_assert_cmpint (data.num_lost, ==, 0);
265 g_main_loop_run (loop);
266 g_assert_cmpint (data.num_bus_acquired, ==, 1);
267 g_assert_cmpint (data.num_acquired, ==, 1);
268 g_assert_cmpint (data.num_lost, ==, 0);
271 * Try owning the name with another object on the same connection - this should
272 * fail because we already own the name.
274 data2.num_free_func = 0;
275 data2.num_bus_acquired = 0;
276 data2.num_acquired = 0;
277 data2.num_lost = 0;
278 data2.expect_null_connection = FALSE;
279 id2 = g_bus_own_name (G_BUS_TYPE_SESSION,
280 name,
281 G_BUS_NAME_OWNER_FLAGS_NONE,
282 bus_acquired_handler,
283 name_acquired_handler,
284 name_lost_handler,
285 &data2,
286 (GDestroyNotify) own_name_data_free_func);
287 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
288 g_assert_cmpint (data2.num_acquired, ==, 0);
289 g_assert_cmpint (data2.num_lost, ==, 0);
290 g_main_loop_run (loop);
291 g_assert_cmpint (data2.num_bus_acquired, ==, 1);
292 g_assert_cmpint (data2.num_acquired, ==, 0);
293 g_assert_cmpint (data2.num_lost, ==, 0);
294 g_main_loop_run (loop);
295 g_assert_cmpint (data2.num_bus_acquired, ==, 1);
296 g_assert_cmpint (data2.num_acquired, ==, 0);
297 g_assert_cmpint (data2.num_lost, ==, 1);
298 g_bus_unown_name (id2);
299 g_assert_cmpint (data2.num_bus_acquired, ==, 1);
300 g_assert_cmpint (data2.num_acquired, ==, 0);
301 g_assert_cmpint (data2.num_lost, ==, 1);
302 g_assert_cmpint (data2.num_free_func, ==, 1);
305 * Create a secondary (e.g. private) connection and try owning the name on that
306 * connection. This should fail both with and without _REPLACE because we
307 * didn't specify ALLOW_REPLACEMENT.
309 c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
310 g_assert (c2 != NULL);
311 g_assert (!g_dbus_connection_is_closed (c2));
312 /* first without _REPLACE */
313 data2.num_bus_acquired = 0;
314 data2.num_acquired = 0;
315 data2.num_lost = 0;
316 data2.expect_null_connection = FALSE;
317 data2.num_free_func = 0;
318 id2 = g_bus_own_name_on_connection (c2,
319 name,
320 G_BUS_NAME_OWNER_FLAGS_NONE,
321 name_acquired_handler,
322 name_lost_handler,
323 &data2,
324 (GDestroyNotify) own_name_data_free_func);
325 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
326 g_assert_cmpint (data2.num_acquired, ==, 0);
327 g_assert_cmpint (data2.num_lost, ==, 0);
328 g_main_loop_run (loop);
329 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
330 g_assert_cmpint (data2.num_acquired, ==, 0);
331 g_assert_cmpint (data2.num_lost, ==, 1);
332 g_bus_unown_name (id2);
333 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
334 g_assert_cmpint (data2.num_acquired, ==, 0);
335 g_assert_cmpint (data2.num_lost, ==, 1);
336 g_assert_cmpint (data2.num_free_func, ==, 1);
337 /* then with _REPLACE */
338 data2.num_bus_acquired = 0;
339 data2.num_acquired = 0;
340 data2.num_lost = 0;
341 data2.expect_null_connection = FALSE;
342 data2.num_free_func = 0;
343 id2 = g_bus_own_name_on_connection (c2,
344 name,
345 G_BUS_NAME_OWNER_FLAGS_REPLACE,
346 name_acquired_handler,
347 name_lost_handler,
348 &data2,
349 (GDestroyNotify) own_name_data_free_func);
350 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
351 g_assert_cmpint (data2.num_acquired, ==, 0);
352 g_assert_cmpint (data2.num_lost, ==, 0);
353 g_main_loop_run (loop);
354 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
355 g_assert_cmpint (data2.num_acquired, ==, 0);
356 g_assert_cmpint (data2.num_lost, ==, 1);
357 g_bus_unown_name (id2);
358 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
359 g_assert_cmpint (data2.num_acquired, ==, 0);
360 g_assert_cmpint (data2.num_lost, ==, 1);
361 g_assert_cmpint (data2.num_free_func, ==, 1);
364 * Stop owning the name and grab it again with _ALLOW_REPLACEMENT.
366 data.expect_null_connection = FALSE;
367 g_bus_unown_name (id);
368 g_assert_cmpint (data.num_bus_acquired, ==, 1);
369 g_assert_cmpint (data.num_acquired, ==, 1);
370 g_assert_cmpint (data.num_free_func, ==, 4);
371 /* grab it again */
372 data.num_bus_acquired = 0;
373 data.num_acquired = 0;
374 data.num_lost = 0;
375 data.expect_null_connection = FALSE;
376 id = g_bus_own_name (G_BUS_TYPE_SESSION,
377 name,
378 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
379 bus_acquired_handler,
380 name_acquired_handler,
381 name_lost_handler,
382 &data,
383 (GDestroyNotify) own_name_data_free_func);
384 g_assert_cmpint (data.num_bus_acquired, ==, 0);
385 g_assert_cmpint (data.num_acquired, ==, 0);
386 g_assert_cmpint (data.num_lost, ==, 0);
387 g_main_loop_run (loop);
388 g_assert_cmpint (data.num_bus_acquired, ==, 1);
389 g_assert_cmpint (data.num_acquired, ==, 0);
390 g_assert_cmpint (data.num_lost, ==, 0);
391 g_main_loop_run (loop);
392 g_assert_cmpint (data.num_bus_acquired, ==, 1);
393 g_assert_cmpint (data.num_acquired, ==, 1);
394 g_assert_cmpint (data.num_lost, ==, 0);
397 * Now try to grab the name from the secondary connection.
400 /* first without _REPLACE - this won't make us acquire the name */
401 data2.num_bus_acquired = 0;
402 data2.num_acquired = 0;
403 data2.num_lost = 0;
404 data2.expect_null_connection = FALSE;
405 data2.num_free_func = 0;
406 id2 = g_bus_own_name_on_connection (c2,
407 name,
408 G_BUS_NAME_OWNER_FLAGS_NONE,
409 name_acquired_handler,
410 name_lost_handler,
411 &data2,
412 (GDestroyNotify) own_name_data_free_func);
413 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
414 g_assert_cmpint (data2.num_acquired, ==, 0);
415 g_assert_cmpint (data2.num_lost, ==, 0);
416 g_main_loop_run (loop);
417 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
418 g_assert_cmpint (data2.num_acquired, ==, 0);
419 g_assert_cmpint (data2.num_lost, ==, 1);
420 g_bus_unown_name (id2);
421 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
422 g_assert_cmpint (data2.num_acquired, ==, 0);
423 g_assert_cmpint (data2.num_lost, ==, 1);
424 g_assert_cmpint (data2.num_free_func, ==, 1);
425 /* then with _REPLACE - here we should acquire the name - e.g. owner should lose it
426 * and owner2 should acquire it */
427 data2.num_bus_acquired = 0;
428 data2.num_acquired = 0;
429 data2.num_lost = 0;
430 data2.expect_null_connection = FALSE;
431 data2.num_free_func = 0;
432 id2 = g_bus_own_name_on_connection (c2,
433 name,
434 G_BUS_NAME_OWNER_FLAGS_REPLACE,
435 name_acquired_handler,
436 name_lost_handler,
437 &data2,
438 (GDestroyNotify) own_name_data_free_func);
439 g_assert_cmpint (data.num_acquired, ==, 1);
440 g_assert_cmpint (data.num_lost, ==, 0);
441 g_assert_cmpint (data2.num_acquired, ==, 0);
442 g_assert_cmpint (data2.num_lost, ==, 0);
443 /* wait for handlers for both owner and owner2 to fire */
444 while (data.num_lost == 0 || data2.num_acquired == 0)
445 g_main_loop_run (loop);
446 g_assert_cmpint (data.num_acquired, ==, 1);
447 g_assert_cmpint (data.num_lost, ==, 1);
448 g_assert_cmpint (data2.num_acquired, ==, 1);
449 g_assert_cmpint (data2.num_lost, ==, 0);
450 g_assert_cmpint (data2.num_bus_acquired, ==, 0);
451 /* ok, make owner2 release the name - then wait for owner to automagically reacquire it */
452 g_bus_unown_name (id2);
453 g_assert_cmpint (data2.num_free_func, ==, 1);
454 g_main_loop_run (loop);
455 g_assert_cmpint (data.num_acquired, ==, 2);
456 g_assert_cmpint (data.num_lost, ==, 1);
459 * Finally, nuke the bus and check name_lost_handler() is invoked.
462 data.expect_null_connection = TRUE;
463 session_bus_stop ();
464 while (data.num_lost != 2)
465 g_main_loop_run (loop);
466 g_assert_cmpint (data.num_acquired, ==, 2);
467 g_assert_cmpint (data.num_lost, ==, 2);
468 g_bus_unown_name (id);
469 g_assert_cmpint (data.num_free_func, ==, 5);
471 g_object_unref (c);
472 g_object_unref (c2);
474 session_bus_down ();
476 /* See https://bugzilla.gnome.org/show_bug.cgi?id=711807 */
477 g_usleep (1000000);
480 /* ---------------------------------------------------------------------------------------------------- */
481 /* Test that g_bus_watch_name() works correctly */
482 /* ---------------------------------------------------------------------------------------------------- */
484 typedef struct
486 gboolean expect_null_connection;
487 guint num_acquired;
488 guint num_lost;
489 guint num_appeared;
490 guint num_vanished;
491 guint num_free_func;
492 } WatchNameData;
494 static void
495 watch_name_data_free_func (WatchNameData *data)
497 data->num_free_func++;
498 g_main_loop_quit (loop);
501 static void
502 w_bus_acquired_handler (GDBusConnection *connection,
503 const gchar *name,
504 gpointer user_data)
508 static void
509 w_name_acquired_handler (GDBusConnection *connection,
510 const gchar *name,
511 gpointer user_data)
513 WatchNameData *data = user_data;
514 data->num_acquired += 1;
515 g_main_loop_quit (loop);
518 static void
519 w_name_lost_handler (GDBusConnection *connection,
520 const gchar *name,
521 gpointer user_data)
523 WatchNameData *data = user_data;
524 data->num_lost += 1;
525 g_main_loop_quit (loop);
528 static void
529 name_appeared_handler (GDBusConnection *connection,
530 const gchar *name,
531 const gchar *name_owner,
532 gpointer user_data)
534 WatchNameData *data = user_data;
535 if (data->expect_null_connection)
537 g_assert (connection == NULL);
539 else
541 g_assert (connection != NULL);
542 g_dbus_connection_set_exit_on_close (connection, FALSE);
544 data->num_appeared += 1;
545 g_main_loop_quit (loop);
548 static void
549 name_vanished_handler (GDBusConnection *connection,
550 const gchar *name,
551 gpointer user_data)
553 WatchNameData *data = user_data;
554 if (data->expect_null_connection)
556 g_assert (connection == NULL);
558 else
560 g_assert (connection != NULL);
561 g_dbus_connection_set_exit_on_close (connection, FALSE);
563 data->num_vanished += 1;
564 g_main_loop_quit (loop);
567 static void
568 test_bus_watch_name (void)
570 WatchNameData data;
571 guint id;
572 guint owner_id;
573 GDBusConnection *connection;
576 * First check that name_vanished_handler() is invoked if there is no bus.
578 * Also make sure name_vanished_handler() isn't invoked when unwatching the name.
580 data.num_free_func = 0;
581 data.num_appeared = 0;
582 data.num_vanished = 0;
583 data.expect_null_connection = TRUE;
584 id = g_bus_watch_name (G_BUS_TYPE_SESSION,
585 "org.gtk.GDBus.Name1",
586 G_BUS_NAME_WATCHER_FLAGS_NONE,
587 name_appeared_handler,
588 name_vanished_handler,
589 &data,
590 (GDestroyNotify) watch_name_data_free_func);
591 g_assert_cmpint (data.num_appeared, ==, 0);
592 g_assert_cmpint (data.num_vanished, ==, 0);
593 g_main_loop_run (loop);
594 g_assert_cmpint (data.num_appeared, ==, 0);
595 g_assert_cmpint (data.num_vanished, ==, 1);
596 g_bus_unwatch_name (id);
597 g_assert_cmpint (data.num_appeared, ==, 0);
598 g_assert_cmpint (data.num_vanished, ==, 1);
599 g_assert_cmpint (data.num_free_func, ==, 1);
602 * Now bring up a bus, own a name, and then start watching it.
604 session_bus_up ();
605 /* own the name */
606 data.num_free_func = 0;
607 data.num_acquired = 0;
608 data.num_lost = 0;
609 data.expect_null_connection = FALSE;
610 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
611 "org.gtk.GDBus.Name1",
612 G_BUS_NAME_OWNER_FLAGS_NONE,
613 w_bus_acquired_handler,
614 w_name_acquired_handler,
615 w_name_lost_handler,
616 &data,
617 (GDestroyNotify) watch_name_data_free_func);
618 g_main_loop_run (loop);
619 g_assert_cmpint (data.num_acquired, ==, 1);
620 g_assert_cmpint (data.num_lost, ==, 0);
622 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
623 g_assert (connection != NULL);
625 /* now watch the name */
626 data.num_appeared = 0;
627 data.num_vanished = 0;
628 id = g_bus_watch_name_on_connection (connection,
629 "org.gtk.GDBus.Name1",
630 G_BUS_NAME_WATCHER_FLAGS_NONE,
631 name_appeared_handler,
632 name_vanished_handler,
633 &data,
634 (GDestroyNotify) watch_name_data_free_func);
635 g_assert_cmpint (data.num_appeared, ==, 0);
636 g_assert_cmpint (data.num_vanished, ==, 0);
637 g_main_loop_run (loop);
638 g_assert_cmpint (data.num_appeared, ==, 1);
639 g_assert_cmpint (data.num_vanished, ==, 0);
642 * Unwatch the name.
644 g_bus_unwatch_name (id);
645 g_assert_cmpint (data.num_free_func, ==, 1);
647 g_object_unref (connection);
649 /* unown the name */
650 g_bus_unown_name (owner_id);
651 g_assert_cmpint (data.num_acquired, ==, 1);
652 g_assert_cmpint (data.num_free_func, ==, 2);
655 * Create a watcher and then make a name be owned.
657 * This should trigger name_appeared_handler() ...
659 /* watch the name */
660 data.num_appeared = 0;
661 data.num_vanished = 0;
662 data.num_free_func = 0;
663 id = g_bus_watch_name_with_closures (G_BUS_TYPE_SESSION,
664 "org.gtk.GDBus.Name1",
665 G_BUS_NAME_WATCHER_FLAGS_NONE,
666 g_cclosure_new (G_CALLBACK (name_appeared_handler),
667 &data,
668 NULL),
669 g_cclosure_new (G_CALLBACK (name_vanished_handler),
670 &data,
671 (GClosureNotify) watch_name_data_free_func));
672 g_assert_cmpint (data.num_appeared, ==, 0);
673 g_assert_cmpint (data.num_vanished, ==, 0);
674 g_main_loop_run (loop);
675 g_assert_cmpint (data.num_appeared, ==, 0);
676 g_assert_cmpint (data.num_vanished, ==, 1);
678 /* own the name */
679 data.num_acquired = 0;
680 data.num_lost = 0;
681 data.expect_null_connection = FALSE;
682 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
683 "org.gtk.GDBus.Name1",
684 G_BUS_NAME_OWNER_FLAGS_NONE,
685 w_bus_acquired_handler,
686 w_name_acquired_handler,
687 w_name_lost_handler,
688 &data,
689 (GDestroyNotify) watch_name_data_free_func);
690 while (data.num_acquired == 0 || data.num_appeared == 0)
691 g_main_loop_run (loop);
692 g_assert_cmpint (data.num_acquired, ==, 1);
693 g_assert_cmpint (data.num_lost, ==, 0);
694 g_assert_cmpint (data.num_appeared, ==, 1);
695 g_assert_cmpint (data.num_vanished, ==, 1);
698 * Nuke the bus and check that the name vanishes and is lost.
700 data.expect_null_connection = TRUE;
701 session_bus_stop ();
702 g_main_loop_run (loop);
703 g_assert_cmpint (data.num_lost, ==, 1);
704 g_assert_cmpint (data.num_vanished, ==, 2);
706 g_bus_unwatch_name (id);
707 g_assert_cmpint (data.num_free_func, ==, 1);
709 g_bus_unown_name (owner_id);
710 g_assert_cmpint (data.num_free_func, ==, 2);
712 session_bus_down ();
715 /* ---------------------------------------------------------------------------------------------------- */
717 static void
718 test_validate_names (void)
720 guint n;
721 static const struct
723 gboolean name;
724 gboolean unique;
725 gboolean interface;
726 const gchar *string;
727 } names[] = {
728 { 1, 0, 1, "valid.well_known.name"},
729 { 1, 0, 0, "valid.well-known.name"},
730 { 1, 1, 0, ":valid.unique.name"},
731 { 0, 0, 0, "invalid.5well_known.name"},
732 { 0, 0, 0, "4invalid.5well_known.name"},
733 { 1, 1, 0, ":4valid.5unique.name"},
734 { 0, 0, 0, ""},
735 { 1, 0, 1, "very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.name1"}, /* 255 */
736 { 0, 0, 0, "very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.name12"}, /* 256 - too long! */
737 { 0, 0, 0, ".starts.with.a.dot"},
738 { 0, 0, 0, "contains.invalid;.characters"},
739 { 0, 0, 0, "contains.inva/lid.characters"},
740 { 0, 0, 0, "contains.inva[lid.characters"},
741 { 0, 0, 0, "contains.inva]lid.characters"},
742 { 0, 0, 0, "contains.inva_æøå_lid.characters"},
743 { 1, 1, 0, ":1.1"},
746 for (n = 0; n < G_N_ELEMENTS (names); n++)
748 if (names[n].name)
749 g_assert (g_dbus_is_name (names[n].string));
750 else
751 g_assert (!g_dbus_is_name (names[n].string));
753 if (names[n].unique)
754 g_assert (g_dbus_is_unique_name (names[n].string));
755 else
756 g_assert (!g_dbus_is_unique_name (names[n].string));
758 if (names[n].interface)
759 g_assert (g_dbus_is_interface_name (names[n].string));
760 else
761 g_assert (!g_dbus_is_interface_name (names[n].string));
765 /* ---------------------------------------------------------------------------------------------------- */
768 main (int argc,
769 char *argv[])
771 gint ret;
773 g_test_init (&argc, &argv, NULL);
775 loop = g_main_loop_new (NULL, FALSE);
777 g_test_dbus_unset ();
779 g_test_add_func ("/gdbus/validate-names", test_validate_names);
780 g_test_add_func ("/gdbus/bus-own-name", test_bus_own_name);
781 g_test_add_func ("/gdbus/bus-watch-name", test_bus_watch_name);
783 ret = g_test_run();
785 g_main_loop_unref (loop);
787 return ret;