Add some more cases to the app-id unit tests
[glib.git] / gio / tests / gdbus-proxy.c
blob384f4c738a4694263cb940dec05bc4ad3a6ba388
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>
23 #include <string.h>
25 #include "gdbus-tests.h"
27 /* all tests rely on a shared mainloop */
28 static GMainLoop *loop = NULL;
30 /* ---------------------------------------------------------------------------------------------------- */
31 /* Test that the method aspects of GDBusProxy works */
32 /* ---------------------------------------------------------------------------------------------------- */
34 static void
35 test_methods (GDBusProxy *proxy)
37 GVariant *result;
38 GError *error;
39 const gchar *str;
40 gchar *dbus_error_name;
42 /* check that we can invoke a method */
43 error = NULL;
44 result = g_dbus_proxy_call_sync (proxy,
45 "HelloWorld",
46 g_variant_new ("(s)", "Hey"),
47 G_DBUS_CALL_FLAGS_NONE,
48 -1,
49 NULL,
50 &error);
51 g_assert_no_error (error);
52 g_assert (result != NULL);
53 g_assert_cmpstr (g_variant_get_type_string (result), ==, "(s)");
54 g_variant_get (result, "(&s)", &str);
55 g_assert_cmpstr (str, ==, "You greeted me with 'Hey'. Thanks!");
56 g_variant_unref (result);
58 /* Check that we can completely recover the returned error */
59 result = g_dbus_proxy_call_sync (proxy,
60 "HelloWorld",
61 g_variant_new ("(s)", "Yo"),
62 G_DBUS_CALL_FLAGS_NONE,
63 -1,
64 NULL,
65 &error);
66 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
67 g_assert (g_dbus_error_is_remote_error (error));
68 g_assert (g_dbus_error_is_remote_error (error));
69 g_assert (result == NULL);
70 dbus_error_name = g_dbus_error_get_remote_error (error);
71 g_assert_cmpstr (dbus_error_name, ==, "com.example.TestException");
72 g_free (dbus_error_name);
73 g_assert (g_dbus_error_strip_remote_error (error));
74 g_assert_cmpstr (error->message, ==, "Yo is not a proper greeting");
75 g_clear_error (&error);
77 /* Check that we get a timeout if the method handling is taking longer than timeout */
78 error = NULL;
79 result = g_dbus_proxy_call_sync (proxy,
80 "Sleep",
81 g_variant_new ("(i)", 500 /* msec */),
82 G_DBUS_CALL_FLAGS_NONE,
83 100 /* msec */,
84 NULL,
85 &error);
86 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
87 g_assert (!g_dbus_error_is_remote_error (error));
88 g_assert (result == NULL);
89 g_clear_error (&error);
91 /* Check that proxy-default timeouts work. */
92 g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1);
94 /* the default timeout is 25000 msec so this should work */
95 result = g_dbus_proxy_call_sync (proxy,
96 "Sleep",
97 g_variant_new ("(i)", 500 /* msec */),
98 G_DBUS_CALL_FLAGS_NONE,
99 -1, /* use proxy default (e.g. -1 -> e.g. 25000 msec) */
100 NULL,
101 &error);
102 g_assert_no_error (error);
103 g_assert (result != NULL);
104 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
105 g_variant_unref (result);
107 /* now set the proxy-default timeout to 250 msec and try the 500 msec call - this should FAIL */
108 g_dbus_proxy_set_default_timeout (proxy, 250);
109 g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, 250);
110 result = g_dbus_proxy_call_sync (proxy,
111 "Sleep",
112 g_variant_new ("(i)", 500 /* msec */),
113 G_DBUS_CALL_FLAGS_NONE,
114 -1, /* use proxy default (e.g. 250 msec) */
115 NULL,
116 &error);
117 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
118 g_assert (!g_dbus_error_is_remote_error (error));
119 g_assert (result == NULL);
120 g_clear_error (&error);
122 /* clean up after ourselves */
123 g_dbus_proxy_set_default_timeout (proxy, -1);
126 static gboolean
127 strv_equal (gchar **strv, ...)
129 gint count;
130 va_list list;
131 const gchar *str;
132 gboolean res;
134 res = TRUE;
135 count = 0;
136 va_start (list, strv);
137 while (1)
139 str = va_arg (list, const gchar *);
140 if (str == NULL)
141 break;
142 if (g_strcmp0 (str, strv[count]) != 0)
144 res = FALSE;
145 break;
147 count++;
149 va_end (list);
151 if (res)
152 res = g_strv_length (strv) == count;
154 return res;
157 /* ---------------------------------------------------------------------------------------------------- */
158 /* Test that the property aspects of GDBusProxy works */
159 /* ---------------------------------------------------------------------------------------------------- */
161 static void
162 test_properties (GDBusProxy *proxy)
164 GError *error;
165 GVariant *variant;
166 GVariant *variant2;
167 GVariant *result;
168 gchar **names;
169 gchar *name_owner;
170 GDBusProxy *proxy2;
172 error = NULL;
174 if (g_dbus_proxy_get_flags (proxy) & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
176 g_assert (g_dbus_proxy_get_cached_property_names (proxy) == NULL);
177 return;
181 * Check that we can list all cached properties.
183 names = g_dbus_proxy_get_cached_property_names (proxy);
185 g_assert (strv_equal (names,
186 "PropertyThatWillBeInvalidated",
187 "ab",
188 "ad",
189 "ai",
190 "an",
191 "ao",
192 "aq",
193 "as",
194 "at",
195 "au",
196 "ax",
197 "ay",
198 "b",
199 "d",
200 "foo",
201 "i",
202 "n",
203 "o",
204 "q",
205 "s",
206 "t",
207 "u",
208 "x",
209 "y",
210 NULL));
212 g_strfreev (names);
215 * Check that we can read cached properties.
217 * No need to test all properties - GVariant has already been tested
219 variant = g_dbus_proxy_get_cached_property (proxy, "y");
220 g_assert (variant != NULL);
221 g_assert_cmpint (g_variant_get_byte (variant), ==, 1);
222 g_variant_unref (variant);
223 variant = g_dbus_proxy_get_cached_property (proxy, "o");
224 g_assert (variant != NULL);
225 g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "/some/path");
226 g_variant_unref (variant);
229 * Now ask the service to change a property and check that #GDBusProxy::g-property-changed
230 * is received. Also check that the cache is updated.
232 variant2 = g_variant_new_byte (42);
233 result = g_dbus_proxy_call_sync (proxy,
234 "FrobSetProperty",
235 g_variant_new ("(sv)",
236 "y",
237 variant2),
238 G_DBUS_CALL_FLAGS_NONE,
240 NULL,
241 &error);
242 g_assert_no_error (error);
243 g_assert (result != NULL);
244 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
245 g_variant_unref (result);
246 _g_assert_signal_received (proxy, "g-properties-changed");
247 variant = g_dbus_proxy_get_cached_property (proxy, "y");
248 g_assert (variant != NULL);
249 g_assert_cmpint (g_variant_get_byte (variant), ==, 42);
250 g_variant_unref (variant);
252 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (142));
253 variant = g_dbus_proxy_get_cached_property (proxy, "y");
254 g_assert (variant != NULL);
255 g_assert_cmpint (g_variant_get_byte (variant), ==, 142);
256 g_variant_unref (variant);
258 g_dbus_proxy_set_cached_property (proxy, "y", NULL);
259 variant = g_dbus_proxy_get_cached_property (proxy, "y");
260 g_assert (variant == NULL);
262 /* Check that the invalidation feature of the PropertiesChanged()
263 * signal works... First, check that we have a cached value of the
264 * property (from the initial GetAll() call)
266 variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated");
267 g_assert (variant != NULL);
268 g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "InitialValue");
269 g_variant_unref (variant);
270 /* now ask to invalidate the property - this causes a
272 * PropertiesChanaged("com.example.Frob",
273 * {},
274 * ["PropertyThatWillBeInvalidated")
276 * signal to be emitted. This is received before the method reply
277 * for FrobInvalidateProperty *but* since the proxy was created in
278 * the same thread as we're doing this synchronous call, we'll get
279 * the method reply before...
281 result = g_dbus_proxy_call_sync (proxy,
282 "FrobInvalidateProperty",
283 g_variant_new ("(s)", "OMGInvalidated"),
284 G_DBUS_CALL_FLAGS_NONE,
286 NULL,
287 &error);
288 g_assert_no_error (error);
289 g_assert (result != NULL);
290 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
291 g_variant_unref (result);
292 /* ... hence we wait for the g-properties-changed signal to be delivered */
293 _g_assert_signal_received (proxy, "g-properties-changed");
294 /* ... and now we finally, check that the cached value has been invalidated */
295 variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated");
296 g_assert (variant == NULL);
298 /* Now test that G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES works - we need a new proxy for that */
299 error = NULL;
300 proxy2 = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy),
301 G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
302 NULL, /* GDBusInterfaceInfo */
303 "com.example.TestService", /* name */
304 "/com/example/TestObject", /* object path */
305 "com.example.Frob", /* interface */
306 NULL, /* GCancellable */
307 &error);
308 g_assert_no_error (error);
310 name_owner = g_dbus_proxy_get_name_owner (proxy2);
311 g_assert (name_owner != NULL);
312 g_free (name_owner);
314 variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated");
315 g_assert (variant != NULL);
316 g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated"); /* from previous test */
317 g_variant_unref (variant);
319 result = g_dbus_proxy_call_sync (proxy2,
320 "FrobInvalidateProperty",
321 g_variant_new ("(s)", "OMGInvalidated2"),
322 G_DBUS_CALL_FLAGS_NONE,
324 NULL,
325 &error);
326 g_assert_no_error (error);
327 g_assert (result != NULL);
328 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
329 g_variant_unref (result);
331 /* this time we should get the ::g-properties-changed _with_ the value */
332 _g_assert_signal_received (proxy2, "g-properties-changed");
334 variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated");
335 g_assert (variant != NULL);
336 g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated2");
337 g_variant_unref (variant);
339 g_object_unref (proxy2);
342 /* ---------------------------------------------------------------------------------------------------- */
343 /* Test that the signal aspects of GDBusProxy works */
344 /* ---------------------------------------------------------------------------------------------------- */
346 static void
347 test_proxy_signals_on_signal (GDBusProxy *proxy,
348 const gchar *sender_name,
349 const gchar *signal_name,
350 GVariant *parameters,
351 gpointer user_data)
353 GString *s = user_data;
355 g_assert_cmpstr (signal_name, ==, "TestSignal");
356 g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(sov)");
358 g_variant_print_string (parameters, s, TRUE);
361 typedef struct
363 GMainLoop *internal_loop;
364 GString *s;
365 } TestSignalData;
367 static void
368 test_proxy_signals_on_emit_signal_cb (GDBusProxy *proxy,
369 GAsyncResult *res,
370 gpointer user_data)
372 TestSignalData *data = user_data;
373 GError *error;
374 GVariant *result;
376 error = NULL;
377 result = g_dbus_proxy_call_finish (proxy,
378 res,
379 &error);
380 g_assert_no_error (error);
381 g_assert (result != NULL);
382 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
383 g_variant_unref (result);
385 /* check that the signal was recieved before we got the method result */
386 g_assert (strlen (data->s->str) > 0);
388 /* break out of the loop */
389 g_main_loop_quit (data->internal_loop);
392 static void
393 test_signals (GDBusProxy *proxy)
395 GError *error;
396 GString *s;
397 gulong signal_handler_id;
398 TestSignalData data;
399 GVariant *result;
401 error = NULL;
404 * Ask the service to emit a signal and check that we receive it.
406 * Note that blocking calls don't block in the mainloop so wait for the signal (which
407 * is dispatched before the method reply)
409 s = g_string_new (NULL);
410 signal_handler_id = g_signal_connect (proxy,
411 "g-signal",
412 G_CALLBACK (test_proxy_signals_on_signal),
415 result = g_dbus_proxy_call_sync (proxy,
416 "EmitSignal",
417 g_variant_new ("(so)",
418 "Accept the next proposition you hear",
419 "/some/path"),
420 G_DBUS_CALL_FLAGS_NONE,
422 NULL,
423 &error);
424 g_assert_no_error (error);
425 g_assert (result != NULL);
426 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
427 g_variant_unref (result);
428 /* check that we haven't received the signal just yet */
429 g_assert (strlen (s->str) == 0);
430 /* and now wait for the signal */
431 _g_assert_signal_received (proxy, "g-signal");
432 g_assert_cmpstr (s->str,
434 "('Accept the next proposition you hear .. in bed!', objectpath '/some/path/in/bed', <'a variant'>)");
435 g_signal_handler_disconnect (proxy, signal_handler_id);
436 g_string_free (s, TRUE);
439 * Now do this async to check the signal is received before the method returns.
441 s = g_string_new (NULL);
442 data.internal_loop = g_main_loop_new (NULL, FALSE);
443 data.s = s;
444 signal_handler_id = g_signal_connect (proxy,
445 "g-signal",
446 G_CALLBACK (test_proxy_signals_on_signal),
448 g_dbus_proxy_call (proxy,
449 "EmitSignal",
450 g_variant_new ("(so)",
451 "You will make a great programmer",
452 "/some/other/path"),
453 G_DBUS_CALL_FLAGS_NONE,
455 NULL,
456 (GAsyncReadyCallback) test_proxy_signals_on_emit_signal_cb,
457 &data);
458 g_main_loop_run (data.internal_loop);
459 g_main_loop_unref (data.internal_loop);
460 g_assert_cmpstr (s->str,
462 "('You will make a great programmer .. in bed!', objectpath '/some/other/path/in/bed', <'a variant'>)");
463 g_signal_handler_disconnect (proxy, signal_handler_id);
464 g_string_free (s, TRUE);
467 /* ---------------------------------------------------------------------------------------------------- */
469 static void
470 test_bogus_method_return (GDBusProxy *proxy)
472 GError *error = NULL;
473 GVariant *result;
475 result = g_dbus_proxy_call_sync (proxy,
476 "PairReturn",
477 NULL,
478 G_DBUS_CALL_FLAGS_NONE,
480 NULL,
481 &error);
482 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
483 g_error_free (error);
484 g_assert (result == NULL);
487 #if 0 /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */
488 static void
489 test_bogus_signal (GDBusProxy *proxy)
491 GError *error = NULL;
492 GVariant *result;
493 GDBusInterfaceInfo *old_iface_info;
495 result = g_dbus_proxy_call_sync (proxy,
496 "EmitSignal2",
497 NULL,
498 G_DBUS_CALL_FLAGS_NONE,
500 NULL,
501 &error);
502 g_assert_no_error (error);
503 g_assert (result != NULL);
504 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
505 g_variant_unref (result);
507 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
509 /* and now wait for the signal that will never arrive */
510 _g_assert_signal_received (proxy, "g-signal");
512 g_test_trap_assert_stderr ("*Dropping signal TestSignal2 of type (i) since the type from the expected interface is (u)*");
513 g_test_trap_assert_failed();
515 /* Our main branch will also do g_warning() when running the mainloop so
516 * temporarily remove the expected interface
518 old_iface_info = g_dbus_proxy_get_interface_info (proxy);
519 g_dbus_proxy_set_interface_info (proxy, NULL);
520 _g_assert_signal_received (proxy, "g-signal");
521 g_dbus_proxy_set_interface_info (proxy, old_iface_info);
524 static void
525 test_bogus_property (GDBusProxy *proxy)
527 GError *error = NULL;
528 GVariant *result;
529 GDBusInterfaceInfo *old_iface_info;
531 /* Make the service emit a PropertiesChanged signal for property 'i' of type 'i' - since
532 * our introspection data has this as type 'u' we should get a warning on stderr.
534 result = g_dbus_proxy_call_sync (proxy,
535 "FrobSetProperty",
536 g_variant_new ("(sv)",
537 "i", g_variant_new_int32 (42)),
538 G_DBUS_CALL_FLAGS_NONE,
540 NULL,
541 &error);
542 g_assert_no_error (error);
543 g_assert (result != NULL);
544 g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
545 g_variant_unref (result);
547 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
549 /* and now wait for the signal that will never arrive */
550 _g_assert_signal_received (proxy, "g-properties-changed");
552 g_test_trap_assert_stderr ("*Received property i with type i does not match expected type u in the expected interface*");
553 g_test_trap_assert_failed();
555 /* Our main branch will also do g_warning() when running the mainloop so
556 * temporarily remove the expected interface
558 old_iface_info = g_dbus_proxy_get_interface_info (proxy);
559 g_dbus_proxy_set_interface_info (proxy, NULL);
560 _g_assert_signal_received (proxy, "g-properties-changed");
561 g_dbus_proxy_set_interface_info (proxy, old_iface_info);
563 #endif /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */
565 /* ---------------------------------------------------------------------------------------------------- */
567 static const gchar *frob_dbus_interface_xml =
568 "<node>"
569 " <interface name='com.example.Frob'>"
570 /* PairReturn() is deliberately different from gdbus-testserver's definition */
571 " <method name='PairReturn'>"
572 " <arg type='u' name='somenumber' direction='in'/>"
573 " <arg type='s' name='somestring' direction='out'/>"
574 " </method>"
575 " <method name='HelloWorld'>"
576 " <arg type='s' name='somestring' direction='in'/>"
577 " <arg type='s' name='somestring' direction='out'/>"
578 " </method>"
579 " <method name='Sleep'>"
580 " <arg type='i' name='timeout' direction='in'/>"
581 " </method>"
582 /* We deliberately only mention a single property here */
583 " <property name='y' type='y' access='readwrite'/>"
584 /* The 'i' property is deliberately different from gdbus-testserver's definition */
585 " <property name='i' type='u' access='readwrite'/>"
586 /* ::TestSignal2 is deliberately different from gdbus-testserver's definition */
587 " <signal name='TestSignal2'>"
588 " <arg type='u' name='somenumber'/>"
589 " </signal>"
590 " </interface>"
591 "</node>";
592 static GDBusInterfaceInfo *frob_dbus_interface_info;
594 static void
595 test_expected_interface (GDBusProxy *proxy)
597 GVariant *value;
598 GError *error;
600 /* This is obviously wrong but expected interface is not set so we don't fail... */
601 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!"));
602 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42));
603 g_dbus_proxy_set_cached_property (proxy, "does-not-exist", g_variant_new_string ("something"));
604 g_dbus_proxy_set_cached_property (proxy, "does-not-exist", NULL);
606 /* Now repeat the method tests, with an expected interface set */
607 g_dbus_proxy_set_interface_info (proxy, frob_dbus_interface_info);
608 test_methods (proxy);
609 test_signals (proxy);
611 /* And also where we deliberately set the expected interface definition incorrectly */
612 test_bogus_method_return (proxy);
613 /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999
614 test_bogus_signal (proxy);
615 test_bogus_property (proxy);
618 if (g_test_undefined ())
620 /* Also check that we complain if setting a cached property of the wrong type */
621 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
622 "*Trying to set property y of type s but according to the expected interface the type is y*");
623 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!"));
624 g_test_assert_expected_messages ();
627 /* this should work, however (since the type is correct) */
628 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42));
630 if (g_test_undefined ())
632 /* Try to get the value of a property where the type we expect is different from
633 * what we have in our cache (e.g. what the service returned)
635 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
636 "*Trying to get property i with type i but according to the expected interface the type is u*");
637 value = g_dbus_proxy_get_cached_property (proxy, "i");
638 g_test_assert_expected_messages ();
641 /* Even if a property does not exist in expected_interface, looking it
642 * up, or setting it, should never fail. Because it could be that the
643 * property has been added to the service but the GDBusInterfaceInfo*
644 * passed to g_dbus_proxy_set_interface_info() just haven't been updated.
646 * See https://bugzilla.gnome.org/show_bug.cgi?id=660886
648 value = g_dbus_proxy_get_cached_property (proxy, "d");
649 g_assert (value != NULL);
650 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE));
651 g_assert_cmpfloat (g_variant_get_double (value), ==, 7.5);
652 g_variant_unref (value);
653 /* update it via the cached property... */
654 g_dbus_proxy_set_cached_property (proxy, "d", g_variant_new_double (75.0));
655 /* ... and finally check that it has changed */
656 value = g_dbus_proxy_get_cached_property (proxy, "d");
657 g_assert (value != NULL);
658 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE));
659 g_assert_cmpfloat (g_variant_get_double (value), ==, 75.0);
660 g_variant_unref (value);
661 /* now update it via the D-Bus interface... */
662 error = NULL;
663 value = g_dbus_proxy_call_sync (proxy, "FrobSetProperty",
664 g_variant_new ("(sv)", "d", g_variant_new_double (85.0)),
665 G_DBUS_CALL_FLAGS_NONE,
666 -1, NULL, &error);
667 g_assert_no_error (error);
668 g_assert (value != NULL);
669 g_assert_cmpstr (g_variant_get_type_string (value), ==, "()");
670 g_variant_unref (value);
671 /* ...ensure we receive the ::PropertiesChanged signal... */
672 _g_assert_signal_received (proxy, "g-properties-changed");
673 /* ... and finally check that it has changed */
674 value = g_dbus_proxy_get_cached_property (proxy, "d");
675 g_assert (value != NULL);
676 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE));
677 g_assert_cmpfloat (g_variant_get_double (value), ==, 85.0);
678 g_variant_unref (value);
681 static void
682 test_basic (GDBusProxy *proxy)
684 GDBusConnection *connection;
685 GDBusConnection *conn;
686 GDBusProxyFlags flags;
687 GDBusInterfaceInfo *info;
688 gchar *name;
689 gchar *path;
690 gchar *interface;
691 gint timeout;
693 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
695 g_assert (g_dbus_proxy_get_connection (proxy) == connection);
696 g_assert (g_dbus_proxy_get_flags (proxy) == G_DBUS_PROXY_FLAGS_NONE);
697 g_assert (g_dbus_proxy_get_interface_info (proxy) == NULL);
698 g_assert_cmpstr (g_dbus_proxy_get_name (proxy), ==, "com.example.TestService");
699 g_assert_cmpstr (g_dbus_proxy_get_object_path (proxy), ==, "/com/example/TestObject");
700 g_assert_cmpstr (g_dbus_proxy_get_interface_name (proxy), ==, "com.example.Frob");
701 g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1);
703 g_object_get (proxy,
704 "g-connection", &conn,
705 "g-interface-info", &info,
706 "g-flags", &flags,
707 "g-name", &name,
708 "g-object-path", &path,
709 "g-interface-name", &interface,
710 "g-default-timeout", &timeout,
711 NULL);
713 g_assert (conn == connection);
714 g_assert (info == NULL);
715 g_assert_cmpint (flags, ==, G_DBUS_PROXY_FLAGS_NONE);
716 g_assert_cmpstr (name, ==, "com.example.TestService");
717 g_assert_cmpstr (path, ==, "/com/example/TestObject");
718 g_assert_cmpstr (interface, ==, "com.example.Frob");
719 g_assert_cmpint (timeout, ==, -1);
721 g_object_unref (conn);
722 g_free (name);
723 g_free (path);
724 g_free (interface);
726 g_object_unref (connection);
729 static void
730 kill_test_service (GDBusConnection *connection)
732 #ifdef G_OS_UNIX
733 guint pid;
734 GVariant *ret;
735 GError *error = NULL;
736 const gchar *name = "com.example.TestService";
738 ret = g_dbus_connection_call_sync (connection,
739 "org.freedesktop.DBus",
740 "/org/freedesktop/DBus",
741 "org.freedesktop.DBus",
742 "GetConnectionUnixProcessID",
743 g_variant_new ("(s)", name),
744 NULL,
745 G_DBUS_CALL_FLAGS_NONE,
747 NULL,
748 &error);
749 g_variant_get (ret, "(u)", &pid);
750 g_variant_unref (ret);
751 kill (pid, SIGTERM);
752 #else
753 g_warning ("Can't kill com.example.TestService");
754 #endif
757 static void
758 test_proxy (void)
760 GDBusProxy *proxy;
761 GDBusConnection *connection;
762 GError *error;
764 error = NULL;
765 connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
766 NULL,
767 &error);
768 g_assert_no_error (error);
769 error = NULL;
770 proxy = g_dbus_proxy_new_sync (connection,
771 G_DBUS_PROXY_FLAGS_NONE,
772 NULL, /* GDBusInterfaceInfo */
773 "com.example.TestService", /* name */
774 "/com/example/TestObject", /* object path */
775 "com.example.Frob", /* interface */
776 NULL, /* GCancellable */
777 &error);
778 g_assert_no_error (error);
780 /* this is safe; testserver will exit once the bus goes away */
781 g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
783 _g_assert_property_notify (proxy, "g-name-owner");
785 test_basic (proxy);
786 test_methods (proxy);
787 test_properties (proxy);
788 test_signals (proxy);
789 test_expected_interface (proxy);
791 g_object_unref (proxy);
792 kill_test_service (connection);
793 g_object_unref (connection);
796 /* ---------------------------------------------------------------------------------------------------- */
798 static void
799 proxy_ready (GObject *source,
800 GAsyncResult *result,
801 gpointer user_data)
803 GDBusProxy *proxy;
804 GError *error;
806 error = NULL;
807 proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
808 g_assert_no_error (error);
810 _g_assert_property_notify (proxy, "g-name-owner");
812 test_basic (proxy);
813 test_methods (proxy);
814 test_properties (proxy);
815 test_signals (proxy);
816 test_expected_interface (proxy);
818 kill_test_service (g_dbus_proxy_get_connection (proxy));
819 g_object_unref (proxy);
820 g_main_loop_quit (loop);
823 static gboolean
824 fail_test (gpointer user_data)
826 g_assert_not_reached ();
829 static void
830 test_async (void)
832 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
833 G_DBUS_PROXY_FLAGS_NONE,
834 NULL, /* GDBusInterfaceInfo */
835 "com.example.TestService", /* name */
836 "/com/example/TestObject", /* object path */
837 "com.example.Frob", /* interface */
838 NULL, /* GCancellable */
839 proxy_ready,
840 NULL);
842 /* this is safe; testserver will exit once the bus goes away */
843 g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
845 g_timeout_add (10000, fail_test, NULL);
846 g_main_loop_run (loop);
849 static void
850 test_no_properties (void)
852 GDBusProxy *proxy;
853 GError *error;
855 error = NULL;
856 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
857 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
858 NULL, /* GDBusInterfaceInfo */
859 "com.example.TestService", /* name */
860 "/com/example/TestObject", /* object path */
861 "com.example.Frob", /* interface */
862 NULL, /* GCancellable */
863 &error);
864 g_assert_no_error (error);
866 test_properties (proxy);
868 g_object_unref (proxy);
871 static void
872 check_error (GObject *source,
873 GAsyncResult *result,
874 gpointer user_data)
876 GError *error = NULL;
877 GVariant *reply;
879 reply = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
880 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
881 g_assert (reply == NULL);
882 g_error_free (error);
884 g_main_loop_quit (loop);
887 static void
888 test_wellknown_noauto (void)
890 GError *error = NULL;
891 GDBusProxy *proxy;
893 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
894 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
895 NULL, "some.name.that.does.not.exist",
896 "/", "some.interface", NULL, &error);
897 g_assert_no_error (error);
898 g_assert (proxy != NULL);
900 g_dbus_proxy_call (proxy, "method", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, check_error, NULL);
901 g_timeout_add (10000, fail_test, NULL);
902 g_main_loop_run (loop);
903 g_object_unref (proxy);
907 main (int argc,
908 char *argv[])
910 gint ret;
911 GDBusNodeInfo *introspection_data = NULL;
913 g_test_init (&argc, &argv, NULL);
915 introspection_data = g_dbus_node_info_new_for_xml (frob_dbus_interface_xml, NULL);
916 g_assert (introspection_data != NULL);
917 frob_dbus_interface_info = introspection_data->interfaces[0];
919 /* all the tests rely on a shared main loop */
920 loop = g_main_loop_new (NULL, FALSE);
922 g_test_add_func ("/gdbus/proxy", test_proxy);
923 g_test_add_func ("/gdbus/proxy/no-properties", test_no_properties);
924 g_test_add_func ("/gdbus/proxy/wellknown-noauto", test_wellknown_noauto);
925 g_test_add_func ("/gdbus/proxy/async", test_async);
927 ret = session_bus_run();
929 g_dbus_node_info_unref (introspection_data);
931 return ret;