gst_plugins_base/tests/check/elements/gnomevfssink.c
changeset 0 0e761a78d257
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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_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 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);