adaptivedemux: tests: added test for fragment download error

https://bugzilla.gnome.org/show_bug.cgi?id=757361
This commit is contained in:
Florin Apostol 2015-10-20 17:21:00 +01:00 committed by Vincent Penquerc'h
parent 695ec674c6
commit 77f4776acb
3 changed files with 136 additions and 1 deletions

View file

@ -1284,6 +1284,112 @@ GST_START_TEST (testDownloadError)
GST_END_TEST;
/* generate error message on adaptive demux pipeline */
static gboolean
testFragmentDownloadErrorCheckDataReceived (GstDashDemuxTestData * testData,
GstDashDemuxTestOutputStreamData * testOutputStreamData, GstBuffer * buffer)
{
checkDataReceived (testData, testOutputStreamData, buffer);
if (testOutputStreamData->scratchData->segmentReceivedSize > 2000) {
GstPad *fakeHttpSrcPad;
GstObject *fakeHttpSrcElement;
/* tell fake soup http src to post an error on the adaptive demux bus */
fakeHttpSrcPad =
gst_pad_get_peer (testOutputStreamData->scratchData->internalPad);
fakeHttpSrcElement = gst_pad_get_parent (fakeHttpSrcPad);
gst_fake_soup_http_src_simulate_download_error ((GstFakeSoupHTTPSrc *)
fakeHttpSrcElement, 404);
gst_object_unref (fakeHttpSrcPad);
gst_object_unref (fakeHttpSrcElement);
testData->expectError = TRUE;
}
return TRUE;
}
/* function to check total size of data received by AppSink
* will be called when AppSink receives eos.
*/
static gboolean
testFragmentDownloadErrorCheckSizeOfDataReceived (GstDashDemuxTestData *
testData, GstDashDemuxTestOutputStreamData * testOutputStreamData)
{
/* expect to receive more than 0 */
fail_unless (testOutputStreamData->scratchData->totalReceivedSize > 0,
"size validation failed for %s, expected > 0, received %d",
testOutputStreamData->name,
testOutputStreamData->scratchData->totalReceivedSize);
/* expect to receive less than file size */
fail_unless (testOutputStreamData->scratchData->totalReceivedSize <
testOutputStreamData->expectedSize,
"size validation failed for %s, expected < %d received %d",
testOutputStreamData->name, testOutputStreamData->expectedSize,
testOutputStreamData->scratchData->totalReceivedSize);
return TRUE;
}
/*
* Test fragment download error
* Let the adaptive demux download a few bytes, then instruct the fake soup http
* src element to generate an error.
*/
GST_START_TEST (testFragmentDownloadError)
{
const gchar *mpd =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\""
" xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd\""
" xmlns:yt=\"http://youtube.com/yt/2012/10/10\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" type=\"static\""
" minBufferTime=\"PT1.500S\""
" mediaPresentationDuration=\"PT0.5S\">"
" <Period>"
" <AdaptationSet mimeType=\"audio/webm\""
" subsegmentAlignment=\"true\">"
" <Representation id=\"171\""
" codecs=\"vorbis\""
" audioSamplingRate=\"44100\""
" startWithSAP=\"1\""
" bandwidth=\"129553\">"
" <AudioChannelConfiguration"
" schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\""
" value=\"2\" />"
" <BaseURL>audio.webm</BaseURL>"
" <SegmentBase indexRange=\"4452-4686\""
" indexRangeExact=\"true\">"
" <Initialization range=\"0-4451\" />"
" </SegmentBase>"
" </Representation></AdaptationSet></Period></MPD>";
const GstFakeHttpSrcInputData inputTestData[] = {
{"http://unit.test/test.mpd", mpd, 0},
{"http://unit.test/audio.webm", NULL, 5000},
{NULL, NULL, 0},
};
GstDashDemuxTestOutputStreamData outputTestData[] = {
{"audio_00", 5000, NULL},
};
Callbacks cb = { 0 };
cb.appSinkGotDataCallback = testFragmentDownloadErrorCheckDataReceived;
cb.appSinkGotEosCallback = testFragmentDownloadErrorCheckSizeOfDataReceived;
runTest (inputTestData, outputTestData,
sizeof (outputTestData) / sizeof (outputTestData[0]), &cb);
}
GST_END_TEST;
/* generate queries to adaptive demux */
static gboolean
testQueryCheckDataReceived (GstDashDemuxTestData * testData,
@ -1408,6 +1514,7 @@ dash_demux_suite (void)
tcase_add_test (tc_basicTest, testParameters);
tcase_add_test (tc_basicTest, testSeek);
tcase_add_test (tc_basicTest, testDownloadError);
tcase_add_test (tc_basicTest, testFragmentDownloadError);
tcase_add_test (tc_basicTest, testQuery);
tcase_add_unchecked_fixture (tc_basicTest, test_setup, test_teardown);

View file

@ -55,6 +55,9 @@ typedef struct _GstFakeSoupHTTPSrc
guint64 position;
/* index immediately after the last byte from the segment to be retrieved */
guint64 segment_end;
/* download error code to simulate during create function */
guint downloadErrorCode;
} GstFakeSoupHTTPSrc;
typedef struct _GstFakeSoupHTTPSrcClass
@ -138,6 +141,7 @@ gst_fake_soup_http_src_init (GstFakeSoupHTTPSrc * src)
src->position = 0;
src->size = 0;
src->segment_end = 0;
src->downloadErrorCode = 0;
gst_base_src_set_blocksize (GST_BASE_SRC (src),
GST_FAKE_SOUP_HTTP_SRC_MAX_BUF_SIZE);
}
@ -163,7 +167,8 @@ gst_fake_soup_http_src_start (GstBaseSrc * basesrc)
src = GST_FAKE_SOUP_HTTP_SRC (basesrc);
if (!src->uri) {
GST_WARNING ("gst_fake_soup_http_src_start without location");
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (("No URL set.")),
("Missing location property"));
return FALSE;
}
@ -176,6 +181,7 @@ gst_fake_soup_http_src_start (GstBaseSrc * basesrc)
else
src->size = input[i].size;
src->segment_end = src->size;
src->downloadErrorCode = 0;
gst_base_src_set_dynamic_size (basesrc, FALSE);
return TRUE;
}
@ -295,6 +301,13 @@ gst_fake_soup_http_src_create (GstBaseSrc * basesrc, guint64 offset,
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
return GST_FLOW_ERROR;
}
if (src->downloadErrorCode) {
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
"Generated requested error"), ("%s (%d), URL: %s, Redirect to: %s",
"Generated requested error", src->downloadErrorCode, src->uri,
GST_STR_NULL (NULL)));
return GST_FLOW_ERROR;
}
bytes_read = MIN ((src->segment_end - src->position),
GST_FAKE_SOUP_HTTP_SRC_MAX_BUF_SIZE);
@ -431,3 +444,10 @@ gst_fake_soup_http_src_set_input_data (const GstFakeHttpSrcInputData * input)
{
gst_fake_soup_http_src_inputData = input;
}
void
gst_fake_soup_http_src_simulate_download_error (GstFakeSoupHTTPSrc *
fakeSoupHTTPSrc, guint downloadErrorCode)
{
fakeSoupHTTPSrc->downloadErrorCode = downloadErrorCode;
}

View file

@ -43,6 +43,8 @@ typedef struct _GstFakeHttpSrcInputData
guint64 size;
} GstFakeHttpSrcInputData;
typedef struct _GstFakeSoupHTTPSrc GstFakeSoupHTTPSrc;
/* GstFakeSoupHTTPSrc will send buffers up to this size */
#define GST_FAKE_SOUP_HTTP_SRC_MAX_BUF_SIZE (1024)
@ -51,3 +53,9 @@ GType gst_fake_soup_http_src_get_type (void);
gboolean gst_fake_soup_http_src_register_plugin (GstRegistry * registry, const gchar * name);
void gst_fake_soup_http_src_set_input_data (const GstFakeHttpSrcInputData *input);
/* TODO: use SoupKnownStatusCode. But it requires makefile support to include
* <libsoup/soup.h>
*/
void gst_fake_soup_http_src_simulate_download_error (
GstFakeSoupHTTPSrc *fakeSoupHTTPSrc, guint downloadErrorCode);