diff --git a/ChangeLog b/ChangeLog index df5705f804..58d8439550 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-15 Jan Schmidt + + * tests/check/Makefile.am: + * tests/check/pipelines/parse-launch.c: (setup_pipeline), + (expected_fail_pipe), (check_pipeline_runs), (GST_START_TEST), + (parse_suite), (main): + Add testsuite for parse launch syntax + 2006-02-14 Tim-Philipp Müller * plugins/elements/gsttypefindelement.c: diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index f7b21ebee5..4ef3f839fb 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -30,7 +30,7 @@ clean-local: clean-local-check if GST_DISABLE_PARSE PARSE_CHECKS = else -PARSE_CHECKS = pipelines/simple-launch-lines pipelines/cleanup +PARSE_CHECKS = pipelines/simple-launch-lines pipelines/cleanup pipelines/parse-launch endif check_PROGRAMS = \ diff --git a/tests/check/pipelines/parse-launch.c b/tests/check/pipelines/parse-launch.c new file mode 100644 index 0000000000..2bf8431b05 --- /dev/null +++ b/tests/check/pipelines/parse-launch.c @@ -0,0 +1,282 @@ +/* GStreamer + * Copyright (C) <2005> Thomas Vander Stichele + * + * cleanup.c: Unit test for cleanup of pipelines + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include + +static GstElement * +setup_pipeline (const gchar * pipe_descr) +{ + GstElement *pipeline; + GError *error = NULL; + + pipeline = gst_parse_launch (pipe_descr, &error); + if (error != NULL) { + fail_if (error != NULL, "Error parsing pipeline %s: %s", pipe_descr, + error->message); + g_error_free (error); + } + fail_unless (pipeline != NULL, "Failed to create pipeline %s", pipe_descr); + return pipeline; +} + +static void +expected_fail_pipe (const gchar * pipe_descr) +{ + GstElement *pipeline; + GError *error = NULL; + +#ifndef GST_DISABLE_GST_DEBUG + gst_debug_set_default_threshold (GST_LEVEL_NONE); +#endif + + pipeline = gst_parse_launch (pipe_descr, &error); + fail_unless (error != NULL, "Expected failure pipeline %s: succeeded!"); + g_error_free (error); +} + +static void +check_pipeline_runs (GstElement * p) +{ + GstStateChangeReturn ret; + + /* Check that the pipeline changes state to PAUSED and back to NULL */ + ret = gst_element_set_state (p, GST_STATE_PAUSED); + if (ret == GST_STATE_CHANGE_ASYNC) + ret = gst_element_get_state (p, NULL, NULL, GST_CLOCK_TIME_NONE); + fail_unless (ret != GST_STATE_CHANGE_FAILURE, + "Could not set pipeline to paused"); + + ret = gst_element_set_state (p, GST_STATE_NULL); + if (ret == GST_STATE_CHANGE_ASYNC) + ret = gst_element_get_state (p, NULL, NULL, GST_CLOCK_TIME_NONE); + fail_unless (ret != GST_STATE_CHANGE_FAILURE, + "Could not set pipeline to null"); +} + +static const gchar *test_lines[] = { + "filesrc location=music.mp3 ! identity ! fakesink", + "filesrc location=music.ogg ! tee ! identity ! identity ! fakesink", + "filesrc location=http://domain.com/music.mp3 ! identity ! fakesink", + "filesrc location=movie.avi ! tee name=demuxer ! ( queue ! identity ! fakesink ) ( demuxer. ! queue ! identity ! fakesink )", + "fakesrc ! video/x-raw-yuv ! fakesink", + "fakesrc ! video/raw, format=(fourcc)YUY2; video/raw, format=(fourcc)YV12 ! fakesink", + "fakesrc ! audio/x-raw-int, width=[16, 32], depth={16, 24, 32}, signed=TRUE ! fakesink", + NULL +}; + +GST_START_TEST (test_launch_lines) +{ + GstElement *pipeline; + const gchar **s; + + for (s = test_lines; *s != NULL; s++) { + pipeline = setup_pipeline (*s); + gst_object_unref (pipeline); + } +} + +GST_END_TEST; + +#define PIPELINE1 "fakesrc" +#define PIPELINE2 "fakesrc name=donald num-buffers= 27 silent =TruE sizetype = 3 data= Subbuffer\\ data" +#define PIPELINE3 "fakesrc identity fakesink" +#define PIPELINE4 "fakesrc num-buffers=4 .src ! identity !.sink identity .src ! .sink fakesink" +#define PIPELINE5 "fakesrc num-buffers=4 name=src identity name=id1 identity name = id2 fakesink name =sink src. ! id1. id1.! id2.sink id2.src!sink.sink" +#define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( bin. ( ! queue ! identity !( queue ! fakesink )) ))" +#define PIPELINE7 "fakesrc num-buffers=4 ! tee name=tee .src%d! queue ! fakesink tee.src%d ! queue ! fakesink queue name =\"foo\" ! fakesink tee.src%d ! foo." +/* aggregator is borked + * #define PIPELINE8 "fakesrc num-buffers=4 ! tee name=tee1 .src0,src1 ! .sink0, sink1 aggregator ! fakesink" + * */ +#define PIPELINE8 "fakesrc num-buffers=4 ! fakesink" +#define PIPELINE9 "fakesrc num-buffers=4 ! test. fakesink name=test" +#define PIPELINE10 "( fakesrc num-buffers=\"4\" ! ) identity ! fakesink" +#define PIPELINE11 "fakesink name = sink identity name=id ( fakesrc num-buffers=\"4\" ! id. ) id. ! sink." +#define PIPELINE12 "fakesrc num-buffers=4 name=\"a=b\" a=b. ! fakesink" +#define PIPELINE13 "file:///tmp/test.file ! fakesink" + +GST_START_TEST (test_launch_lines2) +{ + GstElement *cur; + gint i; + gboolean b; + gchar *s = NULL; + + /** + * checks: + * - specifying an element works :) + * - if only 1 element is requested, no bin is returned, but the element + */ + cur = setup_pipeline (PIPELINE1); + fail_unless (G_OBJECT_TYPE (cur) == g_type_from_name ("GstFakeSrc"), + "parse_launch did not produce a fakesrc"); + gst_object_unref (cur); + + /** + * checks: + * - properties works + * - string, int, boolean and enums can be properly set + * - first test of escaping strings + */ + cur = setup_pipeline (PIPELINE2); + g_object_get (G_OBJECT (cur), "name", &s, "num-buffers", &i, + "silent", &b, NULL); + fail_if (s == NULL, "name was NULL"); + fail_unless (strcmp (s, "donald") == 0, "fakesrc name was not 'donald'"); + fail_unless (i == 27, "num-buffers was not 27"); + fail_unless (b == TRUE, "silent was not TRUE"); + + g_object_get (G_OBJECT (cur), "sizetype", &i, NULL); + fail_unless (i == 3, "sizetype != 3"); + + g_object_get (G_OBJECT (cur), "data", &i, NULL); + fail_unless (i == 2, "data != 2"); + gst_object_unref (cur); + + /** + * checks: + * - specifying multiple elements without links works + * - if multiple toplevel elements exist, a pipeline is returned + */ + cur = setup_pipeline (PIPELINE3); + fail_unless (GST_BIN_NUMCHILDREN (cur) == 3, + "Pipeline does not contain 3 children"); + gst_object_unref (cur); + + /** + * checks: + * - test default link "!" + * - test if specifying pads on links works + */ + cur = setup_pipeline (PIPELINE4); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - test if appending the links works, too + * - check if the pipeline constructed works the same as the one before (how?) + */ + cur = setup_pipeline (PIPELINE5); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - test various types of bins + * - test if linking across bins works + * - test if escaping strings works + */ + cur = setup_pipeline (PIPELINE6); + fail_unless (GST_IS_PIPELINE (cur), "Parse did not produce a pipeline"); + g_object_get (G_OBJECT (cur), "name", &s, NULL); + fail_if (s == NULL, "name was NULL"); + fail_unless (strcmp (s, "john") == 0, "Name was not 'john'"); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - test request pads + */ + cur = setup_pipeline (PIPELINE7); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - multiple pads on 1 link + */ + cur = setup_pipeline (PIPELINE8); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - failed in grammar.y cvs version 1.17 + */ + cur = setup_pipeline (PIPELINE9); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - failed in grammar.y cvs version 1.17 + */ + cur = setup_pipeline (PIPELINE10); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - failed in grammar.y cvs version 1.18 + */ + cur = setup_pipeline (PIPELINE11); + check_pipeline_runs (cur); + gst_object_unref (cur); + + /** + * checks: + * - fails because a=b. is not a valid element reference in parse.l + */ + expected_fail_pipe (PIPELINE12); + + /** + * checks: + * - URI detection works + */ + cur = setup_pipeline (PIPELINE13); + gst_object_unref (cur); +} + +GST_END_TEST; + +Suite * +parse_suite (void) +{ + Suite *s = suite_create ("Parse Launch syntax"); + TCase *tc_chain = tcase_create ("parselaunch"); + + /* time out after 20s, not the default 3 */ + tcase_set_timeout (tc_chain, 20); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_launch_lines); + tcase_add_test (tc_chain, test_launch_lines2); + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = parse_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +}