Line | Branch | Exec | Source |
---|---|---|---|
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License as published by | ||
5 | * the Free Software Foundation; either version 2, or (at your option) | ||
6 | * any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
16 | * | ||
17 | * Copyright 2010 - 2015 Red Hat, Inc. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "nm-default.h" | ||
22 | |||
23 | #include <string.h> | ||
24 | |||
25 | #include "NetworkManager.h" | ||
26 | #include "nm-dbus-compat.h" | ||
27 | |||
28 | #include "nm-test-libnm-utils.h" | ||
29 | |||
30 | /*****************************************************************************/ | ||
31 | |||
32 | static gboolean | ||
33 | 64 | name_exists (GDBusConnection *c, const char *name) | |
34 | { | ||
35 | GVariant *reply; | ||
36 | 64 | gboolean exists = FALSE; | |
37 | |||
38 | 64 | reply = g_dbus_connection_call_sync (c, | |
39 | DBUS_SERVICE_DBUS, | ||
40 | DBUS_PATH_DBUS, | ||
41 | DBUS_INTERFACE_DBUS, | ||
42 | "GetNameOwner", | ||
43 | g_variant_new ("(s)", name), | ||
44 | NULL, | ||
45 | G_DBUS_CALL_FLAGS_NO_AUTO_START, | ||
46 | -1, | ||
47 | NULL, | ||
48 | NULL); | ||
49 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 42 times.
|
64 | if (reply != NULL) { |
50 | 22 | exists = TRUE; | |
51 | 22 | g_variant_unref (reply); | |
52 | } | ||
53 | |||
54 | 64 | return exists; | |
55 | } | ||
56 | |||
57 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
58 | static DBusGProxy * | ||
59 | _libdbus_create_proxy_test (DBusGConnection *bus) | ||
60 | { | ||
61 | DBusGProxy *proxy; | ||
62 | |||
63 | proxy = dbus_g_proxy_new_for_name (bus, | ||
64 | NM_DBUS_SERVICE, | ||
65 | NM_DBUS_PATH, | ||
66 | "org.freedesktop.NetworkManager.LibnmGlibTest"); | ||
67 | g_assert (proxy); | ||
68 | |||
69 | dbus_g_proxy_set_default_timeout (proxy, G_MAXINT); | ||
70 | |||
71 | return proxy; | ||
72 | } | ||
73 | #endif | ||
74 | |||
75 | NMTstcServiceInfo * | ||
76 | 11 | nmtstc_service_init (void) | |
77 | { | ||
78 | NMTstcServiceInfo *info; | ||
79 | 11 | const char *args[] = { TEST_NM_PYTHON, TEST_NM_SERVICE, NULL }; | |
80 | 11 | GError *error = NULL; | |
81 | int i; | ||
82 | |||
83 | 11 | info = g_malloc0 (sizeof (*info)); | |
84 | |||
85 | 11 | info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); | |
86 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | g_assert_no_error (error); |
87 | |||
88 | /* Spawn the test service. info->keepalive_fd will be a pipe to the service's | ||
89 | * stdin; if it closes, the service will exit immediately. We use this to | ||
90 | * make sure the service exits if the test program crashes. | ||
91 | */ | ||
92 | 11 | g_spawn_async_with_pipes (NULL, (char **) args, NULL, | |
93 | G_SPAWN_SEARCH_PATH, | ||
94 | NULL, NULL, | ||
95 | 11 | &info->pid, &info->keepalive_fd, NULL, NULL, &error); | |
96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | g_assert_no_error (error); |
97 | |||
98 | /* Wait until the service is registered on the bus */ | ||
99 |
1/2✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
|
42 | for (i = 1000; i > 0; i--) { |
100 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 31 times.
|
42 | if (name_exists (info->bus, "org.freedesktop.NetworkManager")) |
101 | 11 | break; | |
102 | 31 | g_usleep (G_USEC_PER_SEC / 50); | |
103 | } | ||
104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | g_assert (i > 0); |
105 | |||
106 | /* Grab a proxy to our fake NM service to trigger tests */ | ||
107 | 11 | info->proxy = g_dbus_proxy_new_sync (info->bus, | |
108 | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | | ||
109 | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | | ||
110 | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, | ||
111 | NULL, | ||
112 | NM_DBUS_SERVICE, | ||
113 | NM_DBUS_PATH, | ||
114 | "org.freedesktop.NetworkManager.LibnmGlibTest", | ||
115 | NULL, &error); | ||
116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | g_assert_no_error (error); |
117 | |||
118 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
119 | info->libdbus.bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); | ||
120 | g_assert_no_error (error); | ||
121 | g_assert (info->libdbus.bus); | ||
122 | #endif | ||
123 | 11 | return info; | |
124 | } | ||
125 | |||
126 | void | ||
127 | 11 | nmtstc_service_cleanup (NMTstcServiceInfo *info) | |
128 | { | ||
129 | int i; | ||
130 | |||
131 | 11 | g_object_unref (info->proxy); | |
132 | 11 | kill (info->pid, SIGTERM); | |
133 | |||
134 | /* Wait until the bus notices the service is gone */ | ||
135 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | for (i = 100; i > 0; i--) { |
136 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
|
22 | if (!name_exists (info->bus, "org.freedesktop.NetworkManager")) |
137 | 11 | break; | |
138 | 11 | g_usleep (G_USEC_PER_SEC / 50); | |
139 | } | ||
140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | g_assert (i > 0); |
141 | |||
142 | 11 | g_object_unref (info->bus); | |
143 | 11 | nm_close (info->keepalive_fd); | |
144 | |||
145 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
146 | g_clear_pointer (&info->libdbus.bus, dbus_g_connection_unref); | ||
147 | #endif | ||
148 | |||
149 | 11 | memset (info, 0, sizeof (*info)); | |
150 | 11 | g_free (info); | |
151 | 11 | } | |
152 | |||
153 | #if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB) | ||
154 | typedef struct { | ||
155 | GMainLoop *loop; | ||
156 | const char *ifname; | ||
157 | char *path; | ||
158 | NMDevice *device; | ||
159 | } AddDeviceInfo; | ||
160 | |||
161 | static void | ||
162 | 13 | device_added_cb (NMClient *client, | |
163 | NMDevice *device, | ||
164 | gpointer user_data) | ||
165 | { | ||
166 | 13 | AddDeviceInfo *info = user_data; | |
167 | |||
168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | g_assert (device); |
169 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
|
13 | g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path); |
170 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
|
13 | g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname); |
171 | |||
172 | 13 | info->device = device; | |
173 | 13 | g_main_loop_quit (info->loop); | |
174 | 13 | } | |
175 | |||
176 | static gboolean | ||
177 | ✗ | timeout (gpointer user_data) | |
178 | { | ||
179 | ✗ | g_assert_not_reached (); | |
180 | return G_SOURCE_REMOVE; | ||
181 | } | ||
182 | |||
183 | static GVariant * | ||
184 | 13 | call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr, | |
185 | const char **subchannels, GError **error) | ||
186 | { | ||
187 | 13 | const char *empty[] = { NULL }; | |
188 | |||
189 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | if (!hwaddr) |
190 | ✗ | hwaddr = "/"; | |
191 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if (!subchannels) |
192 | 13 | subchannels = empty; | |
193 | |||
194 | 13 | return g_dbus_proxy_call_sync (proxy, | |
195 | "AddWiredDevice", | ||
196 | g_variant_new ("(ss^as)", ifname, hwaddr, subchannels), | ||
197 | G_DBUS_CALL_FLAGS_NO_AUTO_START, | ||
198 | 3000, | ||
199 | NULL, | ||
200 | error); | ||
201 | } | ||
202 | |||
203 | static GVariant * | ||
204 | ✗ | call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GError **error) | |
205 | { | ||
206 | ✗ | return g_dbus_proxy_call_sync (proxy, | |
207 | method, | ||
208 | g_variant_new ("(s)", ifname), | ||
209 | G_DBUS_CALL_FLAGS_NO_AUTO_START, | ||
210 | 3000, | ||
211 | NULL, | ||
212 | error); | ||
213 | } | ||
214 | |||
215 | static NMDevice * | ||
216 | 13 | add_device_common (NMTstcServiceInfo *sinfo, NMClient *client, | |
217 | const char *method, const char *ifname, | ||
218 | const char *hwaddr, const char **subchannels) | ||
219 | { | ||
220 | AddDeviceInfo info; | ||
221 | 13 | GError *error = NULL; | |
222 | GVariant *ret; | ||
223 | guint timeout_id; | ||
224 | |||
225 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | if (g_strcmp0 (method, "AddWiredDevice") == 0) |
226 | 13 | ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error); | |
227 | else | ||
228 | ✗ | ret = call_add_device (sinfo->proxy, method, ifname, &error); | |
229 | |||
230 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | g_assert_no_error (error); |
231 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | g_assert (ret); |
232 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
|
13 | g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); |
233 | 13 | g_variant_get (ret, "(o)", &info.path); | |
234 | 13 | g_variant_unref (ret); | |
235 | |||
236 | /* Wait for libnm to find the device */ | ||
237 | 13 | info.ifname = ifname; | |
238 | 13 | info.loop = g_main_loop_new (NULL, FALSE); | |
239 | 13 | g_signal_connect (client, "device-added", | |
240 | G_CALLBACK (device_added_cb), &info); | ||
241 | 13 | timeout_id = g_timeout_add_seconds (5, timeout, NULL); | |
242 | 13 | g_main_loop_run (info.loop); | |
243 | |||
244 | 13 | g_source_remove (timeout_id); | |
245 | 13 | g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); | |
246 | 13 | g_free (info.path); | |
247 | 13 | g_main_loop_unref (info.loop); | |
248 | |||
249 | 13 | return info.device; | |
250 | } | ||
251 | |||
252 | NMDevice * | ||
253 | ✗ | nmtstc_service_add_device (NMTstcServiceInfo *sinfo, NMClient *client, | |
254 | const char *method, const char *ifname) | ||
255 | { | ||
256 | ✗ | return add_device_common (sinfo, client, method, ifname, NULL, NULL); | |
257 | } | ||
258 | |||
259 | NMDevice * | ||
260 | 13 | nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo, NMClient *client, | |
261 | const char *ifname, const char *hwaddr, | ||
262 | const char **subchannels) | ||
263 | { | ||
264 | 13 | return add_device_common (sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels); | |
265 | } | ||
266 | #endif | ||
267 | |||
268 | void | ||
269 | ✗ | nmtstc_service_add_connection (NMTstcServiceInfo *sinfo, | |
270 | NMConnection *connection, | ||
271 | gboolean verify_connection, | ||
272 | char **out_path) | ||
273 | { | ||
274 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
275 | gs_unref_hashtable GHashTable *new_settings = NULL; | ||
276 | gboolean success; | ||
277 | gs_free_error GError *error = NULL; | ||
278 | gs_free char *path = NULL; | ||
279 | gs_unref_object DBusGProxy *proxy = NULL; | ||
280 | |||
281 | g_assert (sinfo); | ||
282 | g_assert (NM_IS_CONNECTION (connection)); | ||
283 | |||
284 | new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); | ||
285 | |||
286 | proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus); | ||
287 | |||
288 | success = dbus_g_proxy_call (proxy, | ||
289 | "AddConnection", | ||
290 | &error, | ||
291 | DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, | ||
292 | G_TYPE_BOOLEAN, verify_connection, | ||
293 | G_TYPE_INVALID, | ||
294 | DBUS_TYPE_G_OBJECT_PATH, &path, | ||
295 | G_TYPE_INVALID); | ||
296 | g_assert_no_error (error); | ||
297 | g_assert (success); | ||
298 | |||
299 | g_assert (path && *path); | ||
300 | |||
301 | if (out_path) | ||
302 | *out_path = g_strdup (path); | ||
303 | #else | ||
304 | ✗ | nmtstc_service_add_connection_variant (sinfo, | |
305 | nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), | ||
306 | verify_connection, | ||
307 | out_path); | ||
308 | #endif | ||
309 | ✗ | } | |
310 | |||
311 | void | ||
312 | ✗ | nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo, | |
313 | GVariant *connection, | ||
314 | gboolean verify_connection, | ||
315 | char **out_path) | ||
316 | { | ||
317 | GVariant *result; | ||
318 | ✗ | GError *error = NULL; | |
319 | |||
320 | ✗ | g_assert (sinfo); | |
321 | ✗ | g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); | |
322 | ✗ | g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); | |
323 | |||
324 | ✗ | result = g_dbus_proxy_call_sync (sinfo->proxy, | |
325 | "AddConnection", | ||
326 | g_variant_new ("(vb)", connection, verify_connection), | ||
327 | G_DBUS_CALL_FLAGS_NO_AUTO_START, | ||
328 | 3000, | ||
329 | NULL, | ||
330 | &error); | ||
331 | ✗ | g_assert_no_error (error); | |
332 | ✗ | g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))); | |
333 | ✗ | if (out_path) | |
334 | ✗ | g_variant_get (result, "(o)", out_path); | |
335 | ✗ | g_variant_unref (result); | |
336 | ✗ | } | |
337 | |||
338 | void | ||
339 | ✗ | nmtstc_service_update_connection (NMTstcServiceInfo *sinfo, | |
340 | const char *path, | ||
341 | NMConnection *connection, | ||
342 | gboolean verify_connection) | ||
343 | { | ||
344 | ✗ | if (!path) | |
345 | ✗ | path = nm_connection_get_path (connection); | |
346 | ✗ | g_assert (path); | |
347 | |||
348 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
349 | { | ||
350 | gs_unref_hashtable GHashTable *new_settings = NULL; | ||
351 | gboolean success; | ||
352 | gs_free_error GError *error = NULL; | ||
353 | gs_unref_object DBusGProxy *proxy = NULL; | ||
354 | |||
355 | g_assert (sinfo); | ||
356 | g_assert (NM_IS_CONNECTION (connection)); | ||
357 | |||
358 | new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); | ||
359 | |||
360 | proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus); | ||
361 | |||
362 | success = dbus_g_proxy_call (proxy, | ||
363 | "UpdateConnection", | ||
364 | &error, | ||
365 | DBUS_TYPE_G_OBJECT_PATH, path, | ||
366 | DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, | ||
367 | G_TYPE_BOOLEAN, verify_connection, | ||
368 | G_TYPE_INVALID, | ||
369 | G_TYPE_INVALID); | ||
370 | g_assert_no_error (error); | ||
371 | g_assert (success); | ||
372 | } | ||
373 | #else | ||
374 | ✗ | nmtstc_service_update_connection_variant (sinfo, | |
375 | path, | ||
376 | nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), | ||
377 | verify_connection); | ||
378 | #endif | ||
379 | ✗ | } | |
380 | |||
381 | void | ||
382 | 1 | nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo, | |
383 | const char *path, | ||
384 | GVariant *connection, | ||
385 | gboolean verify_connection) | ||
386 | { | ||
387 | GVariant *result; | ||
388 | 1 | GError *error = NULL; | |
389 | |||
390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert (sinfo); |
391 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
1 | g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); |
392 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); |
393 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | g_assert (path && path[0] == '/'); |
394 | |||
395 | 1 | result = g_dbus_proxy_call_sync (sinfo->proxy, | |
396 | "UpdateConnection", | ||
397 | g_variant_new ("(ovb)", path, connection, verify_connection), | ||
398 | G_DBUS_CALL_FLAGS_NO_AUTO_START, | ||
399 | 3000, | ||
400 | NULL, | ||
401 | &error); | ||
402 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | g_assert_no_error (error); |
403 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()"))); |
404 | 1 | g_variant_unref (result); | |
405 | 1 | } | |
406 | |||
407 | /*****************************************************************************/ | ||
408 | |||
409 | #if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB | ||
410 | NMClient * | ||
411 | nmtstc_nm_client_new (void) | ||
412 | { | ||
413 | NMClient *client; | ||
414 | DBusGConnection *bus; | ||
415 | GError *error = NULL; | ||
416 | gboolean success; | ||
417 | |||
418 | bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); | ||
419 | g_assert_no_error (error); | ||
420 | g_assert (bus); | ||
421 | |||
422 | client = g_object_new (NM_TYPE_CLIENT, | ||
423 | NM_OBJECT_DBUS_CONNECTION, bus, | ||
424 | NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, | ||
425 | NULL); | ||
426 | g_assert (client != NULL); | ||
427 | |||
428 | dbus_g_connection_unref (bus); | ||
429 | |||
430 | success = g_initable_init (G_INITABLE (client), NULL, &error); | ||
431 | g_assert_no_error (error); | ||
432 | g_assert (success == TRUE); | ||
433 | |||
434 | return client; | ||
435 | } | ||
436 | |||
437 | NMRemoteSettings * | ||
438 | nmtstc_nm_remote_settings_new (void) | ||
439 | { | ||
440 | NMRemoteSettings *settings; | ||
441 | DBusGConnection *bus; | ||
442 | GError *error = NULL; | ||
443 | |||
444 | bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); | ||
445 | g_assert_no_error (error); | ||
446 | g_assert (bus); | ||
447 | |||
448 | settings = nm_remote_settings_new (bus); | ||
449 | g_assert (settings); | ||
450 | |||
451 | dbus_g_connection_unref (bus); | ||
452 | |||
453 | return settings; | ||
454 | } | ||
455 | #endif | ||
456 | |||
457 | /*****************************************************************************/ | ||
458 |