1 /* GNet GInetAddr unit test (deterministic, computation-based tests only)
2 * Copyright (C) 2002 David Helder
3 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include "config.h"
21 #include "gnetcheck.h"
22
23 #ifdef HAVE_VALGRIND
24 #include <valgrind/valgrind.h>
25 #endif
26
27 #include <string.h>
28 #include <stdio.h>
29
30 /*** IPv4 tests */
31
GNET_START_TEST(test_inetaddr_ipv4)32 GNET_START_TEST (test_inetaddr_ipv4)
33 {
34 GInetAddr* inetaddr;
35 GInetAddr* inetaddr2;
36 gchar* cname;
37 gchar* cname2;
38 gchar bytes[GNET_INETADDR_MAX_LEN];
39
40 /* new (canonical, IPv4) */
41 inetaddr = gnet_inetaddr_new ("141.213.11.124", 23);
42 fail_unless (inetaddr != NULL);
43
44 /* get_port */
45 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 23);
46
47 /* set_port */
48 gnet_inetaddr_set_port (inetaddr, 42);
49 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 42);
50
51 /* get_canonical_name */
52 cname = gnet_inetaddr_get_canonical_name (inetaddr);
53 fail_unless (cname != NULL);
54 fail_unless_equals_string (cname, "141.213.11.124");
55 g_free (cname);
56
57 /* clone */
58 inetaddr2 = gnet_inetaddr_clone (inetaddr);
59 fail_unless (inetaddr2 != NULL);
60 cname2 = gnet_inetaddr_get_canonical_name (inetaddr2);
61 fail_unless (cname2 != NULL);
62 fail_unless_equals_string (cname2, "141.213.11.124");
63 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr2), 42);
64 g_free(cname2);
65
66 /* equal, noport_equal */
67 fail_unless (gnet_inetaddr_equal (inetaddr, inetaddr2));
68 fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
69 gnet_inetaddr_set_port (inetaddr2, 23);
70 fail_if (gnet_inetaddr_equal (inetaddr, inetaddr2));
71 fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
72
73 /* hash */
74 fail_unless_equals_int (gnet_inetaddr_hash (inetaddr), 2379549526u);
75 /* hash port */
76 fail_unless (gnet_inetaddr_hash (inetaddr) != gnet_inetaddr_hash (inetaddr2));
77
78 gnet_inetaddr_delete (inetaddr);
79 gnet_inetaddr_delete (inetaddr2);
80
81 /* bytes */
82 inetaddr = gnet_inetaddr_new_bytes ("\x8d\xd5\xb\x7c", 4);
83 fail_unless (inetaddr != NULL);
84
85 cname = gnet_inetaddr_get_canonical_name (inetaddr);
86 fail_unless (cname != NULL);
87 fail_unless_equals_string ("141.213.11.124", cname);
88 g_free (cname);
89
90 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 0);
91 gnet_inetaddr_set_port (inetaddr, 2345);
92 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
93
94 fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 4);
95
96 gnet_inetaddr_set_bytes (inetaddr, "\x7c\xb\xd5\x8d", 4);
97 cname = gnet_inetaddr_get_canonical_name (inetaddr);
98 fail_unless (cname != NULL);
99 fail_unless_equals_string ("124.11.213.141", cname);
100 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
101 g_free (cname);
102
103 fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 4);
104
105 gnet_inetaddr_get_bytes (inetaddr, bytes);
106 fail_unless (memcmp(bytes, "\x7c\xb\xd5\x8d", 4) == 0);
107
108 #ifdef HAVE_IPV6
109
110 /* IPv4 -> IPv6 via set_bytes */
111 gnet_inetaddr_set_bytes (inetaddr, "\x3f\xfe\x0b\x00" "\x0c\x18\x1f\xff"
112 "\0\0\0\0" "\0\0\0\x6f", 16);
113 cname = gnet_inetaddr_get_canonical_name (inetaddr);
114 fail_unless (cname != NULL);
115 fail_unless (!strcasecmp("3ffe:b00:c18:1fff::6f", cname));
116 g_free (cname);
117 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
118 fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 16);
119
120 gnet_inetaddr_get_bytes (inetaddr, bytes);
121 fail_unless (!memcmp(bytes, "\x3f\xfe\x0b\x00\x0c\x18\x1f\xff\0\0\0\0\0\0\0\x6f", 16));
122
123 #endif
124
125 gnet_inetaddr_delete (inetaddr);
126 }
127 GNET_END_TEST;
128
129 #define IS_TEST(S,A,F) do { \
130 GInetAddr* _inetaddr; \
131 gchar* _cname; \
132 _inetaddr = gnet_inetaddr_new_nonblock (A, 0); \
133 fail_unless (_inetaddr != NULL); \
134 _cname = gnet_inetaddr_get_canonical_name (_inetaddr); \
135 fail_unless (_cname != NULL); \
136 fail_unless_equals_string (_cname, (A)); \
137 fail_unless (F (_inetaddr)); \
138 g_free (_cname); \
139 gnet_inetaddr_delete (_inetaddr); \
140 } while (0)
141
GNET_START_TEST(test_inetaddr_is_ipv4)142 GNET_START_TEST (test_inetaddr_is_ipv4)
143 {
144 /* IPv4 */
145 IS_TEST ("IPv4", "141.213.11.124", gnet_inetaddr_is_ipv4);
146
147 /* IPv4 Loopback */
148 IS_TEST ("IPv4 Loopback", "127.0.0.1", gnet_inetaddr_is_loopback);
149 IS_TEST ("IPv4 Loopback2", "127.23.42.129", gnet_inetaddr_is_loopback);
150 IS_TEST ("IPv4 !Loopback", "128.23.42.129", !gnet_inetaddr_is_loopback);
151
152 /* IPv4 Multicast */
153 IS_TEST ("IPv4 Multicast", "224.0.0.0", gnet_inetaddr_is_multicast);
154 IS_TEST ("IPv4 Multicast2", "224.0.0.1", gnet_inetaddr_is_multicast);
155 IS_TEST ("IPv4 Multicast3", "239.255.255.255", gnet_inetaddr_is_multicast);
156 IS_TEST ("IPv4 !Multicast", "223.255.255.255", !gnet_inetaddr_is_multicast);
157 IS_TEST ("IPv4 !Multicast2", "240.0.0.0", !gnet_inetaddr_is_multicast);
158
159 /* IPv4 Private */
160 IS_TEST ("IPv4 Private", "10.0.0.0", gnet_inetaddr_is_private);
161 IS_TEST ("IPv4 Private2", "10.255.255.255", gnet_inetaddr_is_private);
162 IS_TEST ("IPv4 !Private", "9.255.255.255", !gnet_inetaddr_is_private);
163 IS_TEST ("IPv4 !Private2", "11.0.0.0", !gnet_inetaddr_is_private);
164 IS_TEST ("IPv4 Private3", "172.16.0.0", gnet_inetaddr_is_private);
165 IS_TEST ("IPv4 Private4", "172.31.255.255", gnet_inetaddr_is_private);
166 IS_TEST ("IPv4 !Private3", "172.15.255.255", !gnet_inetaddr_is_private);
167 IS_TEST ("IPv4 !Private4", "172.32.0.0", !gnet_inetaddr_is_private);
168 IS_TEST ("IPv4 Private5", "192.168.0.0", gnet_inetaddr_is_private);
169 IS_TEST ("IPv4 Private6", "192.168.255.255", gnet_inetaddr_is_private);
170 IS_TEST ("IPv4 !Private5", "192.167.255.255", !gnet_inetaddr_is_private);
171 IS_TEST ("IPv4 !Private6", "192.169.0.0", !gnet_inetaddr_is_private);
172
173
174 /* IPv4 Reserved */
175 IS_TEST ("IPv4 Reserved", "0.0.0.0", gnet_inetaddr_is_reserved);
176 IS_TEST ("IPv4 Reserved2", "0.0.255.255", gnet_inetaddr_is_reserved);
177 IS_TEST ("IPv4 !Reserved2", "1.0.0.0", !gnet_inetaddr_is_reserved);
178 IS_TEST ("IPv4 Reserved3", "240.0.0.0", gnet_inetaddr_is_reserved);
179 IS_TEST ("IPv4 Reserved4", "247.255.255.255", gnet_inetaddr_is_reserved);
180 IS_TEST ("IPv4 !Reserved3", "239.255.255.255", !gnet_inetaddr_is_reserved);
181 IS_TEST ("IPv4 !Reserved4", "248.0.0.0", !gnet_inetaddr_is_reserved);
182
183 /* Internet */
184 IS_TEST ("Internet1", "141.213.11.124", gnet_inetaddr_is_internet);
185 }
186 GNET_END_TEST;
187
188 #if HAVE_IPV6
189
GNET_START_TEST(test_inetaddr_is_ipv6)190 GNET_START_TEST (test_inetaddr_is_ipv6)
191 {
192 /* IPv6 */
193 IS_TEST ("!IPv4", "3ffe:b00:c18:1fff::6f", !gnet_inetaddr_is_ipv4);
194 IS_TEST ("IPv6", "3ffe:b00:c18:1fff::6f", gnet_inetaddr_is_ipv6);
195 IS_TEST ("!IPv6", "141.213.11.124", !gnet_inetaddr_is_ipv6);
196
197 /* IPv6 Loopback */
198 IS_TEST ("IPv6 Loopback", "::1", gnet_inetaddr_is_loopback);
199 IS_TEST ("IPv6 !Loopback", "::", !gnet_inetaddr_is_loopback);
200 IS_TEST ("IPv6 !Loopback2", "::201", !gnet_inetaddr_is_loopback);
201
202 /* IPv6 Multicast */
203 IS_TEST ("IPv6 Multicast", "ffff::1", gnet_inetaddr_is_multicast);
204 IS_TEST ("IPv6 !Multicast", "feff::1", !gnet_inetaddr_is_multicast);
205
206 /* IPv6 Broadcast */
207 IS_TEST ("IPv6 Broadcast", "255.255.255.255", gnet_inetaddr_is_broadcast);
208 IS_TEST ("IPv6 !Broadcast", "255.255.255.254", !gnet_inetaddr_is_broadcast);
209
210 /* IPv6 Private */
211 IS_TEST ("IPv6 Private", "fe80::", gnet_inetaddr_is_private);
212 IS_TEST ("IPv6 Private2", "fecf:ffff::", gnet_inetaddr_is_private);
213 IS_TEST ("IPv6 !Private", "fe7f:ffff::", !gnet_inetaddr_is_private);
214 IS_TEST ("IPv6 !Private2", "ff00::", !gnet_inetaddr_is_private);
215
216 /* IPv6 Reserved */
217 IS_TEST ("IPv6 Reserved", "::", gnet_inetaddr_is_reserved);
218 IS_TEST ("IPv6 !Reserved", "1::", !gnet_inetaddr_is_reserved);
219
220 /* Internet */
221 IS_TEST ("Internet2", "3ffe:b00:c18:1fff::6f", gnet_inetaddr_is_internet);
222 IS_TEST ("!Internet1", "255.255.255.255", !gnet_inetaddr_is_internet);
223 IS_TEST ("!Internet2", "ffff::1", !gnet_inetaddr_is_internet);
224 }
225 GNET_END_TEST;
226
227 #endif /* HAVE_IPV6 */
228
229
230 /*** IPv6 tests ***/
231
232 #if HAVE_IPV6
GNET_START_TEST(test_inetaddr_ipv6)233 GNET_START_TEST (test_inetaddr_ipv6)
234 {
235 GInetAddr* inetaddr;
236 GInetAddr* inetaddr2;
237 gchar* cname;
238 gchar* cname2;
239
240 /* new (canonical, IPv6) */
241 inetaddr = gnet_inetaddr_new ("3ffe:b00:c18:1fff::6f", 23);
242 fail_unless (inetaddr != NULL);
243
244 /* get_port */
245 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 23);
246
247 /* set_port */
248 gnet_inetaddr_set_port (inetaddr, 42);
249 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 42);
250
251 /* get_canonical_name */
252 cname = gnet_inetaddr_get_canonical_name (inetaddr);
253 fail_unless (cname != NULL);
254 fail_unless (!strcasecmp(cname, "3ffe:b00:c18:1fff::6f"));
255 g_free (cname);
256
257 /* clone */
258 inetaddr2 = gnet_inetaddr_clone (inetaddr);
259 fail_unless (inetaddr != NULL);
260 cname2 = gnet_inetaddr_get_canonical_name (inetaddr2);
261 fail_unless (cname2 != NULL);
262 fail_unless (!strcasecmp(cname2, "3ffe:b00:c18:1fff::6f"));
263 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr2), 42);
264 g_free(cname2);
265
266 /* equal, noport_equal */
267 fail_unless (gnet_inetaddr_equal (inetaddr, inetaddr2));
268 fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
269 gnet_inetaddr_set_port (inetaddr2, 23);
270 fail_if (gnet_inetaddr_equal (inetaddr, inetaddr2));
271 fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
272
273 /* hash */
274 fail_unless_equals_int (gnet_inetaddr_hash (inetaddr), 870716602u);
275 /* hash port */
276 fail_unless (gnet_inetaddr_hash (inetaddr) != gnet_inetaddr_hash (inetaddr2));
277
278 gnet_inetaddr_delete (inetaddr);
279 gnet_inetaddr_delete (inetaddr2);
280
281 /* bytes */
282 inetaddr = gnet_inetaddr_new_bytes ("\x3f\xfe\x0b\x00" "\x0c\x18\x1f\xff"
283 "\0\0\0\0" "\0\0\0\x6f", 16);
284 fail_unless (inetaddr != NULL);
285 cname = gnet_inetaddr_get_canonical_name (inetaddr);
286 fail_unless (cname != NULL);
287 fail_unless (!strcasecmp("3ffe:b00:c18:1fff::6f", cname));
288 fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 0);
289 gnet_inetaddr_delete (inetaddr);
290 g_free (cname);
291 }
292 GNET_END_TEST;
293 #endif /* HAVE_IPV6 */
294
GNET_START_TEST(test_inetaddr_is_internet_domainname)295 GNET_START_TEST (test_inetaddr_is_internet_domainname)
296 {
297 fail_unless (gnet_inetaddr_is_internet_domainname ("speak.eecs.umich.edu"));
298 fail_unless (gnet_inetaddr_is_internet_domainname ("141.213.11.124"));
299 fail_if (gnet_inetaddr_is_internet_domainname ("localhost"));
300 fail_if (gnet_inetaddr_is_internet_domainname ("localhost.localdomain"));
301 fail_if (gnet_inetaddr_is_internet_domainname ("speak"));
302 }
303 GNET_END_TEST;
304
305 static void
lookup_list_cb(GList * list,gpointer data)306 lookup_list_cb (GList * list, gpointer data)
307 {
308 gboolean *p_called = (gboolean *) data;
309 GList *l;
310
311 *p_called = TRUE;
312
313 /* g_print ("%d results\n", g_list_length (list)); */
314
315 fail_unless (list != NULL);
316 for (l = list; l != NULL; l = l->next) {
317 GInetAddr *ia;
318 gchar *name;
319
320 ia = (GInetAddr *) l->data;
321 name = gnet_inetaddr_get_canonical_name (ia);
322 fail_unless (name != NULL);
323 fail_unless_equals_int (gnet_inetaddr_get_port (ia), 80);
324 g_free (name);
325 }
326
327 g_list_foreach (list, (GFunc) gnet_inetaddr_unref, NULL);
328 g_list_free (list);
329 }
330
331 static void
lookup_list_cb_do_nothing(GList * list,gpointer data)332 lookup_list_cb_do_nothing (GList * list, gpointer data)
333 {
334 g_list_foreach (list, (GFunc) gnet_inetaddr_unref, NULL);
335 g_list_free (list);
336 }
337
338 static gboolean
do_nothing_timeout(gpointer foo)339 do_nothing_timeout (gpointer foo)
340 {
341 return FALSE; /* don't call again */
342 }
343
344 static void
destroy_notify(gpointer data)345 destroy_notify (gpointer data)
346 {
347 gboolean *p_bool = (gboolean *) data;
348
349 *p_bool = TRUE;
350 }
351
352 static void
do_test_inetaddr_list_async(const gchar * hostname)353 do_test_inetaddr_list_async (const gchar * hostname)
354 {
355 GInetAddrNewListAsyncID list_async_id;
356 GMainContext *ctx;
357 gboolean called, destroyed;
358 gint id;
359
360 /* g_print ("list async: looking up %s ... ", hostname); */
361
362 /* list async (default main context) */
363 called = FALSE;
364 list_async_id = gnet_inetaddr_new_list_async (hostname, 80,
365 lookup_list_cb, &called);
366 id = g_timeout_add (5 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
367 g_main_context_iteration (NULL, TRUE);
368 fail_unless (called);
369 g_source_remove (id);
370
371 /* list async + cancel (default main context) */
372 called = FALSE;
373 list_async_id = gnet_inetaddr_new_list_async (hostname, 80,
374 lookup_list_cb, &called);
375 fail_unless (list_async_id != NULL);
376 gnet_inetaddr_new_list_async_cancel (list_async_id);
377 while (g_main_context_iteration (NULL, FALSE)) {
378 ;
379 }
380 fail_unless (!called);
381
382 /* list async (destroy notify) */
383 destroyed = FALSE;
384 list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
385 lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
386 G_PRIORITY_HIGH);
387 fail_unless (list_async_id != NULL);
388 g_main_context_iteration (NULL, TRUE);
389 fail_unless (destroyed);
390
391 /* list async + cancel (destroy notify; thread unlikely to start) */
392 destroyed = FALSE;
393 list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
394 lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
395 G_PRIORITY_HIGH);
396 fail_unless (list_async_id != NULL);
397 gnet_inetaddr_new_list_async_cancel (list_async_id);
398 /* give thread a chance to execute and act on the cancelled flag */
399 g_usleep (1 * G_USEC_PER_SEC);
400 fail_unless (destroyed);
401
402 /* list async + cancel (destroy notify II) */
403 destroyed = FALSE;
404 list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
405 lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
406 G_PRIORITY_HIGH);
407 fail_unless (list_async_id != NULL);
408 /* give thread a chance to execute and block before we cancel it */
409 g_usleep (1 * G_USEC_PER_SEC);
410 gnet_inetaddr_new_list_async_cancel (list_async_id);
411 fail_unless (destroyed);
412
413 /* list async + cancel (destroy notify III) */
414 destroyed = FALSE;
415 list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
416 lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
417 G_PRIORITY_HIGH);
418 fail_unless (list_async_id != NULL);
419 /* give thread a chance to execute and block and be done before cancelling */
420 g_usleep (3 * G_USEC_PER_SEC);
421 gnet_inetaddr_new_list_async_cancel (list_async_id);
422 fail_unless (destroyed);
423
424 /* list async (custom main context) */
425 called = FALSE;
426 ctx = g_main_context_new ();
427 list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
428 lookup_list_cb, &called, (GDestroyNotify) NULL, ctx,
429 G_PRIORITY_HIGH);
430 /* give thread a chance to execute and block and be done */
431 g_usleep (3 * G_USEC_PER_SEC);
432 fail_unless (!called);
433 /* there shouldn't be anyhing pending in the default context */
434 fail_unless (!g_main_context_pending (NULL));
435 /* but there should be something pending in OUR context now */
436 fail_unless (g_main_context_pending (ctx));
437 fail_unless (!called);
438 /* let's iterate it and dispatch the callback */
439 fail_unless (g_main_context_iteration (ctx, FALSE));
440 fail_unless (called);
441 g_main_context_unref (ctx);
442 }
443
GNET_START_TEST(test_inetaddr_list_async)444 GNET_START_TEST (test_inetaddr_list_async)
445 {
446 do_test_inetaddr_list_async ("localhost");
447 /* FIXME: these might not work right yet because of the timings in the test
448 #ifdef GNET_ENABLE_NETWORK_TESTS
449 do_test_inetaddr_list_async ("www.google.com");
450 do_test_inetaddr_list_async ("www.heise.de");
451 #endif
452 */
453 #ifdef HAVE_VALGRIND
454 if (RUNNING_ON_VALGRIND) {
455 g_print ("Sleeping for a while to let cancelled threads finish ...\n");
456 /* sleep a while to give any cancelled threads a chance to quit, otherwise
457 * valgrind will think the threads were leaked */
458 g_usleep (60 * G_USEC_PER_SEC);
459 }
460 #endif
461 }
462 GNET_END_TEST;
463
464 static void
lookup_name_cb(GInetAddr * ia,gpointer data)465 lookup_name_cb (GInetAddr * ia, gpointer data)
466 {
467 gboolean *p_called = (gboolean *) data;
468 gchar *name;
469
470 *p_called = TRUE;
471
472 fail_unless (ia != NULL);
473
474 name = gnet_inetaddr_get_canonical_name (ia);
475 fail_unless (name != NULL);
476 fail_unless_equals_int (gnet_inetaddr_get_port (ia), 80);
477 g_free (name);
478
479 gnet_inetaddr_unref (ia);
480 }
481
482 static void
lookup_name_cb_do_nothing(GInetAddr * ia,gpointer data)483 lookup_name_cb_do_nothing (GInetAddr * ia, gpointer data)
484 {
485 gnet_inetaddr_unref (ia);
486 }
487
488 static void
do_test_inetaddr_name_async(const gchar * hostname)489 do_test_inetaddr_name_async (const gchar * hostname)
490 {
491 GInetAddrNewAsyncID async_id;
492 GMainContext *ctx;
493 gboolean called, destroyed;
494 gint id;
495
496 /* name async (default main context) */
497 called = FALSE;
498 async_id = gnet_inetaddr_new_async (hostname, 80, lookup_name_cb, &called);
499 fail_unless (async_id != NULL);
500 id = g_timeout_add (5 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
501 g_main_context_iteration (NULL, TRUE);
502 fail_unless (called);
503 g_source_remove (id);
504
505 /* name async + cancel (default main context) */
506 called = FALSE;
507 async_id = gnet_inetaddr_new_async (hostname, 80, lookup_name_cb, &called);
508 fail_unless (async_id != NULL);
509 gnet_inetaddr_new_async_cancel (async_id);
510 while (g_main_context_iteration (NULL, FALSE)) { ; }
511 fail_unless (!called);
512
513 /* name async (destroy notify) */
514 destroyed = FALSE;
515 async_id = gnet_inetaddr_new_async_full (hostname, 80,
516 lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
517 G_PRIORITY_HIGH);
518 fail_unless (async_id != NULL);
519 g_main_context_iteration (NULL, TRUE);
520 fail_unless (destroyed);
521
522 /* name async + cancel (destroy notify; thread unlikely to start) */
523 destroyed = FALSE;
524 async_id = gnet_inetaddr_new_async_full (hostname, 80,
525 lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
526 G_PRIORITY_HIGH);
527 fail_unless (async_id != NULL);
528 gnet_inetaddr_new_async_cancel (async_id);
529 /* give thread a chance to execute and act on the cancelled flag */
530 g_usleep (1 * G_USEC_PER_SEC);
531 fail_unless (destroyed);
532
533 /* name async + cancel (destroy notify II) */
534 destroyed = FALSE;
535 async_id = gnet_inetaddr_new_async_full (hostname, 80,
536 lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
537 G_PRIORITY_HIGH);
538 fail_unless (async_id != NULL);
539 /* give thread a chance to execute and block before we cancel it */
540 g_usleep (1 * G_USEC_PER_SEC);
541 gnet_inetaddr_new_async_cancel (async_id);
542 fail_unless (destroyed);
543
544 /* name async + cancel (destroy notify III) */
545 destroyed = FALSE;
546 async_id = gnet_inetaddr_new_async_full (hostname, 80,
547 lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
548 G_PRIORITY_HIGH);
549 fail_unless (async_id != NULL);
550 /* give thread a chance to execute and block and be done before cancelling */
551 g_usleep (3 * G_USEC_PER_SEC);
552 gnet_inetaddr_new_async_cancel (async_id);
553 fail_unless (destroyed);
554
555 /* name async (custom main context) */
556 called = FALSE;
557 ctx = g_main_context_new ();
558 async_id = gnet_inetaddr_new_async_full (hostname, 80, lookup_name_cb,
559 &called, (GDestroyNotify) NULL, ctx, G_PRIORITY_HIGH);
560 /* give thread a chance to execute and block and be done */
561 g_usleep (3 * G_USEC_PER_SEC);
562 fail_unless (!called);
563 /* there shouldn't be anyhing pending in the default context */
564 fail_unless (!g_main_context_pending (NULL));
565 /* but there should be something pending in OUR context now */
566 fail_unless (g_main_context_pending (ctx));
567 fail_unless (!called);
568 /* let's iterate it and dispatch the callback */
569 fail_unless (g_main_context_iteration (ctx, FALSE));
570 fail_unless (called);
571 g_main_context_unref (ctx);
572 }
573
GNET_START_TEST(test_inetaddr_name_async)574 GNET_START_TEST (test_inetaddr_name_async)
575 {
576 do_test_inetaddr_name_async ("localhost");
577
578 /* FIXME: these might not work right yet because of the timings in the test
579 #ifdef GNET_ENABLE_NETWORK_TESTS
580 do_test_inetaddr_name_async ("www.google.com");
581 #endif
582 */
583 #ifdef HAVE_VALGRIND
584 if (RUNNING_ON_VALGRIND) {
585 g_print ("Sleeping for a while to let cancelled threads finish ...\n");
586 /* sleep a while to give any cancelled threads a chance to quit, otherwise
587 * valgrind will think the threads were leaked */
588 g_usleep (60 * G_USEC_PER_SEC);
589 }
590 #endif
591 }
592 GNET_END_TEST;
593
594 static void
reverse_lookup_func(gchar * hostname,gpointer data)595 reverse_lookup_func (gchar * hostname, gpointer data)
596 {
597 /* should never be called, since we don't iterate the default main context */
598 g_assert_not_reached ();
599 }
600
601 static void
do_test_inetaddr_reverse_async_ipv4_cancel(const gchar * ip_string)602 do_test_inetaddr_reverse_async_ipv4_cancel (const gchar * ip_string)
603 {
604 GInetAddrGetNameAsyncID async_id;
605 GInetAddr *ia;
606
607 g_print ("Starting reverse lookup for %s ...", ip_string);
608 fflush (stdout);
609 ia = gnet_inetaddr_new_nonblock (ip_string, 80);
610 fail_unless (ia != NULL);
611
612 ASSERT_CRITICAL (gnet_inetaddr_get_name_async (ia, NULL, NULL));
613
614 async_id = gnet_inetaddr_get_name_async (ia, reverse_lookup_func, NULL);
615 fail_unless (async_id != NULL);
616 gnet_inetaddr_delete (ia);
617
618 g_usleep (g_random_int_range (0, G_USEC_PER_SEC * 2));
619 gnet_inetaddr_get_name_async_cancel (async_id);
620 g_print (" cancelled.\n");
621 }
622
GNET_START_TEST(test_inetaddr_reverse_async_ipv4_cancel)623 GNET_START_TEST (test_inetaddr_reverse_async_ipv4_cancel)
624 {
625 ASSERT_CRITICAL (
626 gnet_inetaddr_get_name_async (NULL, reverse_lookup_func, NULL)
627 );
628
629 do_test_inetaddr_reverse_async_ipv4_cancel ("127.0.0.1");
630
631 #ifdef GNET_ENABLE_NETWORK_TESTS
632 {
633 gint i;
634
635 for (i = 0; i < 10; ++i) {
636
637 if (i == 1) {
638 do_test_inetaddr_reverse_async_ipv4_cancel ("217.155.155.155");
639 } else if (i == 2) {
640 do_test_inetaddr_reverse_async_ipv4_cancel ("91.189.93.3");
641 } else {
642 gchar *ip_string;
643
644 ip_string = g_strdup_printf ("%u.%u.%u.%u",
645 g_random_int_range (4, 250), g_random_int_range (0, 255),
646 g_random_int_range (0, 255), g_random_int_range (0, 255));
647 do_test_inetaddr_reverse_async_ipv4_cancel (ip_string);
648 g_free (ip_string);
649 }
650 }
651 }
652 #endif
653
654 #ifdef HAVE_VALGRIND
655 if (RUNNING_ON_VALGRIND) {
656 g_print ("Sleeping for a while to let cancelled threads finish ...\n");
657 /* sleep a while to give any cancelled threads a chance to quit, otherwise
658 * valgrind will think the threads were leaked */
659 g_usleep (60 * G_USEC_PER_SEC);
660 }
661 #endif
662 }
663 GNET_END_TEST;
664
665 static GInetAddr *current_ia; /* NULL */
666
667 static void
lookup_reverse_cb(gchar * hostname,gpointer data)668 lookup_reverse_cb (gchar * hostname, gpointer data)
669 {
670 gboolean *p_called = (gboolean *) data;
671
672 *p_called = TRUE;
673
674 fail_unless (hostname != NULL);
675
676 g_free (hostname);
677 }
678
679 static void
lookup_reverse_cb_do_nothing(gchar * hostname,gpointer data)680 lookup_reverse_cb_do_nothing (gchar * hostname, gpointer data)
681 {
682 if (current_ia != NULL && hostname != NULL) {
683 gchar *can_name;
684
685 can_name = gnet_inetaddr_get_canonical_name (current_ia);
686 g_print ("%s --> %s\n", can_name, hostname);
687 g_free (can_name);
688 }
689
690 g_free (hostname);
691 }
692
693 static void
do_test_inetaddr_reverse_async(const gchar * hostname)694 do_test_inetaddr_reverse_async (const gchar * hostname)
695 {
696 GInetAddrGetNameAsyncID async_id;
697 GMainContext *ctx;
698 GInetAddr *ia;
699 gboolean called, destroyed;
700 gchar *ip_string;
701 gint id;
702
703 /* we assume the given host has a 1:1 IP<->hostname mapping */
704 ia = gnet_inetaddr_new (hostname, 80);
705 fail_unless (ia != NULL);
706 ip_string = gnet_inetaddr_get_canonical_name (ia);
707 fail_unless (ip_string != NULL);
708 gnet_inetaddr_unref (ia);
709 ia = NULL;
710
711 g_print ("%s --> %s\n", hostname, ip_string);
712
713 ia = gnet_inetaddr_new_nonblock (ip_string, 80);
714 fail_unless (ia != NULL);
715 current_ia = ia;
716
717 /* name async (default main context) */
718 called = FALSE;
719 async_id = gnet_inetaddr_get_name_async (ia, lookup_reverse_cb, &called);
720 fail_unless (async_id != NULL);
721 id = g_timeout_add (10 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
722 g_main_context_iteration (NULL, TRUE);
723 fail_unless (called);
724 g_source_remove (id);
725
726 /* name async + cancel (default main context) */
727 called = FALSE;
728 async_id = gnet_inetaddr_get_name_async (ia, lookup_reverse_cb, &called);
729 fail_unless (async_id != NULL);
730 gnet_inetaddr_get_name_async_cancel (async_id);
731 while (g_main_context_iteration (NULL, FALSE)) { ; }
732 fail_unless (!called);
733
734 /* name async (destroy notify) */
735 destroyed = FALSE;
736 async_id = gnet_inetaddr_get_name_async_full (ia,
737 lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
738 G_PRIORITY_HIGH);
739 fail_unless (async_id != NULL);
740 g_main_context_iteration (NULL, TRUE);
741 fail_unless (destroyed);
742
743 /* name async + cancel (destroy notify; thread unlikely to start) */
744 destroyed = FALSE;
745 async_id = gnet_inetaddr_get_name_async_full (ia,
746 lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
747 G_PRIORITY_HIGH);
748 fail_unless (async_id != NULL);
749 gnet_inetaddr_get_name_async_cancel (async_id);
750 /* give thread a chance to execute and act on the cancelled flag */
751 g_usleep (1 * G_USEC_PER_SEC);
752 fail_unless (destroyed);
753
754 /* name async + cancel (destroy notify II) */
755 destroyed = FALSE;
756 async_id = gnet_inetaddr_get_name_async_full (ia,
757 lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
758 G_PRIORITY_HIGH);
759 fail_unless (async_id != NULL);
760 /* give thread a chance to execute and block before we cancel it */
761 g_usleep (1 * G_USEC_PER_SEC);
762 gnet_inetaddr_get_name_async_cancel (async_id);
763 fail_unless (destroyed);
764
765 /* name async + cancel (destroy notify III) */
766 destroyed = FALSE;
767 async_id = gnet_inetaddr_get_name_async_full (ia,
768 lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
769 G_PRIORITY_HIGH);
770 fail_unless (async_id != NULL);
771 /* give thread a chance to execute and block and be done before cancelling */
772 g_usleep (3 * G_USEC_PER_SEC);
773 gnet_inetaddr_get_name_async_cancel (async_id);
774 fail_unless (destroyed);
775
776 /* name async (custom main context) */
777 called = FALSE;
778 ctx = g_main_context_new ();
779 async_id = gnet_inetaddr_get_name_async_full (ia, lookup_reverse_cb,
780 &called, (GDestroyNotify) NULL, ctx, G_PRIORITY_HIGH);
781 /* give thread a chance to execute and block and be done */
782 g_usleep (10 * G_USEC_PER_SEC);
783 fail_unless (!called);
784 /* there shouldn't be anyhing pending in the default context */
785 fail_unless (!g_main_context_pending (NULL));
786 /* but there should be something pending in OUR context now */
787 fail_unless (g_main_context_pending (ctx));
788 fail_unless (!called);
789 /* let's iterate it and dispatch the callback */
790 fail_unless (g_main_context_iteration (ctx, FALSE));
791 fail_unless (called);
792 g_main_context_unref (ctx);
793
794 g_free (ip_string);
795 gnet_inetaddr_unref (ia);
796 current_ia = NULL;
797 }
798
GNET_START_TEST(test_inetaddr_reverse_async)799 GNET_START_TEST (test_inetaddr_reverse_async)
800 {
801 do_test_inetaddr_reverse_async ("localhost");
802
803 #ifdef GNET_ENABLE_NETWORK_TESTS
804 do_test_inetaddr_reverse_async ("gabe.freedesktop.org");
805 #endif
806
807 #ifdef HAVE_VALGRIND
808 if (RUNNING_ON_VALGRIND) {
809 g_print ("Sleeping for a while to let cancelled threads finish ...\n");
810 /* sleep a while to give any cancelled threads a chance to quit, otherwise
811 * valgrind will think the threads were leaked */
812 g_usleep (60 * G_USEC_PER_SEC);
813 }
814 #endif
815 }
816 GNET_END_TEST;
817
818 static Suite *
gnetinetaddr_suite(void)819 gnetinetaddr_suite (void)
820 {
821 Suite *s = suite_create ("GInetAddr");
822 TCase *tc_chain = tcase_create ("inetaddr");
823
824 tcase_set_timeout (tc_chain, 0);
825
826 suite_add_tcase (s, tc_chain);
827 tcase_add_test (tc_chain, test_inetaddr_is_internet_domainname);
828 tcase_add_test (tc_chain, test_inetaddr_ipv4);
829 tcase_add_test (tc_chain, test_inetaddr_is_ipv4);
830 tcase_add_test (tc_chain, test_inetaddr_list_async);
831 tcase_add_test (tc_chain, test_inetaddr_name_async);
832 tcase_add_test (tc_chain, test_inetaddr_reverse_async);
833 tcase_add_test (tc_chain, test_inetaddr_reverse_async_ipv4_cancel);
834 #if HAVE_IPV6
835 tcase_add_test (tc_chain, test_inetaddr_ipv6);
836 tcase_add_test (tc_chain, test_inetaddr_is_ipv6);
837 #endif
838
839
840 return s;
841 }
842
843 GNET_CHECK_MAIN (gnetinetaddr);
844
845