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 (¶ms[0].value, G_TYPE_BOOLEAN);
400 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
414 g_value_set_boolean (¶ms[0].value, FALSE);
415
416 params[1].name = "upnp-discovery";
417 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
418 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_STRING);
436 g_value_set_static_string (¶ms[0].value, "127.0.0.1");
437
438 params[1].name = "stun-port";
439 g_value_init (¶ms[1].value, G_TYPE_UINT);
440 g_value_set_uint (¶ms[1].value, 7777);
441
442 params[2].name = "stun-timeout";
443 g_value_init (¶ms[2].value, G_TYPE_UINT);
444 g_value_set_uint (¶ms[2].value, 3);
445
446 params[3].name = "upnp-discovery";
447 g_value_init (¶ms[3].value, G_TYPE_BOOLEAN);
448 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_STRING);
465 g_value_set_static_string (¶ms[0].value, "127.0.0.1");
466
467 params[1].name = "stun-port";
468 g_value_init (¶ms[1].value, G_TYPE_UINT);
469 g_value_set_uint (¶ms[1].value, 3478);
470
471 params[2].name = "stun-timeout";
472 g_value_init (¶ms[2].value, G_TYPE_UINT);
473 g_value_set_uint (¶ms[2].value, 5);
474
475 params[3].name = "upnp-discovery";
476 g_value_init (¶ms[3].value, G_TYPE_BOOLEAN);
477 g_value_set_boolean (¶ms[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 (¶ms[0].value, FS_TYPE_CANDIDATE_LIST);
505 g_value_set_boxed (¶ms[0].value, list);
506
507 params[1].name = "upnp-discovery";
508 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
509 g_value_set_boolean (¶ms[1].value, FALSE);
510
511
512 run_rawudp_transmitter_test (2, params, FLAG_IS_LOCAL);
513
514 g_value_reset (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
575 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
653 g_value_set_boolean (¶ms[0].value, TRUE);
654
655 params[1].name = "upnp-discovery";
656 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
657 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
682 g_value_set_boolean (¶ms[0].value, TRUE);
683
684 params[1].name = "upnp-discovery";
685 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
686 g_value_set_boolean (¶ms[1].value, FALSE);
687
688 params[2].name = "stun-ip";
689 g_value_init (¶ms[2].value, G_TYPE_STRING);
690 g_value_set_static_string (¶ms[2].value, "127.0.0.1");
691
692 params[3].name = "stun-port";
693 g_value_init (¶ms[3].value, G_TYPE_UINT);
694 g_value_set_uint (¶ms[3].value, 3232);
695
696 params[4].name = "stun-timeout";
697 g_value_init (¶ms[4].value, G_TYPE_UINT);
698 g_value_set_uint (¶ms[4].value, 6);
699
700 params[5].name = "upnp-discovery-timeout";
701 g_value_init (¶ms[5].value, G_TYPE_UINT);
702 g_value_set_uint (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
728 g_value_set_boolean (¶ms[0].value, TRUE);
729
730 params[1].name = "upnp-discovery";
731 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
732 g_value_set_boolean (¶ms[1].value, FALSE);
733
734 params[2].name = "stun-ip";
735 g_value_init (¶ms[2].value, G_TYPE_STRING);
736 g_value_set_static_string (¶ms[2].value, "127.0.0.1");
737
738 params[3].name = "stun-port";
739 g_value_init (¶ms[3].value, G_TYPE_UINT);
740 g_value_set_uint (¶ms[3].value, 3478);
741
742 params[4].name = "stun-timeout";
743 g_value_init (¶ms[4].value, G_TYPE_UINT);
744 g_value_set_uint (¶ms[4].value, 6);
745
746 params[5].name = "upnp-discovery-timeout";
747 g_value_init (¶ms[5].value, G_TYPE_UINT);
748 g_value_set_uint (¶ms[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 (¶ms[0].value, G_TYPE_BOOLEAN);
769 g_value_set_boolean (¶ms[0].value, TRUE);
770
771 params[1].name = "upnp-discovery";
772 g_value_init (¶ms[1].value, G_TYPE_BOOLEAN);
773 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_STRING);
791 g_value_set_static_string (¶ms[0].value, "127.0.0.1");
792
793 params[1].name = "stun-port";
794 g_value_init (¶ms[1].value, G_TYPE_UINT);
795 g_value_set_uint (¶ms[1].value, 3480);
796
797 params[2].name = "stun-timeout";
798 g_value_init (¶ms[2].value, G_TYPE_UINT);
799 g_value_set_uint (¶ms[2].value, 5);
800
801 params[3].name = "upnp-discovery";
802 g_value_init (¶ms[3].value, G_TYPE_BOOLEAN);
803 g_value_set_boolean (¶ms[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 (¶ms[0].value, G_TYPE_STRING);
826 g_value_set_static_string (¶ms[0].value, "127.0.0.1");
827
828 params[1].name = "stun-port";
829 g_value_init (¶ms[1].value, G_TYPE_UINT);
830 g_value_set_uint (¶ms[1].value, 3480);
831
832 params[2].name = "stun-timeout";
833 g_value_init (¶ms[2].value, G_TYPE_UINT);
834 g_value_set_uint (¶ms[2].value, 10);
835
836 params[3].name = "upnp-discovery";
837 g_value_init (¶ms[3].value, G_TYPE_BOOLEAN);
838 g_value_set_boolean (¶ms[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