3 * unit test for GstRTSPServer
5 * Copyright (C) 2012 Axis Communications <dev-gstreamer at axis dot com>
6 * @author David Svensson Fors <davidsf at axis dot com>
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.
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.
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., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include <gst/check/gstcheck.h>
25 #include <gst/sdp/gstsdpmessage.h>
28 #include <netinet/in.h>
30 #include "rtsp-server.h"
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"
39 #define TEST_MOUNT_POINT "/test"
40 #define TEST_PROTO "RTP/AVP"
41 #define TEST_ENCODING "X-GST"
42 #define TEST_CLOCK_RATE "90000"
44 /* tested rtsp server */
45 static GstRTSPServer *server = NULL;
47 /* tcp port that the test server listens for rtsp requests on */
48 static gint test_port = 0;
50 /* id of the server's source within the GMainContext */
51 static guint source_id;
53 /* iterate the default main loop until there are no events to dispatch */
57 while (g_main_context_iteration (NULL, FALSE)) {
58 GST_DEBUG ("iteration");
62 /* returns an unused port that can be used by the test */
64 get_unused_port (gint type)
67 struct sockaddr_in addr;
72 fail_unless ((sock = socket (AF_INET, type, 0)) > 0);
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);
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);
87 /* close the socket so the port gets unbound again (and can be used by the
94 /* returns TRUE if the given port is not currently bound */
96 port_is_unused (gint port, gint type)
99 struct sockaddr_in addr;
103 fail_unless ((sock = socket (AF_INET, type, 0)) > 0);
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);
112 /* close the socket, which will unbind if bound by our call to bind */
118 /* get a free rtp/rtcp client port pair */
120 get_client_ports (GstRTSPRange * range)
125 /* get a pair of unused ports, where the rtp port is even */
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);
135 /* start the tested rtsp server */
139 GstRTSPMountPoints *mounts;
141 GstRTSPMediaFactory *factory;
143 mounts = gst_rtsp_server_get_mount_points (server);
145 factory = gst_rtsp_media_factory_new ();
147 gst_rtsp_media_factory_set_launch (factory,
148 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
150 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
151 g_object_unref (mounts);
154 test_port = get_unused_port (SOCK_STREAM);
155 service = g_strdup_printf ("%d", test_port);
156 gst_rtsp_server_set_service (server, service);
159 /* attach to default main context */
160 source_id = gst_rtsp_server_attach (server, NULL);
161 fail_if (source_id == 0);
163 GST_DEBUG ("rtsp server listening on port %d", test_port);
166 /* stop the tested rtsp server */
170 g_source_remove (source_id);
173 GST_DEBUG ("rtsp server stopped");
176 /* create an rtsp connection to the server on test_port */
177 static GstRTSPConnection *
178 connect_to_server (gint port, const gchar * mount_point)
180 GstRTSPConnection *conn = NULL;
183 GstRTSPUrl *url = NULL;
185 address = gst_rtsp_server_get_address (server);
186 uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
188 gst_rtsp_url_parse (uri_string, &url);
191 fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
192 gst_rtsp_url_free (url);
194 fail_unless (gst_rtsp_connection_connect (conn, NULL) == GST_RTSP_OK);
199 /* create an rtsp request */
200 static GstRTSPMessage *
201 create_request (GstRTSPConnection * conn, GstRTSPMethod method,
202 const gchar * control)
204 GstRTSPMessage *request = NULL;
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 : "");
211 if (gst_rtsp_message_new_request (&request, method, full_uri) != GST_RTSP_OK) {
212 GST_DEBUG ("failed to create request object");
220 /* send an rtsp request */
222 send_request (GstRTSPConnection * conn, GstRTSPMessage * request)
224 if (gst_rtsp_connection_send (conn, request, NULL) != GST_RTSP_OK) {
225 GST_DEBUG ("failed to send request");
231 /* read rtsp response. response must be freed by the caller */
232 static GstRTSPMessage *
233 read_response (GstRTSPConnection * conn)
235 GstRTSPMessage *response = NULL;
237 if (gst_rtsp_message_new (&response) != GST_RTSP_OK) {
238 GST_DEBUG ("failed to create response object");
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);
246 fail_unless (gst_rtsp_message_get_type (response) ==
247 GST_RTSP_MESSAGE_RESPONSE);
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)
259 GstRTSPMessage *request;
260 GstRTSPMessage *response;
261 GstRTSPStatusCode code;
265 request = create_request (conn, method, control);
269 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
272 gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
276 fail_unless (send_request (conn, request));
277 gst_rtsp_message_free (request);
282 response = read_response (conn);
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);
291 /* get information from response */
293 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
295 *content_type = g_strdup (value);
298 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
300 *content_base = g_strdup (value);
303 *body = g_malloc (response->body_size + 1);
304 strncpy (*body, (gchar *) response->body, response->body_size);
307 gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
309 value = g_strdup (value);
311 /* Remove the timeout */
313 char *pos = strchr (value, ';');
318 /* check that we got the same session back */
319 fail_unless (!g_strcmp0 (value, session_in));
321 *session_out = value;
324 gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
325 *transport_out = g_strdup (value);
328 gst_rtsp_message_free (response);
332 /* send an rtsp request with a method and a session, and receive response */
333 static GstRTSPStatusCode
334 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
335 const gchar * session)
337 return do_request (conn, method, NULL, session, NULL, NULL, NULL,
341 /* send a DESCRIBE request and receive response. returns a received
342 * GstSDPMessage that must be freed by the caller */
343 static GstSDPMessage *
344 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
346 GstSDPMessage *sdp_message;
351 gchar *expected_content_base;
353 /* send DESCRIBE request */
354 fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL,
355 &content_type, &content_base, &body, NULL, NULL) == GST_RTSP_STS_OK);
357 /* check response values */
358 fail_unless (!g_strcmp0 (content_type, "application/sdp"));
359 address = gst_rtsp_server_get_address (server);
360 expected_content_base =
361 g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
362 fail_unless (!g_strcmp0 (content_base, expected_content_base));
364 /* create sdp message */
365 fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
366 fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
367 strlen (body), sdp_message) == GST_SDP_OK);
370 g_free (content_type);
371 g_free (content_base);
374 g_free (expected_content_base);
379 /* send a SETUP request and receive response. if *session is not NULL,
380 * it is used in the request. otherwise, *session is set to a returned
381 * session string that must be freed by the caller. the returned
382 * transport must be freed by the caller. */
383 static GstRTSPStatusCode
384 do_setup (GstRTSPConnection * conn, const gchar * control,
385 const GstRTSPRange * client_ports, gchar ** session,
386 GstRTSPTransport ** transport)
388 GstRTSPStatusCode code;
389 gchar *session_in = NULL;
390 gchar *transport_string_in = NULL;
391 gchar **session_out = NULL;
392 gchar *transport_string_out = NULL;
394 /* prepare and send SETUP request */
397 session_in = *session;
399 session_out = session;
402 transport_string_in =
403 g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
404 client_ports->min, client_ports->max);
406 do_request (conn, GST_RTSP_SETUP, control, session_in,
407 transport_string_in, NULL, NULL, NULL, session_out,
408 &transport_string_out);
409 g_free (transport_string_in);
411 if (transport_string_out) {
412 /* create transport */
413 fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
414 fail_unless (gst_rtsp_transport_parse (transport_string_out,
415 *transport) == GST_RTSP_OK);
416 g_free (transport_string_out);
422 /* fixture setup function */
426 server = gst_rtsp_server_new ();
429 /* fixture clean-up function */
434 g_object_unref (server);
440 GST_START_TEST (test_connect)
442 GstRTSPConnection *conn;
446 /* connect to server */
447 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
450 gst_rtsp_connection_free (conn);
453 /* iterate so the clean-up can finish */
459 GST_START_TEST (test_describe)
461 GstRTSPConnection *conn;
462 GstSDPMessage *sdp_message = NULL;
463 const GstSDPMedia *sdp_media;
465 gchar *expected_rtpmap;
467 const gchar *control_video;
468 const gchar *control_audio;
472 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
474 /* send DESCRIBE request */
475 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
477 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
479 /* check video sdp */
480 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
481 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
482 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
483 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
486 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
487 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
488 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
489 g_free (expected_rtpmap);
490 control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
491 fail_unless (!g_strcmp0 (control_video, "stream=0"));
493 /* check audio sdp */
494 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
495 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
496 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
497 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
500 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
501 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
502 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
503 g_free (expected_rtpmap);
504 control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
505 fail_unless (!g_strcmp0 (control_audio, "stream=1"));
507 /* clean up and iterate so the clean-up can finish */
508 gst_sdp_message_free (sdp_message);
509 gst_rtsp_connection_free (conn);
516 GST_START_TEST (test_describe_non_existing_mount_point)
518 GstRTSPConnection *conn;
522 /* send DESCRIBE request for a non-existing mount point
523 * and check that we get a 404 Not Found */
524 conn = connect_to_server (test_port, "/non-existing");
525 fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
526 == GST_RTSP_STS_NOT_FOUND);
528 /* clean up and iterate so the clean-up can finish */
529 gst_rtsp_connection_free (conn);
536 GST_START_TEST (test_setup)
538 GstRTSPConnection *conn;
539 GstSDPMessage *sdp_message = NULL;
540 const GstSDPMedia *sdp_media;
541 const gchar *video_control;
542 const gchar *audio_control;
543 GstRTSPRange client_ports;
544 gchar *session = NULL;
545 GstRTSPTransport *video_transport = NULL;
546 GstRTSPTransport *audio_transport = NULL;
550 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
552 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
554 /* get control strings from DESCRIBE response */
555 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
556 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
557 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
558 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
559 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
561 get_client_ports (&client_ports);
563 /* send SETUP request for video */
564 fail_unless (do_setup (conn, video_control, &client_ports, &session,
565 &video_transport) == GST_RTSP_STS_OK);
566 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
568 /* check response from SETUP */
569 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
570 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
571 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
572 fail_unless (video_transport->mode_play);
573 gst_rtsp_transport_free (video_transport);
575 /* send SETUP request for audio */
576 fail_unless (do_setup (conn, audio_control, &client_ports, &session,
577 &audio_transport) == GST_RTSP_STS_OK);
578 GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
580 /* check response from SETUP */
581 fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
582 fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
583 fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
584 fail_unless (audio_transport->mode_play);
585 gst_rtsp_transport_free (audio_transport);
587 /* clean up and iterate so the clean-up can finish */
589 gst_sdp_message_free (sdp_message);
590 gst_rtsp_connection_free (conn);
597 GST_START_TEST (test_setup_non_existing_stream)
599 GstRTSPConnection *conn;
600 GstRTSPRange client_ports;
604 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
606 get_client_ports (&client_ports);
608 /* send SETUP request with a non-existing stream and check that we get a
610 fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
611 NULL) == GST_RTSP_STS_NOT_FOUND);
613 /* clean up and iterate so the clean-up can finish */
614 gst_rtsp_connection_free (conn);
618 /* need to unref the server here, otherwise threads will remain
619 * and teardown won't be run */
620 g_object_unref (server);
629 GstRTSPConnection *conn;
630 GstSDPMessage *sdp_message = NULL;
631 const GstSDPMedia *sdp_media;
632 const gchar *video_control;
633 const gchar *audio_control;
634 GstRTSPRange client_port;
635 gchar *session = NULL;
636 GstRTSPTransport *video_transport = NULL;
637 GstRTSPTransport *audio_transport = NULL;
639 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
641 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
643 /* get control strings from DESCRIBE response */
644 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
645 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
646 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
647 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
648 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
650 get_client_ports (&client_port);
652 /* do SETUP for video and audio */
653 fail_unless (do_setup (conn, video_control, &client_port, &session,
654 &video_transport) == GST_RTSP_STS_OK);
655 fail_unless (do_setup (conn, audio_control, &client_port, &session,
656 &audio_transport) == GST_RTSP_STS_OK);
658 /* send PLAY request and check that we get 200 OK */
659 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
660 session) == GST_RTSP_STS_OK);
662 /* send TEARDOWN request and check that we get 200 OK */
663 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
664 session) == GST_RTSP_STS_OK);
666 /* clean up and iterate so the clean-up can finish */
668 gst_rtsp_transport_free (video_transport);
669 gst_rtsp_transport_free (audio_transport);
670 gst_sdp_message_free (sdp_message);
671 gst_rtsp_connection_free (conn);
675 GST_START_TEST (test_play)
687 GST_START_TEST (test_play_without_session)
689 GstRTSPConnection *conn;
693 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
695 /* send PLAY request without a session and check that we get a
696 * 454 Session Not Found */
697 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
698 NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
700 /* clean up and iterate so the clean-up can finish */
701 gst_rtsp_connection_free (conn);
708 GST_START_TEST (test_bind_already_in_use)
711 GSocketService *service;
712 GError *error = NULL;
716 serv = gst_rtsp_server_new ();
717 service = g_socket_service_new ();
719 /* bind service to port */
721 g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
723 g_assert_no_error (error);
725 port_str = g_strdup_printf ("%d\n", port);
727 /* try to bind server to the same port */
728 g_object_set (serv, "service", port_str, NULL);
731 /* attach to default main context */
732 fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
735 g_object_unref (serv);
736 g_socket_listener_close (G_SOCKET_LISTENER (service));
737 g_object_unref (service);
743 GST_START_TEST (test_play_multithreaded)
745 gst_rtsp_server_set_max_threads (server, -1);
766 media_constructed_block (GstRTSPMediaFactory * factory,
767 GstRTSPMedia * media, gpointer user_data)
769 gint *block_state = user_data;
771 g_mutex_lock (&check_mutex);
773 *block_state = BLOCKED;
774 g_cond_broadcast (&check_cond);
776 while (*block_state != UNBLOCK)
777 g_cond_wait (&check_cond, &check_mutex);
778 g_mutex_unlock (&check_mutex);
782 GST_START_TEST (test_play_multithreaded_block_in_describe)
784 GstRTSPConnection *conn;
785 GstRTSPMountPoints *mounts;
786 GstRTSPMediaFactory *factory;
787 gint block_state = BLOCK_ME;
788 GstRTSPMessage *request;
789 GstRTSPMessage *response;
790 GstRTSPStatusCode code;
792 gst_rtsp_server_set_max_threads (server, 1);
794 mounts = gst_rtsp_server_get_mount_points (server);
795 fail_unless (mounts != NULL);
796 factory = gst_rtsp_media_factory_new ();
797 gst_rtsp_media_factory_set_launch (factory,
798 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
799 g_signal_connect (factory, "media-constructed",
800 G_CALLBACK (media_constructed_block), &block_state);
801 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
802 g_object_unref (mounts);
806 conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
809 /* do describe, it will not return now as we've blocked it */
810 request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
811 fail_unless (send_request (conn, request));
812 gst_rtsp_message_free (request);
814 g_mutex_lock (&check_mutex);
815 while (block_state != BLOCKED)
816 g_cond_wait (&check_cond, &check_mutex);
817 g_mutex_unlock (&check_mutex);
819 /* Do a second connection while the first one is blocked */
822 /* Now unblock the describe */
823 g_mutex_lock (&check_mutex);
824 block_state = UNBLOCK;
825 g_cond_broadcast (&check_cond);
826 g_mutex_unlock (&check_mutex);
828 response = read_response (conn);
829 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
830 fail_unless (code == GST_RTSP_STS_OK);
831 gst_rtsp_message_free (response);
834 gst_rtsp_connection_free (conn);
844 new_session_timeout_one (GstRTSPClient * client,
845 GstRTSPSession * session, gpointer user_data)
847 gst_rtsp_session_set_timeout (session, 1);
849 g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
854 session_connected_new_session_cb (GstRTSPServer * server,
855 GstRTSPClient * client, gpointer user_data)
858 g_signal_connect (client, "new-session", user_data, NULL);
861 GST_START_TEST (test_play_multithreaded_timeout_client)
863 GstRTSPConnection *conn;
864 GstSDPMessage *sdp_message = NULL;
865 const GstSDPMedia *sdp_media;
866 const gchar *video_control;
867 const gchar *audio_control;
868 GstRTSPRange client_port;
869 gchar *session = NULL;
870 GstRTSPTransport *video_transport = NULL;
871 GstRTSPTransport *audio_transport = NULL;
872 GstRTSPSessionPool *pool;
873 GstRTSPMessage *request;
874 GstRTSPMessage *response;
876 gst_rtsp_server_set_max_threads (server, -1);
877 pool = gst_rtsp_server_get_session_pool (server);
878 g_signal_connect (server, "client-connected",
879 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
884 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
886 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
888 /* get control strings from DESCRIBE response */
889 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
890 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
891 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
892 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
893 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
895 get_client_ports (&client_port);
897 /* do SETUP for video and audio */
898 fail_unless (do_setup (conn, video_control, &client_port, &session,
899 &video_transport) == GST_RTSP_STS_OK);
900 fail_unless (do_setup (conn, audio_control, &client_port, &session,
901 &audio_transport) == GST_RTSP_STS_OK);
903 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
905 /* send PLAY request and check that we get 200 OK */
906 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
907 session) == GST_RTSP_STS_OK);
911 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
914 /* send TEARDOWN request and check that we get 454 Session Not found */
915 request = create_request (conn, GST_RTSP_TEARDOWN, NULL);
916 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session);
917 fail_unless (send_request (conn, request));
918 gst_rtsp_message_free (request);
920 fail_unless (gst_rtsp_message_new (&response) == GST_RTSP_OK);
921 fail_unless (gst_rtsp_connection_receive (conn, response, NULL) ==
923 fail_unless (errno == ECONNRESET);
924 gst_rtsp_message_free (response);
926 /* clean up and iterate so the clean-up can finish */
927 g_object_unref (pool);
929 gst_rtsp_transport_free (video_transport);
930 gst_rtsp_transport_free (audio_transport);
931 gst_sdp_message_free (sdp_message);
932 gst_rtsp_connection_free (conn);
941 GST_START_TEST (test_play_multithreaded_timeout_session)
943 GstRTSPConnection *conn;
944 GstSDPMessage *sdp_message = NULL;
945 const GstSDPMedia *sdp_media;
946 const gchar *video_control;
947 const gchar *audio_control;
948 GstRTSPRange client_port;
949 gchar *session1 = NULL;
950 gchar *session2 = NULL;
951 GstRTSPTransport *video_transport = NULL;
952 GstRTSPTransport *audio_transport = NULL;
953 GstRTSPSessionPool *pool;
955 gst_rtsp_server_set_max_threads (server, -1);
956 pool = gst_rtsp_server_get_session_pool (server);
957 g_signal_connect (server, "client-connected",
958 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
963 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
965 gst_rtsp_connection_set_remember_session_id (conn, FALSE);
967 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
969 /* get control strings from DESCRIBE response */
970 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
971 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
972 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
973 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
974 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
976 get_client_ports (&client_port);
978 /* do SETUP for video and audio */
979 fail_unless (do_setup (conn, video_control, &client_port, &session1,
980 &video_transport) == GST_RTSP_STS_OK);
981 fail_unless (do_setup (conn, audio_control, &client_port, &session2,
982 &audio_transport) == GST_RTSP_STS_OK);
984 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
986 /* send PLAY request and check that we get 200 OK */
987 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
988 session1) == GST_RTSP_STS_OK);
989 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
990 session2) == GST_RTSP_STS_OK);
994 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
996 /* send TEARDOWN request and check that we get 454 Session Not found */
997 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
998 session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1000 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1001 session2) == GST_RTSP_STS_OK);
1003 /* clean up and iterate so the clean-up can finish */
1004 g_object_unref (pool);
1007 gst_rtsp_transport_free (video_transport);
1008 gst_rtsp_transport_free (audio_transport);
1009 gst_sdp_message_free (sdp_message);
1010 gst_rtsp_connection_free (conn);
1020 GST_START_TEST (test_play_disconnect)
1022 GstRTSPConnection *conn;
1023 GstSDPMessage *sdp_message = NULL;
1024 const GstSDPMedia *sdp_media;
1025 const gchar *video_control;
1026 const gchar *audio_control;
1027 GstRTSPRange client_port;
1028 gchar *session = NULL;
1029 GstRTSPTransport *video_transport = NULL;
1030 GstRTSPTransport *audio_transport = NULL;
1031 GstRTSPSessionPool *pool;
1033 pool = gst_rtsp_server_get_session_pool (server);
1034 g_signal_connect (server, "client-connected",
1035 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1039 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1041 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1043 /* get control strings from DESCRIBE response */
1044 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1045 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1046 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1047 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1048 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1050 get_client_ports (&client_port);
1052 /* do SETUP for video and audio */
1053 fail_unless (do_setup (conn, video_control, &client_port, &session,
1054 &video_transport) == GST_RTSP_STS_OK);
1055 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1056 &audio_transport) == GST_RTSP_STS_OK);
1058 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1060 /* send PLAY request and check that we get 200 OK */
1061 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1062 session) == GST_RTSP_STS_OK);
1064 gst_rtsp_connection_free (conn);
1068 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1069 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1072 /* clean up and iterate so the clean-up can finish */
1073 g_object_unref (pool);
1075 gst_rtsp_transport_free (video_transport);
1076 gst_rtsp_transport_free (audio_transport);
1077 gst_sdp_message_free (sdp_message);
1086 rtspserver_suite (void)
1088 Suite *s = suite_create ("rtspserver");
1089 TCase *tc = tcase_create ("general");
1091 suite_add_tcase (s, tc);
1092 tcase_add_checked_fixture (tc, setup, teardown);
1093 tcase_set_timeout (tc, 20);
1094 tcase_add_test (tc, test_connect);
1095 tcase_add_test (tc, test_describe);
1096 tcase_add_test (tc, test_describe_non_existing_mount_point);
1097 tcase_add_test (tc, test_setup);
1098 tcase_add_test (tc, test_setup_non_existing_stream);
1099 tcase_add_test (tc, test_play);
1100 tcase_add_test (tc, test_play_without_session);
1101 tcase_add_test (tc, test_bind_already_in_use);
1102 tcase_add_test (tc, test_play_multithreaded);
1103 tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1104 tcase_add_test (tc, test_play_multithreaded_timeout_client);
1105 tcase_add_test (tc, test_play_multithreaded_timeout_session);
1106 tcase_add_test (tc, test_play_disconnect);
1111 GST_CHECK_MAIN (rtspserver);