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, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
27 #include "gdbus-tests.h"
29 static const gchar *binpath;
31 /* all tests rely on a shared mainloop */
32 static GMainLoop *loop = NULL;
34 /* ---------------------------------------------------------------------------------------------------- */
35 /* Test introspection parser */
36 /* ---------------------------------------------------------------------------------------------------- */
39 test_introspection (GDBusProxy *proxy)
42 const gchar *xml_data;
43 GDBusNodeInfo *node_info;
44 GDBusInterfaceInfo *interface_info;
45 GDBusMethodInfo *method_info;
46 GDBusSignalInfo *signal_info;
52 * Invoke Introspect(), then parse the output.
54 result = g_dbus_proxy_call_sync (proxy,
55 "org.freedesktop.DBus.Introspectable.Introspect",
57 G_DBUS_CALL_FLAGS_NONE,
61 g_assert_no_error (error);
62 g_assert (result != NULL);
63 g_variant_get (result, "(&s)", &xml_data);
65 node_info = g_dbus_node_info_new_for_xml (xml_data, &error);
66 g_assert_no_error (error);
67 g_assert (node_info != NULL);
69 /* for now we only check a couple of things. TODO: check more things */
71 interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.NonExistantInterface");
72 g_assert (interface_info == NULL);
74 interface_info = g_dbus_node_info_lookup_interface (node_info, "org.freedesktop.DBus.Introspectable");
75 g_assert (interface_info != NULL);
76 method_info = g_dbus_interface_info_lookup_method (interface_info, "NonExistantMethod");
77 g_assert (method_info == NULL);
78 method_info = g_dbus_interface_info_lookup_method (interface_info, "Introspect");
79 g_assert (method_info != NULL);
80 g_assert (method_info->in_args != NULL);
81 g_assert (method_info->in_args[0] == NULL);
82 g_assert (method_info->out_args != NULL);
83 g_assert (method_info->out_args[0] != NULL);
84 g_assert (method_info->out_args[1] == NULL);
85 g_assert_cmpstr (method_info->out_args[0]->signature, ==, "s");
87 interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.Frob");
88 g_assert (interface_info != NULL);
89 signal_info = g_dbus_interface_info_lookup_signal (interface_info, "TestSignal");
90 g_assert (signal_info != NULL);
91 g_assert (signal_info->args != NULL);
92 g_assert (signal_info->args[0] != NULL);
93 g_assert_cmpstr (signal_info->args[0]->signature, ==, "s");
94 g_assert (signal_info->args[1] != NULL);
95 g_assert_cmpstr (signal_info->args[1]->signature, ==, "o");
96 g_assert (signal_info->args[2] != NULL);
97 g_assert_cmpstr (signal_info->args[2]->signature, ==, "v");
98 g_assert (signal_info->args[3] == NULL);
100 g_dbus_node_info_unref (node_info);
101 g_variant_unref (result);
103 g_main_loop_quit (loop);
107 test_introspection_parser (void)
110 GDBusConnection *connection;
115 connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
118 g_assert_no_error (error);
120 proxy = g_dbus_proxy_new_sync (connection,
121 G_DBUS_PROXY_FLAGS_NONE,
122 NULL, /* GDBusInterfaceInfo */
123 "com.example.TestService", /* name */
124 "/com/example/TestObject", /* object path */
125 "com.example.Frob", /* interface */
126 NULL, /* GCancellable */
128 g_assert_no_error (error);
130 /* this is safe; testserver will exit once the bus goes away */
131 path = g_build_filename (binpath, "gdbus-testserver", NULL);
132 g_assert (g_spawn_command_line_async (path, NULL));
135 _g_assert_property_notify (proxy, "g-name-owner");
137 test_introspection (proxy);
139 g_object_unref (proxy);
140 g_object_unref (connection);
143 /* check that a parse-generate roundtrip produces identical results
149 GDBusNodeInfo *info2;
150 GDBusInterfaceInfo *iinfo;
151 GDBusMethodInfo *minfo;
152 GDBusSignalInfo *sinfo;
153 GDBusArgInfo *arginfo;
154 GDBusPropertyInfo *pinfo;
155 GDBusAnnotationInfo *aninfo;
158 " <interface name='com.example.Frob'>"
159 " <annotation name='foo' value='bar'/>"
160 " <method name='PairReturn'>"
161 " <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
162 " <arg type='u' name='somenumber' direction='in'/>"
163 " <arg type='s' name='somestring' direction='out'/>"
165 " <signal name='HelloWorld'>"
166 " <arg type='s' name='greeting' direction='out'/>"
168 " <method name='Sleep'>"
169 " <arg type='i' name='timeout' direction='in'/>"
171 " <property name='y' type='y' access='readwrite'/>"
180 info = g_dbus_node_info_new_for_xml (data, &error);
181 g_assert_no_error (error);
183 iinfo = g_dbus_node_info_lookup_interface (info, "com.example.Frob");
184 aninfo = iinfo->annotations[0];
185 g_assert_cmpstr (aninfo->key, ==, "foo");
186 g_assert_cmpstr (aninfo->value, ==, "bar");
187 g_assert (iinfo->annotations[1] == NULL);
188 minfo = g_dbus_interface_info_lookup_method (iinfo, "PairReturn");
189 g_assert_cmpstr (g_dbus_annotation_info_lookup (minfo->annotations, "org.freedesktop.DBus.GLib.Async"), ==, "");
190 arginfo = minfo->in_args[0];
191 g_assert_cmpstr (arginfo->name, ==, "somenumber");
192 g_assert_cmpstr (arginfo->signature, ==, "u");
193 g_assert (minfo->in_args[1] == NULL);
194 arginfo = minfo->out_args[0];
195 g_assert_cmpstr (arginfo->name, ==, "somestring");
196 g_assert_cmpstr (arginfo->signature, ==, "s");
197 g_assert (minfo->out_args[1] == NULL);
198 sinfo = g_dbus_interface_info_lookup_signal (iinfo, "HelloWorld");
199 arginfo = sinfo->args[0];
200 g_assert_cmpstr (arginfo->name, ==, "greeting");
201 g_assert_cmpstr (arginfo->signature, ==, "s");
202 g_assert (sinfo->args[1] == NULL);
203 pinfo = g_dbus_interface_info_lookup_property (iinfo, "y");
204 g_assert_cmpstr (pinfo->signature, ==, "y");
205 g_assert_cmpint (pinfo->flags, ==, G_DBUS_PROPERTY_INFO_FLAGS_READABLE |
206 G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE);
208 string = g_string_new ("");
209 g_dbus_node_info_generate_xml (info, 2, string);
211 info2 = g_dbus_node_info_new_for_xml (string->str, &error);
212 string2 = g_string_new ("");
213 g_dbus_node_info_generate_xml (info2, 2, string2);
215 g_assert_cmpstr (string->str, ==, string2->str);
216 g_string_free (string, TRUE);
217 g_string_free (string2, TRUE);
219 g_dbus_node_info_unref (info);
220 g_dbus_node_info_unref (info2);
223 /* test that omitted direction attributes default to 'out' for signals,
224 * and 'in' for methods.
227 test_default_direction (void)
230 GDBusInterfaceInfo *iinfo;
231 GDBusMethodInfo *minfo;
232 GDBusSignalInfo *sinfo;
233 GDBusArgInfo *arginfo;
236 " <interface name='com.example.Frob'>"
237 " <signal name='HelloWorld'>"
238 " <arg type='s' name='greeting'/>"
240 " <method name='Sleep'>"
241 " <arg type='i' name='timeout'/>"
249 info = g_dbus_node_info_new_for_xml (data, &error);
250 g_assert_no_error (error);
252 iinfo = g_dbus_node_info_lookup_interface (info, "com.example.Frob");
253 sinfo = g_dbus_interface_info_lookup_signal (iinfo, "HelloWorld");
254 g_assert (sinfo->args != NULL);
255 arginfo = sinfo->args[0];
256 g_assert_cmpstr (arginfo->name, ==, "greeting");
257 g_assert (sinfo->args[1] == NULL);
258 minfo = g_dbus_interface_info_lookup_method (iinfo, "Sleep");
259 g_assert (minfo->in_args != NULL);
260 arginfo = minfo->in_args[0];
261 g_assert_cmpstr (arginfo->name, ==, "timeout");
262 g_assert (minfo->in_args[1] == NULL);
264 g_dbus_node_info_unref (info);
268 /* XXX: need to figure out how generous we want to be here */
269 /* test that extraneous attributes are ignored
272 test_extra_data (void)
277 " <interface name='com.example.Frob' version='1.0'>"
278 " <annotation name='foo' value='bar' extra='bla'/>"
279 " <method name='PairReturn' anotherattribute='bla'>"
280 " <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
281 " <arg type='u' name='somenumber' direction='in' spin='left'/>"
282 " <arg type='s' name='somestring' direction='out'/>"
284 " <signal name='HelloWorld'>"
285 " <arg type='s' name='somestring'/>"
287 " <method name='Sleep'>"
288 " <arg type='i' name='timeout' direction='in'/>"
290 " <property name='y' type='y' access='readwrite'/>"
296 info = g_dbus_node_info_new_for_xml (data, &error);
297 g_assert_no_error (error);
299 g_dbus_node_info_unref (info);
303 /* ---------------------------------------------------------------------------------------------------- */
311 if (g_getenv ("G_TEST_DATA"))
312 binpath = g_getenv ("G_TEST_DATA");
316 g_test_init (&argc, &argv, NULL);
318 /* all the tests rely on a shared main loop */
319 loop = g_main_loop_new (NULL, FALSE);
323 g_test_add_func ("/gdbus/introspection-parser", test_introspection_parser);
324 g_test_add_func ("/gdbus/introspection-generate", test_generate);
325 g_test_add_func ("/gdbus/introspection-default-direction", test_default_direction);
327 /* XXX: need to figure out how generous we want to be here */
328 g_test_add_func ("/gdbus/introspection-extra-data", test_extra_data);