Plug some leaks in the GIO tests
[platform/upstream/glib.git] / gio / tests / network-monitor.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2011 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
21 #include "gio.h"
22
23 /* hack */
24 #define GIO_COMPILATION
25 #include "gnetworkmonitorbase.h"
26
27 #include <string.h>
28
29 /* Test data; the GInetAddresses and GInetAddressMasks get filled in
30  * in main(). Each address in a TestAddress matches the mask in its
31  * corresponding TestMask, and none of them match any of the other
32  * masks. The addresses in unmatched don't match any of the masks.
33  */
34
35 typedef struct {
36   const char *string;
37   GInetAddress *address;
38 } TestAddress;
39
40 typedef struct {
41   const char *mask_string;
42   GInetAddressMask *mask;
43   TestAddress *addresses;
44 } TestMask;
45
46 TestAddress net127addrs[] = {
47   { "127.0.0.1", NULL },
48   { "127.0.0.2", NULL },
49   { "127.0.0.255", NULL },
50   { "127.0.1.0", NULL },
51   { "127.0.255.0", NULL },
52   { "127.0.255.0", NULL },
53   { "127.255.255.255", NULL },
54   { NULL, NULL }
55 };
56 TestMask net127 = { "127.0.0.0/8", NULL, net127addrs };
57
58 TestAddress net10addrs[] = {
59   { "10.0.0.1", NULL },
60   { "10.0.0.2", NULL },
61   { "10.0.0.255", NULL },
62   { NULL, NULL }
63 };
64 TestMask net10 = { "10.0.0.0/24", NULL, net10addrs };
65
66 TestAddress net192addrs[] = {
67   { "192.168.0.1", NULL },
68   { "192.168.0.2", NULL },
69   { "192.168.0.255", NULL },
70   { "192.168.1.0", NULL },
71   { "192.168.15.0", NULL },
72   { NULL, NULL }
73 };
74 TestMask net192 = { "192.168.0.0/20", NULL, net192addrs };
75
76 TestAddress netlocal6addrs[] = {
77   { "::1", NULL },
78   { NULL, NULL }
79 };
80 TestMask netlocal6 = { "::1/128", NULL, netlocal6addrs };
81
82 TestAddress netfe80addrs[] = {
83   { "fe80::", NULL },
84   { "fe80::1", NULL },
85   { "fe80::21b:77ff:fea2:972a", NULL },
86   { NULL, NULL }
87 };
88 TestMask netfe80 = { "fe80::/64", NULL, netfe80addrs };
89
90 TestAddress unmatched[] = {
91   { "10.0.1.0", NULL },
92   { "10.0.255.0", NULL },
93   { "10.255.255.255", NULL },
94   { "192.168.16.0", NULL },
95   { "192.168.255.0", NULL },
96   { "192.169.0.0", NULL },
97   { "192.255.255.255", NULL },
98   { "::2", NULL },
99   { "1::1", NULL },
100   { "fe80::1:0:0:0:0", NULL },
101   { "fe80:8000::0:0:0:0", NULL },
102   { NULL, NULL }
103 };
104
105 GInetAddressMask *ip4_default, *ip6_default;
106
107 static void
108 notify_handler (GObject    *object,
109                 GParamSpec *pspec,
110                 gpointer    user_data)
111 {
112   gboolean *emitted = user_data;
113
114   *emitted = TRUE;
115 }
116
117 static void
118 network_changed_handler (GNetworkMonitor *monitor,
119                          gboolean         available,
120                          gpointer         user_data)
121 {
122   gboolean *emitted = user_data;
123
124   *emitted = TRUE;
125 }
126
127 static void
128 assert_signals (GNetworkMonitor *monitor,
129                 gboolean         should_emit_notify,
130                 gboolean         should_emit_network_changed,
131                 gboolean         expected_network_available)
132 {
133   gboolean emitted_notify = FALSE, emitted_network_changed = FALSE;
134   guint h1, h2;
135
136   h1 = g_signal_connect (monitor, "notify::network-available",
137                          G_CALLBACK (notify_handler),
138                          &emitted_notify);
139   h2 = g_signal_connect (monitor, "network-changed",
140                          G_CALLBACK (network_changed_handler),
141                          &emitted_network_changed);
142
143   g_main_context_iteration (NULL, FALSE);
144
145   g_signal_handler_disconnect (monitor, h1);
146   g_signal_handler_disconnect (monitor, h2);
147
148   g_assert (emitted_notify == should_emit_notify);
149   g_assert (emitted_network_changed == should_emit_network_changed);
150
151   g_assert (g_network_monitor_get_network_available (monitor) == expected_network_available);
152 }
153
154 static void
155 run_tests (GNetworkMonitor *monitor,
156            TestAddress     *addresses,
157            gboolean         should_be_reachable)
158 {
159   GError *error = NULL;
160   int i;
161   gboolean reachable;
162   GSocketAddress *sockaddr;
163
164   for (i = 0; addresses[i].address; i++)
165     {
166       sockaddr = g_inet_socket_address_new (addresses[i].address, 0);
167       reachable = g_network_monitor_can_reach (monitor,
168                                                G_SOCKET_CONNECTABLE (sockaddr),
169                                                NULL, &error);
170       g_object_unref (sockaddr);
171       g_assert_cmpint (reachable, ==, should_be_reachable);
172       if (should_be_reachable)
173         g_assert_no_error (error);
174       else
175         {
176           g_assert (error != NULL);
177           g_clear_error (&error);
178         }
179     }
180 }
181
182 static void
183 test_default (void)
184 {
185   GNetworkMonitor *monitor;
186   GError *error = NULL;
187
188   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
189   g_assert_no_error (error);
190
191   /* In the default configuration, all addresses are reachable */
192   run_tests (monitor, net127.addresses, TRUE);
193   run_tests (monitor, net10.addresses, TRUE);
194   run_tests (monitor, net192.addresses, TRUE);
195   run_tests (monitor, netlocal6.addresses, TRUE);
196   run_tests (monitor, netfe80.addresses, TRUE);
197   run_tests (monitor, unmatched, TRUE);
198
199   assert_signals (monitor, FALSE, FALSE, TRUE);
200
201   g_object_unref (monitor);
202 }
203
204 static void
205 test_remove_default (void)
206 {
207   GNetworkMonitor *monitor;
208   GError *error = NULL;
209
210   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
211   g_assert_no_error (error);
212   assert_signals (monitor, FALSE, FALSE, TRUE);
213
214   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
215                                          ip4_default);
216   assert_signals (monitor, FALSE, TRUE, TRUE);
217   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
218                                          ip6_default);
219   assert_signals (monitor, TRUE, TRUE, FALSE);
220
221   /* Now nothing should be reachable */
222   run_tests (monitor, net127.addresses, FALSE);
223   run_tests (monitor, net10.addresses, FALSE);
224   run_tests (monitor, net192.addresses, FALSE);
225   run_tests (monitor, netlocal6.addresses, FALSE);
226   run_tests (monitor, netfe80.addresses, FALSE);
227   run_tests (monitor, unmatched, FALSE);
228
229   g_object_unref (monitor);
230 }
231
232 static void
233 test_add_networks (void)
234 {
235   GNetworkMonitor *monitor;
236   GError *error = NULL;
237
238   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
239   g_assert_no_error (error);
240   assert_signals (monitor, FALSE, FALSE, TRUE);
241
242   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
243                                          ip4_default);
244   assert_signals (monitor, FALSE, TRUE, TRUE);
245   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
246                                          ip6_default);
247   assert_signals (monitor, TRUE, TRUE, FALSE);
248
249   /* Now add the masks one by one */
250
251   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
252                                       net127.mask);
253   assert_signals (monitor, FALSE, TRUE, FALSE);
254
255   run_tests (monitor, net127.addresses, TRUE);
256   run_tests (monitor, net10.addresses, FALSE);
257   run_tests (monitor, net192.addresses, FALSE);
258   run_tests (monitor, netlocal6.addresses, FALSE);
259   run_tests (monitor, netfe80.addresses, FALSE);
260   run_tests (monitor, unmatched, FALSE);
261
262   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
263                                       net10.mask);
264   assert_signals (monitor, FALSE, TRUE, FALSE);
265   run_tests (monitor, net127.addresses, TRUE);
266   run_tests (monitor, net10.addresses, TRUE);
267   run_tests (monitor, net192.addresses, FALSE);
268   run_tests (monitor, netlocal6.addresses, FALSE);
269   run_tests (monitor, netfe80.addresses, FALSE);
270   run_tests (monitor, unmatched, FALSE);
271
272   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
273                                       net192.mask);
274   assert_signals (monitor, FALSE, TRUE, FALSE);
275   run_tests (monitor, net127.addresses, TRUE);
276   run_tests (monitor, net10.addresses, TRUE);
277   run_tests (monitor, net192.addresses, TRUE);
278   run_tests (monitor, netlocal6.addresses, FALSE);
279   run_tests (monitor, netfe80.addresses, FALSE);
280   run_tests (monitor, unmatched, FALSE);
281
282   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
283                                       netlocal6.mask);
284   assert_signals (monitor, FALSE, TRUE, FALSE);
285   run_tests (monitor, net127.addresses, TRUE);
286   run_tests (monitor, net10.addresses, TRUE);
287   run_tests (monitor, net192.addresses, TRUE);
288   run_tests (monitor, netlocal6.addresses, TRUE);
289   run_tests (monitor, netfe80.addresses, FALSE);
290   run_tests (monitor, unmatched, FALSE);
291
292   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
293                                       netfe80.mask);
294   assert_signals (monitor, FALSE, TRUE, FALSE);
295   run_tests (monitor, net127.addresses, TRUE);
296   run_tests (monitor, net10.addresses, TRUE);
297   run_tests (monitor, net192.addresses, TRUE);
298   run_tests (monitor, netlocal6.addresses, TRUE);
299   run_tests (monitor, netfe80.addresses, TRUE);
300   run_tests (monitor, unmatched, FALSE);
301
302   g_object_unref (monitor);
303 }
304
305 static void
306 test_remove_networks (void)
307 {
308   GNetworkMonitor *monitor;
309   GError *error = NULL;
310
311   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
312   g_assert_no_error (error);
313   assert_signals (monitor, FALSE, FALSE, TRUE);
314
315   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
316                                          ip4_default);
317   assert_signals (monitor, FALSE, TRUE, TRUE);
318   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
319                                          ip6_default);
320   assert_signals (monitor, TRUE, TRUE, FALSE);
321
322   /* First add them */
323   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
324                                       net127.mask);
325   assert_signals (monitor, FALSE, TRUE, FALSE);
326   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
327                                       net10.mask);
328   assert_signals (monitor, FALSE, TRUE, FALSE);
329   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
330                                       net192.mask);
331   assert_signals (monitor, FALSE, TRUE, FALSE);
332   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
333                                       netlocal6.mask);
334   assert_signals (monitor, FALSE, TRUE, FALSE);
335   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
336                                       netfe80.mask);
337   assert_signals (monitor, FALSE, TRUE, FALSE);
338
339   run_tests (monitor, net127.addresses, TRUE);
340   run_tests (monitor, net10.addresses, TRUE);
341   run_tests (monitor, net192.addresses, TRUE);
342   run_tests (monitor, netlocal6.addresses, TRUE);
343   run_tests (monitor, netfe80.addresses, TRUE);
344   run_tests (monitor, unmatched, FALSE);
345
346   /* Now remove them one by one */
347   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
348                                          net127.mask);
349   assert_signals (monitor, FALSE, TRUE, FALSE);
350   run_tests (monitor, net127.addresses, FALSE);
351   run_tests (monitor, net10.addresses, TRUE);
352   run_tests (monitor, net192.addresses, TRUE);
353   run_tests (monitor, netlocal6.addresses, TRUE);
354   run_tests (monitor, netfe80.addresses, TRUE);
355   run_tests (monitor, unmatched, FALSE);
356
357   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
358                                          net10.mask);
359   assert_signals (monitor, FALSE, TRUE, FALSE);
360   run_tests (monitor, net127.addresses, FALSE);
361   run_tests (monitor, net10.addresses, FALSE);
362   run_tests (monitor, net192.addresses, TRUE);
363   run_tests (monitor, netlocal6.addresses, TRUE);
364   run_tests (monitor, netfe80.addresses, TRUE);
365   run_tests (monitor, unmatched, FALSE);
366
367   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
368                                          net192.mask);
369   assert_signals (monitor, FALSE, TRUE, FALSE);
370   run_tests (monitor, net127.addresses, FALSE);
371   run_tests (monitor, net10.addresses, FALSE);
372   run_tests (monitor, net192.addresses, FALSE);
373   run_tests (monitor, netlocal6.addresses, TRUE);
374   run_tests (monitor, netfe80.addresses, TRUE);
375   run_tests (monitor, unmatched, FALSE);
376
377   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
378                                          netlocal6.mask);
379   assert_signals (monitor, FALSE, TRUE, FALSE);
380   run_tests (monitor, net127.addresses, FALSE);
381   run_tests (monitor, net10.addresses, FALSE);
382   run_tests (monitor, net192.addresses, FALSE);
383   run_tests (monitor, netlocal6.addresses, FALSE);
384   run_tests (monitor, netfe80.addresses, TRUE);
385   run_tests (monitor, unmatched, FALSE);
386
387   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
388                                          netfe80.mask);
389   assert_signals (monitor, FALSE, TRUE, FALSE);
390   run_tests (monitor, net127.addresses, FALSE);
391   run_tests (monitor, net10.addresses, FALSE);
392   run_tests (monitor, net192.addresses, FALSE);
393   run_tests (monitor, netlocal6.addresses, FALSE);
394   run_tests (monitor, netfe80.addresses, FALSE);
395   run_tests (monitor, unmatched, FALSE);
396
397   g_object_unref (monitor);
398 }
399
400
401 static void
402 init_test (TestMask *test)
403 {
404   GError *error = NULL;
405   int i;
406
407   test->mask = g_inet_address_mask_new_from_string (test->mask_string, &error);
408   g_assert_no_error (error);
409
410   for (i = 0; test->addresses[i].string; i++)
411     {
412       test->addresses[i].address = g_inet_address_new_from_string (test->addresses[i].string);
413       if (strchr (test->addresses[i].string, ':'))
414         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV6);
415       else
416         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV4);
417     }
418 }
419
420 static void
421 watch_network_changed (GNetworkMonitor *monitor,
422                        gboolean         available,
423                        gpointer         user_data)
424 {
425   g_print ("Network is %s\n", available ? "up" : "down");
426 }
427
428 static void
429 do_watch_network (void)
430 {
431   GNetworkMonitor *monitor = g_network_monitor_get_default ();
432   GMainLoop *loop;
433
434   g_print ("Monitoring via %s\n", g_type_name_from_instance ((GTypeInstance *) monitor));
435
436   g_signal_connect (monitor, "network-changed",
437                     G_CALLBACK (watch_network_changed), NULL);
438   watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL);
439
440   loop = g_main_loop_new (NULL, FALSE);
441   g_main_loop_run (loop);
442 }
443
444 int
445 main (int argc, char **argv)
446 {
447   g_type_init ();
448
449   if (argc == 2 && !strcmp (argv[1], "--watch"))
450     {
451       do_watch_network ();
452       return 0;
453     }
454
455   g_test_init (&argc, &argv, NULL);
456
457   init_test (&net127);
458   init_test (&net10);
459   init_test (&net192);
460   init_test (&netlocal6);
461   init_test (&netfe80);
462   ip4_default = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL);
463   ip6_default = g_inet_address_mask_new_from_string ("::/0", NULL);
464
465   g_test_add_func ("/network-monitor/default", test_default);
466   g_test_add_func ("/network-monitor/remove_default", test_remove_default);
467   g_test_add_func ("/network-monitor/add_networks", test_add_networks);
468   g_test_add_func ("/network-monitor/remove_networks", test_remove_networks);
469
470   return g_test_run ();
471 }