From 8f25333976589b70d3bd3991c2b853dbecec272d Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Tue, 2 Feb 2016 17:02:41 -0300 Subject: [PATCH] tests: mssdemux: add unit tests Adds unit tests similar to the ones that we have for DASH and HLS. Tests: * manifest parsing finishes successfully * some queries (duration, seekable, latency) * seeking with various values and flags --- tests/check/Makefile.am | 16 + tests/check/elements/.gitignore | 1 + tests/check/elements/mssdemux.c | 632 ++++++++++++++++++++++++++++++++ 3 files changed, 649 insertions(+) create mode 100644 tests/check/elements/mssdemux.c diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 43a112258c..49dd52e62d 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -96,6 +96,12 @@ else check_mplex = endif +if USE_SMOOTHSTREAMING +check_mssdemux = elements/mssdemux +else +check_mssdemux = +endif + if USE_NEON check_neon = elements/neonhttpsrc else @@ -248,6 +254,7 @@ check_PROGRAMS = \ $(check_voamrwbenc) \ $(check_mpeg2enc) \ $(check_mplex) \ + $(check_mssdemux) \ $(check_ofa) \ $(check_timidity) \ $(check_kate) \ @@ -469,6 +476,15 @@ elements_dash_demux_LDADD = \ elements_dash_demux_SOURCES = elements/test_http_src.c elements/test_http_src.h elements/adaptive_demux_engine.c elements/adaptive_demux_engine.h elements/adaptive_demux_common.c elements/adaptive_demux_common.h elements/dash_demux.c +elements_mssdemux_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS) +elements_mssdemux_LDADD = \ + $(LDADD) $(LIBXML2_LIBS) $(GST_BASE_LIBS) \ + -lgsttag-$(GST_API_VERSION) \ + -lgstapp-$(GST_API_VERSION) \ + $(top_builddir)/gst-libs/gst/adaptivedemux/libgstadaptivedemux-@GST_API_VERSION@.la + +elements_mssdemux_SOURCES = elements/test_http_src.c elements/test_http_src.h elements/adaptive_demux_engine.c elements/adaptive_demux_engine.h elements/adaptive_demux_common.c elements/adaptive_demux_common.h elements/mssdemux.c + pipelines_streamheader_CFLAGS = $(GIO_CFLAGS) $(AM_CFLAGS) pipelines_streamheader_LDADD = $(GIO_LIBS) $(LDADD) diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore index 241c441800..06f0978401 100644 --- a/tests/check/elements/.gitignore +++ b/tests/check/elements/.gitignore @@ -40,6 +40,7 @@ mpeg4videoparse mpegtsmux mpg123audiodec mplex +mssdemux mxfdemux mxfmux neonhttpsrc diff --git a/tests/check/elements/mssdemux.c b/tests/check/elements/mssdemux.c new file mode 100644 index 0000000000..78a18631bc --- /dev/null +++ b/tests/check/elements/mssdemux.c @@ -0,0 +1,632 @@ +/* GStreamer unit test for MSS + * + * Copyright (C) 2016 Samsung Electronics. All rights reserved. + * Author: Thiago Santos + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include "adaptive_demux_common.h" + +#define DEMUX_ELEMENT_NAME "mssdemux" + +#define COPY_OUTPUT_TEST_DATA(outputTestData,testData) do { \ + guint otdPos, otdLen = sizeof((outputTestData)) / sizeof((outputTestData)[0]); \ + for(otdPos=0; otdPosoutput_streams = g_list_append ((testData)->output_streams, &(outputTestData)[otdPos]); \ + } \ + } while(0) + +typedef struct _GstMssDemuxTestInputData +{ + const gchar *uri; + const guint8 *payload; + guint64 size; +} GstMssDemuxTestInputData; + +static gboolean +gst_mssdemux_http_src_start (GstTestHTTPSrc * src, + const gchar * uri, GstTestHTTPSrcInput * input_data, gpointer user_data) +{ + const GstMssDemuxTestInputData *input = + (const GstMssDemuxTestInputData *) user_data; + + + for (guint i = 0; input[i].uri; ++i) { + if (strcmp (input[i].uri, uri) == 0) { + input_data->context = (gpointer) & input[i]; + input_data->size = input[i].size; + if (input[i].size == 0) + input_data->size = strlen ((gchar *) input[i].payload); + return TRUE; + } + } + + return FALSE; +} + +static GstFlowReturn +gst_mssdemux_http_src_create (GstTestHTTPSrc * src, + guint64 offset, + guint length, GstBuffer ** retbuf, gpointer context, gpointer user_data) +{ + /* const GstMssDemuxTestInputData *input = + (const GstMssDemuxTestInputData *) user_data; */ + const GstMssDemuxTestInputData *input = + (const GstMssDemuxTestInputData *) context; + GstBuffer *buf; + + buf = gst_buffer_new_allocate (NULL, length, NULL); + fail_if (buf == NULL, "Not enough memory to allocate buffer"); + + if (input->payload) { + gst_buffer_fill (buf, 0, input->payload + offset, length); + } else { + GstMapInfo info; + guint pattern; + + pattern = offset - offset % sizeof (pattern); + + gst_buffer_map (buf, &info, GST_MAP_WRITE); + for (guint64 i = 0; i < length; ++i) { + gchar pattern_byte_to_write = (offset + i) % sizeof (pattern); + if (pattern_byte_to_write == 0) { + pattern = offset + i; + } + info.data[i] = (pattern >> (pattern_byte_to_write * 8)) & 0xFF; + } + gst_buffer_unmap (buf, &info); + } + *retbuf = buf; + return GST_FLOW_OK; +} + +/******************** Test specific code starts here **************************/ + +/* + * Test an mpd with an audio and a video stream + * + */ +GST_START_TEST (simpleTest) +{ + const gchar *mpd = + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" "" ""; + + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {"http://unit.test/QualityLevels(480111)/Fragments(video=0)", NULL, 9000}, + {"http://unit.test/QualityLevels(480111)/Fragments(video=10000000)", NULL, + 9000}, + {"http://unit.test/QualityLevels(480111)/Fragments(video=20000000)", NULL, + 9000}, + {"http://unit.test/QualityLevels(480111)/Fragments(video=30000000)", NULL, + 9000}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=0)", NULL, + 5000}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + {"audio_00", 5000, NULL}, + {"video_00", 4 * 9000, NULL} + }; + GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = gst_mssdemux_http_src_create; + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + test_callbacks.appsink_received_data = + gst_adaptive_demux_test_check_received_data; + test_callbacks.appsink_eos = + gst_adaptive_demux_test_check_size_of_received_data; + + gst_adaptive_demux_test_run (DEMUX_ELEMENT_NAME, "http://unit.test/Manifest", + &test_callbacks, testData); + g_object_unref (testData); +} + +GST_END_TEST; + +/* + * Test seeking + * + */ +GST_START_TEST (testSeek) +{ + const gchar *mpd = + "" + "" + "" + "" + "" + "" ""; + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=0)", NULL, + 10000}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + {"audio_00", 10000, NULL}, + }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = gst_mssdemux_http_src_create; + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + + /* media segment starts at 4687 + * Issue a seek request after media segment has started to be downloaded + * on the first pad listed in GstAdaptiveDemuxTestOutputStreamData and the + * first chunk of at least one byte has already arrived in AppSink + */ + testData->threshold_for_seek = 4687 + 1; + + /* seek to 5ms. + * Because there is only one fragment, we expect the whole file to be + * downloaded again + */ + testData->seek_event = + gst_event_new_seek (1.0, GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, GST_SEEK_TYPE_SET, + 5 * GST_MSECOND, GST_SEEK_TYPE_NONE, 0); + + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + gst_adaptive_demux_test_seek (DEMUX_ELEMENT_NAME, + "http://unit.test/Manifest", testData); + gst_object_unref (testData); +} + +GST_END_TEST; + + +static void +run_seek_position_test (gdouble rate, GstSeekType start_type, + guint64 seek_start, GstSeekType stop_type, guint64 seek_stop, + GstSeekFlags flags, guint64 segment_start, guint64 segment_stop, + gint segments) +{ + const gchar *mpd = + "" + "" + "" + "" + "" + "" + "" + "" "" ""; + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=0)", NULL, + 10000}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=10000000)", + NULL, 10000}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=20000000)", + NULL, 10000}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=30000000)", + NULL, 10000}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + /* 1 from the init segment */ + {"audio_00", segments * 10000, NULL}, + }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = gst_mssdemux_http_src_create; + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + + /* media segment starts at 4687 + * Issue a seek request after media segment has started to be downloaded + * on the first pad listed in GstAdaptiveDemuxTestOutputStreamData and the + * first chunk of at least one byte has already arrived in AppSink + */ + testData->threshold_for_seek = 4687 + 1; + + /* FIXME hack to avoid having a 0 seqnum */ + gst_util_seqnum_next (); + + /* seek to 5ms. + * Because there is only one fragment, we expect the whole file to be + * downloaded again + */ + testData->seek_event = + gst_event_new_seek (rate, GST_FORMAT_TIME, flags, start_type, + seek_start, stop_type, seek_stop); + + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + gst_adaptive_demux_test_seek (DEMUX_ELEMENT_NAME, + "http://unit.test/Manifest", testData); + gst_object_unref (testData); +} + +GST_START_TEST (testSeekKeyUnitPosition) +{ + /* Seek to 1.5s with key unit, it should go back to 1.0s. 3 segments will be + * pushed */ + run_seek_position_test (1.0, GST_SEEK_TYPE_SET, 1500 * GST_MSECOND, + GST_SEEK_TYPE_NONE, 0, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, + 1000 * GST_MSECOND, -1, 3); +} + +GST_END_TEST; + + +GST_START_TEST (testSeekUpdateStopPosition) +{ + run_seek_position_test (1.0, GST_SEEK_TYPE_NONE, 1500 * GST_MSECOND, + GST_SEEK_TYPE_SET, 3000 * GST_MSECOND, 0, 0, 3000 * GST_MSECOND, 3); +} + +GST_END_TEST; + +GST_START_TEST (testSeekPosition) +{ + /* Seek to 1.5s without key unit, it should keep the 1.5s, but still push + * from the 1st segment, so 3 segments will be + * pushed */ + run_seek_position_test (1.0, GST_SEEK_TYPE_SET, 1500 * GST_MSECOND, + GST_SEEK_TYPE_NONE, 0, GST_SEEK_FLAG_FLUSH, 1500 * GST_MSECOND, -1, 3); +} + +GST_END_TEST; + +GST_START_TEST (testSeekSnapBeforePosition) +{ + /* Seek to 1.5s, snap before, it go to 1s */ + run_seek_position_test (1.0, GST_SEEK_TYPE_SET, 1500 * GST_MSECOND, + GST_SEEK_TYPE_NONE, 0, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_BEFORE, + 1000 * GST_MSECOND, -1, 3); +} + +GST_END_TEST; + + +GST_START_TEST (testSeekSnapAfterPosition) +{ + /* Seek to 1.5s with snap after, it should move to 2s */ + run_seek_position_test (1.0, GST_SEEK_TYPE_SET, 1500 * GST_MSECOND, + GST_SEEK_TYPE_NONE, 0, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_AFTER, + 2000 * GST_MSECOND, -1, 2); +} + +GST_END_TEST; + + +GST_START_TEST (testReverseSeekSnapBeforePosition) +{ + run_seek_position_test (-1.0, GST_SEEK_TYPE_SET, 1000 * GST_MSECOND, + GST_SEEK_TYPE_SET, 2500 * GST_MSECOND, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_BEFORE, 1000 * GST_MSECOND, + 3000 * GST_MSECOND, 2); +} + +GST_END_TEST; + + +GST_START_TEST (testReverseSeekSnapAfterPosition) +{ + run_seek_position_test (-1.0, GST_SEEK_TYPE_SET, 1000 * GST_MSECOND, + GST_SEEK_TYPE_SET, 2500 * GST_MSECOND, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_AFTER, 1000 * GST_MSECOND, + 2000 * GST_MSECOND, 1); +} + +GST_END_TEST; + +static void +testDownloadErrorMessageCallback (GstAdaptiveDemuxTestEngine * engine, + GstMessage * msg, gpointer user_data) +{ + GError *err = NULL; + gchar *dbg_info = NULL; + + fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); + gst_message_parse_error (msg, &err, &dbg_info); + GST_DEBUG ("Error from element %s : %s\n", + GST_OBJECT_NAME (msg->src), err->message); + fail_unless_equals_string (GST_OBJECT_NAME (msg->src), DEMUX_ELEMENT_NAME); + /*GST_DEBUG ("dbg_info=%s\n", dbg_info); */ + g_error_free (err); + g_free (dbg_info); + g_main_loop_quit (engine->loop); +} + +/* + * Test error case of failing to download a segment + */ +GST_START_TEST (testDownloadError) +{ + const gchar *mpd = + "" + "" + "" + "" + "" "" ""; + + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + {"audio_00", 0, NULL}, + }; + GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = gst_mssdemux_http_src_create; + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + test_callbacks.appsink_received_data = + gst_adaptive_demux_test_check_received_data; + test_callbacks.bus_error_message = testDownloadErrorMessageCallback; + test_callbacks.appsink_eos = + gst_adaptive_demux_test_check_size_of_received_data; + + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + gst_adaptive_demux_test_run (DEMUX_ELEMENT_NAME, "http://unit.test/Manifest", + &test_callbacks, testData); + gst_object_unref (testData); +} + +GST_END_TEST; + +/* generate queries to adaptive demux */ +static gboolean +testQueryCheckDataReceived (GstAdaptiveDemuxTestEngine * engine, + GstAdaptiveDemuxTestOutputStream * stream, + GstBuffer * buffer, gpointer user_data) +{ + GList *pads; + GstPad *pad; + GstQuery *query; + gboolean ret; + gint64 duration; + gboolean seekable; + gint64 segment_start; + gint64 segment_end; + gchar *uri; + gchar *redirect_uri; + gboolean redirect_permanent; + + pads = GST_ELEMENT_PADS (stream->appsink); + + /* AppSink should have only 1 pad */ + fail_unless (pads != NULL); + fail_unless (g_list_length (pads) == 1); + pad = GST_PAD (pads->data); + + query = gst_query_new_duration (GST_FORMAT_TIME); + ret = gst_pad_peer_query (pad, query); + fail_unless (ret == TRUE); + gst_query_parse_duration (query, NULL, &duration); + fail_unless (duration == GST_SECOND); + gst_query_unref (query); + + query = gst_query_new_seeking (GST_FORMAT_TIME); + ret = gst_pad_peer_query (pad, query); + fail_unless (ret == TRUE); + gst_query_parse_seeking (query, NULL, &seekable, &segment_start, + &segment_end); + fail_unless (seekable == TRUE); + fail_unless (segment_start == 0); + fail_unless (segment_end == duration); + gst_query_unref (query); + + query = gst_query_new_uri (); + ret = gst_pad_peer_query (pad, query); + fail_unless (ret == TRUE); + gst_query_parse_uri (query, &uri); + gst_query_parse_uri_redirection (query, &redirect_uri); + gst_query_parse_uri_redirection_permanent (query, &redirect_permanent); + fail_unless (strcmp (uri, "http://unit.test/Manifest") == 0); + /* adaptive demux does not reply with redirect information */ + fail_unless (redirect_uri == NULL); + fail_unless (redirect_permanent == FALSE); + g_free (uri); + g_free (redirect_uri); + gst_query_unref (query); + + return gst_adaptive_demux_test_check_received_data (engine, + stream, buffer, user_data); +} + +/* + * Test queries + * + */ +GST_START_TEST (testQuery) +{ + const gchar *mpd = + "" + "" + "" + "" + "" "" ""; + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=0)", NULL, + 5000}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + {"audio_00", 5000, NULL}, + }; + GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = gst_mssdemux_http_src_create; + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + test_callbacks.appsink_received_data = testQueryCheckDataReceived; + test_callbacks.appsink_eos = + gst_adaptive_demux_test_check_size_of_received_data; + + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + gst_adaptive_demux_test_run (DEMUX_ELEMENT_NAME, + "http://unit.test/Manifest", &test_callbacks, testData); + gst_object_unref (testData); +} + +GST_END_TEST; + +static GstFlowReturn +test_fragment_download_error_src_create (GstTestHTTPSrc * src, + guint64 offset, + guint length, GstBuffer ** retbuf, gpointer context, gpointer user_data) +{ + const GstMssDemuxTestInputData *input = + (const GstMssDemuxTestInputData *) context; + fail_unless (input != NULL); + if (!g_str_has_suffix (input->uri, ".mpd") && offset > 2000) { + GST_DEBUG ("network_error %s %" G_GUINT64_FORMAT " @ %d", + input->uri, offset, 2000); + GST_ELEMENT_ERROR (src, RESOURCE, READ, + (("A network error occurred, or the server closed the connection unexpectedly.")), ("A network error occurred, or the server closed the connection unexpectedly.")); + return GST_FLOW_ERROR; + } + return gst_mssdemux_http_src_create (src, offset, length, retbuf, context, + user_data); +} + +/* function to check total size of data received by AppSink + * will be called when AppSink receives eos. + */ +static void +testFragmentDownloadErrorCheckSizeOfDataReceived (GstAdaptiveDemuxTestEngine * + engine, GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data) +{ + GstAdaptiveDemuxTestCase *testData = GST_ADAPTIVE_DEMUX_TEST_CASE (user_data); + GstAdaptiveDemuxTestExpectedOutput *testOutputStreamData; + + testOutputStreamData = + gst_adaptive_demux_test_find_test_data_by_stream (testData, stream, NULL); + fail_unless (testOutputStreamData != NULL); + + /* expect to receive more than 0 */ + fail_unless (stream->total_received_size > 0, + "size validation failed for %s, expected > 0, received %d", + testOutputStreamData->name, stream->total_received_size); + + /* expect to receive less than file size */ + fail_unless (stream->total_received_size < + testOutputStreamData->expected_size, + "size validation failed for %s, expected < %d received %d", + testOutputStreamData->name, testOutputStreamData->expected_size, + stream->total_received_size); +} + +/* + * Test fragment download error + * Let the adaptive demux download a few bytes, then instruct the + * GstTestHTTPSrc element to generate an error. + */ +GST_START_TEST (testFragmentDownloadError) +{ + const gchar *mpd = + "" + "" + "" + "" + "" "" ""; + + GstMssDemuxTestInputData inputTestData[] = { + {"http://unit.test/Manifest", (guint8 *) mpd, 0}, + {"http://unit.test/QualityLevels(200029)/Fragments(audio_eng=0)", NULL, + 5000}, + {NULL, NULL, 0}, + }; + GstTestHTTPSrcCallbacks http_src_callbacks = { 0 }; + GstAdaptiveDemuxTestExpectedOutput outputTestData[] = { + {"audio_00", 5000, NULL}, + }; + GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 }; + GstAdaptiveDemuxTestCase *testData; + + testData = gst_adaptive_demux_test_case_new (); + http_src_callbacks.src_start = gst_mssdemux_http_src_start; + http_src_callbacks.src_create = test_fragment_download_error_src_create; + COPY_OUTPUT_TEST_DATA (outputTestData, testData); + test_callbacks.appsink_received_data = + gst_adaptive_demux_test_check_received_data; + test_callbacks.appsink_eos = testFragmentDownloadErrorCheckSizeOfDataReceived; + /* test_callbacks.demux_sent_eos = gst_adaptive_demux_test_check_size_of_received_data; */ + + test_callbacks.bus_error_message = testDownloadErrorMessageCallback; + + gst_test_http_src_install_callbacks (&http_src_callbacks, inputTestData); + gst_adaptive_demux_test_run (DEMUX_ELEMENT_NAME, + "http://unit.test/Manifest", &test_callbacks, testData); + gst_object_unref (testData); +} + +GST_END_TEST; + +static Suite * +mss_demux_suite (void) +{ + Suite *s = suite_create ("mss_demux"); + TCase *tc_basicTest = tcase_create ("basicTest"); + + tcase_add_test (tc_basicTest, simpleTest); + tcase_add_test (tc_basicTest, testSeek); + tcase_add_test (tc_basicTest, testSeekKeyUnitPosition); + tcase_add_test (tc_basicTest, testSeekPosition); + tcase_add_test (tc_basicTest, testSeekUpdateStopPosition); + tcase_add_test (tc_basicTest, testSeekSnapBeforePosition); + tcase_add_test (tc_basicTest, testSeekSnapAfterPosition); + tcase_add_test (tc_basicTest, testReverseSeekSnapBeforePosition); + tcase_add_test (tc_basicTest, testReverseSeekSnapAfterPosition); + tcase_add_test (tc_basicTest, testDownloadError); + tcase_add_test (tc_basicTest, testFragmentDownloadError); + tcase_add_test (tc_basicTest, testQuery); + + tcase_add_unchecked_fixture (tc_basicTest, gst_adaptive_demux_test_setup, + gst_adaptive_demux_test_teardown); + + suite_add_tcase (s, tc_basicTest); + + return s; +} + +GST_CHECK_MAIN (mss_demux);