1 /* Farstream unit tests for FsRawUdpTransmitter
2  *
3  * Copyright (C) 2007 Collabora, Nokia
4  * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
19 */
20 
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 
25 #include <gst/check/gstcheck.h>
26 #include <farstream/fs-transmitter.h>
27 #include <farstream/fs-conference.h>
28 
29 #include <arpa/inet.h>
30 #include <netdb.h>
31 
32 #include <unistd.h>
33 
34 #include "check-threadsafe.h"
35 #include "generic.h"
36 #include "transmitter/rawudp-upnp.h"
37 #include "testutils.h"
38 
39 #include "stunalternd.h"
40 
41 
42 gint buffer_count[2] = {0, 0};
43 GMainLoop *loop = NULL;
44 gint candidates[2] = {0, 0};
45 GstElement *pipeline = NULL;
46 gboolean src_setup[2] = {FALSE, FALSE};
47 volatile gint running = TRUE;
48 guint received_known[2] = {0, 0};
49 gboolean has_stun = FALSE;
50 gboolean associate_on_source = TRUE;
51 
52 gboolean pipeline_done = FALSE;
53 GMutex pipeline_mod_mutex;
54 
55 void *stun_alternd_data = NULL;
56 
57 enum {
58   FLAG_HAS_STUN  = 1 << 0,
59   FLAG_IS_LOCAL  = 1 << 1,
60   FLAG_NO_SOURCE = 1 << 2,
61   FLAG_NOT_SENDING = 1 << 3
62 };
63 
64 #define RTP_PORT 9828
65 #define RTCP_PORT 9829
66 
67 
GST_START_TEST(test_rawudptransmitter_new)68 GST_START_TEST (test_rawudptransmitter_new)
69 {
70   gchar **transmitters;
71   gint i;
72   gboolean found_it = FALSE;
73 
74   transmitters = fs_transmitter_list_available ();
75   for (i=0; transmitters != NULL && transmitters[i]; i++)
76   {
77     if (!strcmp ("rawudp", transmitters[i]))
78     {
79       found_it = TRUE;
80       break;
81     }
82   }
83   g_strfreev (transmitters);
84 
85   ts_fail_unless (found_it, "Did not find rawudp transmitter");
86 
87   test_transmitter_creation ("rawudp");
88   test_transmitter_creation ("rawudp");
89 }
90 GST_END_TEST;
91 
92 static void
_new_local_candidate(FsStreamTransmitter * st,FsCandidate * candidate,gpointer user_data)93 _new_local_candidate (FsStreamTransmitter *st, FsCandidate *candidate,
94   gpointer user_data)
95 {
96   gboolean is_local = GPOINTER_TO_INT (user_data) & FLAG_IS_LOCAL;
97   GError *error = NULL;
98   GList *item = NULL;
99   gboolean ret;
100 
101   GST_DEBUG ("Has local candidate %s:%u of type %d",
102     candidate->ip, candidate->port, candidate->type);
103 
104   ts_fail_if (candidate == NULL, "Passed NULL candidate");
105   ts_fail_unless (candidate->ip != NULL, "Null IP in candidate");
106   ts_fail_if (candidate->port == 0, "Candidate has port 0");
107   ts_fail_unless (candidate->proto == FS_NETWORK_PROTOCOL_UDP,
108     "Protocol is not UDP");
109 
110   if (has_stun)
111     ts_fail_unless (candidate->type == FS_CANDIDATE_TYPE_SRFLX,
112       "Has stun, but candidate is not server reflexive,"
113       " it is: %s:%u of type %d on component %u",
114       candidate->ip, candidate->port, candidate->type, candidate->component_id);
115   else {
116     ts_fail_unless (candidate->type == FS_CANDIDATE_TYPE_HOST,
117         "Does not have stun, but candidate is not host");
118     if (candidate->component_id == FS_COMPONENT_RTP) {
119       ts_fail_unless (candidate->port % 2 == 0, "RTP port should be odd");
120     } else if (candidate->component_id == FS_COMPONENT_RTCP) {
121       ts_fail_unless (candidate->port % 2 == 1, "RTCP port should be event");
122     }
123   }
124 
125   if (is_local) {
126     ts_fail_unless (!strcmp (candidate->ip, "127.0.0.1"),
127       "IP is wrong, it is %s but should be 127.0.0.1 when local candidate set",
128       candidate->ip);
129 
130     if (candidate->component_id == FS_COMPONENT_RTP) {
131       ts_fail_unless (candidate->port >= RTP_PORT  , "RTP port invalid");
132     } else if (candidate->component_id == FS_COMPONENT_RTCP) {
133       ts_fail_unless (candidate->port >= RTCP_PORT, "RTCP port invalid");
134     }
135   }
136 
137 
138   candidates[candidate->component_id-1] = 1;
139 
140   GST_DEBUG ("New local candidate %s:%d of type %d for component %d",
141     candidate->ip, candidate->port, candidate->type, candidate->component_id);
142 
143   item = g_list_prepend (NULL, candidate);
144 
145   ret = fs_stream_transmitter_force_remote_candidates (st, item, &error);
146 
147   g_list_free (item);
148 
149   if (error)
150     ts_fail ("Error while adding candidate: (%s:%d) %s",
151       g_quark_to_string (error->domain), error->code, error->message);
152 
153   ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate");
154 
155 }
156 
157 static void
_local_candidates_prepared(FsStreamTransmitter * st,gpointer user_data)158 _local_candidates_prepared (FsStreamTransmitter *st, gpointer user_data)
159 {
160   ts_fail_if (candidates[0] == 0, "candidates-prepared with no RTP candidate");
161   ts_fail_if (candidates[1] == 0, "candidates-prepared with no RTCP candidate");
162 
163   GST_DEBUG ("Local Candidates Prepared");
164 
165   /*
166    * This doesn't work on my router
167    */
168 
169   if (has_stun)
170   {
171     g_main_loop_quit (loop);
172     g_atomic_int_set(&running, FALSE);
173   }
174 }
175 
176 
177 static void
_new_active_candidate_pair(FsStreamTransmitter * st,FsCandidate * local,FsCandidate * remote,gpointer user_data)178 _new_active_candidate_pair (FsStreamTransmitter *st, FsCandidate *local,
179   FsCandidate *remote, gpointer user_data)
180 {
181   ts_fail_if (local == NULL, "Local candidate NULL");
182   ts_fail_if (remote == NULL, "Remote candidate NULL");
183 
184   ts_fail_unless (local->component_id == remote->component_id,
185     "Local and remote candidates dont have the same component id");
186 
187   GST_DEBUG ("New active candidate pair for component %d", local->component_id);
188 
189   g_mutex_lock (&pipeline_mod_mutex);
190   if (!pipeline_done && !src_setup[local->component_id-1])
191     setup_fakesrc (user_data, pipeline, local->component_id);
192   src_setup[local->component_id-1] = TRUE;
193   g_mutex_unlock (&pipeline_mod_mutex);
194 }
195 
196 static void
_handoff_handler(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)197 _handoff_handler (GstElement *element, GstBuffer *buffer, GstPad *pad,
198   gpointer user_data)
199 {
200   gint component_id = GPOINTER_TO_INT (user_data);
201 
202   ts_fail_unless (gst_buffer_get_size (buffer) == component_id * 10,
203     "Buffer is size %d but component_id is %d", gst_buffer_get_size (buffer),
204     component_id);
205 
206   buffer_count[component_id-1]++;
207 
208   GST_LOG ("Buffer %d component: %d size: %" G_GSIZE_FORMAT,
209       buffer_count[component_id-1], component_id, gst_buffer_get_size (buffer));
210 
211   ts_fail_if (buffer_count[component_id-1] > 20,
212     "Too many buffers %d > 20 for component",
213     buffer_count[component_id-1], component_id);
214 
215   if (buffer_count[0] == 20 && buffer_count[1] == 20) {
216     /* TEST OVER */
217     if (associate_on_source)
218       ts_fail_unless (buffer_count[0] == received_known[0] &&
219           buffer_count[1] == received_known[1], "Some known buffers from known"
220           " sources have not been reported (%d != %u || %d != %u)",
221           buffer_count[0], received_known[0],
222           buffer_count[1], received_known[1]);
223     else
224       ts_fail_unless (received_known[0] == 0 && received_known[1] == 0,
225           "Got a known-source-packet-received signal when we shouldn't have");
226     g_atomic_int_set(&running, FALSE);
227     g_main_loop_quit (loop);
228   }
229 }
230 
231 static void
_known_source_packet_received(FsStreamTransmitter * st,guint component_id,GstBuffer * buffer,gpointer user_data)232 _known_source_packet_received (FsStreamTransmitter *st, guint component_id,
233     GstBuffer *buffer, gpointer user_data)
234 {
235   ts_fail_unless (associate_on_source == TRUE,
236       "Got known-source-packet-received when we shouldn't have");
237 
238   ts_fail_unless (component_id == 1 || component_id == 2,
239       "Invalid component id %u", component_id);
240 
241   ts_fail_unless (GST_IS_BUFFER (buffer), "Invalid buffer received at %p",
242       buffer);
243 
244   received_known[component_id - 1]++;
245 }
246 
247 static gboolean
check_running(gpointer data)248 check_running (gpointer data)
249 {
250   if (g_atomic_int_get (&running) == FALSE)
251     g_main_loop_quit (loop);
252 
253   return FALSE;
254 }
255 
256 void
sync_error_handler(GstBus * bus,GstMessage * message,gpointer blob)257 sync_error_handler (GstBus *bus, GstMessage *message, gpointer blob)
258 {
259   GError *error = NULL;
260   gchar *debug;
261   gst_message_parse_error (message, &error, &debug);
262   g_error ("bus sync error %s", error->message);
263 }
264 
265 
266 static void
run_rawudp_transmitter_test(gint n_parameters,GParameter * params,gint flags)267 run_rawudp_transmitter_test (gint n_parameters, GParameter *params,
268   gint flags)
269 {
270   GError *error = NULL;
271   FsTransmitter *trans;
272   FsStreamTransmitter *st;
273   GstBus *bus = NULL;
274   guint tos;
275 
276   buffer_count[0] = 0;
277   buffer_count[1] = 0;
278   received_known[0] = 0;
279   received_known[1] = 0;
280   pipeline_done = FALSE;
281 
282   has_stun = flags & FLAG_HAS_STUN;
283   associate_on_source = !(flags & FLAG_NO_SOURCE);
284 
285   if ((flags & FLAG_NOT_SENDING))
286   {
287     buffer_count[0] = 20;
288     received_known[0] = 20;
289   }
290 
291   loop = g_main_loop_new (NULL, FALSE);
292   trans = fs_transmitter_new ("rawudp", 2, 0, &error);
293 
294   if (error) {
295     ts_fail ("Error creating transmitter: (%s:%d) %s",
296       g_quark_to_string (error->domain), error->code, error->message);
297   }
298 
299   ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL");
300 
301   g_object_set (trans, "tos", 2, NULL);
302   g_object_get (trans, "tos", &tos, NULL);
303   ts_fail_unless (tos == 2);
304 
305   pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler));
306 
307   bus = gst_element_get_bus (pipeline);
308   gst_bus_add_watch (bus, bus_error_callback, NULL);
309 
310   gst_bus_enable_sync_message_emission (bus);
311   g_signal_connect (bus, "sync-message::error", G_CALLBACK (sync_error_handler), NULL);
312 
313   gst_object_unref (bus);
314 
315   st = fs_transmitter_new_stream_transmitter (trans, NULL, n_parameters, params,
316     &error);
317 
318   if (error) {
319     if (has_stun &&
320         error->domain == FS_ERROR &&
321         error->code == FS_ERROR_NETWORK &&
322         error->message && strstr (error->message, "unreachable"))
323     {
324       GST_WARNING ("Skipping stunserver test, we have no network");
325       goto skip;
326     }
327     else
328       ts_fail ("Error creating stream transmitter: (%s:%d) %s",
329           g_quark_to_string (error->domain), error->code, error->message);
330   }
331 
332   ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL");
333 
334   g_object_set (st, "sending", !(flags & FLAG_NOT_SENDING), NULL);
335 
336   ts_fail_unless (g_signal_connect (st, "new-local-candidate",
337       G_CALLBACK (_new_local_candidate), GINT_TO_POINTER (flags)),
338     "Could not connect new-local-candidate signal");
339   ts_fail_unless (g_signal_connect (st, "local-candidates-prepared",
340       G_CALLBACK (_local_candidates_prepared), GINT_TO_POINTER (flags)),
341     "Could not connect local-candidates-prepared signal");
342   ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair",
343       G_CALLBACK (_new_active_candidate_pair), trans),
344     "Could not connect new-active-candidate-pair signal");
345   ts_fail_unless (g_signal_connect (st, "error",
346       G_CALLBACK (stream_transmitter_error), NULL),
347     "Could not connect error signal");
348   ts_fail_unless (g_signal_connect (st, "known-source-packet-received",
349       G_CALLBACK (_known_source_packet_received), NULL),
350     "Could not connect known-source-packet-received signal");
351 
352   ts_fail_if (gst_element_set_state (pipeline, GST_STATE_PLAYING) ==
353     GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing");
354 
355   if (!fs_stream_transmitter_gather_local_candidates (st, &error))
356   {
357     if (error)
358     {
359       ts_fail ("Could not start gathering local candidates (%s:%d) %s",
360           g_quark_to_string (error->domain), error->code, error->message);
361     }
362     else
363       ts_fail ("Could not start gathering candidates"
364           " (without a specified error)");
365   }
366 
367   g_idle_add (check_running, NULL);
368 
369   g_main_loop_run (loop);
370 
371  skip:
372 
373   g_mutex_lock (&pipeline_mod_mutex);
374   pipeline_done = TRUE;
375   g_mutex_unlock (&pipeline_mod_mutex);
376 
377   gst_element_set_state (pipeline, GST_STATE_NULL);
378 
379   if (st)
380   {
381     fs_stream_transmitter_stop (st);
382     g_object_unref (st);
383   }
384 
385   g_object_unref (trans);
386 
387   gst_object_unref (pipeline);
388 
389   g_main_loop_unref (loop);
390 }
391 
GST_START_TEST(test_rawudptransmitter_run_nostun)392 GST_START_TEST (test_rawudptransmitter_run_nostun)
393 {
394   GParameter params[1];
395 
396   memset (params, 0, sizeof (GParameter));
397 
398   params[0].name = "upnp-discovery";
399   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
400   g_value_set_boolean (&params[0].value, FALSE);
401 
402   run_rawudp_transmitter_test (1, params, 0);
403 }
404 GST_END_TEST;
405 
GST_START_TEST(test_rawudptransmitter_run_nostun_nosource)406 GST_START_TEST (test_rawudptransmitter_run_nostun_nosource)
407 {
408   GParameter params[2];
409 
410   memset (params, 0, sizeof (GParameter) * 2);
411 
412   params[0].name = "associate-on-source";
413   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
414   g_value_set_boolean (&params[0].value, FALSE);
415 
416   params[1].name = "upnp-discovery";
417   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
418   g_value_set_boolean (&params[1].value, FALSE);
419 
420   run_rawudp_transmitter_test (2, params, FLAG_NO_SOURCE);
421 }
422 GST_END_TEST;
423 
GST_START_TEST(test_rawudptransmitter_run_invalid_stun)424 GST_START_TEST (test_rawudptransmitter_run_invalid_stun)
425 {
426   GParameter params[4];
427 
428   /*
429    * Hopefully not one is runing a stun server on local port 7777
430    */
431 
432   memset (params, 0, sizeof (GParameter) * 4);
433 
434   params[0].name = "stun-ip";
435   g_value_init (&params[0].value, G_TYPE_STRING);
436   g_value_set_static_string (&params[0].value, "127.0.0.1");
437 
438   params[1].name = "stun-port";
439   g_value_init (&params[1].value, G_TYPE_UINT);
440   g_value_set_uint (&params[1].value, 7777);
441 
442   params[2].name = "stun-timeout";
443   g_value_init (&params[2].value, G_TYPE_UINT);
444   g_value_set_uint (&params[2].value, 3);
445 
446   params[3].name = "upnp-discovery";
447   g_value_init (&params[3].value, G_TYPE_BOOLEAN);
448   g_value_set_boolean (&params[3].value, FALSE);
449 
450   run_rawudp_transmitter_test (4, params, 0);
451 }
452 GST_END_TEST;
453 
GST_START_TEST(test_rawudptransmitter_run_stund)454 GST_START_TEST (test_rawudptransmitter_run_stund)
455 {
456   GParameter params[4];
457 
458   if (stund_pid <= 0)
459     return;
460 
461   memset (params, 0, sizeof (GParameter) * 4);
462 
463   params[0].name = "stun-ip";
464   g_value_init (&params[0].value, G_TYPE_STRING);
465   g_value_set_static_string (&params[0].value, "127.0.0.1");
466 
467   params[1].name = "stun-port";
468   g_value_init (&params[1].value, G_TYPE_UINT);
469   g_value_set_uint (&params[1].value, 3478);
470 
471   params[2].name = "stun-timeout";
472   g_value_init (&params[2].value, G_TYPE_UINT);
473   g_value_set_uint (&params[2].value, 5);
474 
475   params[3].name = "upnp-discovery";
476   g_value_init (&params[3].value, G_TYPE_BOOLEAN);
477   g_value_set_boolean (&params[3].value, FALSE);
478 
479 
480   run_rawudp_transmitter_test (3, params, FLAG_HAS_STUN);
481 }
482 GST_END_TEST;
483 
484 
GST_START_TEST(test_rawudptransmitter_run_local_candidates)485 GST_START_TEST (test_rawudptransmitter_run_local_candidates)
486 {
487   GParameter params[2];
488   GList *list = NULL;
489   FsCandidate *candidate;
490 
491   memset (params, 0, sizeof (GParameter) * 2);
492 
493   candidate = fs_candidate_new ("L1",
494       FS_COMPONENT_RTP, FS_CANDIDATE_TYPE_HOST,
495       FS_NETWORK_PROTOCOL_UDP, "127.0.0.1", RTP_PORT);
496   list = g_list_prepend (list, candidate);
497 
498   candidate = fs_candidate_new ("L1",
499       FS_COMPONENT_RTCP, FS_CANDIDATE_TYPE_HOST,
500       FS_NETWORK_PROTOCOL_UDP, "127.0.0.1", RTCP_PORT);
501   list = g_list_prepend (list, candidate);
502 
503   params[0].name = "preferred-local-candidates";
504   g_value_init (&params[0].value, FS_TYPE_CANDIDATE_LIST);
505   g_value_set_boxed (&params[0].value, list);
506 
507   params[1].name = "upnp-discovery";
508   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
509   g_value_set_boolean (&params[1].value, FALSE);
510 
511 
512   run_rawudp_transmitter_test (2, params, FLAG_IS_LOCAL);
513 
514   g_value_reset (&params[0].value);
515 
516   fs_candidate_list_destroy (list);
517 }
518 GST_END_TEST;
519 
520 static gboolean
_bus_stop_stream_cb(GstBus * bus,GstMessage * message,gpointer user_data)521 _bus_stop_stream_cb (GstBus *bus, GstMessage *message, gpointer user_data)
522 {
523   FsStreamTransmitter *st = user_data;
524   GstState oldstate, newstate, pending;
525 
526   if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_STATE_CHANGED ||
527       G_OBJECT_TYPE (GST_MESSAGE_SRC (message)) != GST_TYPE_PIPELINE)
528     return bus_error_callback (bus, message, user_data);
529 
530   gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);
531 
532   if (newstate != GST_STATE_PLAYING)
533     return TRUE;
534 
535   if (pending != GST_STATE_VOID_PENDING)
536     ts_fail ("New state playing, but pending is %d", pending);
537 
538   GST_DEBUG ("Stopping stream transmitter");
539 
540   fs_stream_transmitter_stop (st);
541   g_object_unref (st);
542 
543   GST_DEBUG ("Stopped stream transmitter");
544 
545   g_atomic_int_set(&running, FALSE);
546   g_main_loop_quit (loop);
547 
548   return TRUE;
549 }
550 
551 static void
_handoff_handler_empty(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)552 _handoff_handler_empty (GstElement *element, GstBuffer *buffer, GstPad *pad,
553   gpointer user_data)
554 {
555 }
556 
557 
558 /*
559  * This test checks that starting a stream, getting it to playing
560  * then stopping it, while the pipeline is playing works
561  */
562 
GST_START_TEST(test_rawudptransmitter_stop_stream)563 GST_START_TEST (test_rawudptransmitter_stop_stream)
564 {
565   GError *error = NULL;
566   FsTransmitter *trans;
567   FsStreamTransmitter *st;
568   GstBus *bus = NULL;
569   GParameter params[1];
570 
571   memset (params, 0, sizeof (GParameter));
572 
573   params[0].name = "upnp-discovery";
574   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
575   g_value_set_boolean (&params[0].value, FALSE);
576 
577   has_stun = FALSE;
578 
579   loop = g_main_loop_new (NULL, FALSE);
580   trans = fs_transmitter_new ("rawudp", 2, 0, &error);
581 
582   if (error) {
583     ts_fail ("Error creating transmitter: (%s:%d) %s",
584       g_quark_to_string (error->domain), error->code, error->message);
585   }
586 
587   ts_fail_if (trans == NULL, "No transmitter create, yet error is still NULL");
588 
589   pipeline = setup_pipeline (trans, G_CALLBACK (_handoff_handler_empty));
590 
591   st = fs_transmitter_new_stream_transmitter (trans, NULL, 1, params, &error);
592 
593   if (error)
594     ts_fail ("Error creating stream transmitter: (%s:%d) %s",
595         g_quark_to_string (error->domain), error->code, error->message);
596 
597   ts_fail_if (st == NULL, "No stream transmitter created, yet error is NULL");
598 
599   bus = gst_element_get_bus (pipeline);
600   gst_bus_add_watch (bus, _bus_stop_stream_cb, st);
601   gst_object_unref (bus);
602 
603   ts_fail_unless (g_signal_connect (st, "new-local-candidate",
604           G_CALLBACK (_new_local_candidate), NULL),
605       "Could not connect new-local-candidate signal");
606   ts_fail_unless (g_signal_connect (st, "new-active-candidate-pair",
607           G_CALLBACK (_new_active_candidate_pair), trans),
608       "Could not connect new-active-candidate-pair signal");
609   ts_fail_unless (g_signal_connect (st, "error",
610           G_CALLBACK (stream_transmitter_error), NULL),
611       "Could not connect error signal");
612 
613   ts_fail_if (gst_element_set_state (pipeline, GST_STATE_PLAYING) ==
614     GST_STATE_CHANGE_FAILURE, "Could not set the pipeline to playing");
615 
616   if (!fs_stream_transmitter_gather_local_candidates (st, &error))
617   {
618     if (error)
619       ts_fail ("Could not start gathering local candidates %s",
620           error->message);
621     else
622       ts_fail ("Could not start gathering candidates"
623           " (without a specified error)");
624   }
625 
626   g_idle_add (check_running, NULL);
627 
628   g_main_loop_run (loop);
629 
630   gst_element_set_state (pipeline, GST_STATE_NULL);
631 
632   g_object_unref (trans);
633 
634   gst_object_unref (pipeline);
635 
636   g_main_loop_unref (loop);
637 }
638 GST_END_TEST;
639 
640 #ifdef HAVE_GUPNP
641 
GST_START_TEST(test_rawudptransmitter_run_upnp_discovery)642 GST_START_TEST (test_rawudptransmitter_run_upnp_discovery)
643 {
644   GParameter params[2];
645   GObject *context;
646   gboolean got_address = FALSE;
647   gboolean added_mapping = FALSE;
648 
649   memset (params, 0, sizeof (GParameter) * 2);
650 
651   params[0].name = "associate-on-source";
652   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
653   g_value_set_boolean (&params[0].value, TRUE);
654 
655   params[1].name = "upnp-discovery";
656   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
657   g_value_set_boolean (&params[1].value, TRUE);
658 
659   context = start_upnp_server ();
660 
661   run_rawudp_transmitter_test (2, params, 0);
662 
663 
664   get_vars (&got_address, &added_mapping);
665   ts_fail_unless (got_address, "did not get address");
666   ts_fail_unless (added_mapping, "did not add mapping");
667   g_object_unref (context);
668 }
669 GST_END_TEST;
670 
GST_START_TEST(test_rawudptransmitter_run_upnp_fallback)671 GST_START_TEST (test_rawudptransmitter_run_upnp_fallback)
672 {
673   GParameter params[6];
674   GObject *context;
675   gboolean got_address = FALSE;
676   gboolean added_mapping = FALSE;
677 
678   memset (params, 0, sizeof (GParameter) * 6);
679 
680   params[0].name = "associate-on-source";
681   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
682   g_value_set_boolean (&params[0].value, TRUE);
683 
684   params[1].name = "upnp-discovery";
685   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
686   g_value_set_boolean (&params[1].value, FALSE);
687 
688   params[2].name = "stun-ip";
689   g_value_init (&params[2].value, G_TYPE_STRING);
690   g_value_set_static_string (&params[2].value, "127.0.0.1");
691 
692   params[3].name = "stun-port";
693   g_value_init (&params[3].value, G_TYPE_UINT);
694   g_value_set_uint (&params[3].value, 3232);
695 
696   params[4].name = "stun-timeout";
697   g_value_init (&params[4].value, G_TYPE_UINT);
698   g_value_set_uint (&params[4].value, 6);
699 
700   params[5].name = "upnp-discovery-timeout";
701   g_value_init (&params[5].value, G_TYPE_UINT);
702   g_value_set_uint (&params[5].value, 3);
703 
704   context = start_upnp_server ();
705 
706   run_rawudp_transmitter_test (6, params, 0);
707 
708   get_vars (&got_address, &added_mapping);
709   ts_fail_unless (got_address, "did not get address");
710   ts_fail_unless (added_mapping, "did not add mapping");
711 
712   g_object_unref (context);
713 }
714 GST_END_TEST;
715 
GST_START_TEST(test_rawudptransmitter_run_upnp_ignored)716 GST_START_TEST (test_rawudptransmitter_run_upnp_ignored)
717 {
718   GParameter params[6];
719   GObject *context;
720 
721   if (stund_pid <= 0)
722     return;
723 
724   memset (params, 0, sizeof (GParameter) * 6);
725 
726   params[0].name = "associate-on-source";
727   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
728   g_value_set_boolean (&params[0].value, TRUE);
729 
730   params[1].name = "upnp-discovery";
731   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
732   g_value_set_boolean (&params[1].value, FALSE);
733 
734   params[2].name = "stun-ip";
735   g_value_init (&params[2].value, G_TYPE_STRING);
736   g_value_set_static_string (&params[2].value, "127.0.0.1");
737 
738   params[3].name = "stun-port";
739   g_value_init (&params[3].value, G_TYPE_UINT);
740   g_value_set_uint (&params[3].value, 3478);
741 
742   params[4].name = "stun-timeout";
743   g_value_init (&params[4].value, G_TYPE_UINT);
744   g_value_set_uint (&params[4].value, 6);
745 
746   params[5].name = "upnp-discovery-timeout";
747   g_value_init (&params[5].value, G_TYPE_UINT);
748   g_value_set_uint (&params[5].value, 3);
749 
750   context = start_upnp_server ();
751 
752   run_rawudp_transmitter_test (6, params, FLAG_HAS_STUN);
753 
754   g_object_unref (context);
755 }
756 GST_END_TEST;
757 
758 #endif /* HAVE_GUPNP */
759 
760 
GST_START_TEST(test_rawudptransmitter_sending_half)761 GST_START_TEST (test_rawudptransmitter_sending_half)
762 {
763   GParameter params[2];
764 
765   memset (params, 0, sizeof (GParameter) * 2);
766 
767   params[0].name = "associate-on-source";
768   g_value_init (&params[0].value, G_TYPE_BOOLEAN);
769   g_value_set_boolean (&params[0].value, TRUE);
770 
771   params[1].name = "upnp-discovery";
772   g_value_init (&params[1].value, G_TYPE_BOOLEAN);
773   g_value_set_boolean (&params[1].value, FALSE);
774 
775   run_rawudp_transmitter_test (2, params, FLAG_NOT_SENDING);
776 }
777 GST_END_TEST;
778 
779 
GST_START_TEST(test_rawudptransmitter_run_stunalternd)780 GST_START_TEST (test_rawudptransmitter_run_stunalternd)
781 {
782   GParameter params[4];
783 
784   if (stund_pid <= 0 || stun_alternd_data == NULL)
785     return;
786 
787   memset (params, 0, sizeof (GParameter) * 4);
788 
789   params[0].name = "stun-ip";
790   g_value_init (&params[0].value, G_TYPE_STRING);
791   g_value_set_static_string (&params[0].value, "127.0.0.1");
792 
793   params[1].name = "stun-port";
794   g_value_init (&params[1].value, G_TYPE_UINT);
795   g_value_set_uint (&params[1].value, 3480);
796 
797   params[2].name = "stun-timeout";
798   g_value_init (&params[2].value, G_TYPE_UINT);
799   g_value_set_uint (&params[2].value, 5);
800 
801   params[3].name = "upnp-discovery";
802   g_value_init (&params[3].value, G_TYPE_BOOLEAN);
803   g_value_set_boolean (&params[3].value, FALSE);
804 
805 
806   run_rawudp_transmitter_test (3, params, FLAG_HAS_STUN);
807 }
808 GST_END_TEST;
809 
810 
GST_START_TEST(test_rawudptransmitter_run_stun_altern_to_nowhere)811 GST_START_TEST (test_rawudptransmitter_run_stun_altern_to_nowhere)
812 {
813   GParameter params[4];
814 
815   if (stun_alternd_data == NULL)
816     return;
817 
818   /*
819    * Hopefully not one is runing a stun server on local port 3478
820    */
821 
822   memset (params, 0, sizeof (GParameter) * 4);
823 
824   params[0].name = "stun-ip";
825   g_value_init (&params[0].value, G_TYPE_STRING);
826   g_value_set_static_string (&params[0].value, "127.0.0.1");
827 
828   params[1].name = "stun-port";
829   g_value_init (&params[1].value, G_TYPE_UINT);
830   g_value_set_uint (&params[1].value, 3480);
831 
832   params[2].name = "stun-timeout";
833   g_value_init (&params[2].value, G_TYPE_UINT);
834   g_value_set_uint (&params[2].value, 10);
835 
836   params[3].name = "upnp-discovery";
837   g_value_init (&params[3].value, G_TYPE_BOOLEAN);
838   g_value_set_boolean (&params[3].value, FALSE);
839 
840   run_rawudp_transmitter_test (4, params, 0);
841 }
842 GST_END_TEST;
843 
GST_START_TEST(test_rawudptransmitter_strange_arguments)844 GST_START_TEST (test_rawudptransmitter_strange_arguments)
845 {
846   FsTransmitter *trans = NULL;
847   FsStreamTransmitter *st = NULL;
848   GError *error = NULL;
849   guint comps = 0;
850   FsCandidate *cand;
851   GList *list;
852 
853   trans = fs_transmitter_new ("rawudp", 3, 0, &error);
854   ts_fail_if (trans == NULL);
855   ts_fail_unless (error == NULL);
856 
857   g_object_get (trans, "components", &comps, NULL);
858   ts_fail_unless (comps == 3);
859 
860   /* valid */
861   st = fs_transmitter_new_stream_transmitter (trans, NULL, 0, NULL, &error);
862   ts_fail_if (st == NULL);
863   ts_fail_unless (error == NULL);
864 
865   /* Valid candidate, port 0 */
866   cand = fs_candidate_new ("abc", 1,
867       FS_CANDIDATE_TYPE_HOST, FS_NETWORK_PROTOCOL_UDP, "1.2.3.4", 0);
868   list = g_list_prepend (NULL, cand);
869   ts_fail_unless (fs_stream_transmitter_force_remote_candidates (st, list,
870           &error));
871   ts_fail_unless (error == NULL);
872   fs_candidate_list_destroy (list);
873 
874   fs_stream_transmitter_stop (st);
875   g_object_unref (st);
876   g_object_unref (trans);
877 }
878 GST_END_TEST;
879 
880 void
setup_stunalternd_valid(void)881 setup_stunalternd_valid (void)
882 {
883   stun_alternd_data = stun_alternd_init (G_SOCKET_FAMILY_IPV4,
884       "127.0.0.1", 3478, 3480);
885 
886   if (!stun_alternd_data)
887     GST_WARNING ("Could not spawn stunalternd,"
888         " skipping stun alternate server testing");
889 }
890 
891 static void
setup_stunalternd_loop(void)892 setup_stunalternd_loop (void)
893 {
894   stun_alternd_data = stun_alternd_init (G_SOCKET_FAMILY_IPV4,
895       "127.0.0.1", 3478, 3478);
896 
897   if (!stun_alternd_data)
898     GST_WARNING ("Could not spawn stunalternd,"
899         " skipping stun alternate server testing");
900 }
901 
902 static void
teardown_stunalternd(void)903 teardown_stunalternd (void)
904 {
905   if (!stun_alternd_data)
906     return;
907 
908   stun_alternd_stop (stun_alternd_data);
909   stun_alternd_data = NULL;
910 }
911 
912 static void
setup_stund_stunalternd(void)913 setup_stund_stunalternd (void)
914 {
915   setup_stund ();
916   setup_stunalternd_valid ();
917 }
918 
919 
920 static void
teardown_stund_stunalternd(void)921 teardown_stund_stunalternd (void)
922 {
923   teardown_stund ();
924   teardown_stunalternd ();
925 }
926 
927 
928 static Suite *
rawudptransmitter_suite(void)929 rawudptransmitter_suite (void)
930 {
931   Suite *s = suite_create ("rawudptransmitter");
932   TCase *tc_chain;
933   GLogLevelFlags fatal_mask;
934 
935   fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
936   fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
937   g_log_set_always_fatal (fatal_mask);
938 
939   tc_chain = tcase_create ("rawudptransmitter_new");
940   tcase_add_test (tc_chain, test_rawudptransmitter_new);
941   suite_add_tcase (s, tc_chain);
942 
943   tc_chain = tcase_create ("rawudptransmitter_nostun");
944   tcase_add_test (tc_chain, test_rawudptransmitter_run_nostun);
945   suite_add_tcase (s, tc_chain);
946 
947   tc_chain = tcase_create ("rawudptransmitter_nostun_nosource");
948   tcase_add_test (tc_chain, test_rawudptransmitter_run_nostun_nosource);
949   suite_add_tcase (s, tc_chain);
950 
951   tc_chain = tcase_create ("rawudptransmitter-stun-timeout");
952   tcase_set_timeout (tc_chain, 10);
953   tcase_add_test (tc_chain, test_rawudptransmitter_run_invalid_stun);
954   suite_add_tcase (s, tc_chain);
955 
956   tc_chain = tcase_create ("rawudptransmitter-stund");
957   tcase_set_timeout (tc_chain, 15);
958   tcase_add_checked_fixture (tc_chain, setup_stund, teardown_stund);
959   tcase_add_test (tc_chain, test_rawudptransmitter_run_stund);
960   suite_add_tcase (s, tc_chain);
961 
962   tc_chain = tcase_create ("rawudptransmitter-local-candidates");
963   tcase_add_test (tc_chain, test_rawudptransmitter_run_local_candidates);
964   suite_add_tcase (s, tc_chain);
965 
966   tc_chain = tcase_create ("rawudptransmitter-stop-stream");
967   tcase_add_test (tc_chain, test_rawudptransmitter_stop_stream);
968   suite_add_tcase (s, tc_chain);
969 
970 #ifdef HAVE_GUPNP
971   if (g_getenv ("UPNP")) {
972     gchar *multicast_addr;
973 
974     multicast_addr = find_multicast_capable_address ();
975     g_free (multicast_addr);
976 
977     if (multicast_addr)
978     {
979       tc_chain = tcase_create ("rawudptransmitter-upnp-discovery");
980       tcase_add_test (tc_chain, test_rawudptransmitter_run_upnp_discovery);
981       suite_add_tcase (s, tc_chain);
982 
983       tc_chain = tcase_create ("rawudptransmitter-upnp-fallback");
984       tcase_add_test (tc_chain, test_rawudptransmitter_run_upnp_fallback);
985       suite_add_tcase (s, tc_chain);
986 
987       tc_chain = tcase_create ("rawudptransmitter-upnp-ignored");
988       tcase_add_checked_fixture (tc_chain, setup_stund, teardown_stund);
989       tcase_add_test (tc_chain, test_rawudptransmitter_run_upnp_ignored);
990       suite_add_tcase (s, tc_chain);
991     }
992   }
993 #endif
994 
995   tc_chain = tcase_create ("rawudptransmitter-sending-half");
996   tcase_add_test (tc_chain, test_rawudptransmitter_sending_half);
997   suite_add_tcase (s, tc_chain);
998 
999   tc_chain = tcase_create ("rawudptransmitter-stunalternd");
1000   tcase_set_timeout (tc_chain, 5);
1001   tcase_add_checked_fixture (tc_chain, setup_stund_stunalternd,
1002       teardown_stund_stunalternd);
1003   tcase_add_test (tc_chain, test_rawudptransmitter_run_stunalternd);
1004   suite_add_tcase (s, tc_chain);
1005 
1006   tc_chain = tcase_create ("rawudptransmitter-stunalternd-to-nowhere");
1007   tcase_set_timeout (tc_chain, 20);
1008   tcase_add_checked_fixture (tc_chain, setup_stunalternd_valid,
1009       teardown_stunalternd);
1010   tcase_add_test (tc_chain, test_rawudptransmitter_run_stun_altern_to_nowhere);
1011   suite_add_tcase (s, tc_chain);
1012 
1013   tc_chain = tcase_create ("rawudptransmitter-stunalternd-loop");
1014   tcase_set_timeout (tc_chain, 20);
1015   tcase_add_checked_fixture (tc_chain, setup_stunalternd_loop,
1016       teardown_stunalternd);
1017   tcase_add_test (tc_chain, test_rawudptransmitter_run_stun_altern_to_nowhere);
1018   suite_add_tcase (s, tc_chain);
1019 
1020   tc_chain = tcase_create ("rawudptransmitter-strange-arguments");
1021   tcase_add_test (tc_chain, test_rawudptransmitter_strange_arguments);
1022   suite_add_tcase (s, tc_chain);
1023 
1024   return s;
1025 }
1026 
1027 
1028 GST_CHECK_MAIN (rawudptransmitter);
1029