client: free threadpool
[platform/upstream/gstreamer.git] / tests / check / gst / client.c
1 /* GStreamer
2  * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <gst/check/gstcheck.h>
21
22 #include <rtsp-client.h>
23
24 static gint cseq;
25 static guint expected_session_timeout = 60;
26
27 static gboolean
28 test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
29     gboolean close, gpointer user_data)
30 {
31   GstRTSPStatusCode code;
32   const gchar *reason;
33   GstRTSPVersion version;
34
35   fail_unless (gst_rtsp_message_get_type (response) ==
36       GST_RTSP_MESSAGE_RESPONSE);
37
38   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
39           &version)
40       == GST_RTSP_OK);
41   fail_unless (code == GST_RTSP_STS_OK);
42   fail_unless (g_str_equal (reason, "OK"));
43   fail_unless (version == GST_RTSP_VERSION_1_0);
44
45   return TRUE;
46 }
47
48 static gboolean
49 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
50     gboolean close, gpointer user_data)
51 {
52   GstRTSPStatusCode code;
53   const gchar *reason;
54   GstRTSPVersion version;
55
56   fail_unless (gst_rtsp_message_get_type (response) ==
57       GST_RTSP_MESSAGE_RESPONSE);
58
59   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
60           &version)
61       == GST_RTSP_OK);
62   fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
63   fail_unless (g_str_equal (reason, "Bad Request"));
64   fail_unless (version == GST_RTSP_VERSION_1_0);
65
66   return TRUE;
67 }
68
69 static gboolean
70 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
71     gboolean close, gpointer user_data)
72 {
73   GstRTSPStatusCode code;
74   const gchar *reason;
75   GstRTSPVersion version;
76
77   fail_unless (gst_rtsp_message_get_type (response) ==
78       GST_RTSP_MESSAGE_RESPONSE);
79
80   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
81           &version)
82       == GST_RTSP_OK);
83   fail_unless (code == GST_RTSP_STS_NOT_FOUND);
84   fail_unless (g_str_equal (reason, "Not Found"));
85   fail_unless (version == GST_RTSP_VERSION_1_0);
86
87   return TRUE;
88 }
89
90 static gboolean
91 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
92     gboolean close, gpointer user_data)
93 {
94   GstRTSPStatusCode code;
95   const gchar *reason;
96   GstRTSPVersion version;
97
98   fail_unless (gst_rtsp_message_get_type (response) ==
99       GST_RTSP_MESSAGE_RESPONSE);
100
101   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
102           &version)
103       == GST_RTSP_OK);
104   fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
105   fail_unless (g_str_equal (reason, "Session Not Found"));
106   fail_unless (version == GST_RTSP_VERSION_1_0);
107
108   return TRUE;
109 }
110
111 static GstRTSPClient *
112 setup_client (const gchar * launch_line)
113 {
114   GstRTSPClient *client;
115   GstRTSPSessionPool *session_pool;
116   GstRTSPMountPoints *mount_points;
117   GstRTSPMediaFactory *factory;
118   GstRTSPThreadPool *thread_pool;
119
120   client = gst_rtsp_client_new ();
121
122   session_pool = gst_rtsp_session_pool_new ();
123   gst_rtsp_client_set_session_pool (client, session_pool);
124
125   mount_points = gst_rtsp_mount_points_new ();
126   factory = gst_rtsp_media_factory_new ();
127   if (launch_line == NULL)
128     gst_rtsp_media_factory_set_launch (factory,
129         "videotestsrc ! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96");
130   else
131     gst_rtsp_media_factory_set_launch (factory, launch_line);
132
133   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
134   gst_rtsp_client_set_mount_points (client, mount_points);
135
136   thread_pool = gst_rtsp_thread_pool_new ();
137   gst_rtsp_client_set_thread_pool (client, thread_pool);
138
139   g_object_unref (mount_points);
140   g_object_unref (session_pool);
141   g_object_unref (thread_pool);
142
143   return client;
144 }
145
146 static void
147 teardown_client (GstRTSPClient *client)
148 {
149   gst_rtsp_client_set_thread_pool (client, NULL);
150   g_object_unref (client);
151 }
152
153 GST_START_TEST (test_request)
154 {
155   GstRTSPClient *client;
156   GstRTSPMessage request = { 0, };
157   gchar *str;
158
159   client = gst_rtsp_client_new ();
160
161   /* OPTIONS with invalid url */
162   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
163           "foopy://padoop/") == GST_RTSP_OK);
164   str = g_strdup_printf ("%d", cseq);
165   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
166   g_free (str);
167
168   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
169   fail_unless (gst_rtsp_client_handle_message (client,
170           &request) == GST_RTSP_OK);
171
172   gst_rtsp_message_unset (&request);
173
174   /* OPTIONS with unknown session id */
175   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
176           "rtsp://localhost/test") == GST_RTSP_OK);
177   str = g_strdup_printf ("%d", cseq);
178   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
179   g_free (str);
180   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
181
182   gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
183   fail_unless (gst_rtsp_client_handle_message (client,
184           &request) == GST_RTSP_OK);
185
186   gst_rtsp_message_unset (&request);
187
188   g_object_unref (client);
189 }
190
191 GST_END_TEST;
192
193 static gboolean
194 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
195     gboolean close, gpointer user_data)
196 {
197   GstRTSPStatusCode code;
198   const gchar *reason;
199   GstRTSPVersion version;
200   gchar *str;
201   GstRTSPMethod methods;
202
203   fail_unless (gst_rtsp_message_get_type (response) ==
204       GST_RTSP_MESSAGE_RESPONSE);
205
206   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
207           &version)
208       == GST_RTSP_OK);
209   fail_unless (code == GST_RTSP_STS_OK);
210   fail_unless (g_str_equal (reason, "OK"));
211   fail_unless (version == GST_RTSP_VERSION_1_0);
212
213   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
214           0) == GST_RTSP_OK);
215   fail_unless (atoi (str) == cseq++);
216
217   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
218           0) == GST_RTSP_OK);
219
220   methods = gst_rtsp_options_from_text (str);
221   fail_if (methods == 0);
222   fail_unless (methods == (GST_RTSP_DESCRIBE |
223           GST_RTSP_OPTIONS |
224           GST_RTSP_PAUSE |
225           GST_RTSP_PLAY |
226           GST_RTSP_SETUP |
227           GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
228
229   return TRUE;
230 }
231
232 GST_START_TEST (test_options)
233 {
234   GstRTSPClient *client;
235   GstRTSPMessage request = { 0, };
236   gchar *str;
237
238   client = gst_rtsp_client_new ();
239
240   /* simple OPTIONS */
241   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
242           "rtsp://localhost/test") == GST_RTSP_OK);
243   str = g_strdup_printf ("%d", cseq);
244   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
245   g_free (str);
246
247   gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
248   fail_unless (gst_rtsp_client_handle_message (client,
249           &request) == GST_RTSP_OK);
250   gst_rtsp_message_unset (&request);
251
252   g_object_unref (client);
253 }
254
255 GST_END_TEST;
256
257 GST_START_TEST (test_describe)
258 {
259   GstRTSPClient *client;
260   GstRTSPMessage request = { 0, };
261   gchar *str;
262
263   client = gst_rtsp_client_new ();
264
265   /* simple DESCRIBE for non-existing url */
266   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
267           "rtsp://localhost/test") == GST_RTSP_OK);
268   str = g_strdup_printf ("%d", cseq);
269   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
270   g_free (str);
271
272   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
273   fail_unless (gst_rtsp_client_handle_message (client,
274           &request) == GST_RTSP_OK);
275   gst_rtsp_message_unset (&request);
276
277   g_object_unref (client);
278
279   /* simple DESCRIBE for an existing url */
280   client = setup_client (NULL);
281   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
282           "rtsp://localhost/test") == GST_RTSP_OK);
283   str = g_strdup_printf ("%d", cseq);
284   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
285   g_free (str);
286
287   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
288   fail_unless (gst_rtsp_client_handle_message (client,
289           &request) == GST_RTSP_OK);
290   gst_rtsp_message_unset (&request);
291
292   teardown_client (client);
293 }
294
295 GST_END_TEST;
296
297 gchar *expected_transport = NULL;;
298
299 static gboolean
300 test_setup_response_200_multicast (GstRTSPClient * client,
301     GstRTSPMessage * response, gboolean close, gpointer user_data)
302 {
303   GstRTSPStatusCode code;
304   const gchar *reason;
305   GstRTSPVersion version;
306   gchar *str;
307   GstRTSPSessionPool *session_pool;
308   GstRTSPSession *session;
309   gchar **session_hdr_params;
310
311   fail_unless (expected_transport != NULL);
312
313   fail_unless (gst_rtsp_message_get_type (response) ==
314       GST_RTSP_MESSAGE_RESPONSE);
315
316   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
317           &version)
318       == GST_RTSP_OK);
319   fail_unless (code == GST_RTSP_STS_OK);
320   fail_unless (g_str_equal (reason, "OK"));
321   fail_unless (version == GST_RTSP_VERSION_1_0);
322
323   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
324           0) == GST_RTSP_OK);
325   fail_unless (atoi (str) == cseq++);
326
327   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
328           &str, 0) == GST_RTSP_OK);
329
330   fail_unless (!strcmp (str, expected_transport));
331
332   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
333           &str, 0) == GST_RTSP_OK);
334   session_hdr_params = g_strsplit (str, ";", -1);
335
336   /* session-id value */
337   fail_unless (session_hdr_params[0] != NULL);
338
339   if (expected_session_timeout != 60) {
340     /* session timeout param */
341     gchar *timeout_str = g_strdup_printf ("timeout=%u",
342         expected_session_timeout);
343
344     fail_unless (session_hdr_params[1] != NULL);
345     g_strstrip (session_hdr_params[1]);
346     fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0);
347     g_free (timeout_str);
348   }
349
350   session_pool = gst_rtsp_client_get_session_pool (client);
351   fail_unless (session_pool != NULL);
352
353   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
354   session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]);
355   g_strfreev (session_hdr_params);
356
357   fail_unless (session != NULL);
358   g_object_unref (session);
359
360   g_object_unref (session_pool);
361
362
363   return TRUE;
364 }
365
366 static GstRTSPClient *
367 setup_multicast_client (void)
368 {
369   GstRTSPClient *client;
370   GstRTSPSessionPool *session_pool;
371   GstRTSPMountPoints *mount_points;
372   GstRTSPMediaFactory *factory;
373   GstRTSPAddressPool *address_pool;
374   GstRTSPThreadPool *thread_pool;
375
376   client = gst_rtsp_client_new ();
377
378   session_pool = gst_rtsp_session_pool_new ();
379   gst_rtsp_client_set_session_pool (client, session_pool);
380
381   mount_points = gst_rtsp_mount_points_new ();
382   factory = gst_rtsp_media_factory_new ();
383   gst_rtsp_media_factory_set_launch (factory,
384       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
385   address_pool = gst_rtsp_address_pool_new ();
386   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
387           "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
388   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
389   gst_rtsp_media_factory_add_role (factory, "user",
390       "media.factory.access", G_TYPE_BOOLEAN, TRUE,
391       "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
392   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
393   gst_rtsp_client_set_mount_points (client, mount_points);
394
395   thread_pool = gst_rtsp_thread_pool_new ();
396   gst_rtsp_client_set_thread_pool (client, thread_pool);
397
398   g_object_unref (mount_points);
399   g_object_unref (session_pool);
400   g_object_unref (address_pool);
401   g_object_unref (thread_pool);
402
403   return client;
404 }
405
406 GST_START_TEST (test_client_multicast_transport_404)
407 {
408   GstRTSPClient *client;
409   GstRTSPMessage request = { 0, };
410   gchar *str;
411
412   client = setup_multicast_client ();
413
414   /* simple SETUP for non-existing url */
415   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
416           "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
417   str = g_strdup_printf ("%d", cseq);
418   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
419   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
420       "RTP/AVP;multicast");
421
422   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
423   fail_unless (gst_rtsp_client_handle_message (client,
424           &request) == GST_RTSP_OK);
425   gst_rtsp_message_unset (&request);
426
427   teardown_client (client);
428 }
429
430 GST_END_TEST;
431
432 static void
433 new_session_cb (GObject * client, GstRTSPSession * session, gpointer user_data)
434 {
435   GST_DEBUG ("%p: new session %p", client, session);
436   gst_rtsp_session_set_timeout (session, expected_session_timeout);
437 }
438
439 GST_START_TEST (test_client_multicast_transport)
440 {
441   GstRTSPClient *client;
442   GstRTSPMessage request = { 0, };
443   gchar *str;
444
445   client = setup_multicast_client ();
446
447   expected_session_timeout = 20;
448   g_signal_connect (G_OBJECT (client), "new-session",
449       G_CALLBACK (new_session_cb), NULL);
450
451   /* simple SETUP with a valid URI and multicast */
452   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
453           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
454   str = g_strdup_printf ("%d", cseq);
455   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
456   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
457       "RTP/AVP;multicast");
458
459   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
460       "ttl=1;port=5000-5001;mode=\"PLAY\"";
461   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
462       NULL, NULL);
463   fail_unless (gst_rtsp_client_handle_message (client,
464           &request) == GST_RTSP_OK);
465   gst_rtsp_message_unset (&request);
466   expected_transport = NULL;
467   expected_session_timeout = 60;
468   teardown_client (client);
469 }
470
471 GST_END_TEST;
472
473 GST_START_TEST (test_client_multicast_ignore_transport_specific)
474 {
475   GstRTSPClient *client;
476   GstRTSPMessage request = { 0, };
477   gchar *str;
478
479   client = setup_multicast_client ();
480
481   /* simple SETUP with a valid URI and multicast and a specific dest,
482    * but ignore it  */
483   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
484           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
485   str = g_strdup_printf ("%d", cseq);
486   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
487   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
488       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
489
490   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
491       "ttl=1;port=5000-5001;mode=\"PLAY\"";
492   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
493       NULL, NULL);
494   fail_unless (gst_rtsp_client_handle_message (client,
495           &request) == GST_RTSP_OK);
496   gst_rtsp_message_unset (&request);
497   expected_transport = NULL;
498
499   teardown_client (client);
500 }
501
502 GST_END_TEST;
503
504 static gboolean
505 test_setup_response_461 (GstRTSPClient * client,
506     GstRTSPMessage * response, gboolean close, gpointer user_data)
507 {
508   GstRTSPStatusCode code;
509   const gchar *reason;
510   GstRTSPVersion version;
511   gchar *str;
512
513   fail_unless (expected_transport == NULL);
514
515   fail_unless (gst_rtsp_message_get_type (response) ==
516       GST_RTSP_MESSAGE_RESPONSE);
517
518   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
519           &version)
520       == GST_RTSP_OK);
521   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
522   fail_unless (g_str_equal (reason, "Unsupported transport"));
523   fail_unless (version == GST_RTSP_VERSION_1_0);
524
525   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
526           0) == GST_RTSP_OK);
527   fail_unless (atoi (str) == cseq++);
528
529
530   return TRUE;
531 }
532
533 GST_START_TEST (test_client_multicast_invalid_transport_specific)
534 {
535   GstRTSPClient *client;
536   GstRTSPMessage request = { 0, };
537   gchar *str;
538   GstRTSPSessionPool *session_pool;
539   GstRTSPContext ctx = { NULL };
540
541   client = setup_multicast_client ();
542
543   ctx.client = client;
544   ctx.auth = gst_rtsp_auth_new ();
545   ctx.token =
546       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
547       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
548       "user", NULL);
549   gst_rtsp_context_push_current (&ctx);
550
551   /* simple SETUP with a valid URI and multicast, but an invalid ip */
552   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
553           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
554   str = g_strdup_printf ("%d", cseq);
555   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
556   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
557       "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;");
558
559   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
560   fail_unless (gst_rtsp_client_handle_message (client,
561           &request) == GST_RTSP_OK);
562   gst_rtsp_message_unset (&request);
563
564   session_pool = gst_rtsp_client_get_session_pool (client);
565   fail_unless (session_pool != NULL);
566   /* FIXME: There seems to be a leak of a session here ! */
567   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
568   g_object_unref (session_pool);
569
570
571
572   /* simple SETUP with a valid URI and multicast, but an invalid prt */
573   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
574           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
575   str = g_strdup_printf ("%d", cseq);
576   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
577   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
578       "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;");
579
580   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
581   fail_unless (gst_rtsp_client_handle_message (client,
582           &request) == GST_RTSP_OK);
583   gst_rtsp_message_unset (&request);
584
585   session_pool = gst_rtsp_client_get_session_pool (client);
586   fail_unless (session_pool != NULL);
587   /* FIXME: There seems to be a leak of a session here ! */
588   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
589   g_object_unref (session_pool);
590
591
592
593   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
594   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
595           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
596   str = g_strdup_printf ("%d", cseq);
597   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
598   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
599       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
600
601   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
602   fail_unless (gst_rtsp_client_handle_message (client,
603           &request) == GST_RTSP_OK);
604   gst_rtsp_message_unset (&request);
605
606   session_pool = gst_rtsp_client_get_session_pool (client);
607   fail_unless (session_pool != NULL);
608   /* FIXME: There seems to be a leak of a session here ! */
609   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
610   g_object_unref (session_pool);
611
612
613   teardown_client (client);
614   g_object_unref (ctx.auth);
615   gst_rtsp_token_unref (ctx.token);
616   gst_rtsp_context_pop_current (&ctx);
617 }
618
619 GST_END_TEST;
620
621 GST_START_TEST (test_client_multicast_transport_specific)
622 {
623   GstRTSPClient *client;
624   GstRTSPMessage request = { 0, };
625   gchar *str;
626   GstRTSPSessionPool *session_pool;
627   GstRTSPContext ctx = { NULL };
628
629   client = setup_multicast_client ();
630
631   ctx.client = client;
632   ctx.auth = gst_rtsp_auth_new ();
633   ctx.token =
634       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
635       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
636       "user", NULL);
637   gst_rtsp_context_push_current (&ctx);
638
639   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
640       "ttl=1;port=5000-5001;mode=\"PLAY\"";
641
642   /* simple SETUP with a valid URI and multicast, but an invalid ip */
643   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
644           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
645   str = g_strdup_printf ("%d", cseq);
646   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
647   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
648       expected_transport);
649
650   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
651       NULL, NULL);
652   fail_unless (gst_rtsp_client_handle_message (client,
653           &request) == GST_RTSP_OK);
654   gst_rtsp_message_unset (&request);
655   expected_transport = NULL;
656
657   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
658       NULL, NULL);
659   session_pool = gst_rtsp_client_get_session_pool (client);
660   fail_unless (session_pool != NULL);
661   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
662   g_object_unref (session_pool);
663
664   teardown_client (client);
665   g_object_unref (ctx.auth);
666   gst_rtsp_token_unref (ctx.token);
667   gst_rtsp_context_pop_current (&ctx);
668 }
669
670 GST_END_TEST;
671
672 static gboolean
673 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
674     gboolean close, gpointer user_data)
675 {
676   guint8 *data;
677   guint size;
678   GstSDPMessage *sdp_msg;
679   const GstSDPMedia *sdp_media;
680   const GstSDPBandwidth *bw;
681   gint bandwidth_val = GPOINTER_TO_INT (user_data);
682
683   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
684       == GST_RTSP_OK);
685   gst_sdp_message_new (&sdp_msg);
686   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
687       == GST_SDP_OK);
688
689   /* session description */
690   /* v= */
691   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
692   /* o= */
693   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
694   /* s= */
695   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
696   /* t=0 0 */
697   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
698
699   /* verify number of medias */
700   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
701
702   /* media description */
703   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
704   fail_unless (sdp_media != NULL);
705
706   /* m= */
707   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
708
709   /* media bandwidth */
710   if (bandwidth_val) {
711     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
712     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
713     fail_unless (bw != NULL);
714     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
715     fail_unless (bw->bandwidth == bandwidth_val);
716   } else {
717     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
718   }
719
720   gst_sdp_message_free (sdp_msg);
721
722   return TRUE;
723 }
724
725 static void
726 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
727 {
728   GstRTSPClient *client;
729   GstRTSPMessage request = { 0, };
730   gchar *str;
731
732   /* simple DESCRIBE for an existing url */
733   client = setup_client (launch_line);
734   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
735           "rtsp://localhost/test") == GST_RTSP_OK);
736   str = g_strdup_printf ("%d", cseq);
737   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
738   g_free (str);
739
740   gst_rtsp_client_set_send_func (client, test_response_sdp,
741       (gpointer) bandwidth_val, NULL);
742   fail_unless (gst_rtsp_client_handle_message (client,
743           &request) == GST_RTSP_OK);
744   gst_rtsp_message_unset (&request);
745
746   teardown_client (client);
747 }
748
749 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
750 {
751   test_client_sdp ("videotestsrc "
752       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
753       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
754       GUINT_TO_POINTER (50000));
755
756
757   /* max-bitrate=0: no bandwidth line */
758   test_client_sdp ("videotestsrc "
759       "! taginject tags=\"maximum-bitrate=(uint)0\" "
760       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
761       GUINT_TO_POINTER (0));
762 }
763
764 GST_END_TEST;
765
766 GST_START_TEST (test_client_sdp_with_bitrate_tag)
767 {
768   test_client_sdp ("videotestsrc "
769       "! taginject tags=\"bitrate=(uint)7000000\" "
770       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
771       GUINT_TO_POINTER (7000));
772
773   /* bitrate=0: no bandwdith line */
774   test_client_sdp ("videotestsrc "
775       "! taginject tags=\"bitrate=(uint)0\" "
776       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
777       GUINT_TO_POINTER (0));
778 }
779
780 GST_END_TEST;
781
782 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
783 {
784   test_client_sdp ("videotestsrc "
785       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
786       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
787       GUINT_TO_POINTER (50000));
788
789   /* max-bitrate is zero: fallback to bitrate */
790   test_client_sdp ("videotestsrc "
791       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
792       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
793       GUINT_TO_POINTER (7000));
794
795   /* max-bitrate=bitrate=0o: no bandwidth line */
796   test_client_sdp ("videotestsrc "
797       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
798       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
799       GUINT_TO_POINTER (0));
800 }
801
802 GST_END_TEST;
803
804 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
805 {
806   test_client_sdp ("videotestsrc "
807       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
808 }
809
810 GST_END_TEST;
811
812 static Suite *
813 rtspclient_suite (void)
814 {
815   Suite *s = suite_create ("rtspclient");
816   TCase *tc = tcase_create ("general");
817
818   suite_add_tcase (s, tc);
819   tcase_set_timeout (tc, 20);
820   tcase_add_test (tc, test_request);
821   tcase_add_test (tc, test_options);
822   tcase_add_test (tc, test_describe);
823   tcase_add_test (tc, test_client_multicast_transport_404);
824   tcase_add_test (tc, test_client_multicast_transport);
825   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
826   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
827   tcase_add_test (tc, test_client_multicast_transport_specific);
828   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
829   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
830   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
831   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
832
833   return s;
834 }
835
836 GST_CHECK_MAIN (rtspclient);