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>
27 #include <sys/socket.h>
34 GDBusInterfaceSkeleton parent
;
39 GDBusInterfaceSkeletonClass parent_class
;
42 static GType
mock_interface_get_type (void);
43 G_DEFINE_TYPE (MockInterface
, mock_interface
, G_TYPE_DBUS_INTERFACE_SKELETON
);
46 mock_interface_init (MockInterface
*self
)
51 static GDBusInterfaceInfo
*
52 mock_interface_get_info (GDBusInterfaceSkeleton
*skeleton
)
54 static GDBusPropertyInfo path_info
= {
58 G_DBUS_PROPERTY_INFO_FLAGS_READABLE
,
62 static GDBusPropertyInfo number_info
= {
66 G_DBUS_PROPERTY_INFO_FLAGS_READABLE
,
70 static GDBusPropertyInfo
*property_info
[] = {
76 static GDBusInterfaceInfo interface_info
= {
78 (gchar
*) "org.mock.Interface",
81 (GDBusPropertyInfo
**) &property_info
,
85 return &interface_info
;
89 mock_interface_get_property (GDBusConnection
*connection
,
91 const gchar
*object_path
,
92 const gchar
*interface_name
,
93 const gchar
*property_name
,
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
);
106 static GDBusInterfaceVTable
*
107 mock_interface_get_vtable (GDBusInterfaceSkeleton
*interface
)
109 static GDBusInterfaceVTable vtable
= {
111 mock_interface_get_property
,
119 mock_interface_get_properties (GDBusInterfaceSkeleton
*interface
)
121 GVariantBuilder builder
;
122 GDBusInterfaceInfo
*info
;
123 GDBusInterfaceVTable
*vtable
;
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
)
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
,
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
);
155 mock_interface_flush (GDBusInterfaceSkeleton
*skeleton
)
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
;
170 GDBusConnection
*server
;
171 GDBusConnection
*client
;
173 GAsyncResult
*result
;
177 on_server_connection (GObject
*source
,
178 GAsyncResult
*result
,
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
);
194 on_client_connection (GObject
*source
,
195 GAsyncResult
*result
,
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
);
212 gconstpointer unused
)
214 GError
*error
= NULL
;
216 GSocketConnection
*stream
;
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
);
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
);
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
);
274 on_result (GObject
*source
,
275 GAsyncResult
*result
,
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
);
286 test_object_manager (Test
*test
,
287 gconstpointer unused
)
289 GDBusObjectManager
*client
;
290 GDBusObjectManagerServer
*server
;
292 GDBusObjectSkeleton
*skeleton
;
293 const gchar
*dbus_name
;
294 GError
*error
= NULL
;
295 GDBusInterface
*proxy
;
298 server
= g_dbus_object_manager_server_new ("/objects");
300 mock
= g_object_new (mock_interface_get_type (), NULL
);
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
);
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
);
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
);
360 g_test_init (&argc
, &argv
, NULL
);
362 g_test_add ("/gdbus/peer-object-manager", Test
, NULL
, setup
, test_object_manager
, teardown
);