1 /* GStreamer gst_parse_launch unit tests
2 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
3 * Copyright (C) <2008> Tim-Philipp Müller <tim centricular net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
25 #ifdef HAVE_VALGRIND_H
26 # include <valgrind/valgrind.h>
27 # include <valgrind/memcheck.h>
30 #include <gst/check/gstcheck.h>
32 #define GST_TYPE_PARSE_TEST_ELEMENT (gst_parse_test_element_get_type())
33 static GType gst_parse_test_element_get_type (void);
36 setup_pipeline (const gchar * pipe_descr)
41 pipeline = gst_parse_launch (pipe_descr, &error);
43 GST_DEBUG ("created %s", pipe_descr);
46 fail_if (error != NULL, "Error parsing pipeline %s: %s", pipe_descr,
50 fail_unless (pipeline != NULL, "Failed to create pipeline %s", pipe_descr);
55 expected_fail_pipe (const gchar * pipe_descr)
60 #ifndef GST_DISABLE_GST_DEBUG
61 gst_debug_set_default_threshold (GST_LEVEL_NONE);
64 pipeline = gst_parse_launch (pipe_descr, &error);
65 fail_unless (pipeline == NULL || error != NULL,
66 "Expected failure pipeline %s: succeeded!", pipe_descr);
69 /* We get a pipeline back even when parsing has failed, sometimes! */
71 gst_object_unref (pipeline);
75 check_pipeline_runs (GstElement * p)
77 GstStateChangeReturn ret;
79 /* Check that the pipeline changes state to PAUSED and back to NULL */
80 ret = gst_element_set_state (p, GST_STATE_PAUSED);
81 if (ret == GST_STATE_CHANGE_ASYNC)
82 ret = gst_element_get_state (p, NULL, NULL, GST_CLOCK_TIME_NONE);
83 fail_unless (ret != GST_STATE_CHANGE_FAILURE,
84 "Could not set pipeline to paused");
86 ret = gst_element_set_state (p, GST_STATE_NULL);
87 if (ret == GST_STATE_CHANGE_ASYNC)
88 ret = gst_element_get_state (p, NULL, NULL, GST_CLOCK_TIME_NONE);
89 fail_unless (ret != GST_STATE_CHANGE_FAILURE,
90 "Could not set pipeline to null");
93 static const gchar *test_lines[] = {
94 "filesrc location=music.mp3 ! identity silent=true ! fakesink silent=true",
95 "filesrc location=music.ogg ! tee ! identity silent=true ! identity silent=true ! fakesink silent=true",
96 "filesrc location=http://domain.com/music.mp3 ! identity silent=true ! fakesink silent=true",
97 "filesrc location=movie.avi ! tee name=demuxer ! ( queue ! identity silent=true ! fakesink silent=true ) ( demuxer. ! queue ! identity silent=true ! fakesink silent=true )",
98 "fakesrc ! video/x-raw-yuv ! fakesink silent=true",
99 "fakesrc ! video/raw, format=(string)YUY2; video/raw, format=(string)YV12 ! fakesink silent=true",
100 "fakesrc ! audio/x-raw-int, width=[16, 32], depth={16, 24, 32}, signed=TRUE ! fakesink silent=true",
101 "fakesrc ! identity silent=true ! identity silent=true ! identity silent=true ! fakesink silent=true",
102 "fakesrc name=100 fakesink name=101 silent=true 100. ! 101.",
103 "fakesrc ! 1dentity ! fakesink silent=true",
107 GST_START_TEST (test_launch_lines)
109 GstElement *pipeline;
112 GstElementFactory *efac;
114 efac = gst_element_factory_find ("identity");
115 fail_unless (efac != NULL);
117 GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE (efac)));
118 fail_unless (efac != NULL);
119 type = gst_element_factory_get_element_type (efac);
120 fail_unless (type != 0);
121 g_object_unref (efac);
122 fail_unless (gst_element_register (NULL, "1dentity", GST_RANK_NONE, type));
124 for (s = test_lines; *s != NULL; s++) {
125 pipeline = setup_pipeline (*s);
126 gst_object_unref (pipeline);
132 #define PIPELINE1 "fakesrc"
133 #define PIPELINE2 "fakesrc name=donald num-buffers= 27 silent =TruE sizetype = 3 data= Subbuffer\\ data"
134 #define PIPELINE3 "fakesrc identity silent=true fakesink silent=true"
135 #define PIPELINE4 "fakesrc num-buffers=4 .src ! identity silent=true !.sink identity silent=true .src ! .sink fakesink silent=true"
136 #define PIPELINE5 "fakesrc num-buffers=4 name=src identity silent=true name=id1 identity silent=true name = id2 fakesink silent=true name =sink src. ! id1. id1.! id2.sink id2.src!sink.sink"
137 #define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( bin. ( ! queue ! identity silent=true !( queue ! fakesink silent=true )) ))"
138 #define PIPELINE7 "fakesrc num-buffers=4 ! tee name=tee .src%d! queue ! fakesink silent=true tee.src%d ! queue ! fakesink silent=true queue name =\"foo\" ! fakesink silent=true tee.src%d ! foo."
139 /* aggregator is borked
140 * #define PIPELINE8 "fakesrc num-buffers=4 ! tee name=tee1 .src0,src1 ! .sink0, sink1 aggregator ! fakesink silent=true"
142 #define PIPELINE8 "fakesrc num-buffers=4 ! fakesink silent=true"
143 #define PIPELINE9 "fakesrc num-buffers=4 ! test. fakesink silent=true name=test"
144 #define PIPELINE10 "( fakesrc num-buffers=\"4\" ! ) identity silent=true ! fakesink silent=true"
145 #define PIPELINE11 "fakesink silent=true name = sink identity silent=true name=id ( fakesrc num-buffers=\"4\" ! id. ) id. ! sink."
146 #define PIPELINE12 "file:///tmp/test.file ! fakesink silent=true"
147 #define PIPELINE13 "fakesrc ! file:///tmp/test.file"
148 #define PIPELINE14 "capsfilter caps=application/x-rtp,sprop-parameter-sets=(string)\"x\\,x\""
149 #define PIPELINE15 "capsfilter caps=application/x-rtp,sprop-parameter-sets=(string)\"x\\\"x\\,x\""
151 GST_START_TEST (test_launch_lines2)
160 * - specifying an element works :)
161 * - if only 1 element is requested, no bin is returned, but the element
163 cur = setup_pipeline (PIPELINE1);
164 fail_unless (G_OBJECT_TYPE (cur) == g_type_from_name ("GstFakeSrc"),
165 "parse_launch did not produce a fakesrc");
166 gst_object_unref (cur);
171 * - string, int, boolean and enums can be properly set
172 * - first test of escaping strings
174 cur = setup_pipeline (PIPELINE2);
175 g_object_get (G_OBJECT (cur), "name", &s, "num-buffers", &i,
177 fail_if (s == NULL, "name was NULL");
178 fail_unless (strcmp (s, "donald") == 0, "fakesrc name was not 'donald'");
179 fail_unless (i == 27, "num-buffers was not 27");
180 fail_unless (b == TRUE, "silent was not TRUE");
183 g_object_get (G_OBJECT (cur), "sizetype", &i, NULL);
184 fail_unless (i == 3, "sizetype != 3");
186 g_object_get (G_OBJECT (cur), "data", &i, NULL);
187 fail_unless (i == 2, "data != 2");
188 gst_object_unref (cur);
192 * - specifying multiple elements without links works
193 * - if multiple toplevel elements exist, a pipeline is returned
195 cur = setup_pipeline (PIPELINE3);
196 fail_unless (GST_BIN_NUMCHILDREN (cur) == 3,
197 "Pipeline does not contain 3 children");
198 gst_object_unref (cur);
202 * - test default link "!"
203 * - test if specifying pads on links works
205 cur = setup_pipeline (PIPELINE4);
206 check_pipeline_runs (cur);
207 gst_object_unref (cur);
211 * - test if appending the links works, too
212 * - check if the pipeline constructed works the same as the one before (how?)
214 cur = setup_pipeline (PIPELINE5);
215 check_pipeline_runs (cur);
216 gst_object_unref (cur);
220 * - test various types of bins
221 * - test if linking across bins works
222 * - test if escaping strings works
224 cur = setup_pipeline (PIPELINE6);
225 fail_unless (GST_IS_PIPELINE (cur), "Parse did not produce a pipeline");
226 g_object_get (G_OBJECT (cur), "name", &s, NULL);
227 fail_if (s == NULL, "name was NULL");
228 fail_unless (strcmp (s, "john") == 0, "Name was not 'john'");
230 check_pipeline_runs (cur);
231 gst_object_unref (cur);
235 * - test request pads
237 cur = setup_pipeline (PIPELINE7);
238 check_pipeline_runs (cur);
239 gst_object_unref (cur);
243 * - multiple pads on 1 link
245 cur = setup_pipeline (PIPELINE8);
246 check_pipeline_runs (cur);
247 gst_object_unref (cur);
251 * - failed in grammar.y cvs version 1.17
253 cur = setup_pipeline (PIPELINE9);
254 check_pipeline_runs (cur);
255 gst_object_unref (cur);
259 * - failed in grammar.y cvs version 1.17
261 cur = setup_pipeline (PIPELINE10);
262 check_pipeline_runs (cur);
263 gst_object_unref (cur);
267 * - failed in grammar.y cvs version 1.18
269 cur = setup_pipeline (PIPELINE11);
270 check_pipeline_runs (cur);
271 gst_object_unref (cur);
275 * - URI detection works
277 cur = setup_pipeline (PIPELINE12);
278 gst_object_unref (cur);
281 * - URI sink detection works
283 cur = setup_pipeline (PIPELINE13);
284 gst_object_unref (cur);
286 /* Checks handling of a assignment followed by error inside a bin.
287 * This should warn, but ignore the error and carry on */
288 cur = setup_pipeline ("( filesrc blocksize=4 location=/dev/null @ )");
289 gst_object_unref (cur);
292 * Checks if characters inside quotes are not escaped.
294 cur = setup_pipeline (PIPELINE14);
295 gst_object_unref (cur);
298 * Checks if escaped quotes inside quotes are not treated as end string quotes.
299 * This would make the rest of characters to be escaped incorrectly.
301 cur = setup_pipeline (PIPELINE15);
302 gst_object_unref (cur);
307 static const gchar *expected_failures[] = {
308 /* checks: fails because a=b. is not a valid element reference in parse.l */
309 "fakesrc num-buffers=4 name=\"a=b\" a=b. ! fakesink silent=true",
310 /* checks: Error branch for a non-deserialisable property value */
311 "filesrc blocksize=absdff",
312 /* checks: That broken caps which don't parse can't create a pipeline */
313 "fakesrc ! video/raw,format=(antwerp)monkeys ! fakesink silent=true",
314 /* checks: Empty pipeline is invalid */
316 /* checks: Link without sink element failes */
318 /* checks: Link without src element failes */
319 " ! fakesink silent=true",
320 /* checks: Source URI for which no element exists is a failure */
321 "borky://fdaffd ! fakesink silent=true",
322 /* checks: Sink URI for which no element exists is a failure */
323 "fakesrc ! borky://fdaffd",
324 /* checks: Referencing non-existent source element by name can't link */
325 "fakesrc name=src fakesink silent=true name=sink noexiste. ! sink.",
326 /* checks: Referencing non-existent sink element by name can't link */
327 "fakesrc name=src fakesink silent=true name=sink src. ! noexiste.",
328 /* checks: Can't link 2 elements that only have sink pads */
329 "fakesink silent=true ! fakesink silent=true",
330 /* checks multi-chain link without src element fails. */
331 "! identity silent=true ! identity silent=true ! fakesink silent=true",
332 /* Empty bin not allowed */
334 /* bin with non-existent element counts as empty, and not allowed */
335 "bin.( non_existent_element )",
340 GST_START_TEST (expected_to_fail_pipes)
344 for (s = expected_failures; *s != NULL; s++) {
345 expected_fail_pipe (*s);
351 static const gchar *leaking_failures[] = {
352 /* checks: Invalid pipeline syntax fails */
353 "fakesrc ! identity silent=true ! sgsdfagfd @ gfdgfdsgfsgSF",
354 /* checks: Attempting to link to a non-existent pad on an element
355 * created via URI handler should fail */
356 "fakesrc ! .foo file:///dev/null",
357 /* checks: That requesting an element which doesn't exist doesn't work */
358 "error-does-not-exist-src",
362 GST_START_TEST (leaking_fail_pipes)
366 for (s = leaking_failures; *s != NULL; s++) {
367 /* Uncomment if you want to try fixing the leaks */
369 g_print ("Trying pipe: %s\n", *s);
370 expected_fail_pipe (*s);
372 #ifdef HAVE_VALGRIND_H
373 VALGRIND_DO_LEAK_CHECK;
380 /* Helper function to test delayed linking support in parse_launch by creating
381 * a test element based on bin, which contains a fakesrc and a sometimes
382 * pad-template, and trying to link to a fakesink. When the bin transitions
383 * to paused it adds a pad, which should get linked to the fakesink */
385 run_delayed_test (const gchar * pipe_str, const gchar * peer,
386 gboolean expect_link)
388 GstElement *pipe, *src, *sink;
389 GstPad *srcpad, *sinkpad, *peerpad = NULL;
391 pipe = setup_pipeline (pipe_str);
393 src = gst_bin_get_by_name (GST_BIN (pipe), "src");
394 fail_if (src == NULL, "Test source element was not created");
396 sink = gst_bin_get_by_name (GST_BIN (pipe), "sink");
397 fail_if (sink == NULL, "Test sink element was not created");
399 /* The src should not yet have a src pad */
400 srcpad = gst_element_get_static_pad (src, "src");
401 fail_unless (srcpad == NULL, "Source element already has a source pad");
403 /* Set the state to PAUSED and wait until the src at least reaches that
405 fail_if (gst_element_set_state (pipe, GST_STATE_PAUSED) ==
406 GST_STATE_CHANGE_FAILURE);
408 fail_if (gst_element_get_state (src, NULL, NULL, GST_CLOCK_TIME_NONE) ==
409 GST_STATE_CHANGE_FAILURE);
411 /* Now, the source element should have a src pad, and if "peer" was passed,
412 * then the src pad should have gotten linked to the 'sink' pad of that
414 srcpad = gst_element_get_static_pad (src, "src");
415 fail_if (srcpad == NULL, "Source element did not create source pad");
417 peerpad = gst_pad_get_peer (srcpad);
419 if (expect_link == TRUE) {
420 fail_if (peerpad == NULL, "Source element pad did not get linked");
422 fail_if (peerpad != NULL,
423 "Source element pad got linked but should not have");
426 gst_object_unref (peerpad);
429 GstElement *peer_elem = gst_bin_get_by_name (GST_BIN (pipe), peer);
431 fail_if (peer_elem == NULL, "Could not retrieve peer %s", peer);
433 sinkpad = gst_element_get_static_pad (peer_elem, "sink");
434 fail_if (sinkpad == NULL, "Peer element did not have a 'sink' pad");
436 fail_unless (peerpad == sinkpad,
437 "Source src pad got connected to the wrong peer");
438 gst_object_unref (sinkpad);
441 gst_object_unref (srcpad);
443 gst_object_unref (src);
444 gst_object_unref (sink);
446 gst_element_set_state (pipe, GST_STATE_NULL);
447 gst_object_unref (pipe);
450 GST_START_TEST (delayed_link)
452 fail_unless (gst_element_register (NULL, "parsetestelement",
453 GST_RANK_NONE, GST_TYPE_PARSE_TEST_ELEMENT));
455 /* This tests the delayed linking support in parse_launch by creating
456 * a test element based on bin, which contains a fakesrc and a sometimes
457 * pad-template, and trying to link to a fakesink. When the bin transitions
458 * to paused it adds a pad, which should get linked to the fakesink */
460 ("parsetestelement name=src ! fakesink silent=true name=sink", "sink",
463 /* Test, but this time specifying both pad names */
464 run_delayed_test ("parsetestelement name=src .src ! "
465 ".sink fakesink silent=true name=sink", "sink", TRUE);
467 /* Now try with a caps filter, but not testing that
468 * the peerpad == sinkpad, because the peer will actually
470 run_delayed_test ("parsetestelement name=src ! application/x-test-caps ! "
471 "fakesink silent=true name=sink", NULL, TRUE);
473 /* Now try with mutually exclusive caps filters that
474 * will prevent linking, but only once gets around to happening -
475 * ie, the pipeline should create ok but fail to change state */
476 run_delayed_test ("parsetestelement name=src ! application/x-test-caps ! "
477 "identity silent=true ! application/x-other-caps ! "
478 "fakesink silent=true name=sink silent=true", NULL, FALSE);
483 typedef struct _GstParseTestElement
488 } GstParseTestElement;
490 typedef struct _GstParseTestElementClass
493 } GstParseTestElementClass;
495 static GstStaticPadTemplate test_element_pad_template =
496 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC,
497 GST_PAD_SOMETIMES, GST_STATIC_CAPS ("application/x-test-caps"));
498 #define gst_parse_test_element_parent_class parent_class
499 G_DEFINE_TYPE (GstParseTestElement, gst_parse_test_element, GST_TYPE_BIN);
501 static GstStateChangeReturn
502 gst_parse_test_element_change_state (GstElement * element,
503 GstStateChange transition);
506 gst_parse_test_element_class_init (GstParseTestElementClass * klass)
508 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
510 gst_element_class_add_pad_template (gstelement_class,
511 gst_static_pad_template_get (&test_element_pad_template));
513 gst_element_class_set_details_simple (gstelement_class,
514 "Test element for parse launch tests", "Source",
515 "Test element for parse launch tests in core",
516 "GStreamer Devel <gstreamer-devel@lists.sf.net>");
518 gstelement_class->change_state = gst_parse_test_element_change_state;
522 gst_parse_test_element_init (GstParseTestElement * src)
524 /* Create a fakesrc and add it to ourselves */
525 src->fakesrc = gst_element_factory_make ("fakesrc", NULL);
527 gst_bin_add (GST_BIN (src), src->fakesrc);
530 static GstStateChangeReturn
531 gst_parse_test_element_change_state (GstElement * element,
532 GstStateChange transition)
534 GstParseTestElement *src = (GstParseTestElement *) element;
536 if (transition == GST_STATE_CHANGE_READY_TO_PAUSED) {
541 if (src->fakesrc == NULL)
542 return GST_STATE_CHANGE_FAILURE;
544 pad = gst_element_get_static_pad (src->fakesrc, "src");
546 return GST_STATE_CHANGE_FAILURE;
548 ghost = gst_ghost_pad_new ("src", pad);
549 fail_if (ghost == NULL, "Failed to create ghost pad");
550 /* activate and add */
551 gst_pad_set_active (ghost, TRUE);
552 gst_element_add_pad (GST_ELEMENT (src), ghost);
553 gst_object_unref (pad);
556 return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
559 GST_START_TEST (test_missing_elements)
561 GstParseContext *ctx;
566 /* avoid misleading 'no such element' error debug messages when using cvs */
567 if (!g_getenv ("GST_DEBUG"))
568 gst_debug_set_default_threshold (GST_LEVEL_NONE);
570 /* one missing element */
571 ctx = gst_parse_context_new ();
572 element = gst_parse_launch_full ("fakesrc ! coffeesink", ctx,
573 GST_PARSE_FLAG_FATAL_ERRORS, &err);
574 fail_unless (err != NULL, "expected error");
575 fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT);
576 fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS");
577 arr = gst_parse_context_get_missing_elements (ctx);
578 fail_unless (arr != NULL, "expected missing elements");
579 fail_unless_equals_string (arr[0], "coffeesink");
580 fail_unless (arr[1] == NULL);
582 gst_parse_context_free (ctx);
586 /* multiple missing elements */
587 ctx = gst_parse_context_new ();
588 element = gst_parse_launch_full ("fakesrc ! bogusenc ! identity ! goomux ! "
589 "fakesink", ctx, GST_PARSE_FLAG_FATAL_ERRORS, &err);
590 fail_unless (err != NULL, "expected error");
591 fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT);
592 fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS");
593 arr = gst_parse_context_get_missing_elements (ctx);
594 fail_unless (arr != NULL, "expected missing elements");
595 fail_unless_equals_string (arr[0], "bogusenc");
596 fail_unless_equals_string (arr[1], "goomux");
597 fail_unless (arr[2] == NULL);
599 gst_parse_context_free (ctx);
603 /* multiple missing elements, different link pattern */
604 ctx = gst_parse_context_new ();
605 element = gst_parse_launch_full ("fakesrc ! bogusenc ! mux.sink "
606 "blahsrc ! goomux name=mux ! fakesink fakesrc ! goosink", ctx,
607 GST_PARSE_FLAG_FATAL_ERRORS, &err);
608 fail_unless (err != NULL, "expected error");
609 fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT);
610 fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS");
611 arr = gst_parse_context_get_missing_elements (ctx);
612 fail_unless (arr != NULL, "expected missing elements");
613 fail_unless_equals_string (arr[0], "bogusenc");
614 fail_unless_equals_string (arr[1], "blahsrc");
615 fail_unless_equals_string (arr[2], "goomux");
616 fail_unless_equals_string (arr[3], "goosink");
617 fail_unless (arr[4] == NULL);
619 gst_parse_context_free (ctx);
626 GST_START_TEST (test_flags)
631 /* avoid misleading 'no such element' error debug messages when using cvs */
632 if (!g_getenv ("GST_DEBUG"))
633 gst_debug_set_default_threshold (GST_LEVEL_NONE);
635 /* default behaviour is to return any already constructed bins/elements */
636 element = gst_parse_launch_full ("fakesrc ! coffeesink", NULL, 0, &err);
637 fail_unless (err != NULL, "expected error");
638 fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT);
639 fail_unless (element != NULL, "expected partial pipeline/element");
642 gst_object_unref (element);
644 /* test GST_PARSE_FLAG_FATAL_ERRORS */
645 element = gst_parse_launch_full ("fakesrc ! coffeesink", NULL,
646 GST_PARSE_FLAG_FATAL_ERRORS, &err);
647 fail_unless (err != NULL, "expected error");
648 fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT);
649 fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS");
656 GST_START_TEST (test_parsing)
658 GstElement *pipeline;
660 /* make sure we don't read beyond the end of the string */
661 pipeline = gst_parse_launch_full ("filesrc location=x\\", NULL, 0, NULL);
662 gst_object_unref (pipeline);
670 Suite *s = suite_create ("Parse Launch syntax");
671 TCase *tc_chain = tcase_create ("parselaunch");
673 /* time out after 20s, not the default 3 */
674 tcase_set_timeout (tc_chain, 20);
676 suite_add_tcase (s, tc_chain);
677 tcase_add_test (tc_chain, test_launch_lines);
678 tcase_add_test (tc_chain, test_launch_lines2);
679 tcase_add_test (tc_chain, expected_to_fail_pipes);
680 tcase_add_test (tc_chain, leaking_fail_pipes);
681 tcase_add_test (tc_chain, delayed_link);
682 tcase_add_test (tc_chain, test_flags);
683 tcase_add_test (tc_chain, test_missing_elements);
684 tcase_add_test (tc_chain, test_parsing);
688 GST_CHECK_MAIN (parse);