Update tests for new truncate behavior
[platform/upstream/glib.git] / gio / tests / gdbus-peer-object-manager.c
1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2012 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: Stef Walter <stefw@gnome.org>
21  */
22
23 #include "config.h"
24
25 #include <gio/gio.h>
26
27 #include <sys/socket.h>
28
29 #include <errno.h>
30 #include <string.h>
31 #include <unistd.h>
32
33 typedef struct {
34   GDBusInterfaceSkeleton parent;
35   gint number;
36 } MockInterface;
37
38 typedef struct {
39   GDBusInterfaceSkeletonClass parent_class;
40 } MockInterfaceClass;
41
42 static GType mock_interface_get_type (void);
43 G_DEFINE_TYPE (MockInterface, mock_interface, G_TYPE_DBUS_INTERFACE_SKELETON);
44
45 static void
46 mock_interface_init (MockInterface *self)
47 {
48
49 }
50
51 static GDBusInterfaceInfo *
52 mock_interface_get_info (GDBusInterfaceSkeleton *skeleton)
53 {
54   static GDBusPropertyInfo path_info = {
55     -1,
56     "Path",
57     "o",
58     G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
59     NULL,
60   };
61
62   static GDBusPropertyInfo number_info = {
63     -1,
64     "Number",
65     "i",
66     G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
67     NULL,
68   };
69
70   static GDBusPropertyInfo *property_info[] = {
71     &path_info,
72     &number_info,
73     NULL
74   };
75
76   static GDBusInterfaceInfo interface_info = {
77     -1,
78     (gchar *) "org.mock.Interface",
79     NULL,
80     NULL,
81     (GDBusPropertyInfo **) &property_info,
82     NULL
83   };
84
85   return &interface_info;
86 }
87
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)
96 {
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;
104 }
105
106 static GDBusInterfaceVTable *
107 mock_interface_get_vtable (GDBusInterfaceSkeleton *interface)
108 {
109   static GDBusInterfaceVTable vtable = {
110     NULL,
111     mock_interface_get_property,
112     NULL,
113   };
114
115   return &vtable;
116 }
117
118 static GVariant *
119 mock_interface_get_properties (GDBusInterfaceSkeleton *interface)
120 {
121   GVariantBuilder builder;
122   GDBusInterfaceInfo *info;
123   GDBusInterfaceVTable *vtable;
124   guint n;
125
126   /* Groan, this is completely generic code and should be in gdbus */
127
128   info = g_dbus_interface_skeleton_get_info (interface);
129   vtable = g_dbus_interface_skeleton_get_vtable (interface);
130
131   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
132   for (n = 0; info->properties[n] != NULL; n++)
133     {
134       if (info->properties[n]->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
135         {
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)
143             {
144               g_variant_take_ref (value);
145               g_variant_builder_add (&builder, "{sv}", info->properties[n]->name, value);
146               g_variant_unref (value);
147             }
148         }
149     }
150
151   return g_variant_builder_end (&builder);
152 }
153
154 static void
155 mock_interface_flush (GDBusInterfaceSkeleton *skeleton)
156 {
157
158 }
159
160 static void
161 mock_interface_class_init (MockInterfaceClass *klass)
162 {
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;
168 }
169 typedef struct {
170   GDBusConnection *server;
171   GDBusConnection *client;
172   GMainLoop *loop;
173   GAsyncResult *result;
174 } Test;
175
176 static void
177 on_server_connection (GObject *source,
178                       GAsyncResult *result,
179                       gpointer user_data)
180 {
181   Test *test = user_data;
182   GError *error = NULL;
183
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);
188
189   if (test->server && test->client)
190     g_main_loop_quit (test->loop);
191 }
192
193 static void
194 on_client_connection (GObject *source,
195                       GAsyncResult *result,
196                       gpointer user_data)
197 {
198   Test *test = user_data;
199   GError *error = NULL;
200
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);
205
206   if (test->server && test->client)
207     g_main_loop_quit (test->loop);
208 }
209
210 static void
211 setup (Test *test,
212        gconstpointer unused)
213 {
214   GError *error = NULL;
215   GSocket *socket;
216   GSocketConnection *stream;
217   gchar *guid;
218   int pair[2];
219
220   test->loop = g_main_loop_new (NULL, FALSE);
221
222   if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0)
223     {
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);
227     }
228
229   /* Build up the server stuff */
230   socket = g_socket_new_from_fd (pair[1], &error);
231   g_assert_no_error (error);
232
233   stream = g_socket_connection_factory_create_connection (socket);
234   g_assert (stream != NULL);
235   g_object_unref (socket);
236
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);
244
245   /* Build up the client stuff */
246   socket = g_socket_new_from_fd (pair[0], &error);
247   g_assert_no_error (error);
248
249   stream = g_socket_connection_factory_create_connection (socket);
250   g_assert (stream != NULL);
251   g_object_unref (socket);
252
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);
257
258   g_main_loop_run (test->loop);
259
260   g_assert (test->server);
261   g_assert (test->client);
262 }
263
264 static void
265 teardown (Test *test,
266           gconstpointer unused)
267 {
268   g_clear_object (&test->client);
269   g_clear_object (&test->server);
270   g_main_loop_unref (test->loop);
271 }
272
273 static void
274 on_result (GObject *source,
275            GAsyncResult *result,
276            gpointer user_data)
277 {
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);
282
283 }
284
285 static void
286 test_object_manager (Test *test,
287                      gconstpointer unused)
288 {
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;
297
298   server = g_dbus_object_manager_server_new ("/objects");
299
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);
305
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);
311
312   g_dbus_object_manager_server_set_connection (server, test->server);
313
314   dbus_name = NULL;
315
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);
318
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);
323
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);
337
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);
351
352   g_object_unref (server);
353   g_object_unref (client);
354 }
355
356 int
357 main (int   argc,
358       char *argv[])
359 {
360   g_test_init (&argc, &argv, NULL);
361
362   g_test_add ("/gdbus/peer-object-manager", Test, NULL, setup, test_object_manager, teardown);
363
364   return g_test_run();
365 }