GSettings: small internal refactor
[glib.git] / gio / tests / gdbus-peer-object-manager.c
blob7a19c71159c82ed807cf9ff26ecf173be8216945
1 /* GLib testing framework examples and tests
3 * Copyright (C) 2012 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: Stef Walter <stefw@gnome.org>
23 #include "config.h"
25 #include <gio/gio.h>
27 #include <sys/socket.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <unistd.h>
33 typedef struct {
34 GDBusInterfaceSkeleton parent;
35 gint number;
36 } MockInterface;
38 typedef struct {
39 GDBusInterfaceSkeletonClass parent_class;
40 } MockInterfaceClass;
42 static GType mock_interface_get_type (void);
43 G_DEFINE_TYPE (MockInterface, mock_interface, G_TYPE_DBUS_INTERFACE_SKELETON);
45 static void
46 mock_interface_init (MockInterface *self)
51 static GDBusInterfaceInfo *
52 mock_interface_get_info (GDBusInterfaceSkeleton *skeleton)
54 static GDBusPropertyInfo path_info = {
55 -1,
56 "Path",
57 "o",
58 G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
59 NULL,
62 static GDBusPropertyInfo number_info = {
63 -1,
64 "Number",
65 "i",
66 G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
67 NULL,
70 static GDBusPropertyInfo *property_info[] = {
71 &path_info,
72 &number_info,
73 NULL
76 static GDBusInterfaceInfo interface_info = {
77 -1,
78 (gchar *) "org.mock.Interface",
79 NULL,
80 NULL,
81 (GDBusPropertyInfo **) &property_info,
82 NULL
85 return &interface_info;
88 static GVariant *
89 mock_interface_get_property (GDBusConnection *connection,
90 const gchar *sender,
91 const gchar *object_path,
92 const gchar *interface_name,
93 const gchar *property_name,
94 GError **error,
95 gpointer user_data)
97 MockInterface *self = user_data;
98 if (g_str_equal (property_name, "Path"))
99 return g_variant_new_object_path (object_path);
100 else if (g_str_equal (property_name, "Number"))
101 return g_variant_new_int32 (self->number);
102 else
103 return NULL;
106 static GDBusInterfaceVTable *
107 mock_interface_get_vtable (GDBusInterfaceSkeleton *interface)
109 static GDBusInterfaceVTable vtable = {
110 NULL,
111 mock_interface_get_property,
112 NULL,
115 return &vtable;
118 static GVariant *
119 mock_interface_get_properties (GDBusInterfaceSkeleton *interface)
121 GVariantBuilder builder;
122 GDBusInterfaceInfo *info;
123 GDBusInterfaceVTable *vtable;
124 guint n;
126 /* Groan, this is completely generic code and should be in gdbus */
128 info = g_dbus_interface_skeleton_get_info (interface);
129 vtable = g_dbus_interface_skeleton_get_vtable (interface);
131 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
132 for (n = 0; info->properties[n] != NULL; n++)
134 if (info->properties[n]->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
136 GVariant *value;
137 g_return_val_if_fail (vtable->get_property != NULL, NULL);
138 value = (vtable->get_property) (g_dbus_interface_skeleton_get_connection (interface), NULL,
139 g_dbus_interface_skeleton_get_object_path (interface),
140 info->name, info->properties[n]->name,
141 NULL, interface);
142 if (value != NULL)
144 g_variant_take_ref (value);
145 g_variant_builder_add (&builder, "{sv}", info->properties[n]->name, value);
146 g_variant_unref (value);
151 return g_variant_builder_end (&builder);
154 static void
155 mock_interface_flush (GDBusInterfaceSkeleton *skeleton)
160 static void
161 mock_interface_class_init (MockInterfaceClass *klass)
163 GDBusInterfaceSkeletonClass *skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
164 skeleton_class->get_info = mock_interface_get_info;
165 skeleton_class->get_properties = mock_interface_get_properties;
166 skeleton_class->flush = mock_interface_flush;
167 skeleton_class->get_vtable = mock_interface_get_vtable;
169 typedef struct {
170 GDBusConnection *server;
171 GDBusConnection *client;
172 GMainLoop *loop;
173 GAsyncResult *result;
174 } Test;
176 static void
177 on_server_connection (GObject *source,
178 GAsyncResult *result,
179 gpointer user_data)
181 Test *test = user_data;
182 GError *error = NULL;
184 g_assert (test->server == NULL);
185 test->server = g_dbus_connection_new_finish (result, &error);
186 g_assert_no_error (error);
187 g_assert (test->server != NULL);
189 if (test->server && test->client)
190 g_main_loop_quit (test->loop);
193 static void
194 on_client_connection (GObject *source,
195 GAsyncResult *result,
196 gpointer user_data)
198 Test *test = user_data;
199 GError *error = NULL;
201 g_assert (test->client == NULL);
202 test->client = g_dbus_connection_new_finish (result, &error);
203 g_assert_no_error (error);
204 g_assert (test->client != NULL);
206 if (test->server && test->client)
207 g_main_loop_quit (test->loop);
210 static void
211 setup (Test *test,
212 gconstpointer unused)
214 GError *error = NULL;
215 GSocket *socket;
216 GSocketConnection *stream;
217 gchar *guid;
218 int pair[2];
220 test->loop = g_main_loop_new (NULL, FALSE);
222 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0)
224 g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errno),
225 "%s", g_strerror (errno));
226 g_assert_no_error (error);
229 /* Build up the server stuff */
230 socket = g_socket_new_from_fd (pair[1], &error);
231 g_assert_no_error (error);
233 stream = g_socket_connection_factory_create_connection (socket);
234 g_assert (stream != NULL);
235 g_object_unref (socket);
237 guid = g_dbus_generate_guid ();
238 g_dbus_connection_new (G_IO_STREAM (stream), guid,
239 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
240 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
241 NULL, NULL, on_server_connection, test);
242 g_object_unref (stream);
243 g_free (guid);
245 /* Build up the client stuff */
246 socket = g_socket_new_from_fd (pair[0], &error);
247 g_assert_no_error (error);
249 stream = g_socket_connection_factory_create_connection (socket);
250 g_assert (stream != NULL);
251 g_object_unref (socket);
253 g_dbus_connection_new (G_IO_STREAM (stream), NULL,
254 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
255 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
256 NULL, NULL, on_client_connection, test);
258 g_main_loop_run (test->loop);
260 g_assert (test->server);
261 g_assert (test->client);
264 static void
265 teardown (Test *test,
266 gconstpointer unused)
268 g_clear_object (&test->client);
269 g_clear_object (&test->server);
270 g_main_loop_unref (test->loop);
273 static void
274 on_result (GObject *source,
275 GAsyncResult *result,
276 gpointer user_data)
278 Test *test = user_data;
279 g_assert (test->result == NULL);
280 test->result = g_object_ref (result);
281 g_main_loop_quit (test->loop);
285 static void
286 test_object_manager (Test *test,
287 gconstpointer unused)
289 GDBusObjectManager *client;
290 GDBusObjectManagerServer *server;
291 MockInterface *mock;
292 GDBusObjectSkeleton *skeleton;
293 const gchar *dbus_name;
294 GError *error = NULL;
295 GDBusInterface *proxy;
296 GVariant *prop;
298 server = g_dbus_object_manager_server_new ("/objects");
300 mock = g_object_new (mock_interface_get_type (), NULL);
301 mock->number = 1;
302 skeleton = g_dbus_object_skeleton_new ("/objects/number_1");
303 g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
304 g_dbus_object_manager_server_export (server, skeleton);
306 mock = g_object_new (mock_interface_get_type (), NULL);
307 mock->number = 2;
308 skeleton = g_dbus_object_skeleton_new ("/objects/number_2");
309 g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
310 g_dbus_object_manager_server_export (server, skeleton);
312 g_dbus_object_manager_server_set_connection (server, test->server);
314 dbus_name = NULL;
316 g_dbus_object_manager_client_new (test->client, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
317 dbus_name, "/objects", NULL, NULL, NULL, NULL, on_result, test);
319 g_main_loop_run (test->loop);
320 client = g_dbus_object_manager_client_new_finish (test->result, &error);
321 g_assert_no_error (error);
322 g_clear_object (&test->result);
324 proxy = g_dbus_object_manager_get_interface (client, "/objects/number_1", "org.mock.Interface");
325 g_assert (proxy != NULL);
326 prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
327 g_assert (prop != NULL);
328 g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
329 g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_1");
330 g_variant_unref (prop);
331 prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
332 g_assert (prop != NULL);
333 g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32);
334 g_assert_cmpint (g_variant_get_int32 (prop), ==, 1);
335 g_variant_unref (prop);
336 g_object_unref (proxy);
338 proxy = g_dbus_object_manager_get_interface (client, "/objects/number_2", "org.mock.Interface");
339 g_assert (proxy != NULL);
340 prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
341 g_assert (prop != NULL);
342 g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
343 g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_2");
344 g_variant_unref (prop);
345 prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
346 g_assert (prop != NULL);
347 g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32);
348 g_assert_cmpint (g_variant_get_int32 (prop), ==, 2);
349 g_variant_unref (prop);
350 g_object_unref (proxy);
352 g_object_unref (server);
353 g_object_unref (client);
357 main (int argc,
358 char *argv[])
360 g_test_init (&argc, &argv, NULL);
362 g_test_add ("/gdbus/peer-object-manager", Test, NULL, setup, test_object_manager, teardown);
364 return g_test_run();