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.1 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)
223 g_set_error (&error
, G_IO_ERROR
, g_io_error_from_errno (errsv
),
224 "%s", g_strerror (errsv
));
225 g_assert_no_error (error
);
228 /* Build up the server stuff */
229 socket
= g_socket_new_from_fd (pair
[1], &error
);
230 g_assert_no_error (error
);
232 stream
= g_socket_connection_factory_create_connection (socket
);
233 g_assert (stream
!= NULL
);
234 g_object_unref (socket
);
236 guid
= g_dbus_generate_guid ();
237 g_dbus_connection_new (G_IO_STREAM (stream
), guid
,
238 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER
|
239 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS
,
240 NULL
, NULL
, on_server_connection
, test
);
241 g_object_unref (stream
);
244 /* Build up the client stuff */
245 socket
= g_socket_new_from_fd (pair
[0], &error
);
246 g_assert_no_error (error
);
248 stream
= g_socket_connection_factory_create_connection (socket
);
249 g_assert (stream
!= NULL
);
250 g_object_unref (socket
);
252 g_dbus_connection_new (G_IO_STREAM (stream
), NULL
,
253 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
|
254 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS
,
255 NULL
, NULL
, on_client_connection
, test
);
257 g_main_loop_run (test
->loop
);
259 g_assert (test
->server
);
260 g_assert (test
->client
);
262 g_object_unref (stream
);
266 teardown (Test
*test
,
267 gconstpointer unused
)
269 g_clear_object (&test
->client
);
270 g_clear_object (&test
->server
);
271 g_main_loop_unref (test
->loop
);
275 on_result (GObject
*source
,
276 GAsyncResult
*result
,
279 Test
*test
= user_data
;
280 g_assert (test
->result
== NULL
);
281 test
->result
= g_object_ref (result
);
282 g_main_loop_quit (test
->loop
);
287 test_object_manager (Test
*test
,
288 gconstpointer test_data
)
290 GDBusObjectManager
*client
;
291 GDBusObjectManagerServer
*server
;
293 GDBusObjectSkeleton
*skeleton
;
294 const gchar
*dbus_name
;
295 GError
*error
= NULL
;
296 GDBusInterface
*proxy
;
298 const gchar
*object_path
= test_data
;
299 gchar
*number1_path
= NULL
, *number2_path
= NULL
;
301 if (g_strcmp0 (object_path
, "/") == 0)
303 number1_path
= g_strdup ("/number_1");
304 number2_path
= g_strdup ("/number_2");
308 number1_path
= g_strdup_printf ("%s/number_1", object_path
);
309 number2_path
= g_strdup_printf ("%s/number_2", object_path
);
312 server
= g_dbus_object_manager_server_new (object_path
);
314 mock
= g_object_new (mock_interface_get_type (), NULL
);
316 skeleton
= g_dbus_object_skeleton_new (number1_path
);
317 g_dbus_object_skeleton_add_interface (skeleton
, G_DBUS_INTERFACE_SKELETON (mock
));
318 g_dbus_object_manager_server_export (server
, skeleton
);
320 mock
= g_object_new (mock_interface_get_type (), NULL
);
322 skeleton
= g_dbus_object_skeleton_new (number2_path
);
323 g_dbus_object_skeleton_add_interface (skeleton
, G_DBUS_INTERFACE_SKELETON (mock
));
324 g_dbus_object_manager_server_export (server
, skeleton
);
326 g_dbus_object_manager_server_set_connection (server
, test
->server
);
330 g_dbus_object_manager_client_new (test
->client
, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
,
331 dbus_name
, object_path
, NULL
, NULL
, NULL
, NULL
, on_result
, test
);
333 g_main_loop_run (test
->loop
);
334 client
= g_dbus_object_manager_client_new_finish (test
->result
, &error
);
335 g_assert_no_error (error
);
336 g_clear_object (&test
->result
);
338 proxy
= g_dbus_object_manager_get_interface (client
, number1_path
, "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
), ==, number1_path
);
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
), ==, 1);
349 g_variant_unref (prop
);
350 g_object_unref (proxy
);
352 proxy
= g_dbus_object_manager_get_interface (client
, number2_path
, "org.mock.Interface");
353 g_assert (proxy
!= NULL
);
354 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Path");
355 g_assert (prop
!= NULL
);
356 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_OBJECT_PATH
);
357 g_assert_cmpstr (g_variant_get_string (prop
, NULL
), ==, number2_path
);
358 g_variant_unref (prop
);
359 prop
= g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy
), "Number");
360 g_assert (prop
!= NULL
);
361 g_assert_cmpstr ((gchar
*)g_variant_get_type (prop
), ==, (gchar
*)G_VARIANT_TYPE_INT32
);
362 g_assert_cmpint (g_variant_get_int32 (prop
), ==, 2);
363 g_variant_unref (prop
);
364 g_object_unref (proxy
);
366 g_object_unref (server
);
367 g_object_unref (client
);
369 g_free (number2_path
);
370 g_free (number1_path
);
377 g_test_init (&argc
, &argv
, NULL
);
379 g_test_add ("/gdbus/peer-object-manager/normal", Test
, "/objects",
380 setup
, test_object_manager
, teardown
);
381 g_test_add ("/gdbus/peer-object-manager/root", Test
, "/",
382 setup
, test_object_manager
, teardown
);