tests: Make sure packets are actually received
[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
26 static gboolean
27 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
28     gboolean close, gpointer user_data)
29 {
30   GstRTSPStatusCode code;
31   const gchar *reason;
32   GstRTSPVersion version;
33
34   fail_unless (gst_rtsp_message_get_type (response) ==
35       GST_RTSP_MESSAGE_RESPONSE);
36
37   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
38           &version)
39       == GST_RTSP_OK);
40   fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
41   fail_unless (g_str_equal (reason, "Bad Request"));
42   fail_unless (version == GST_RTSP_VERSION_1_0);
43
44   return TRUE;
45 }
46
47 static gboolean
48 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
49     gboolean close, gpointer user_data)
50 {
51   GstRTSPStatusCode code;
52   const gchar *reason;
53   GstRTSPVersion version;
54
55   fail_unless (gst_rtsp_message_get_type (response) ==
56       GST_RTSP_MESSAGE_RESPONSE);
57
58   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
59           &version)
60       == GST_RTSP_OK);
61   fail_unless (code == GST_RTSP_STS_NOT_FOUND);
62   fail_unless (g_str_equal (reason, "Not Found"));
63   fail_unless (version == GST_RTSP_VERSION_1_0);
64
65   return TRUE;
66 }
67
68 static gboolean
69 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
70     gboolean close, gpointer user_data)
71 {
72   GstRTSPStatusCode code;
73   const gchar *reason;
74   GstRTSPVersion version;
75
76   fail_unless (gst_rtsp_message_get_type (response) ==
77       GST_RTSP_MESSAGE_RESPONSE);
78
79   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
80           &version)
81       == GST_RTSP_OK);
82   fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
83   fail_unless (g_str_equal (reason, "Session Not Found"));
84   fail_unless (version == GST_RTSP_VERSION_1_0);
85
86   return TRUE;
87 }
88
89 GST_START_TEST (test_request)
90 {
91   GstRTSPClient *client;
92   GstRTSPMessage request = { 0, };
93   gchar *str;
94
95   client = gst_rtsp_client_new ();
96
97   /* OPTIONS with invalid url */
98   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
99           "foopy://padoop/") == GST_RTSP_OK);
100   str = g_strdup_printf ("%d", cseq);
101   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
102   g_free (str);
103
104   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
105   fail_unless (gst_rtsp_client_handle_message (client,
106           &request) == GST_RTSP_OK);
107
108   gst_rtsp_message_unset (&request);
109
110   /* OPTIONS with unknown session id */
111   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
112           "rtsp://localhost/test") == GST_RTSP_OK);
113   str = g_strdup_printf ("%d", cseq);
114   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
115   g_free (str);
116   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
117
118   gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
119   fail_unless (gst_rtsp_client_handle_message (client,
120           &request) == GST_RTSP_OK);
121
122   gst_rtsp_message_unset (&request);
123
124   g_object_unref (client);
125 }
126
127 GST_END_TEST;
128
129 static gboolean
130 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
131     gboolean close, gpointer user_data)
132 {
133   GstRTSPStatusCode code;
134   const gchar *reason;
135   GstRTSPVersion version;
136   gchar *str;
137   GstRTSPMethod methods;
138
139   fail_unless (gst_rtsp_message_get_type (response) ==
140       GST_RTSP_MESSAGE_RESPONSE);
141
142   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
143           &version)
144       == GST_RTSP_OK);
145   fail_unless (code == GST_RTSP_STS_OK);
146   fail_unless (g_str_equal (reason, "OK"));
147   fail_unless (version == GST_RTSP_VERSION_1_0);
148
149   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
150           0) == GST_RTSP_OK);
151   fail_unless (atoi (str) == cseq++);
152
153   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
154           0) == GST_RTSP_OK);
155
156   methods = gst_rtsp_options_from_text (str);
157   fail_if (methods == 0);
158   fail_unless (methods == (GST_RTSP_DESCRIBE |
159           GST_RTSP_OPTIONS |
160           GST_RTSP_PAUSE |
161           GST_RTSP_PLAY |
162           GST_RTSP_SETUP |
163           GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
164
165   return TRUE;
166 }
167
168 GST_START_TEST (test_options)
169 {
170   GstRTSPClient *client;
171   GstRTSPMessage request = { 0, };
172   gchar *str;
173
174   client = gst_rtsp_client_new ();
175
176   /* simple OPTIONS */
177   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
178           "rtsp://localhost/test") == GST_RTSP_OK);
179   str = g_strdup_printf ("%d", cseq);
180   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
181   g_free (str);
182
183   gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
184   fail_unless (gst_rtsp_client_handle_message (client,
185           &request) == GST_RTSP_OK);
186   gst_rtsp_message_unset (&request);
187
188   g_object_unref (client);
189 }
190
191 GST_END_TEST;
192
193 GST_START_TEST (test_describe)
194 {
195   GstRTSPClient *client;
196   GstRTSPMessage request = { 0, };
197   gchar *str;
198
199   client = gst_rtsp_client_new ();
200
201   /* simple DESCRIBE for non-existing url */
202   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
203           "rtsp://localhost/test") == GST_RTSP_OK);
204   str = g_strdup_printf ("%d", cseq);
205   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
206   g_free (str);
207
208   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
209   fail_unless (gst_rtsp_client_handle_message (client,
210           &request) == GST_RTSP_OK);
211   gst_rtsp_message_unset (&request);
212
213   g_object_unref (client);
214 }
215
216 GST_END_TEST;
217
218 gchar *expected_transport = NULL;;
219
220 static gboolean
221 test_setup_response_200_multicast (GstRTSPClient * client,
222     GstRTSPMessage * response, gboolean close, gpointer user_data)
223 {
224   GstRTSPStatusCode code;
225   const gchar *reason;
226   GstRTSPVersion version;
227   gchar *str;
228   GstRTSPSessionPool *session_pool;
229   GstRTSPSession *session;
230
231   fail_unless (expected_transport != NULL);
232
233   fail_unless (gst_rtsp_message_get_type (response) ==
234       GST_RTSP_MESSAGE_RESPONSE);
235
236   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
237           &version)
238       == GST_RTSP_OK);
239   fail_unless (code == GST_RTSP_STS_OK);
240   fail_unless (g_str_equal (reason, "OK"));
241   fail_unless (version == GST_RTSP_VERSION_1_0);
242
243   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
244           0) == GST_RTSP_OK);
245   fail_unless (atoi (str) == cseq++);
246
247   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
248           &str, 0) == GST_RTSP_OK);
249
250   fail_unless (!strcmp (str, expected_transport));
251
252   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
253           &str, 0) == GST_RTSP_OK);
254
255   session_pool = gst_rtsp_client_get_session_pool (client);
256   fail_unless (session_pool != NULL);
257
258   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
259   session = gst_rtsp_session_pool_find (session_pool, str);
260   fail_unless (session != NULL);
261   g_object_unref (session);
262
263   g_object_unref (session_pool);
264
265
266   return TRUE;
267 }
268
269 static GstRTSPClient *
270 setup_multicast_client (void)
271 {
272   GstRTSPClient *client;
273   GstRTSPSessionPool *session_pool;
274   GstRTSPMountPoints *mount_points;
275   GstRTSPMediaFactory *factory;
276   GstRTSPAddressPool *address_pool;
277
278   client = gst_rtsp_client_new ();
279
280   session_pool = gst_rtsp_session_pool_new ();
281   gst_rtsp_client_set_session_pool (client, session_pool);
282
283   mount_points = gst_rtsp_mount_points_new ();
284   factory = gst_rtsp_media_factory_new ();
285   gst_rtsp_media_factory_set_launch (factory,
286       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
287   address_pool = gst_rtsp_address_pool_new ();
288   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
289           "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
290   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
291   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
292   gst_rtsp_client_set_mount_points (client, mount_points);
293
294   g_object_unref (mount_points);
295   g_object_unref (session_pool);
296   g_object_unref (address_pool);
297
298   return client;
299 }
300
301 GST_START_TEST (test_client_multicast_transport_404)
302 {
303   GstRTSPClient *client;
304   GstRTSPMessage request = { 0, };
305   gchar *str;
306
307   client = setup_multicast_client ();
308
309   /* simple SETUP for non-existing url */
310   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
311           "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
312   str = g_strdup_printf ("%d", cseq);
313   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
314   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
315       "RTP/AVP;multicast");
316
317   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
318   fail_unless (gst_rtsp_client_handle_message (client,
319           &request) == GST_RTSP_OK);
320   gst_rtsp_message_unset (&request);
321
322   g_object_unref (client);
323 }
324
325 GST_END_TEST;
326
327 GST_START_TEST (test_client_multicast_transport)
328 {
329   GstRTSPClient *client;
330   GstRTSPMessage request = { 0, };
331   gchar *str;
332
333   client = setup_multicast_client ();
334
335   /* simple SETUP with a valid URI and multicast */
336   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
337           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
338   str = g_strdup_printf ("%d", cseq);
339   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
340   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
341       "RTP/AVP;multicast");
342
343   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
344       "ttl=1;port=5000-5001;mode=\"PLAY\"";
345   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
346       NULL, NULL);
347   fail_unless (gst_rtsp_client_handle_message (client,
348           &request) == GST_RTSP_OK);
349   gst_rtsp_message_unset (&request);
350   expected_transport = NULL;
351
352   g_object_unref (client);
353 }
354
355 GST_END_TEST;
356
357 GST_START_TEST (test_client_multicast_ignore_transport_specific)
358 {
359   GstRTSPClient *client;
360   GstRTSPMessage request = { 0, };
361   gchar *str;
362
363   client = setup_multicast_client ();
364
365   /* simple SETUP with a valid URI and multicast and a specific dest,
366    * but ignore it  */
367   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
368           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
369   str = g_strdup_printf ("%d", cseq);
370   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
371   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
372       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
373
374   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
375       "ttl=1;port=5000-5001;mode=\"PLAY\"";
376   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
377       NULL, NULL);
378   fail_unless (gst_rtsp_client_handle_message (client,
379           &request) == GST_RTSP_OK);
380   gst_rtsp_message_unset (&request);
381   expected_transport = NULL;
382
383   g_object_unref (client);
384 }
385
386 GST_END_TEST;
387
388 static gboolean
389 test_setup_response_461 (GstRTSPClient * client,
390     GstRTSPMessage * response, gboolean close, gpointer user_data)
391 {
392   GstRTSPStatusCode code;
393   const gchar *reason;
394   GstRTSPVersion version;
395   gchar *str;
396
397   fail_unless (expected_transport == NULL);
398
399   fail_unless (gst_rtsp_message_get_type (response) ==
400       GST_RTSP_MESSAGE_RESPONSE);
401
402   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
403           &version)
404       == GST_RTSP_OK);
405   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
406   fail_unless (g_str_equal (reason, "Unsupported transport"));
407   fail_unless (version == GST_RTSP_VERSION_1_0);
408
409   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
410           0) == GST_RTSP_OK);
411   fail_unless (atoi (str) == cseq++);
412
413
414   return TRUE;
415 }
416
417 GST_START_TEST (test_client_multicast_invalid_transport_specific)
418 {
419   GstRTSPClient *client;
420   GstRTSPMessage request = { 0, };
421   gchar *str;
422   GstRTSPSessionPool *session_pool;
423
424   client = setup_multicast_client ();
425
426   gst_rtsp_client_set_use_client_settings (client, TRUE);
427   fail_unless (gst_rtsp_client_get_use_client_settings (client));
428
429
430   /* simple SETUP with a valid URI and multicast, but an invalid ip */
431   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
432           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
433   str = g_strdup_printf ("%d", cseq);
434   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
435   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
436       "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;");
437
438   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
439   fail_unless (gst_rtsp_client_handle_message (client,
440           &request) == GST_RTSP_OK);
441   gst_rtsp_message_unset (&request);
442
443   session_pool = gst_rtsp_client_get_session_pool (client);
444   fail_unless (session_pool != NULL);
445   /* FIXME: There seems to be a leak of a session here ! */
446   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
447   g_object_unref (session_pool);
448
449
450
451   /* simple SETUP with a valid URI and multicast, but an invalid prt */
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;destination=233.252.0.1;ttl=1;port=6000-6001;");
458
459   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
460   fail_unless (gst_rtsp_client_handle_message (client,
461           &request) == GST_RTSP_OK);
462   gst_rtsp_message_unset (&request);
463
464   session_pool = gst_rtsp_client_get_session_pool (client);
465   fail_unless (session_pool != NULL);
466   /* FIXME: There seems to be a leak of a session here ! */
467   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
468   g_object_unref (session_pool);
469
470
471
472   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
473   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
474           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
475   str = g_strdup_printf ("%d", cseq);
476   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
477   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
478       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
479
480   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
481   fail_unless (gst_rtsp_client_handle_message (client,
482           &request) == GST_RTSP_OK);
483   gst_rtsp_message_unset (&request);
484
485   session_pool = gst_rtsp_client_get_session_pool (client);
486   fail_unless (session_pool != NULL);
487   /* FIXME: There seems to be a leak of a session here ! */
488   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
489   g_object_unref (session_pool);
490
491
492   g_object_unref (client);
493 }
494
495 GST_END_TEST;
496
497 GST_START_TEST (test_client_multicast_transport_specific)
498 {
499   GstRTSPClient *client;
500   GstRTSPMessage request = { 0, };
501   gchar *str;
502   GstRTSPSessionPool *session_pool;
503
504   client = setup_multicast_client ();
505
506   gst_rtsp_client_set_use_client_settings (client, TRUE);
507   fail_unless (gst_rtsp_client_get_use_client_settings (client));
508
509   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
510       "ttl=1;port=5000-5001;mode=\"PLAY\"";
511
512   /* simple SETUP with a valid URI and multicast, but an invalid ip */
513   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
514           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
515   str = g_strdup_printf ("%d", cseq);
516   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
517   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
518       expected_transport);
519
520   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
521       NULL, NULL);
522   fail_unless (gst_rtsp_client_handle_message (client,
523           &request) == GST_RTSP_OK);
524   gst_rtsp_message_unset (&request);
525   expected_transport = NULL;
526
527   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
528       NULL, NULL);
529   session_pool = gst_rtsp_client_get_session_pool (client);
530   fail_unless (session_pool != NULL);
531   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
532   g_object_unref (session_pool);
533
534   g_object_unref (client);
535 }
536
537 GST_END_TEST;
538
539
540 static Suite *
541 rtspclient_suite (void)
542 {
543   Suite *s = suite_create ("rtspclient");
544   TCase *tc = tcase_create ("general");
545
546   suite_add_tcase (s, tc);
547   tcase_set_timeout (tc, 20);
548   tcase_add_test (tc, test_request);
549   tcase_add_test (tc, test_options);
550   tcase_add_test (tc, test_describe);
551   tcase_add_test (tc, test_client_multicast_transport_404);
552   tcase_add_test (tc, test_client_multicast_transport);
553   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
554   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
555   tcase_add_test (tc, test_client_multicast_transport_specific);
556
557   return s;
558 }
559
560 GST_CHECK_MAIN (rtspclient);