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, see <http://www.gnu.org/licenses/>.
18 * Author: Stef Walter <stefw@gnome.org>
25 #include <sys/socket.h>
32 GDBusInterfaceSkeleton parent
;
37 GDBusInterfaceSkeletonClass parent_class
;
40 static GType
mock_interface_get_type (void);
41 G_DEFINE_TYPE (MockInterface
, mock_interface
, G_TYPE_DBUS_INTERFACE_SKELETON
);
44 mock_interface_init (MockInterface
*self
)
49 static GDBusInterfaceInfo
*
50 mock_interface_get_info (GDBusInterfaceSkeleton
*skeleton
)
52 static GDBusPropertyInfo path_info
= {
56 G_DBUS_PROPERTY_INFO_FLAGS_READABLE
,
60 static GDBusPropertyInfo number_info
= {
64 G_DBUS_PROPERTY_INFO_FLAGS_READABLE
,
68 static GDBusPropertyInfo
*property_info
[] = {
74 static GDBusInterfaceInfo interface_info
= {
76 (gchar
*) "org.mock.Interface",
79 (GDBusPropertyInfo
**) &property_info
,
83 return &interface_info
;
87 mock_interface_get_property (GDBusConnection
*connection
,
89 const gchar
*object_path
,
90 const gchar
*interface_name
,
91 const gchar
*property_name
,
95 MockInterface
*self
= user_data
;
96 if (g_str_equal (property_name
, "Path"))
97 return g_variant_new_object_path (object_path
);
98 else if (g_str_equal (property_name
, "Number"))
99 return g_variant_new_int32 (self
->number
);
104 static GDBusInterfaceVTable
*
105 mock_interface_get_vtable (GDBusInterfaceSkeleton
*interface
)
107 static GDBusInterfaceVTable vtable
= {
109 mock_interface_get_property
,
117 mock_interface_get_properties (GDBusInterfaceSkeleton
*interface
)
119 GVariantBuilder builder
;
120 GDBusInterfaceInfo
*info
;
121 GDBusInterfaceVTable
*vtable
;
124 /* Groan, this is completely generic code and should be in gdbus */
126 info
= g_dbus_interface_skeleton_get_info (interface
);
127 vtable
= g_dbus_interface_skeleton_get_vtable (interface
);
129 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("a{sv}"));
130 for (n
= 0; info
->properties
[n
] != NULL
; n
++)
132 if (info
->properties
[n
]->flags
& G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
135 g_return_val_if_fail (vtable
->get_property
!= NULL
, NULL
);
136 value
= (vtable
->get_property
) (g_dbus_interface_skeleton_get_connection (interface
), NULL
,
137 g_dbus_interface_skeleton_get_object_path (interface
),
138 info
->name
, info
->properties
[n
]->name
,
142 g_variant_take_ref (value
);
143 g_variant_builder_add (&builder
, "{sv}", info
->properties
[n
]->name
, value
);
144 g_variant_unref (value
);
149 return g_variant_builder_end (&builder
);
153 mock_interface_flush (GDBusInterfaceSkeleton
*skeleton
)
159 mock_interface_class_init (MockInterfaceClass
*klass
)
161 GDBusInterfaceSkeletonClass
*skeleton_class
= G_DBUS_INTERFACE_SKELETON_CLASS (klass
);
162 skeleton_class
->get_info
= mock_interface_get_info
;
163 skeleton_class
->get_properties
= mock_interface_get_properties
;
164 skeleton_class
->flush
= mock_interface_flush
;
165 skeleton_class
->get_vtable
= mock_interface_get_vtable
;
168 GDBusConnection
*server
;
169 GDBusConnection
*client
;
171 GAsyncResult
*result
;
175 on_server_connection (GObject
*source
,
176 GAsyncResult
*result
,
179 Test
*test
= user_data
;
180 GError
*error
= NULL
;
182 g_assert (test
->server
== NULL
);
183 test
->server
= g_dbus_connection_new_finish (result
, &error
);
184 g_assert_no_error (error
);
185 g_assert (test
->server
!= NULL
);
187 if (test
->server
&& test
->client
)
188 g_main_loop_quit (test
->loop
);
192 on_client_connection (GObject
*source
,
193 GAsyncResult
*result
,
196 Test
*test
= user_data
;
197 GError
*error
= NULL
;
199 g_assert (test
->client
== NULL
);
200 test
->client
= g_dbus_connection_new_finish (result
, &error
);
201 g_assert_no_error (error
);
202 g_assert (test
->client
!= NULL
);
204 if (test
->server
&& test
->client
)
205 g_main_loop_quit (test
->loop
);
210 gconstpointer unused
)
212 GError
*error
= NULL
;
214 GSocketConnection
*stream
;
218 test
->loop
= g_main_loop_new (NULL
, FALSE
);
220 if (socketpair (AF_UNIX
, SOCK_STREAM
, 0, pair
) < 0)
222 g_set_error (&error
, G_IO_ERROR
, g_io_error_from_errno (errno
),
223 "%s", g_strerror (errno
));
224 g_assert_no_error (error
);
227 /* Build up the server stuff */
228 socket
= g_socket_new_from_fd (pair
[1], &error
);
229 g_assert_no_error (error
);
231 stream
= g_socket_connection_factory_create_connection (socket
);
232 g_assert (stream
!= NULL
);
233 g_object_unref (socket
);
235 guid
= g_dbus_generate_guid ();
236 g_dbus_connection_new (G_IO_STREAM (stream
), guid
,
237 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER
|
238 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS
,
239 NULL
, NULL
, on_server_connection
, test
);
240 g_object_unref (stream
);
243 /* Build up the client stuff */
244 socket
= g_socket_new_from_fd (pair
[0], &error
);
245 g_assert_no_error (error
);
247 stream
= g_socket_connection_factory_create_connection (socket
);
248 g_assert (stream
!= NULL
);
249 g_object_unref (socket
);
251 g_dbus_connection_new (G_IO_STREAM (stream
), NULL
,
252 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
|
253 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS
,
254 NULL
, NULL
, on_client_connection
, test
);
256 g_main_loop_run (test
->loop
);
258 g_assert (test
->server
);
259 g_assert (test
->client
);
263 teardown (Test
*test
,
264 gconstpointer unused
)
266 g_clear_object (&test
->client
);
267 g_clear_object (&test
->server
);
268 g_main_loop_unref (test
->loop
);
272 on_result (GObject
*source
,
273 GAsyncResult
*result
,
276 Test
*test
= user_data
;
277 g_assert (test
->result
== NULL
);
278 test
->result
= g_object_ref (result
);
279 g_main_loop_quit (test
->loop
);
284 test_object_manager (Test
*test
,
285 gconstpointer test_data
)
287 GDBusObjectManager
*client
;
288 GDBusObjectManagerServer
*server
;
290 GDBusObjectSkeleton
*skeleton
;
291 const gchar
*dbus_name
;
292 GError
*error
= NULL
;
293 GDBusInterface
*proxy
;
295 const gchar
*object_path
= test_data
;
296 gchar
*number1_path
= NULL
, *number2_path
= NULL
;
298 if (g_strcmp0 (object_path
, "/") == 0)
300 number1_path
= g_strdup ("/number_1");
301 number2_path
= g_strdup ("/number_2");
305 number1_path
= g_strdup_printf ("%s/number_1", object_path
);
306 number2_path
= g_strdup_printf ("%s/number_2", object_path
);
309 server
= g_dbus_object_manager_server_new (object_path
);
311 mock
= g_object_new (mock_interface_get_type (), NULL
);
313 skeleton
= g_dbus_object_skeleton_new (number1_path
);
314 g_dbus_object_skeleton_add_interface (skeleton
, G_DBUS_INTERFACE_SKELETON (mock
));
315 g_dbus_object_manager_server_export (server
, skeleton
);
317 mock
= g_object_new (mock_interface_get_type (), NULL
);
319 skeleton
= g_dbus_object_skeleton_new (number2_path
);
320 g_dbus_object_skeleton_add_interface (skeleton
, G_DBUS_INTERFACE_SKELETON (mock
));
321 g_dbus_object_manager_server_export (server
, skeleton
);
323 g_dbus_object_manager_server_set_connection (server
, test
->server
);
327 g_dbus_object_manager_client_new (test
->client
, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
,
328 dbus_name
, object_path
, NULL
, NULL
, NULL
, NULL
, on_result
, test
);
330 g_main_loop_run (test
->loop
);
331 client
= g_dbus_object_manager_client_new_finish (test
->result
, &error
);
332 g_assert_no_error (error
);
333 g_clear_object (&test
->result
);
335 proxy
= g_dbus_object_manager_get_interface (client
, number1_path
, "org.mock.Interface");
336 g_assert (proxy
!= NULL
);
337 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Path");
338 g_assert (prop
!= NULL
);
339 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_OBJECT_PATH
);
340 g_assert_cmpstr (g_variant_get_string (prop
, NULL
), ==, number1_path
);
341 g_variant_unref (prop
);
342 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Number");
343 g_assert (prop
!= NULL
);
344 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_INT32
);
345 g_assert_cmpint (g_variant_get_int32 (prop
), ==, 1);
346 g_variant_unref (prop
);
347 g_object_unref (proxy
);
349 proxy
= g_dbus_object_manager_get_interface (client
, number2_path
, "org.mock.Interface");
350 g_assert (proxy
!= NULL
);
351 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Path");
352 g_assert (prop
!= NULL
);
353 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_OBJECT_PATH
);
354 g_assert_cmpstr (g_variant_get_string (prop
, NULL
), ==, number2_path
);
355 g_variant_unref (prop
);
356 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Number");
357 g_assert (prop
!= NULL
);
358 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_INT32
);
359 g_assert_cmpint (g_variant_get_int32 (prop
), ==, 2);
360 g_variant_unref (prop
);
361 g_object_unref (proxy
);
363 g_object_unref (server
);
364 g_object_unref (client
);
366 g_free (number2_path
);
367 g_free (number1_path
);
374 g_test_init (&argc
, &argv
, NULL
);
376 g_test_add ("/gdbus/peer-object-manager/normal", Test
, "/objects",
377 setup
, test_object_manager
, teardown
);
378 g_test_add ("/gdbus/peer-object-manager/root", Test
, "/",
379 setup
, test_object_manager
, teardown
);