Merge branch 'gdbus-merge'
[platform/upstream/glib.git] / gio / tests / gdbus-introspection.c
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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include <gio/gio.h>
24 #include <unistd.h>
25 #include <string.h>
26
27 #include "gdbus-tests.h"
28
29 /* all tests rely on a shared mainloop */
30 static GMainLoop *loop = NULL;
31
32 /* ---------------------------------------------------------------------------------------------------- */
33 /* Test introspection parser */
34 /* ---------------------------------------------------------------------------------------------------- */
35
36 static void
37 introspection_on_proxy_appeared (GDBusConnection *connection,
38                                  const gchar     *name,
39                                  const gchar     *name_owner,
40                                  GDBusProxy      *proxy,
41                                  gpointer         user_data)
42 {
43   GError *error;
44   const gchar *xml_data;
45   GDBusNodeInfo *node_info;
46   const GDBusInterfaceInfo *interface_info;
47   const GDBusMethodInfo *method_info;
48   const GDBusSignalInfo *signal_info;
49   GVariant *result;
50
51   error = NULL;
52
53   /*
54    * Invoke Introspect(), then parse the output.
55    */
56   result = g_dbus_proxy_call_sync (proxy,
57                                    "org.freedesktop.DBus.Introspectable.Introspect",
58                                    NULL,
59                                    G_DBUS_CALL_FLAGS_NONE,
60                                    -1,
61                                    NULL,
62                                    &error);
63   g_assert_no_error (error);
64   g_assert (result != NULL);
65   g_variant_get (result, "(s)", &xml_data);
66
67   node_info = g_dbus_node_info_new_for_xml (xml_data, &error);
68   g_assert_no_error (error);
69   g_assert (node_info != NULL);
70
71   /* for now we only check a couple of things. TODO: check more things */
72
73   interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.NonExistantInterface");
74   g_assert (interface_info == NULL);
75
76   interface_info = g_dbus_node_info_lookup_interface (node_info, "org.freedesktop.DBus.Introspectable");
77   g_assert (interface_info != NULL);
78   method_info = g_dbus_interface_info_lookup_method (interface_info, "NonExistantMethod");
79   g_assert (method_info == NULL);
80   method_info = g_dbus_interface_info_lookup_method (interface_info, "Introspect");
81   g_assert (method_info != NULL);
82   g_assert (method_info->in_args == NULL);
83   g_assert (method_info->out_args != NULL);
84   g_assert (method_info->out_args[0] != NULL);
85   g_assert (method_info->out_args[1] == NULL);
86   g_assert_cmpstr (method_info->out_args[0]->signature, ==, "s");
87
88   interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.Frob");
89   g_assert (interface_info != NULL);
90   signal_info = g_dbus_interface_info_lookup_signal (interface_info, "TestSignal");
91   g_assert (signal_info != NULL);
92   g_assert (signal_info->args != NULL);
93   g_assert (signal_info->args[0] != NULL);
94   g_assert_cmpstr (signal_info->args[0]->signature, ==, "s");
95   g_assert (signal_info->args[1] != NULL);
96   g_assert_cmpstr (signal_info->args[1]->signature, ==, "o");
97   g_assert (signal_info->args[2] != NULL);
98   g_assert_cmpstr (signal_info->args[2]->signature, ==, "v");
99   g_assert (signal_info->args[3] == NULL);
100
101   g_dbus_node_info_unref (node_info);
102   g_variant_unref (result);
103
104   g_main_loop_quit (loop);
105 }
106
107 static void
108 introspection_on_proxy_vanished (GDBusConnection *connection,
109                                  const gchar     *name,
110                                  gpointer         user_data)
111 {
112 }
113
114 static void
115 test_introspection_parser (void)
116 {
117   guint watcher_id;
118
119   session_bus_up ();
120
121   watcher_id = g_bus_watch_proxy (G_BUS_TYPE_SESSION,
122                                   "com.example.TestService",
123                                   G_BUS_NAME_WATCHER_FLAGS_NONE,
124                                   "/com/example/TestObject",
125                                   "com.example.Frob",
126                                   G_TYPE_DBUS_PROXY,
127                                   G_DBUS_PROXY_FLAGS_NONE,
128                                   introspection_on_proxy_appeared,
129                                   introspection_on_proxy_vanished,
130                                   NULL,
131                                   NULL);
132
133   /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return
134    * until one can connect to the bus but that's not how things work right now
135    */
136   usleep (500 * 1000);
137   /* this is safe; testserver will exit once the bus goes away */
138   g_assert (g_spawn_command_line_async ("./gdbus-testserver.py", NULL));
139
140   g_main_loop_run (loop);
141
142   g_bus_unwatch_proxy (watcher_id);
143
144   /* tear down bus */
145   session_bus_down ();
146 }
147
148
149 /* ---------------------------------------------------------------------------------------------------- */
150
151 int
152 main (int   argc,
153       char *argv[])
154 {
155   g_type_init ();
156   g_test_init (&argc, &argv, NULL);
157
158   /* all the tests rely on a shared main loop */
159   loop = g_main_loop_new (NULL, FALSE);
160
161   /* all the tests use a session bus with a well-known address that we can bring up and down
162    * using session_bus_up() and session_bus_down().
163    */
164   g_unsetenv ("DISPLAY");
165   g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE);
166
167   g_test_add_func ("/gdbus/introspection-parser", test_introspection_parser);
168   return g_test_run();
169 }