Imported Upstream version 0.10.36
[profile/ivi/gst-plugins-base.git] / tests / check / elements / gnomevfssink.c
1 /* GStreamer unit test for the gnomevfssink element
2  *
3  * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
4  * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <stdio.h>
27
28 #include <glib.h>
29 #include <glib/gstdio.h>
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>             /* for close() */
33 #endif
34
35 #include <gst/check/gstcheck.h>
36
37 static GstPad *mysrcpad;
38
39 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
40     GST_PAD_SRC,
41     GST_PAD_ALWAYS,
42     GST_STATIC_CAPS_ANY);
43
44 static GstElement *
45 setup_gnomevfssink (void)
46 {
47   GstElement *gnomevfssink;
48
49   GST_DEBUG ("setup_gnomevfssink");
50   gnomevfssink = gst_check_setup_element ("gnomevfssink");
51   mysrcpad = gst_check_setup_src_pad (gnomevfssink, &srctemplate, NULL);
52   gst_pad_set_active (mysrcpad, TRUE);
53   return gnomevfssink;
54 }
55
56 static void
57 cleanup_gnomevfssink (GstElement * gnomevfssink)
58 {
59   gst_pad_set_active (mysrcpad, FALSE);
60   gst_check_teardown_src_pad (gnomevfssink);
61   gst_check_teardown_element (gnomevfssink);
62 }
63
64 #if 0
65 /* this queries via the element vfunc, which is currently not implemented */
66 #define CHECK_QUERY_POSITION(gnomevfssink,format,position)                  \
67     G_STMT_START {                                                       \
68       GstFormat fmt = format;                                            \
69       gint64 pos;                                                        \
70       fail_unless (gst_element_query_position (gnomevfssink, &fmt, &pos));   \
71       fail_unless_equals_int (pos, position);                            \
72     } G_STMT_END
73 #else
74 #define CHECK_QUERY_POSITION(gnomevfssink,format,position)               \
75     G_STMT_START {                                                       \
76       GstFormat fmt = format;                                            \
77       GstPad *pad;                                                       \
78       gint64 pos;                                                        \
79       pad = gst_element_get_static_pad (gnomevfssink, "sink");           \
80       fail_unless (gst_pad_query_position (pad, &fmt, &pos));            \
81       fail_unless_equals_int (pos, position);                            \
82       gst_object_unref (pad);                                            \
83     } G_STMT_END
84 #endif
85
86 #define PUSH_BYTES(num_bytes)                                             \
87     G_STMT_START {                                                        \
88       GstBuffer *buf = gst_buffer_new_and_alloc(num_bytes);               \
89       GRand *rand = g_rand_new_with_seed (num_bytes);                     \
90       guint i;                                                            \
91       for (i = 0; i < num_bytes; ++i)                                     \
92         GST_BUFFER_DATA(buf)[i] = (g_rand_int (rand) >> 24) & 0xff;       \
93       fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_OK); \
94       g_rand_free (rand);                                                 \
95     } G_STMT_END
96
97 /* TODO: we don't check that the data is actually written to the right
98  * position after a seek */
99 GST_START_TEST (test_seeking)
100 {
101   const gchar *tmpdir;
102   GstElement *gnomevfssink;
103   gchar *tmp_fn;
104   gint fd;
105
106   tmpdir = g_get_tmp_dir ();
107   if (tmpdir == NULL)
108     return;
109
110   /* this is just silly, but gcc warns if we try to use tpmnam() */
111   tmp_fn =
112       g_build_filename (tmpdir, "gstreamer-gnomevfssink-test-XXXXXX", NULL);
113   fd = g_mkstemp (tmp_fn);
114   if (fd < 0) {
115     GST_ERROR ("can't create temp file %s: %s", tmp_fn, g_strerror (errno));
116     g_free (tmp_fn);
117     return;
118   }
119   /* don't want the file, just a filename (hence silly, see above) */
120   close (fd);
121   g_remove (tmp_fn);
122
123   gnomevfssink = setup_gnomevfssink ();
124
125   GST_LOG ("using temp file '%s'", tmp_fn);
126   g_object_set (gnomevfssink, "location", tmp_fn, NULL);
127
128   fail_unless_equals_int (gst_element_set_state (gnomevfssink,
129           GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC);
130
131 #if 0
132   /* Test that gnomevfssink is seekable with a file fd */
133   /* gnomevfssink doesn't implement seekable query at the moment */
134   GstQuery *seeking_query;
135   gboolean seekable;
136
137   fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
138       != NULL);
139   fail_unless (gst_element_query (gnomevfssink, seeking_query) == TRUE);
140   gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL);
141   fail_unless (seekable == TRUE);
142   gst_query_unref (seeking_query);
143 #endif
144
145   fail_unless (gst_pad_push_event (mysrcpad,
146           gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)));
147
148   CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 0);
149
150   /* push buffer with size 0 and NULL data */
151   PUSH_BYTES (0);
152   CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 0);
153
154   PUSH_BYTES (1);
155   CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 1);
156
157   PUSH_BYTES (99);
158   CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 100);
159
160   PUSH_BYTES (8800);
161   CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 8900);
162
163   if (gst_pad_push_event (mysrcpad,
164           gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 8800, -1,
165               0))) {
166     GST_LOG ("seek ok");
167     /* make sure that new position is reported immediately */
168     CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 8800);
169     PUSH_BYTES (1);
170     CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 8801);
171     PUSH_BYTES (9256);
172     CHECK_QUERY_POSITION (gnomevfssink, GST_FORMAT_BYTES, 18057);
173   } else {
174     GST_INFO ("seeking not supported for tempfile?!");
175   }
176
177   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
178
179   fail_unless_equals_int (gst_element_set_state (gnomevfssink, GST_STATE_NULL),
180       GST_STATE_CHANGE_SUCCESS);
181
182   /* cleanup */
183   cleanup_gnomevfssink (gnomevfssink);
184
185   /* check that we wrote data to the right position after the seek */
186   {
187     gchar *data = NULL;
188     gsize len;
189
190     fail_unless (g_file_get_contents (tmp_fn, &data, &len, NULL),
191         "Failed to read in newly-created file '%s'", tmp_fn);
192     fail_unless_equals_int (len, 18057);
193     {
194       /* we wrote 9256 bytes at position 8801 */
195       GRand *rand = g_rand_new_with_seed (9256);
196       guint i;
197
198       for (i = 0; i < 9256; ++i) {
199         guint8 byte_written = *(((guint8 *) data) + 8801 + i);
200
201         fail_unless_equals_int (byte_written, g_rand_int (rand) >> 24);
202       }
203       g_rand_free (rand);
204     }
205     g_free (data);
206   }
207
208   /* remove file */
209   g_remove (tmp_fn);
210   g_free (tmp_fn);
211 }
212
213 GST_END_TEST;
214
215 GST_START_TEST (test_coverage)
216 {
217   GstElement *gnomevfssink;
218   gchar *location;
219   GstBus *bus;
220   GstMessage *message;
221
222   gnomevfssink = setup_gnomevfssink ();
223   bus = gst_bus_new ();
224
225   gst_element_set_bus (gnomevfssink, bus);
226
227   g_object_set (gnomevfssink, "location", "/i/do/not/exist", NULL);
228   g_object_get (gnomevfssink, "location", &location, NULL);
229   fail_unless_equals_string (location, "/i/do/not/exist");
230   g_free (location);
231
232   fail_unless_equals_int (gst_element_set_state (gnomevfssink,
233           GST_STATE_PLAYING), GST_STATE_CHANGE_FAILURE);
234
235   /* a state change and an error */
236   fail_if ((message = gst_bus_pop (bus)) == NULL);
237   fail_unless_message_error (message, RESOURCE, OPEN_WRITE);
238   gst_message_unref (message);
239
240   g_object_set (gnomevfssink, "location", NULL, NULL);
241   g_object_get (gnomevfssink, "location", &location, NULL);
242   fail_if (location);
243
244   /* cleanup */
245   gst_element_set_bus (gnomevfssink, NULL);
246   gst_object_unref (GST_OBJECT (bus));
247   cleanup_gnomevfssink (gnomevfssink);
248 }
249
250 GST_END_TEST;
251
252 GST_START_TEST (test_uri_interface)
253 {
254   GstElement *gnomevfssink;
255   gchar *location;
256   GstBus *bus;
257
258   gnomevfssink = setup_gnomevfssink ();
259   bus = gst_bus_new ();
260
261   gst_element_set_bus (gnomevfssink, bus);
262
263   g_object_set (G_OBJECT (gnomevfssink), "location", "/i/do/not/exist", NULL);
264   g_object_get (G_OBJECT (gnomevfssink), "location", &location, NULL);
265   fail_unless_equals_string (location, "/i/do/not/exist");
266   g_free (location);
267
268   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (gnomevfssink));
269   fail_unless_equals_string (location, "file://%2Fi%2Fdo%2Fnot%2Fexist");
270
271   /* should accept file:///foo/bar URIs */
272   fail_unless (gst_uri_handler_set_uri (GST_URI_HANDLER (gnomevfssink),
273           "file:///foo/bar"));
274   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (gnomevfssink));
275   fail_unless_equals_string (location, "file://%2Ffoo%2Fbar");
276   g_object_get (G_OBJECT (gnomevfssink), "location", &location, NULL);
277   fail_unless_equals_string (location, "/foo/bar");
278   g_free (location);
279
280   /* should accept file://localhost/foo/bar URIs */
281   fail_unless (gst_uri_handler_set_uri (GST_URI_HANDLER (gnomevfssink),
282           "file://localhost/foo/baz"));
283   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (gnomevfssink));
284   fail_unless_equals_string (location, "file://%2Ffoo%2Fbaz");
285   g_object_get (G_OBJECT (gnomevfssink), "location", &location, NULL);
286   fail_unless_equals_string (location, "/foo/baz");
287   g_free (location);
288
289   /* should fail with other hostnames */
290   fail_if (gst_uri_handler_set_uri (GST_URI_HANDLER (gnomevfssink),
291           "file://hostname/foo/foo"));
292
293   /* cleanup */
294   gst_element_set_bus (gnomevfssink, NULL);
295   gst_object_unref (GST_OBJECT (bus));
296   cleanup_gnomevfssink (gnomevfssink);
297 }
298
299 GST_END_TEST;
300
301 static Suite *
302 gnomevfssink_suite (void)
303 {
304   Suite *s = suite_create ("gnomevfssink");
305   TCase *tc_chain = tcase_create ("general");
306
307   suite_add_tcase (s, tc_chain);
308
309   /* FIXME: these two tests fail right now because of uri/location stuff */
310   if (0) {
311     tcase_add_test (tc_chain, test_coverage);
312     tcase_add_test (tc_chain, test_uri_interface);
313   }
314   tcase_add_test (tc_chain, test_seeking);
315
316   return s;
317 }
318
319 GST_CHECK_MAIN (gnomevfssink);