rtsp-server: fixed segfault in gst_rtsp_server_create_socket
[platform/upstream/gstreamer.git] / tests / check / gst / rtspserver.c
1 /* GStreamer
2  *
3  * unit test for GstRTSPServer
4  *
5  * Copyright (C) 2012 Axis Communications <dev-gstreamer at axis dot com>
6  * @author David Svensson Fors <davidsf at axis dot com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/sdp/gstsdpmessage.h>
26
27 #include <stdio.h>
28 #include <netinet/in.h>
29
30 #include "rtsp-server.h"
31
32 #define VIDEO_PIPELINE "videotestsrc ! " \
33   "video/x-raw,width=352,height=288 ! " \
34   "rtpgstpay name=pay0 pt=96"
35 #define AUDIO_PIPELINE "audiotestsrc ! " \
36   "audio/x-raw,rate=8000 ! " \
37   "rtpgstpay name=pay1 pt=97"
38
39 #define TEST_MOUNT_POINT  "/test"
40 #define TEST_PROTO        "RTP/AVP"
41 #define TEST_ENCODING     "X-GST"
42 #define TEST_CLOCK_RATE   "90000"
43
44 /* tested rtsp server */
45 static GstRTSPServer *server = NULL;
46
47 /* tcp port that the test server listens for rtsp requests on */
48 static gint test_port = 0;
49
50 /* id of the server's source within the GMainContext */
51 static guint source_id;
52
53 /* iterate the default main loop until there are no events to dispatch */
54 static void
55 iterate (void)
56 {
57   while (g_main_context_iteration (NULL, FALSE)) {
58     GST_DEBUG ("iteration");
59   }
60 }
61
62 /* returns an unused port that can be used by the test */
63 static int
64 get_unused_port (gint type)
65 {
66   int sock;
67   struct sockaddr_in addr;
68   socklen_t addr_len;
69   gint port;
70
71   /* create socket */
72   fail_unless ((sock = socket (AF_INET, type, 0)) > 0);
73
74   /* pass port 0 to bind, which will bind to any free port */
75   memset (&addr, 0, sizeof addr);
76   addr.sin_family = AF_INET;
77   addr.sin_addr.s_addr = INADDR_ANY;
78   addr.sin_port = htons (0);
79   fail_unless (bind (sock, (struct sockaddr *) &addr, sizeof addr) == 0);
80
81   /* ask what port was bound using getsockname */
82   addr_len = sizeof addr;
83   memset (&addr, 0, addr_len);
84   fail_unless (getsockname (sock, (struct sockaddr *) &addr, &addr_len) == 0);
85   port = ntohs (addr.sin_port);
86
87   /* close the socket so the port gets unbound again (and can be used by the
88    * test) */
89   close (sock);
90
91   return port;
92 }
93
94 /* returns TRUE if the given port is not currently bound */
95 static gboolean
96 port_is_unused (gint port, gint type)
97 {
98   int sock;
99   struct sockaddr_in addr;
100   gboolean is_bound;
101
102   /* create socket */
103   fail_unless ((sock = socket (AF_INET, type, 0)) > 0);
104
105   /* check if the port is already bound by trying to bind to it (again) */
106   memset (&addr, 0, sizeof addr);
107   addr.sin_family = AF_INET;
108   addr.sin_addr.s_addr = INADDR_ANY;
109   addr.sin_port = htons (port);
110   is_bound = (bind (sock, (struct sockaddr *) &addr, sizeof addr) != 0);
111
112   /* close the socket, which will unbind if bound by our call to bind */
113   close (sock);
114
115   return !is_bound;
116 }
117
118 /* get a free rtp/rtcp client port pair */
119 static void
120 get_client_ports (GstRTSPRange * range)
121 {
122   gint rtp_port;
123   gint rtcp_port;
124
125   /* get a pair of unused ports, where the rtp port is even */
126   do {
127     rtp_port = get_unused_port (SOCK_DGRAM);
128     rtcp_port = rtp_port + 1;
129   } while (rtp_port % 2 != 0 || !port_is_unused (rtcp_port, SOCK_DGRAM));
130   range->min = rtp_port;
131   range->max = rtcp_port;
132   GST_DEBUG ("client_port=%d-%d", range->min, range->max);
133 }
134
135 /* start the tested rtsp server */
136 static void
137 start_server ()
138 {
139   GstRTSPMediaMapping *mapping;
140   gchar *service;
141   GstRTSPMediaFactory *factory;
142
143   mapping = gst_rtsp_server_get_media_mapping (server);
144
145   factory = gst_rtsp_media_factory_new ();
146
147   gst_rtsp_media_factory_set_launch (factory,
148       "( " VIDEO_PIPELINE "  " AUDIO_PIPELINE " )");
149
150   gst_rtsp_media_mapping_add_factory (mapping, TEST_MOUNT_POINT, factory);
151   g_object_unref (mapping);
152
153   /* set port */
154   test_port = get_unused_port (SOCK_STREAM);
155   service = g_strdup_printf ("%d", test_port);
156   gst_rtsp_server_set_service (server, service);
157   g_free (service);
158
159   /* attach to default main context */
160   source_id = gst_rtsp_server_attach (server, NULL);
161   fail_if (source_id == 0);
162
163   GST_DEBUG ("rtsp server listening on port %d", test_port);
164 }
165
166 /* stop the tested rtsp server */
167 static void
168 stop_server ()
169 {
170   g_source_remove (source_id);
171   source_id = 0;
172
173   GST_DEBUG ("rtsp server stopped");
174 }
175
176 /* create an rtsp connection to the server on test_port */
177 static GstRTSPConnection *
178 connect_to_server (gint port, const gchar * mount_point)
179 {
180   GstRTSPConnection *conn = NULL;
181   gchar *address;
182   gchar *uri_string;
183   GstRTSPUrl *url = NULL;
184
185   address = gst_rtsp_server_get_address (server);
186   uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
187   g_free (address);
188   gst_rtsp_url_parse (uri_string, &url);
189   g_free (uri_string);
190
191   fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
192   gst_rtsp_url_free (url);
193
194   fail_unless (gst_rtsp_connection_connect (conn, NULL) == GST_RTSP_OK);
195
196   return conn;
197 }
198
199 /* create an rtsp request */
200 static GstRTSPMessage *
201 create_request (GstRTSPConnection * conn, GstRTSPMethod method,
202     const gchar * control)
203 {
204   GstRTSPMessage *request = NULL;
205   gchar *base_uri;
206   gchar *full_uri;
207
208   base_uri = gst_rtsp_url_get_request_uri (gst_rtsp_connection_get_url (conn));
209   full_uri = g_strdup_printf ("%s/%s", base_uri, control ? control : "");
210   g_free (base_uri);
211   if (gst_rtsp_message_new_request (&request, method, full_uri) != GST_RTSP_OK) {
212     GST_DEBUG ("failed to create request object");
213     g_free (full_uri);
214     return NULL;
215   }
216   g_free (full_uri);
217   return request;
218 }
219
220 /* send an rtsp request */
221 static gboolean
222 send_request (GstRTSPConnection * conn, GstRTSPMessage * request)
223 {
224   if (gst_rtsp_connection_send (conn, request, NULL) != GST_RTSP_OK) {
225     GST_DEBUG ("failed to send request");
226     return FALSE;
227   }
228   return TRUE;
229 }
230
231 /* read rtsp response. response must be freed by the caller */
232 static GstRTSPMessage *
233 read_response (GstRTSPConnection * conn)
234 {
235   GstRTSPMessage *response = NULL;
236
237   if (gst_rtsp_message_new (&response) != GST_RTSP_OK) {
238     GST_DEBUG ("failed to create response object");
239     return NULL;
240   }
241   if (gst_rtsp_connection_receive (conn, response, NULL) != GST_RTSP_OK) {
242     GST_DEBUG ("failed to read response");
243     gst_rtsp_message_free (response);
244     return NULL;
245   }
246   fail_unless (gst_rtsp_message_get_type (response) ==
247       GST_RTSP_MESSAGE_RESPONSE);
248   return response;
249 }
250
251 /* send an rtsp request and receive response. gchar** parameters are out
252  * parameters that have to be freed by the caller */
253 static GstRTSPStatusCode
254 do_request (GstRTSPConnection * conn, GstRTSPMethod method,
255     const gchar * control, const gchar * session_in, const gchar * transport_in,
256     gchar ** content_type, gchar ** content_base, gchar ** body,
257     gchar ** session_out, gchar ** transport_out)
258 {
259   GstRTSPMessage *request;
260   GstRTSPMessage *response;
261   GstRTSPStatusCode code;
262   gchar *value;
263
264   /* create request */
265   request = create_request (conn, method, control);
266
267   /* add headers */
268   if (session_in) {
269     gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
270   }
271   if (transport_in) {
272     gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
273   }
274
275   /* send request */
276   fail_unless (send_request (conn, request));
277   gst_rtsp_message_free (request);
278
279   iterate ();
280
281   /* read response */
282   response = read_response (conn);
283
284   /* check status line */
285   gst_rtsp_message_parse_response (response, &code, NULL, NULL);
286   if (code != GST_RTSP_STS_OK) {
287     gst_rtsp_message_free (response);
288     return code;
289   }
290
291   /* get information from response */
292   if (content_type) {
293     gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
294         &value, 0);
295     *content_type = g_strdup (value);
296   }
297   if (content_base) {
298     gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
299         &value, 0);
300     *content_base = g_strdup (value);
301   }
302   if (body) {
303     *body = g_malloc (response->body_size + 1);
304     strncpy (*body, (gchar *) response->body, response->body_size);
305   }
306   if (session_out) {
307     gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
308     if (session_in) {
309       /* check that we got the same session back */
310       fail_unless (!g_strcmp0 (value, session_in));
311     }
312     *session_out = g_strdup (value);
313   }
314   if (transport_out) {
315     gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
316     *transport_out = g_strdup (value);
317   }
318
319   gst_rtsp_message_free (response);
320   return code;
321 }
322
323 /* send an rtsp request with a method and a session, and receive response */
324 static GstRTSPStatusCode
325 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
326     const gchar * session)
327 {
328   return do_request (conn, method, NULL, session, NULL, NULL, NULL,
329       NULL, NULL, NULL);
330 }
331
332 /* send a DESCRIBE request and receive response. returns a received
333  * GstSDPMessage that must be freed by the caller */
334 static GstSDPMessage *
335 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
336 {
337   GstSDPMessage *sdp_message;
338   gchar *content_type;
339   gchar *content_base;
340   gchar *body;
341   gchar *address;
342   gchar *expected_content_base;
343
344   /* send DESCRIBE request */
345   fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL,
346           &content_type, &content_base, &body, NULL, NULL) == GST_RTSP_STS_OK);
347
348   /* check response values */
349   fail_unless (!g_strcmp0 (content_type, "application/sdp"));
350   address = gst_rtsp_server_get_address (server);
351   expected_content_base =
352       g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
353   fail_unless (!g_strcmp0 (content_base, expected_content_base));
354
355   /* create sdp message */
356   fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
357   fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
358           strlen (body), sdp_message) == GST_SDP_OK);
359
360   /* clean up */
361   g_free (content_type);
362   g_free (content_base);
363   g_free (body);
364   g_free (address);
365   g_free (expected_content_base);
366
367   return sdp_message;
368 }
369
370 /* send a SETUP request and receive response. if *session is not NULL,
371  * it is used in the request. otherwise, *session is set to a returned
372  * session string that must be freed by the caller. the returned
373  * transport must be freed by the caller. */
374 static GstRTSPStatusCode
375 do_setup (GstRTSPConnection * conn, const gchar * control,
376     const GstRTSPRange * client_ports, gchar ** session,
377     GstRTSPTransport ** transport)
378 {
379   GstRTSPStatusCode code;
380   gchar *session_in = NULL;
381   gchar *transport_string_in = NULL;
382   gchar **session_out = NULL;
383   gchar *transport_string_out = NULL;
384
385   /* prepare and send SETUP request */
386   if (session) {
387     if (*session) {
388       session_in = *session;
389     } else {
390       session_out = session;
391     }
392   }
393   transport_string_in =
394       g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
395       client_ports->min, client_ports->max);
396   code =
397       do_request (conn, GST_RTSP_SETUP, control, session_in,
398       transport_string_in, NULL, NULL, NULL, session_out,
399       &transport_string_out);
400   g_free (transport_string_in);
401
402   if (transport_string_out) {
403     /* create transport */
404     fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
405     fail_unless (gst_rtsp_transport_parse (transport_string_out,
406             *transport) == GST_RTSP_OK);
407     g_free (transport_string_out);
408   }
409
410   return code;
411 }
412
413 /* fixture setup function */
414 static void
415 setup (void)
416 {
417   server = gst_rtsp_server_new ();
418 }
419
420 /* fixture clean-up function */
421 static void
422 teardown (void)
423 {
424   if (server) {
425     g_object_unref (server);
426     server = NULL;
427   }
428   test_port = 0;
429 }
430
431 GST_START_TEST (test_connect)
432 {
433   GstRTSPConnection *conn;
434
435   start_server ();
436
437   /* connect to server */
438   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
439
440   /* clean up */
441   gst_rtsp_connection_free (conn);
442   stop_server ();
443
444   /* iterate so the clean-up can finish */
445   iterate ();
446 }
447
448 GST_END_TEST;
449
450 GST_START_TEST (test_describe)
451 {
452   GstRTSPConnection *conn;
453   GstSDPMessage *sdp_message = NULL;
454   const GstSDPMedia *sdp_media;
455   gint32 format;
456   gchar *expected_rtpmap;
457   const gchar *rtpmap;
458   const gchar *control_video;
459   const gchar *control_audio;
460
461   start_server ();
462
463   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
464
465   /* send DESCRIBE request */
466   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
467
468   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
469
470   /* check video sdp */
471   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
472   fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
473   fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
474   sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
475       &format);
476   expected_rtpmap =
477       g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
478   rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
479   fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
480   g_free (expected_rtpmap);
481   control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
482   fail_unless (!g_strcmp0 (control_video, "stream=0"));
483
484   /* check audio sdp */
485   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
486   fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
487   fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
488   sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
489       &format);
490   expected_rtpmap =
491       g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
492   rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
493   fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
494   g_free (expected_rtpmap);
495   control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
496   fail_unless (!g_strcmp0 (control_audio, "stream=1"));
497
498   /* clean up and iterate so the clean-up can finish */
499   gst_sdp_message_free (sdp_message);
500   gst_rtsp_connection_free (conn);
501   stop_server ();
502   iterate ();
503 }
504
505 GST_END_TEST;
506
507 GST_START_TEST (test_describe_non_existing_mount_point)
508 {
509   GstRTSPConnection *conn;
510
511   start_server ();
512
513   /* send DESCRIBE request for a non-existing mount point
514    * and check that we get a 404 Not Found */
515   conn = connect_to_server (test_port, "/non-existing");
516   fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
517       == GST_RTSP_STS_NOT_FOUND);
518
519   /* clean up and iterate so the clean-up can finish */
520   gst_rtsp_connection_free (conn);
521   stop_server ();
522   iterate ();
523 }
524
525 GST_END_TEST;
526
527 GST_START_TEST (test_setup)
528 {
529   GstRTSPConnection *conn;
530   GstSDPMessage *sdp_message = NULL;
531   const GstSDPMedia *sdp_media;
532   const gchar *video_control;
533   const gchar *audio_control;
534   GstRTSPRange client_ports;
535   gchar *session = NULL;
536   GstRTSPTransport *video_transport = NULL;
537   GstRTSPTransport *audio_transport = NULL;
538
539   start_server ();
540
541   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
542
543   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
544
545   /* get control strings from DESCRIBE response */
546   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
547   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
548   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
549   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
550   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
551
552   get_client_ports (&client_ports);
553
554   /* send SETUP request for video */
555   fail_unless (do_setup (conn, video_control, &client_ports, &session,
556           &video_transport) == GST_RTSP_STS_OK);
557   GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
558
559   /* check response from SETUP */
560   fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
561   fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
562   fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
563   fail_unless (video_transport->mode_play);
564   gst_rtsp_transport_free (video_transport);
565
566   /* send SETUP request for audio */
567   fail_unless (do_setup (conn, audio_control, &client_ports, &session,
568           &audio_transport) == GST_RTSP_STS_OK);
569   GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
570
571   /* check response from SETUP */
572   fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
573   fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
574   fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
575   fail_unless (audio_transport->mode_play);
576   gst_rtsp_transport_free (audio_transport);
577
578   /* clean up and iterate so the clean-up can finish */
579   g_free (session);
580   gst_sdp_message_free (sdp_message);
581   gst_rtsp_connection_free (conn);
582   stop_server ();
583   iterate ();
584 }
585
586 GST_END_TEST;
587
588 GST_START_TEST (test_setup_non_existing_stream)
589 {
590   GstRTSPConnection *conn;
591   GstRTSPRange client_ports;
592
593   start_server ();
594
595   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
596
597   get_client_ports (&client_ports);
598
599   /* send SETUP request with a non-existing stream and check that we get a
600    * 404 Not Found */
601   fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
602           NULL) == GST_RTSP_STS_NOT_FOUND);
603
604   /* clean up and iterate so the clean-up can finish */
605   gst_rtsp_connection_free (conn);
606   stop_server ();
607   iterate ();
608
609   /* need to unref the server here, otherwise threads will remain
610    * and teardown won't be run */
611   g_object_unref (server);
612   server = NULL;
613 }
614
615 GST_END_TEST;
616
617 GST_START_TEST (test_play)
618 {
619   GstRTSPConnection *conn;
620   GstSDPMessage *sdp_message = NULL;
621   const GstSDPMedia *sdp_media;
622   const gchar *video_control;
623   const gchar *audio_control;
624   GstRTSPRange client_port;
625   gchar *session = NULL;
626   GstRTSPTransport *video_transport = NULL;
627   GstRTSPTransport *audio_transport = NULL;
628
629   start_server ();
630
631   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
632
633   sdp_message = do_describe (conn, TEST_MOUNT_POINT);
634
635   /* get control strings from DESCRIBE response */
636   fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
637   sdp_media = gst_sdp_message_get_media (sdp_message, 0);
638   video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
639   sdp_media = gst_sdp_message_get_media (sdp_message, 1);
640   audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
641
642   get_client_ports (&client_port);
643
644   /* do SETUP for video and audio */
645   fail_unless (do_setup (conn, video_control, &client_port, &session,
646           &video_transport) == GST_RTSP_STS_OK);
647   fail_unless (do_setup (conn, audio_control, &client_port, &session,
648           &audio_transport) == GST_RTSP_STS_OK);
649
650   /* send PLAY request and check that we get 200 OK */
651   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
652           session) == GST_RTSP_STS_OK);
653
654   /* send TEARDOWN request and check that we get 200 OK */
655   fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
656           session) == GST_RTSP_STS_OK);
657
658   /* clean up and iterate so the clean-up can finish */
659   g_free (session);
660   gst_rtsp_transport_free (video_transport);
661   gst_rtsp_transport_free (audio_transport);
662   gst_sdp_message_free (sdp_message);
663   gst_rtsp_connection_free (conn);
664   stop_server ();
665   iterate ();
666 }
667
668 GST_END_TEST;
669
670 GST_START_TEST (test_play_without_session)
671 {
672   GstRTSPConnection *conn;
673
674   start_server ();
675
676   conn = connect_to_server (test_port, TEST_MOUNT_POINT);
677
678   /* send PLAY request without a session and check that we get a
679    * 454 Session Not Found */
680   fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
681           NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
682
683   /* clean up and iterate so the clean-up can finish */
684   gst_rtsp_connection_free (conn);
685   stop_server ();
686   iterate ();
687 }
688
689 GST_END_TEST;
690
691 GST_START_TEST (test_bind_already_in_use)
692 {
693   GstRTSPServer *serv;
694   GSocketService *service;
695   GError *error = NULL;
696   guint16 port;
697   gchar *port_str;
698
699   serv = gst_rtsp_server_new ();
700   service = g_socket_service_new ();
701
702   /* bind service to port */
703   port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error);
704   g_assert_no_error (error);
705
706   port_str = g_strdup_printf ("%d\n", port);
707
708   /* try to bind server to the same port */
709   g_object_set (serv, "service", port_str, NULL);
710   g_free (port_str);
711
712   /* attach to default main context */
713   fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
714
715   /* cleanup */
716   g_object_unref (serv);
717   g_socket_listener_close (G_SOCKET_LISTENER (service));
718   g_object_unref (service);
719 }
720
721 GST_END_TEST;
722
723
724 static Suite *
725 rtspserver_suite (void)
726 {
727   Suite *s = suite_create ("rtspserver");
728   TCase *tc = tcase_create ("general");
729
730   suite_add_tcase (s, tc);
731   tcase_add_checked_fixture (tc, setup, teardown);
732   tcase_set_timeout (tc, 20);
733   tcase_add_test (tc, test_connect);
734   tcase_add_test (tc, test_describe);
735   tcase_add_test (tc, test_describe_non_existing_mount_point);
736   tcase_add_test (tc, test_setup);
737   tcase_add_test (tc, test_setup_non_existing_stream);
738   tcase_add_test (tc, test_play);
739   tcase_add_test (tc, test_play_without_session);
740   tcase_add_test (tc, test_bind_already_in_use);
741
742   return s;
743 }
744
745 GST_CHECK_MAIN (rtspserver);