nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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 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 /* Test that the method aspects of GDBusProxy works */
32 /* ---------------------------------------------------------------------------------------------------- */
33  
34 static void
35 test_methods (GDBusProxy *proxy)
36 {
37 GVariant *result;
38 GError *error;
39 const gchar *str;
40 gchar *dbus_error_name;
41  
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);
57  
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);
76  
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);
90  
91 /* Check that proxy-default timeouts work. */
92 g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1);
93  
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);
106  
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);
121  
122 /* clean up after ourselves */
123 g_dbus_proxy_set_default_timeout (proxy, -1);
124 }
125  
126 static gboolean
127 strv_equal (gchar **strv, ...)
128 {
129 gint count;
130 va_list list;
131 const gchar *str;
132 gboolean res;
133  
134 res = TRUE;
135 count = 0;
136 va_start (list, strv);
137 while (1)
138 {
139 str = va_arg (list, const gchar *);
140 if (str == NULL)
141 break;
142 if (g_strcmp0 (str, strv[count]) != 0)
143 {
144 res = FALSE;
145 break;
146 }
147 count++;
148 }
149 va_end (list);
150  
151 if (res)
152 res = g_strv_length (strv) == count;
153  
154 return res;
155 }
156  
157 /* ---------------------------------------------------------------------------------------------------- */
158 /* Test that the property aspects of GDBusProxy works */
159 /* ---------------------------------------------------------------------------------------------------- */
160  
161 static void
162 test_properties (GDBusProxy *proxy)
163 {
164 GError *error;
165 GVariant *variant;
166 GVariant *variant2;
167 GVariant *result;
168 gchar **names;
169 gchar *name_owner;
170 GDBusProxy *proxy2;
171  
172 error = NULL;
173  
174 if (g_dbus_proxy_get_flags (proxy) & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)
175 {
176 g_assert (g_dbus_proxy_get_cached_property_names (proxy) == NULL);
177 return;
178 }
179  
180 /*
181 * Check that we can list all cached properties.
182 */
183 names = g_dbus_proxy_get_cached_property_names (proxy);
184  
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));
211  
212 g_strfreev (names);
213  
214 /*
215 * Check that we can read cached properties.
216 *
217 * No need to test all properties - GVariant has already been tested
218 */
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);
227  
228 /*
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.
231 */
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,
239 -1,
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);
251  
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);
257  
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);
261  
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)
265 */
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
271 *
272 * PropertiesChanaged("com.example.Frob",
273 * {},
274 * ["PropertyThatWillBeInvalidated")
275 *
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...
280 */
281 result = g_dbus_proxy_call_sync (proxy,
282 "FrobInvalidateProperty",
283 g_variant_new ("(s)", "OMGInvalidated"),
284 G_DBUS_CALL_FLAGS_NONE,
285 -1,
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);
297  
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);
309  
310 name_owner = g_dbus_proxy_get_name_owner (proxy2);
311 g_assert (name_owner != NULL);
312 g_free (name_owner);
313  
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);
318  
319 result = g_dbus_proxy_call_sync (proxy2,
320 "FrobInvalidateProperty",
321 g_variant_new ("(s)", "OMGInvalidated2"),
322 G_DBUS_CALL_FLAGS_NONE,
323 -1,
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);
330  
331 /* this time we should get the ::g-properties-changed _with_ the value */
332 _g_assert_signal_received (proxy2, "g-properties-changed");
333  
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);
338  
339 g_object_unref (proxy2);
340 }
341  
342 /* ---------------------------------------------------------------------------------------------------- */
343 /* Test that the signal aspects of GDBusProxy works */
344 /* ---------------------------------------------------------------------------------------------------- */
345  
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)
352 {
353 GString *s = user_data;
354  
355 g_assert_cmpstr (signal_name, ==, "TestSignal");
356 g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(sov)");
357  
358 g_variant_print_string (parameters, s, TRUE);
359 }
360  
361 typedef struct
362 {
363 GMainLoop *internal_loop;
364 GString *s;
365 } TestSignalData;
366  
367 static void
368 test_proxy_signals_on_emit_signal_cb (GDBusProxy *proxy,
369 GAsyncResult *res,
370 gpointer user_data)
371 {
372 TestSignalData *data = user_data;
373 GError *error;
374 GVariant *result;
375  
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);
384  
385 /* check that the signal was recieved before we got the method result */
386 g_assert (strlen (data->s->str) > 0);
387  
388 /* break out of the loop */
389 g_main_loop_quit (data->internal_loop);
390 }
391  
392 static void
393 test_signals (GDBusProxy *proxy)
394 {
395 GError *error;
396 GString *s;
397 gulong signal_handler_id;
398 TestSignalData data;
399 GVariant *result;
400  
401 error = NULL;
402  
403 /*
404 * Ask the service to emit a signal and check that we receive it.
405 *
406 * Note that blocking calls don't block in the mainloop so wait for the signal (which
407 * is dispatched before the method reply)
408 */
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),
413 s);
414  
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,
421 -1,
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,
433 ==,
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);
437  
438 /*
439 * Now do this async to check the signal is received before the method returns.
440 */
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),
447 s);
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,
454 -1,
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,
461 ==,
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);
465 }
466  
467 /* ---------------------------------------------------------------------------------------------------- */
468  
469 static void
470 test_bogus_method_return (GDBusProxy *proxy)
471 {
472 GError *error = NULL;
473 GVariant *result;
474  
475 result = g_dbus_proxy_call_sync (proxy,
476 "PairReturn",
477 NULL,
478 G_DBUS_CALL_FLAGS_NONE,
479 -1,
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);
485 }
486  
487 #if 0 /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */
488 static void
489 test_bogus_signal (GDBusProxy *proxy)
490 {
491 GError *error = NULL;
492 GVariant *result;
493 GDBusInterfaceInfo *old_iface_info;
494  
495 result = g_dbus_proxy_call_sync (proxy,
496 "EmitSignal2",
497 NULL,
498 G_DBUS_CALL_FLAGS_NONE,
499 -1,
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);
506  
507 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
508 {
509 /* and now wait for the signal that will never arrive */
510 _g_assert_signal_received (proxy, "g-signal");
511 }
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();
514  
515 /* Our main branch will also do g_warning() when running the mainloop so
516 * temporarily remove the expected interface
517 */
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);
522 }
523  
524 static void
525 test_bogus_property (GDBusProxy *proxy)
526 {
527 GError *error = NULL;
528 GVariant *result;
529 GDBusInterfaceInfo *old_iface_info;
530  
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.
533 */
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,
539 -1,
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);
546  
547 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
548 {
549 /* and now wait for the signal that will never arrive */
550 _g_assert_signal_received (proxy, "g-properties-changed");
551 }
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();
554  
555 /* Our main branch will also do g_warning() when running the mainloop so
556 * temporarily remove the expected interface
557 */
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);
562 }
563 #endif /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */
564  
565 /* ---------------------------------------------------------------------------------------------------- */
566  
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;
593  
594 static void
595 test_expected_interface (GDBusProxy *proxy)
596 {
597 GVariant *value;
598 GError *error;
599  
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);
605  
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);
610  
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);
616 */
617  
618 if (g_test_undefined ())
619 {
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 ();
625 }
626  
627 /* this should work, however (since the type is correct) */
628 g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42));
629  
630 if (g_test_undefined ())
631 {
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)
634 */
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 ();
639 }
640  
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.
645 *
646 * See https://bugzilla.gnome.org/show_bug.cgi?id=660886
647 */
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);
679 }
680  
681 static void
682 test_basic (GDBusProxy *proxy)
683 {
684 GDBusConnection *connection;
685 GDBusConnection *conn;
686 GDBusProxyFlags flags;
687 GDBusInterfaceInfo *info;
688 gchar *name;
689 gchar *path;
690 gchar *interface;
691 gint timeout;
692  
693 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
694  
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);
702  
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);
712  
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);
720  
721 g_object_unref (conn);
722 g_free (name);
723 g_free (path);
724 g_free (interface);
725  
726 g_object_unref (connection);
727 }
728  
729 static void
730 kill_test_service (GDBusConnection *connection)
731 {
732 #ifdef G_OS_UNIX
733 guint pid;
734 GVariant *ret;
735 GError *error = NULL;
736 const gchar *name = "com.example.TestService";
737  
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,
746 -1,
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
755 }
756  
757 static void
758 test_proxy (void)
759 {
760 GDBusProxy *proxy;
761 GDBusConnection *connection;
762 GError *error;
763  
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);
779  
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));
782  
783 _g_assert_property_notify (proxy, "g-name-owner");
784  
785 test_basic (proxy);
786 test_methods (proxy);
787 test_properties (proxy);
788 test_signals (proxy);
789 test_expected_interface (proxy);
790  
791 g_object_unref (proxy);
792 kill_test_service (connection);
793 g_object_unref (connection);
794 }
795  
796 /* ---------------------------------------------------------------------------------------------------- */
797  
798 static void
799 proxy_ready (GObject *source,
800 GAsyncResult *result,
801 gpointer user_data)
802 {
803 GDBusProxy *proxy;
804 GError *error;
805  
806 error = NULL;
807 proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
808 g_assert_no_error (error);
809  
810 _g_assert_property_notify (proxy, "g-name-owner");
811  
812 test_basic (proxy);
813 test_methods (proxy);
814 test_properties (proxy);
815 test_signals (proxy);
816 test_expected_interface (proxy);
817  
818 kill_test_service (g_dbus_proxy_get_connection (proxy));
819 g_object_unref (proxy);
820 g_main_loop_quit (loop);
821 }
822  
823 static gboolean
824 fail_test (gpointer user_data)
825 {
826 g_assert_not_reached ();
827 }
828  
829 static void
830 test_async (void)
831 {
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);
841  
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));
844  
845 g_timeout_add (10000, fail_test, NULL);
846 g_main_loop_run (loop);
847 }
848  
849 static void
850 test_no_properties (void)
851 {
852 GDBusProxy *proxy;
853 GError *error;
854  
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);
865  
866 test_properties (proxy);
867  
868 g_object_unref (proxy);
869 }
870  
871 static void
872 check_error (GObject *source,
873 GAsyncResult *result,
874 gpointer user_data)
875 {
876 GError *error = NULL;
877 GVariant *reply;
878  
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);
883  
884 g_main_loop_quit (loop);
885 }
886  
887 static void
888 test_wellknown_noauto (void)
889 {
890 GError *error = NULL;
891 GDBusProxy *proxy;
892  
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);
899  
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);
904 }
905  
906 int
907 main (int argc,
908 char *argv[])
909 {
910 gint ret;
911 GDBusNodeInfo *introspection_data = NULL;
912  
913 g_test_init (&argc, &argv, NULL);
914  
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];
918  
919 /* all the tests rely on a shared main loop */
920 loop = g_main_loop_new (NULL, FALSE);
921  
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);
926  
927 ret = session_bus_run();
928  
929 g_dbus_node_info_unref (introspection_data);
930  
931 return ret;
932 }