Imported Upstream version 0.14.4
[platform/upstream/gssdp.git] / tests / gtest / test-functional.c
1 /*
2  * Copyright (C) 2012 Openismus GmbH
3  *
4  * Author: Jens Georg <jensg@openismus.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include <string.h>
23
24 #include <gio/gio.h>
25
26 #include <libgssdp/gssdp-resource-browser.h>
27 #include <libgssdp/gssdp-protocol.h>
28
29 #include "test-util.h"
30
31 #define UUID_1 "uuid:81909e94-ebf4-469e-ac68-81f2f189de1b"
32 #define VERSIONED_NT_1 "urn:org-gupnp:device:FunctionalTest:1"
33 #define VERSIONED_NT_2 "urn:org-gupnp:device:FunctionalTest:9"
34 #define VERSIONED_USN_1 UUID_1"::"VERSIONED_NT_1
35 #define VERSIONED_USN_2 UUID_1"::"VERSIONED_NT_2
36
37 /* Helper functions */
38
39 static GSocket *
40 create_socket()
41 {
42         GSocket *socket;
43         GError *error = NULL;
44         GSocketAddress *sock_addr;
45         GInetAddress *address;
46
47         socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
48                                G_SOCKET_TYPE_DATAGRAM,
49                                G_SOCKET_PROTOCOL_DEFAULT,
50                                &error);
51         g_assert (error == NULL);
52
53         address = g_inet_address_new_from_string ("127.0.0.1");
54         sock_addr = g_inet_socket_address_new (address, 0);
55         g_object_unref (address);
56
57         g_socket_bind (socket, sock_addr, TRUE, &error);
58         g_assert (error == NULL);
59         g_object_unref (sock_addr);
60
61         return socket;
62 }
63
64 char *
65 create_alive_message (const char *nt)
66 {
67         char *usn, *msg;
68
69         if (strcmp (nt, UUID_1) == 0)
70                 usn = g_strdup (UUID_1);
71         else
72                 usn = g_strconcat (UUID_1, "::", nt, NULL);
73
74         msg = g_strdup_printf (SSDP_ALIVE_MESSAGE,
75                                1800,
76                                "http://127.0.0.1:1234",
77                                "",
78                                "Linux/3.0 UPnP/1.0 GSSDPTesting/0.0.0",
79                                nt,
80                                usn);
81         g_free (usn);
82
83         return msg;
84 }
85
86 char *
87 create_byebye_message (const char *nt)
88 {
89         char *usn, *msg;
90
91         if (strcmp (nt, UUID_1) == 0)
92                 usn = g_strdup (UUID_1);
93         else
94                 usn = g_strconcat (UUID_1, "::", nt, NULL);
95
96         msg = g_strdup_printf (SSDP_BYEBYE_MESSAGE, nt, usn);
97         g_free (usn);
98
99         return msg;
100 }
101
102 typedef struct {
103         const char *usn;
104         GMainLoop  *loop;
105         gboolean    found;
106 } TestDiscoverySSDPAllData;
107
108
109 static void
110 on_test_discovery_ssdp_all_resource_available (GSSDPResourceBrowser *src,
111                                                const char           *usn,
112                                                gpointer              locations,
113                                                gpointer              user_data)
114 {
115         TestDiscoverySSDPAllData *data = (TestDiscoverySSDPAllData *) user_data;
116
117         g_assert_cmpstr (usn, ==, data->usn);
118
119         data->found = TRUE;
120
121         g_main_loop_quit (data->loop);
122 }
123
124 static void
125 on_test_discovery_ssdp_all_resource_unavailable (GSSDPResourceBrowser *src,
126                                                  const char           *usn,
127                                                  gpointer              user_data)
128 {
129         TestDiscoverySSDPAllData *data = (TestDiscoverySSDPAllData *) user_data;
130
131         g_assert_cmpstr (usn, ==, data->usn);
132
133         data->found = TRUE;
134
135         g_main_loop_quit (data->loop);
136 }
137
138 static gboolean
139 test_discovery_send_packet (gpointer user_data)
140 {
141         GSocket *socket;
142         GError *error = NULL;
143         GSocketAddress *sock_addr;
144         GInetAddress *address;
145         char *msg = (char *) user_data;
146
147         socket = create_socket ();
148
149         address = g_inet_address_new_from_string (SSDP_ADDR);
150
151         sock_addr = g_inet_socket_address_new (address, SSDP_PORT);
152         g_object_unref (address);
153
154         g_socket_send_to (socket, sock_addr, msg, strlen (msg), NULL, &error);
155         g_assert (error == NULL);
156
157         g_object_unref (sock_addr);
158         g_object_unref (socket);
159
160         g_free (msg);
161
162         return FALSE;
163 }
164
165 static void
166 test_discovery_ssdp_all (void)
167 {
168         GSSDPClient *client;
169         GSSDPResourceBrowser *browser;
170         GError *error = NULL;
171         TestDiscoverySSDPAllData data;
172         gulong signal_id;
173         guint timeout_id;
174
175         data.loop = g_main_loop_new (NULL, FALSE);
176         data.usn = UUID_1"::MyService:1";
177         data.found = FALSE;
178
179         client = gssdp_client_new (NULL, "lo", &error);
180         g_assert (client != NULL);
181         g_assert (error == NULL);
182
183         browser = gssdp_resource_browser_new (client, "ssdp:all");
184         signal_id = g_signal_connect (browser,
185                                       "resource-available",
186                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_available),
187                                       &data);
188         gssdp_resource_browser_set_active (browser, TRUE);
189
190         timeout_id = g_timeout_add_seconds (10, quit_loop, data.loop);
191
192         /* delay announcement until browser issued its M-SEARCH */
193         g_timeout_add_seconds (1,
194                                test_discovery_send_packet,
195                                create_alive_message ("MyService:1"));
196         g_main_loop_run (data.loop);
197
198         g_assert (data.found);
199
200         data.found = FALSE;
201         g_signal_handler_disconnect (browser, signal_id);
202         g_timeout_add_seconds (1,
203                                test_discovery_send_packet,
204                                create_byebye_message ("MyService:1"));
205         signal_id = g_signal_connect (browser,
206                                       "resource-unavailable",
207                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_unavailable),
208                                       &data);
209         g_main_loop_run (data.loop);
210
211         g_assert (data.found);
212
213         g_source_remove (timeout_id);
214         g_object_unref (browser);
215         g_object_unref (client);
216         g_main_loop_unref (data.loop);
217 }
218
219 static void
220 test_discovery_upnp_rootdevice (void)
221 {
222         GSSDPClient *client;
223         GSSDPResourceBrowser *browser;
224         GError *error = NULL;
225         TestDiscoverySSDPAllData data;
226         gulong signal_id;
227         guint timeout_id;
228
229         data.loop = g_main_loop_new (NULL, FALSE);
230         data.usn = UUID_1"::upnp:rootdevice";
231         data.found = FALSE;
232
233         client = gssdp_client_new (NULL, "lo", &error);
234         g_assert (client != NULL);
235         g_assert (error == NULL);
236
237         browser = gssdp_resource_browser_new (client, "upnp:rootdevice");
238         signal_id = g_signal_connect (browser,
239                                       "resource-available",
240                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_available),
241                                       &data);
242         gssdp_resource_browser_set_active (browser, TRUE);
243
244         timeout_id = g_timeout_add_seconds (10, quit_loop, data.loop);
245
246         /* delay announcement until browser issued its M-SEARCH */
247         g_timeout_add_seconds (1,
248                                test_discovery_send_packet,
249                                create_alive_message ("upnp:rootdevice"));
250         g_main_loop_run (data.loop);
251
252         g_assert (data.found);
253
254         data.found = FALSE;
255         g_signal_handler_disconnect (browser, signal_id);
256         g_timeout_add_seconds (1,
257                                test_discovery_send_packet,
258                                create_byebye_message ("upnp:rootdevice"));
259         signal_id = g_signal_connect (browser,
260                                       "resource-unavailable",
261                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_unavailable),
262                                       &data);
263         g_main_loop_run (data.loop);
264
265         g_assert (data.found);
266
267         g_source_remove (timeout_id);
268         g_object_unref (browser);
269         g_object_unref (client);
270         g_main_loop_unref (data.loop);
271 }
272
273 static void
274 test_discovery_uuid (void)
275 {
276         GSSDPClient *client;
277         GSSDPResourceBrowser *browser;
278         GError *error = NULL;
279         TestDiscoverySSDPAllData data;
280         gulong signal_id;
281         guint timeout_id;
282
283         data.loop = g_main_loop_new (NULL, FALSE);
284         data.usn = UUID_1;
285         data.found = FALSE;
286
287         client = gssdp_client_new (NULL, "lo", &error);
288         g_assert (client != NULL);
289         g_assert (error == NULL);
290
291         browser = gssdp_resource_browser_new (client, UUID_1);
292         signal_id = g_signal_connect (browser,
293                                       "resource-available",
294                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_available),
295                                       &data);
296         gssdp_resource_browser_set_active (browser, TRUE);
297
298         timeout_id = g_timeout_add_seconds (10, quit_loop, data.loop);
299
300         /* delay announcement until browser issued its M-SEARCH */
301         g_timeout_add_seconds (1,
302                                test_discovery_send_packet,
303                                create_alive_message (UUID_1));
304         g_main_loop_run (data.loop);
305
306         g_assert (data.found);
307
308         data.found = FALSE;
309         g_signal_handler_disconnect (browser, signal_id);
310         g_timeout_add_seconds (1,
311                                test_discovery_send_packet,
312                                create_byebye_message (UUID_1));
313         signal_id = g_signal_connect (browser,
314                                       "resource-unavailable",
315                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_unavailable),
316                                       &data);
317         g_main_loop_run (data.loop);
318
319         g_assert (data.found);
320
321         g_source_remove (timeout_id);
322         g_object_unref (browser);
323         g_object_unref (client);
324         g_main_loop_unref (data.loop);
325 }
326
327
328 static void
329 test_discovery_versioned (void)
330 {
331         GSSDPClient *client;
332         GSSDPResourceBrowser *browser;
333         GError *error = NULL;
334         TestDiscoverySSDPAllData data;
335         gulong signal_id;
336         guint timeout_id;
337
338         data.loop = g_main_loop_new (NULL, FALSE);
339         data.usn = VERSIONED_USN_1;
340         data.found = FALSE;
341
342         client = gssdp_client_new (NULL, "lo", &error);
343         g_assert (client != NULL);
344         g_assert (error == NULL);
345
346         browser = gssdp_resource_browser_new (client, VERSIONED_NT_1);
347         signal_id = g_signal_connect (browser,
348                                       "resource-available",
349                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_available),
350                                       &data);
351         gssdp_resource_browser_set_active (browser, TRUE);
352
353         timeout_id = g_timeout_add_seconds (10, quit_loop, data.loop);
354
355         /* delay announcement until browser issued its M-SEARCH */
356         g_timeout_add_seconds (1,
357                                test_discovery_send_packet,
358                                create_alive_message (VERSIONED_NT_1));
359         g_main_loop_run (data.loop);
360
361         g_assert (data.found);
362
363         data.found = FALSE;
364         g_signal_handler_disconnect (browser, signal_id);
365         g_timeout_add_seconds (1,
366                                test_discovery_send_packet,
367                                create_byebye_message (VERSIONED_NT_1));
368         signal_id = g_signal_connect (browser,
369                                       "resource-unavailable",
370                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_unavailable),
371                                       &data);
372         g_main_loop_run (data.loop);
373
374         g_assert (data.found);
375
376         /* check that the resource group doesn't trigger on other resources */
377         g_signal_handler_disconnect (browser, signal_id);
378         g_timeout_add_seconds (1,
379                                test_discovery_send_packet,
380                                create_byebye_message ("MyService:1"));
381         signal_id = g_signal_connect (browser,
382                                       "resource-available",
383                                       G_CALLBACK (on_resource_available_assert_not_reached),
384                                       NULL);
385         g_source_remove (timeout_id);
386         timeout_id = g_timeout_add_seconds (5, quit_loop, data.loop);
387         g_main_loop_run (data.loop);
388         g_source_remove (timeout_id);
389
390         g_object_unref (browser);
391         g_object_unref (client);
392         g_main_loop_unref (data.loop);
393 }
394
395 /*
396  * Search for FunctionalTest:1 and accept FunctionalTest:9
397  */
398 static void
399 test_discovery_versioned_backwards_compatible (void)
400 {
401         GSSDPClient *client;
402         GSSDPResourceBrowser *browser;
403         GError *error = NULL;
404         TestDiscoverySSDPAllData data;
405         gulong signal_id;
406         guint timeout_id;
407
408         data.loop = g_main_loop_new (NULL, FALSE);
409         data.usn = VERSIONED_USN_2;
410         data.found = FALSE;
411
412         client = gssdp_client_new (NULL, "lo", &error);
413         g_assert (client != NULL);
414         g_assert (error == NULL);
415
416         browser = gssdp_resource_browser_new (client, VERSIONED_NT_1);
417         signal_id = g_signal_connect (browser,
418                                       "resource-available",
419                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_available),
420                                       &data);
421         gssdp_resource_browser_set_active (browser, TRUE);
422
423         timeout_id = g_timeout_add_seconds (10, quit_loop, data.loop);
424
425         /* delay announcement until browser issued its M-SEARCH */
426         g_timeout_add_seconds (1,
427                                test_discovery_send_packet,
428                                create_alive_message (VERSIONED_NT_2));
429         g_main_loop_run (data.loop);
430
431         g_assert (data.found);
432
433         data.found = FALSE;
434         g_signal_handler_disconnect (browser, signal_id);
435         g_timeout_add_seconds (1,
436                                test_discovery_send_packet,
437                                create_byebye_message (VERSIONED_NT_2));
438         signal_id = g_signal_connect (browser,
439                                       "resource-unavailable",
440                                       G_CALLBACK (on_test_discovery_ssdp_all_resource_unavailable),
441                                       &data);
442         g_main_loop_run (data.loop);
443
444         g_assert (data.found);
445
446         g_source_remove (timeout_id);
447         g_object_unref (browser);
448         g_object_unref (client);
449         g_main_loop_unref (data.loop);
450 }
451
452 /*
453  * Search for FunctionalTest:9 and ignore FunctionalTest:1
454  */
455 static void
456 test_discovery_versioned_ignore_older (void)
457 {
458         GSSDPClient *client;
459         GSSDPResourceBrowser *browser;
460         GError *error = NULL;
461         GMainLoop *loop;
462
463         loop = g_main_loop_new (NULL, FALSE);
464
465         client = gssdp_client_new (NULL, "lo", &error);
466         g_assert (client != NULL);
467         g_assert (error == NULL);
468
469         browser = gssdp_resource_browser_new (client, VERSIONED_NT_2);
470         g_signal_connect (browser,
471                           "resource-available",
472                           G_CALLBACK (on_resource_available_assert_not_reached),
473                           NULL);
474         gssdp_resource_browser_set_active (browser, TRUE);
475
476         g_timeout_add_seconds (5, quit_loop, loop);
477
478         /* delay announcement until browser issued its M-SEARCH */
479         g_timeout_add_seconds (1,
480                                test_discovery_send_packet,
481                                create_alive_message (VERSIONED_NT_1));
482         g_main_loop_run (loop);
483
484         g_object_unref (browser);
485         g_object_unref (client);
486         g_main_loop_unref (loop);
487 }
488
489
490 int main(int argc, char *argv[])
491 {
492 #if !GLIB_CHECK_VERSION (2, 35, 0)
493         g_type_init ();
494 #endif
495         g_test_init (&argc, &argv, NULL);
496
497         g_test_add_func ("/functional/resource-group/discovery/ssdp:all",
498                          test_discovery_ssdp_all);
499
500         g_test_add_func ("/functional/resource-group/discovery/upnp:rootdevice",
501                          test_discovery_upnp_rootdevice);
502
503         g_test_add_func ("/functional/resource-group/discovery/uuid",
504                          test_discovery_uuid);
505
506         g_test_add_func ("/functional/resource-group/discovery/versioned/matching",
507                          test_discovery_versioned);
508
509         g_test_add_func ("/functional/resource-group/discovery/versioned/backwards-compatible",
510                          test_discovery_versioned_backwards_compatible);
511
512         g_test_add_func ("/functional/resource-group/discovery/versioned/ignore-older",
513                          test_discovery_versioned_ignore_older);
514
515         g_test_run ();
516
517         return 0;
518 }