This commit is contained in:
Akkariin Meiko
2022-03-12 03:16:09 +08:00
Unverified
parent 12b76e0c7a
commit 27c4ec74a1
10075 changed files with 5122287 additions and 1 deletions
@@ -0,0 +1,49 @@
# tests and condition when to skip the test
validate_tests = [
['validate/padmonitor'],
['validate/monitoring'],
['validate/reporting'],
['validate/overrides'],
['validate/scenario'],
['validate/utilities'],
['validate/expression_parser'],
]
test_defines = [
'-UG_DISABLE_ASSERT',
'-UG_DISABLE_CAST_CHECKS',
'-DGST_CHECK_TEST_ENVIRONMENT_BEACON="GST_STATE_IGNORE_ELEMENTS"',
'-DTESTFILE="' + meson.current_source_dir() + '/meson.build"',
'-DGST_USE_UNSTABLE_API',
]
foreach t : validate_tests
fname = '@0@.c'.format(t.get(0))
test_name = t.get(0).underscorify()
if t.length() == 2
skip_test = t.get(1)
else
skip_test = false
endif
if not skip_test
env = environment()
env.set('GST_STATE_IGNORE_ELEMENTS', '')
env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '')
env.set('GST_PLUGIN_PATH_1_0', [meson.global_build_root()] + pluginsdirs)
env.set('GST_REGISTRY', '@0@/@1@.registry'.format(meson.current_build_dir(), test_name))
env.set('GST_PLUGIN_SCANNER_1_0', gst_plugin_scanner_path)
exe = executable(test_name, fname,
'validate/test-utils.c',
c_args : gst_c_args + test_defines,
include_directories : [inc_dirs],
dependencies : [validate_dep, gst_check_dep],
link_with: gstvalidate
)
env.set('GST_REGISTRY',
'@0@/@1@.registry'.format(meson.current_build_dir(), test_name))
test(test_name, exe, env: env)
endif
endforeach
@@ -0,0 +1,51 @@
#include <gst/check/gstcheck.h>
#include <glib/gstdio.h>
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-utils.h>
static int
get_var (const gchar * name, double *value, gpointer udata)
{
*value = (double) GPOINTER_TO_INT (udata);
return 1;
}
GST_START_TEST (test_expression_parser)
{
fail_unless_equals_float (gst_validate_utils_parse_expression ("10 / 2", NULL,
NULL, NULL), 5.0);
fail_unless_equals_float (gst_validate_utils_parse_expression ("10 / 0.5",
NULL, NULL, NULL), 20);
fail_unless_equals_float (gst_validate_utils_parse_expression
("max(100, (10 / 0.1))", NULL, NULL, NULL), 100);
fail_unless_equals_float (gst_validate_utils_parse_expression
("min(10, (duration - 0.1) / 0.1)", get_var, GINT_TO_POINTER (1), NULL),
9);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("registry");
TCase *tc_chain = tcase_create ("registry");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE);
gst_validate_init ();
tcase_add_test (tc_chain, test_expression_parser);
gst_validate_deinit ();
return s;
}
GST_CHECK_MAIN (gst_validate);
@@ -0,0 +1,111 @@
/* GstValidate
* Copyright (C) 2014 Thibault Saunier <thibault.saunier@collabora.com>
*
* 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 <gst/validate/validate.h>
#include <gst/validate/gst-validate-pad-monitor.h>
#include <gst/validate/gst-validate-bin-monitor.h>
#include <gst/check/gstcheck.h>
#include "test-utils.h"
GST_START_TEST (monitors_added)
{
GList *tmp;
GstValidateRunner *runner;
GstValidateMonitor *monitor;
GstElement *pipeline = gst_pipeline_new ("validate-pipeline");
GstElement *src, *sink;
src = gst_element_factory_make ("fakesrc", "source");
sink = gst_element_factory_make ("fakesink", "sink");
runner = gst_validate_runner_new ();
fail_unless (GST_IS_VALIDATE_RUNNER (runner));
monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline),
runner, NULL);
fail_unless (GST_IS_VALIDATE_BIN_MONITOR (monitor));
gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
gst_element_link (src, sink);
/* Check that the elements are properly monitored */
fail_unless_equals_int (g_list_length (src->srcpads), 1);
for (tmp = src->srcpads; tmp; tmp = tmp->next)
fail_unless (GST_IS_VALIDATE_PAD_MONITOR (g_object_get_data ((GObject *)
tmp->data, "validate-monitor")));
fail_unless_equals_int (g_list_length (sink->sinkpads), 1);
for (tmp = sink->sinkpads; tmp; tmp = tmp->next)
fail_unless (GST_IS_VALIDATE_PAD_MONITOR (g_object_get_data ((GObject *)
tmp->data, "validate-monitor")));
/* clean up */
gst_object_unref (pipeline);
gst_object_unref (monitor);
gst_object_unref (runner);
}
GST_END_TEST;
GST_START_TEST (monitors_cleanup)
{
GstElement *src, *sink;
GstValidateMonitor *monitor, *pmonitor1, *pmonitor2;
GstValidateRunner *runner = gst_validate_runner_new ();
GstElement *pipeline = gst_pipeline_new ("validate-pipeline");
src = gst_element_factory_make ("fakesrc", "source");
sink = gst_element_factory_make ("fakesink", "sink");
monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline),
runner, NULL);
gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
gst_element_link (src, sink);
/* Check cleanup */
pmonitor1 =
g_object_get_data ((GObject *) src->srcpads->data, "validate-monitor");
pmonitor2 =
g_object_get_data ((GObject *) sink->sinkpads->data, "validate-monitor");
gst_check_objects_destroyed_on_unref (monitor, pmonitor1, pmonitor2, NULL);
gst_check_objects_destroyed_on_unref (pipeline, src, sink, NULL);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("monitoring");
TCase *tc_chain = tcase_create ("monitoring");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
tcase_add_test (tc_chain, monitors_added);
tcase_add_test (tc_chain, monitors_cleanup);
return s;
}
GST_CHECK_MAIN (gst_validate);
@@ -0,0 +1,115 @@
/* GstValidate
* Copyright (C) 2014 Thibault Saunier <thibault.saunier@collabora.com>
*
* 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 <gst/check/gstcheck.h>
#include <glib/gstdio.h>
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-override-registry.h>
static const gchar *some_overrides =
"change-severity, issue-id=buffer::not-expected-one, new-severity=critical\n"
"change-severity, issue-id=buffer::not-expected-one, new-severity=warning, element-factory-name=queue";
static void
_check_message_level (GstValidateRunner * runner,
gint previous_reports, const gchar * factoryname,
GstValidateReportLevel level, const gchar * message_id)
{
GList *reports;
GstElement *element;
GstValidateMonitor *monitor;
element = gst_element_factory_make (factoryname, NULL);
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE));
monitor =
gst_validate_monitor_factory_create (GST_OBJECT (element), runner, NULL);
GST_VALIDATE_REPORT (monitor, g_quark_from_string (message_id),
"Just some fakery");
reports = gst_validate_runner_get_reports (runner);
fail_unless_equals_int (g_list_length (reports), previous_reports + 1);
fail_unless_equals_int (((GstValidateReport *) g_list_nth_data (reports,
previous_reports))->level, level);
g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref);
gst_object_unref (element);
gst_object_unref (monitor);
}
GST_START_TEST (check_text_overrides)
{
GstValidateIssue *issue;
GstValidateRunner *runner = gst_validate_runner_new ();
gchar *override_filename =
g_strdup_printf ("%s%c%s", g_get_tmp_dir (), G_DIR_SEPARATOR,
"some_overrides");
fail_unless (g_file_set_contents (override_filename,
some_overrides, -1, NULL));
issue =
gst_validate_issue_from_id (g_quark_from_string
("buffer::not-expected-one"));
fail_unless (issue != NULL);
assert_equals_int (issue->default_level, GST_VALIDATE_REPORT_LEVEL_WARNING);
g_setenv ("GST_VALIDATE_OVERRIDE", override_filename, TRUE);
gst_validate_override_registry_preload ();
assert_equals_int (issue->default_level, GST_VALIDATE_REPORT_LEVEL_CRITICAL);
/* Check that with a queue, the level of a
* buffer::not-expected-one is WARNING */
_check_message_level (runner, 0, "queue", GST_VALIDATE_REPORT_LEVEL_WARNING,
"buffer::not-expected-one");
/* Check that with an identity, the level of a
* buffer::not-expected-one is CRITICAL */
_check_message_level (runner, 1, "identity",
GST_VALIDATE_REPORT_LEVEL_CRITICAL, "buffer::not-expected-one");
g_remove (override_filename);
g_free (override_filename);
gst_object_unref (runner);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("registry");
TCase *tc_chain = tcase_create ("registry");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE);
gst_validate_init ();
tcase_add_test (tc_chain, check_text_overrides);
gst_validate_deinit ();
return s;
}
GST_CHECK_MAIN (gst_validate);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,286 @@
/* GstValidate
* Copyright (C) 2014 Mathieu Duponchelle <mathieu.duponchelle@collabora.com>
*
* 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 <gst/validate/validate.h>
#include <gst/check/gstcheck.h>
#include "test-utils.h"
GST_START_TEST (test_report_levels_all)
{
GstValidateRunner *runner;
/* FIXME: for now the only interface to set the reporting level is through an
* environment variable parsed at the time of the runner initialization,
* we can simplify that if the runner exposes API for that at some point
*/
/* Try to set the default reporting level to ALL, the code is supposed to
* be case insensitive */
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "AlL", TRUE));
runner = gst_validate_runner_new ();
fail_unless (gst_validate_runner_get_default_reporting_level (runner) ==
GST_VALIDATE_SHOW_ALL);
g_object_unref (runner);
}
GST_END_TEST;
GST_START_TEST (test_report_levels_2)
{
GstValidateRunner *runner;
/* Try to set the default reporting level to subchain, the code is supposed to
* parse numbers as well */
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "2", TRUE));
runner = gst_validate_runner_new ();
fail_unless (gst_validate_runner_get_default_reporting_level (runner) ==
GST_VALIDATE_SHOW_SYNTHETIC);
g_object_unref (runner);
}
GST_END_TEST;
GST_START_TEST (test_report_levels_complex_parsing)
{
GstValidateRunner *runner;
/* Try to set the reporting level for an object */
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS",
"synthetic,test_object:monitor,other_*:all", TRUE));
runner = gst_validate_runner_new ();
fail_unless (gst_validate_runner_get_reporting_level_for_name (runner,
"test_object") == GST_VALIDATE_SHOW_MONITOR);
fail_unless (gst_validate_runner_get_reporting_level_for_name (runner,
"other_test_object") == GST_VALIDATE_SHOW_ALL);
fail_unless (gst_validate_runner_get_reporting_level_for_name (runner,
"dummy_test_object") == GST_VALIDATE_SHOW_UNKNOWN);
g_object_unref (runner);
}
GST_END_TEST;
GST_START_TEST (test_complex_reporting_details)
{
GstPad *pad;
GstObject *pipeline;
GstElement *element;
GError *error = NULL;
GstValidateMonitor *monitor, *pipeline_monitor;
GstValidateRunner *runner;
/* Now let's try to see if the created monitors actually understand the
* situation they've put themselves into */
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS",
"none,pipeline*:monitor,sofake1:all,sofake*::sink:subchain", TRUE));
runner = gst_validate_runner_new ();
pipeline = (GstObject *)
gst_parse_launch ("fakesrc name=sofake1 ! fakesink name=sofake2", &error);
fail_unless (pipeline != NULL);
pipeline_monitor =
gst_validate_monitor_factory_create (GST_OBJECT (pipeline), runner, NULL);
element = gst_bin_get_by_name (GST_BIN (pipeline), "sofake1");
monitor =
(GstValidateMonitor *) g_object_get_data (G_OBJECT (element),
"validate-monitor");
fail_unless (gst_validate_reporter_get_reporting_level (GST_VALIDATE_REPORTER
(monitor)) == GST_VALIDATE_SHOW_ALL);
pad = gst_element_get_static_pad (element, "src");
monitor =
(GstValidateMonitor *) g_object_get_data (G_OBJECT (pad),
"validate-monitor");
/* The pad should have inherited the reporting level */
fail_unless (gst_validate_reporter_get_reporting_level (GST_VALIDATE_REPORTER
(monitor)) == GST_VALIDATE_SHOW_ALL);
gst_object_unref (pad);
gst_object_unref (element);
element = gst_bin_get_by_name (GST_BIN (pipeline), "sofake2");
monitor =
(GstValidateMonitor *) g_object_get_data (G_OBJECT (element),
"validate-monitor");
/* The element should have inherited its reporting level from the pipeline */
fail_unless (gst_validate_reporter_get_reporting_level (GST_VALIDATE_REPORTER
(monitor)) == GST_VALIDATE_SHOW_MONITOR);
pad = gst_element_get_static_pad (element, "sink");
monitor =
(GstValidateMonitor *) g_object_get_data (G_OBJECT (pad),
"validate-monitor");
/* But its pad should not as it falls in the sofake*::sink pattern */
fail_unless (gst_validate_reporter_get_reporting_level (GST_VALIDATE_REPORTER
(monitor)) == GST_VALIDATE_SHOW_SUBCHAIN);
gst_object_unref (pad);
gst_object_unref (element);
g_object_unref (pipeline_monitor);
gst_object_unref (pipeline);
g_object_unref (runner);
}
GST_END_TEST;
static void
_create_issues (GstValidateRunner * runner)
{
GstPad *srcpad1, *srcpad2, *sinkpad, *funnel_sink1, *funnel_sink2;
GstElement *src1, *src2, *sink, *fakemixer;
GstSegment segment;
src1 = create_and_monitor_element ("fakesrc2", "fakesrc1", runner);
src2 = create_and_monitor_element ("fakesrc2", "fakesrc2", runner);
fakemixer = create_and_monitor_element ("fakemixer", "fakemixer", runner);
sink = create_and_monitor_element ("fakesink", "fakesink", runner);
srcpad1 = gst_element_get_static_pad (src1, "src");
srcpad2 = gst_element_get_static_pad (src2, "src");
funnel_sink1 = gst_element_request_pad_simple (fakemixer, "sink_%u");
funnel_sink2 = gst_element_request_pad_simple (fakemixer, "sink_%u");
sinkpad = gst_element_get_static_pad (sink, "sink");
fail_unless (gst_element_link (fakemixer, sink));
fail_unless (gst_pad_link (srcpad1, funnel_sink1) == GST_PAD_LINK_OK);
fail_unless (gst_pad_link (srcpad2, funnel_sink2) == GST_PAD_LINK_OK);
/* We want to handle the src behaviour ourselves */
fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, TRUE));
fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, TRUE));
/* Setup all needed events */
gst_segment_init (&segment, GST_FORMAT_TIME);
segment.start = 0;
segment.stop = GST_SECOND;
fail_unless (gst_pad_push_event (srcpad1,
gst_event_new_stream_start ("the-stream")));
fail_unless (gst_pad_push_event (srcpad1, gst_event_new_segment (&segment)));
fail_unless (gst_pad_push_event (srcpad2,
gst_event_new_stream_start ("the-stream")));
fail_unless (gst_pad_push_event (srcpad2, gst_event_new_segment (&segment)));
fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_PLAYING),
GST_STATE_CHANGE_SUCCESS);
fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_PLAYING),
GST_STATE_CHANGE_ASYNC);
/* Send an unexpected flush stop */
_gst_check_expecting_log = TRUE;
fail_unless (gst_pad_push_event (srcpad1, gst_event_new_flush_stop (TRUE)));
/* Once again but on the other fakemixer sink */
fail_unless (gst_pad_push_event (srcpad2, gst_event_new_flush_stop (TRUE)));
/* clean up */
fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, FALSE));
fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, FALSE));
fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_NULL),
GST_STATE_CHANGE_SUCCESS);
fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_NULL),
GST_STATE_CHANGE_SUCCESS);
gst_object_unref (srcpad1);
gst_object_unref (srcpad2);
gst_object_unref (sinkpad);
gst_object_unref (funnel_sink1);
gst_object_unref (funnel_sink2);
gst_check_objects_destroyed_on_unref (fakemixer, funnel_sink1, funnel_sink2,
NULL);
gst_check_objects_destroyed_on_unref (src1, srcpad1, NULL);
gst_check_objects_destroyed_on_unref (src2, srcpad2, NULL);
gst_check_objects_destroyed_on_unref (sink, sinkpad, NULL);
}
#define TEST_LEVELS(name, details, num_issues) \
GST_START_TEST (test_global_level_##name) { \
GstValidateRunner *runner; \
fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", details, TRUE)); \
runner = gst_validate_runner_new (); \
_create_issues (runner); \
fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), num_issues); \
g_object_unref (runner); \
} GST_END_TEST
TEST_LEVELS (none, "none", 0);
TEST_LEVELS (synthetic, "synthetic", 1);
TEST_LEVELS (monitor, "monitor", 6);
TEST_LEVELS (all, "all", 8);
TEST_LEVELS (none_fakesink_synthetic, "none,fakesrc1:synthetic", 1);
/* 5 issues because all pads will report their own issues separately, except
* for the sink which will not report an issue */
TEST_LEVELS (monitor_sink_none, "monitor,sink:none", 5);
/* 3 issues because both fake sources will have subsequent subchains of
* issues, and the sink will report its issue separately */
TEST_LEVELS (subchain_sink_monitor, "subchain,sink:monitor", 3);
/* 4 issues because the fakemixer sink issues will be concatenated with the
* fakesrc issues, the fakemixer src will report its issue separately, and the
* sink will not find a report immediately upstream */
TEST_LEVELS
(synthetic_fakesrc1_subchain_fakesrc2_subchain_fakemixer_src_monitor,
"synthetic,fakesrc1:subchain,fakesrc2:subchain,fakemixer*::src*:monitor",
4);
/* 2 issues repeated on the fakesink's sink */
TEST_LEVELS (none_fakesink_all, "none,fakesink*:all", 2);
TEST_LEVELS (issue_type, "event::flush-stop-unexpected:none", 0);
#undef TEST_LEVELS
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("reporting");
TCase *tc_chain = tcase_create ("reporting");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
fake_elements_register ();
tcase_add_test (tc_chain, test_report_levels_all);
tcase_add_test (tc_chain, test_report_levels_2);
tcase_add_test (tc_chain, test_report_levels_complex_parsing);
tcase_add_test (tc_chain, test_complex_reporting_details);
tcase_add_test (tc_chain, test_global_level_none);
tcase_add_test (tc_chain, test_global_level_synthetic);
tcase_add_test (tc_chain, test_global_level_monitor);
tcase_add_test (tc_chain, test_global_level_all);
tcase_add_test (tc_chain, test_global_level_none_fakesink_synthetic);
tcase_add_test (tc_chain, test_global_level_monitor_sink_none);
tcase_add_test (tc_chain, test_global_level_subchain_sink_monitor);
tcase_add_test (tc_chain,
test_global_level_synthetic_fakesrc1_subchain_fakesrc2_subchain_fakemixer_src_monitor);
tcase_add_test (tc_chain, test_global_level_none_fakesink_all);
tcase_add_test (tc_chain, test_global_level_issue_type);
return s;
}
GST_CHECK_MAIN (gst_validate);
@@ -0,0 +1,64 @@
#include <gst/check/gstcheck.h>
#include <glib/gstdio.h>
#include <gst/validate/validate.h>
GST_START_TEST (test_expression_parser)
{
GstClockTime start;
GstValidateRunner *runner = gst_validate_runner_new ();
GstValidateActionType *set_vars = gst_validate_get_action_type ("set-vars");
GstValidateActionType *seek_type = gst_validate_get_action_type ("seek");
GstValidateScenario *scenario =
g_object_new (GST_TYPE_VALIDATE_SCENARIO, "validate-runner",
runner, NULL);
GstValidateAction *action;
GstStructure *st;
fail_unless (seek_type);
st = gst_structure_from_string
("set-vars, a=(string)\"50\", b=(string)\"70\", default_flags=flush",
NULL);
action = gst_validate_action_new (scenario, set_vars, st, FALSE);
fail_unless_equals_int (gst_validate_execute_action (set_vars, action),
GST_VALIDATE_EXECUTE_ACTION_OK);
gst_structure_free (st);
gst_validate_action_unref (action);
st = gst_structure_from_string
("seek, start=\"min($(a), $(b))\", flags=\"$(default_flags)\"", NULL);
action = gst_validate_action_new (scenario, seek_type, st, FALSE);
gst_structure_free (st);
fail_unless (action);
fail_unless (seek_type->prepare (action));
fail_unless (gst_validate_action_get_clocktime (scenario, action, "start",
&start));
fail_unless_equals_uint64 (start, 50 * GST_SECOND);
gst_validate_action_unref (action);
gst_object_unref (runner);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("registry");
TCase *tc_chain = tcase_create ("registry");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE);
gst_validate_init ();
tcase_add_test (tc_chain, test_expression_parser);
gst_validate_deinit ();
return s;
}
GST_CHECK_MAIN (gst_validate);
@@ -0,0 +1,521 @@
/* GstValidate
* Copyright (C) 2014 Thibault Saunier <thibault.saunier@collabora.com>
*
* 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 "test-utils.h"
typedef struct _DestroyedObjectStruct
{
GObject *object;
gboolean destroyed;
} DestroyedObjectStruct;
static void
weak_notify (DestroyedObjectStruct * destroyed, GObject ** object)
{
destroyed->destroyed = TRUE;
}
void
check_destroyed (gpointer object_to_unref, gpointer first_object, ...)
{
gint i = 0;
GObject *object;
GList *objs = NULL, *tmp;
DestroyedObjectStruct *destroyed = g_slice_new0 (DestroyedObjectStruct);
destroyed->object = G_OBJECT (object_to_unref);
g_object_weak_ref (G_OBJECT (object_to_unref), (GWeakNotify) weak_notify,
destroyed);
objs = g_list_prepend (objs, destroyed);
if (first_object) {
va_list varargs;
object = G_OBJECT (first_object);
va_start (varargs, first_object);
while (object) {
destroyed = g_slice_new0 (DestroyedObjectStruct);
destroyed->object = object;
g_object_weak_ref (object, (GWeakNotify) weak_notify, destroyed);
objs = g_list_append (objs, destroyed);
object = va_arg (varargs, GObject *);
}
va_end (varargs);
}
gst_object_unref (object_to_unref);
for (tmp = objs; tmp; tmp = tmp->next) {
fail_unless (((DestroyedObjectStruct *) tmp->data)->destroyed == TRUE,
"%p is not destroyed (object nb %i)",
((DestroyedObjectStruct *) tmp->data)->object, i);
g_slice_free (DestroyedObjectStruct, tmp->data);
i++;
}
g_list_free (objs);
}
void
clean_bus (GstElement * element)
{
GstBus *bus;
bus = gst_element_get_bus (element);
gst_bus_set_flushing (bus, TRUE);
gst_object_unref (bus);
}
GstValidatePadMonitor *
get_pad_monitor (GstPad * pad)
{
return g_object_get_data ((GObject *) pad, "validate-monitor");
}
static GstStaticPadTemplate fake_demuxer_src_template =
GST_STATIC_PAD_TEMPLATE ("src%u",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("something")
);
static GstStaticPadTemplate fake_demuxer_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("something")
);
static GstFlowReturn
_demuxer_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
{
gst_buffer_unref (buffer);
return FAKE_DEMUXER (self)->return_value;
}
static void
fake_demuxer_init (FakeDemuxer * self, gpointer * g_class)
{
GstPad *pad;
GstElement *element = GST_ELEMENT (self);
GstPadTemplate *pad_template;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src%u");
pad = gst_pad_new_from_template (pad_template, "src0");
gst_element_add_pad (element, pad);
pad = gst_pad_new_from_template (pad_template, "src1");
gst_element_add_pad (element, pad);
pad = gst_pad_new_from_template (pad_template, "src2");
gst_element_add_pad (element, pad);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
pad = gst_pad_new_from_template (pad_template, "sink");
gst_element_add_pad (element, pad);
self->return_value = GST_FLOW_OK;
gst_pad_set_chain_function (pad, _demuxer_chain);
}
static void
fake_demuxer_class_init (FakeDemuxerClass * self_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_demuxer_src_template);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_demuxer_sink_template);
gst_element_class_set_static_metadata (gstelement_class, "Fake Demuxer",
"Demuxer", "Some demuxer", "Thibault Saunier");
}
GType
fake_demuxer_get_type (void)
{
static gsize type = 0;
if (g_once_init_enter (&type)) {
GType _type;
static const GTypeInfo info = {
sizeof (FakeDemuxerClass),
NULL,
NULL,
(GClassInitFunc) fake_demuxer_class_init,
NULL,
NULL,
sizeof (FakeDemuxer),
0,
(GInstanceInitFunc) fake_demuxer_init,
};
_type = g_type_register_static (GST_TYPE_ELEMENT, "FakeDemuxer", &info, 0);
g_once_init_leave (&type, _type);
}
return type;
}
GstElement *
fake_demuxer_new (void)
{
return GST_ELEMENT (g_object_new (FAKE_DEMUXER_TYPE, NULL));
}
GstElement *
create_and_monitor_element (const gchar * factoryname, const gchar * name,
GstValidateRunner * runner)
{
GstElement *element;
GstValidateMonitor *monitor;
element = gst_element_factory_make (factoryname, name);
if (runner) {
monitor =
gst_validate_monitor_factory_create (GST_OBJECT (element), runner,
NULL);
fail_unless (GST_IS_VALIDATE_ELEMENT_MONITOR (monitor));
}
return element;
}
void
free_element_monitor (GstElement * element)
{
GstValidateMonitor *monitor;
monitor =
(GstValidateMonitor *) g_object_get_data (G_OBJECT (element),
"validate-monitor");
g_object_unref (G_OBJECT (monitor));
}
/******************************************
* Fake decoder *
******************************************/
static GstStaticPadTemplate fake_decoder_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("video/x-raw")
);
static GstStaticPadTemplate fake_decoder_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw")
);
static GstFlowReturn
_decoder_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
{
gst_buffer_unref (buffer);
return FAKE_DECODER (self)->return_value;
}
static void
fake_decoder_init (FakeDecoder * self, gpointer * g_class)
{
GstPad *pad;
GstElement *element = GST_ELEMENT (self);
GstPadTemplate *pad_template;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
pad = gst_pad_new_from_template (pad_template, "src");
gst_element_add_pad (element, pad);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
pad = gst_pad_new_from_template (pad_template, "sink");
gst_element_add_pad (element, pad);
self->return_value = GST_FLOW_OK;
gst_pad_set_chain_function (pad, _decoder_chain);
}
static void
fake_decoder_class_init (FakeDecoderClass * self_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_decoder_src_template);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_decoder_sink_template);
gst_element_class_set_static_metadata (gstelement_class, "Fake Decoder",
"Decoder", "Some decoder", "Thibault Saunier");
}
GType
fake_decoder_get_type (void)
{
static gsize type = 0;
if (g_once_init_enter (&type)) {
GType _type;
static const GTypeInfo info = {
sizeof (FakeDecoderClass),
NULL,
NULL,
(GClassInitFunc) fake_decoder_class_init,
NULL,
NULL,
sizeof (FakeDecoder),
0,
(GInstanceInitFunc) fake_decoder_init,
};
_type = g_type_register_static (GST_TYPE_ELEMENT, "FakeDecoder", &info, 0);
g_once_init_leave (&type, _type);
}
return type;
}
GstElement *
fake_decoder_new (void)
{
return GST_ELEMENT (g_object_new (FAKE_DECODER_TYPE, NULL));
}
/******************************************
* Fake mixer *
******************************************/
static GstElementClass *fake_mixer_parent_class = NULL;
static GstStaticPadTemplate fake_mixer_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("something")
);
static GstStaticPadTemplate fake_mixer_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink_%u",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS ("something")
);
static gboolean
_mixer_event (GstPad * pad, GstObject * obj, GstEvent * event)
{
FakeMixer *self = FAKE_MIXER (obj);
switch (event->type) {
case GST_EVENT_STREAM_START:
if (g_atomic_int_compare_and_exchange (&self->sent_stream_start, FALSE,
TRUE)) {
return gst_pad_event_default (pad, obj, event);
} else {
gst_event_unref (event);
return TRUE;
}
case GST_EVENT_SEGMENT:
if (g_atomic_int_compare_and_exchange (&self->sent_segment, FALSE, TRUE)) {
return gst_pad_event_default (pad, obj, event);
} else {
gst_event_unref (event);
return TRUE;
}
default:
return gst_pad_event_default (pad, obj, event);
}
}
static GstFlowReturn
_mixer_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
{
gst_buffer_unref (buffer);
return FAKE_MIXER (self)->return_value;
}
static GstPad *
_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
GstPad *pad;
GstPadTemplate *pad_template;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
(element)), "sink_%u");
pad = gst_pad_new_from_template (pad_template, req_name);
gst_pad_set_chain_function (pad, _mixer_chain);
gst_pad_set_event_function (pad, _mixer_event);
gst_element_add_pad (element, pad);
return pad;
}
static void
fake_mixer_init (FakeMixer * self, FakeMixerClass * g_class)
{
GstPad *pad;
GstElement *element = GST_ELEMENT (self);
GstPadTemplate *pad_template;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
pad = gst_pad_new_from_template (pad_template, "src");
gst_element_add_pad (element, pad);
self->return_value = GST_FLOW_OK;
}
static void
fake_mixer_class_init (FakeMixerClass * self_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
fake_mixer_parent_class = g_type_class_peek_parent (self_class);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_mixer_src_template);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_mixer_sink_template);
gst_element_class_set_static_metadata (gstelement_class, "Fake mixer",
"Mixer", "Some mixer", "Thibault Saunier");
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (_request_new_pad);
}
GType
fake_mixer_get_type (void)
{
static gsize type = 0;
if (g_once_init_enter (&type)) {
GType _type;
static const GTypeInfo info = {
sizeof (FakeMixerClass),
NULL,
NULL,
(GClassInitFunc) fake_mixer_class_init,
NULL,
NULL,
sizeof (FakeMixer),
0,
(GInstanceInitFunc) fake_mixer_init,
};
_type = g_type_register_static (GST_TYPE_ELEMENT, "FakeMixer", &info, 0);
g_once_init_leave (&type, _type);
}
return type;
}
GstElement *
fake_mixer_new (void)
{
return GST_ELEMENT (g_object_new (FAKE_MIXER_TYPE, NULL));
}
/******************************************
* Fake Source *
*******************************************/
static GstElementClass *fake_src_parent_class = NULL;
static GstStaticPadTemplate fake_src_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS ("something")
);
static void
fake_src_init (FakeSrc * self, FakeSrcClass * g_class)
{
GstPad *pad;
GstElement *element = GST_ELEMENT (self);
GstPadTemplate *pad_template;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
pad = gst_pad_new_from_template (pad_template, "src");
gst_element_add_pad (element, pad);
self->return_value = GST_FLOW_OK;
}
static void
fake_src_class_init (FakeSrcClass * self_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
fake_src_parent_class = g_type_class_peek_parent (self_class);
gst_element_class_add_static_pad_template (gstelement_class,
&fake_src_src_template);
gst_element_class_set_static_metadata (gstelement_class, "Fake src", "Source",
"Some src", "Thibault Saunier");
}
GType
fake_src_get_type (void)
{
static gsize type = 0;
if (g_once_init_enter (&type)) {
GType _type;
static const GTypeInfo info = {
sizeof (FakeSrcClass),
NULL,
NULL,
(GClassInitFunc) fake_src_class_init,
NULL,
NULL,
sizeof (FakeSrc),
0,
(GInstanceInitFunc) fake_src_init,
};
_type = g_type_register_static (GST_TYPE_ELEMENT, "FakeSrc", &info, 0);
g_once_init_leave (&type, _type);
}
return type;
}
GstElement *
fake_src_new (void)
{
return GST_ELEMENT (g_object_new (FAKE_SRC_TYPE, NULL));
}
void
fake_elements_register (void)
{
gst_element_register (NULL, "fakemixer", 0, FAKE_MIXER_TYPE);
gst_element_register (NULL, "fakedecoder", 0, FAKE_DECODER_TYPE);
gst_element_register (NULL, "fakedemuxer", 0, FAKE_DEMUXER_TYPE);
gst_element_register (NULL, "fakesrc2", 0, FAKE_SRC_TYPE);
}
@@ -0,0 +1,126 @@
/* GstValidate
* Copyright (C) 2014 Thibault Saunier <thibault.saunier@collabora.com>
*
* 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.
*/
#ifndef _GST_VALIDATE_TEST_UTILS
#define _GST_VALIDATE_TEST_UTILS
#include "test-utils.h"
#include <gst/check/gstcheck.h>
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-pad-monitor.h>
G_BEGIN_DECLS
void check_destroyed (gpointer object_to_unref, gpointer first_object, ...) G_GNUC_NULL_TERMINATED;
GstValidateRunner * setup_runner (GstObject * object);
void clean_bus (GstElement *element);
GstValidatePadMonitor * get_pad_monitor (GstPad *pad);
GstElement * create_and_monitor_element (const gchar *factoryname, const gchar *name, GstValidateRunner *runner);
void free_element_monitor (GstElement *element);
typedef struct {
GstElement parent;
GstFlowReturn return_value;
} FakeDemuxer;
typedef struct {
GstElementClass parent;
} FakeDemuxerClass;
#define FAKE_DEMUXER_TYPE (fake_demuxer_get_type ())
#define FAKE_DEMUXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_DEMUXER_TYPE, FakeDemuxer))
#define FAKE_DEMUXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_DEMUXER_TYPE, FakeDemuxerClass))
#define IS_FAKE_DEMUXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_DEMUXER_TYPE))
#define IS_FAKE_DEMUXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_DEMUXER_TYPE))
#define FAKE_DEMUXER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_DEMUXER_TYPE, FakeDemuxerClass))
GType fake_demuxer_get_type (void);
GstElement * fake_demuxer_new (void);
typedef struct {
GstElement parent;
GstFlowReturn return_value;
} FakeDecoder;
typedef struct {
GstElementClass parent;
} FakeDecoderClass;
#define FAKE_DECODER_TYPE (fake_decoder_get_type ())
#define FAKE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_DECODER_TYPE, FakeDecoder))
#define FAKE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_DECODER_TYPE, FakeDecoderClass))
#define IS_FAKE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_DECODER_TYPE))
#define IS_FAKE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_DECODER_TYPE))
#define FAKE_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_DECODER_TYPE, FakeDecoderClass))
GType fake_decoder_get_type (void);
GstElement * fake_decoder_new (void);
typedef struct {
GstElement parent;
GstFlowReturn return_value;
/* <private> */
gboolean sent_stream_start;
gboolean sent_segment;
} FakeMixer;
typedef struct {
GstElementClass parent;
} FakeMixerClass;
#define FAKE_MIXER_TYPE (fake_mixer_get_type ())
#define FAKE_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_MIXER_TYPE, FakeMixer))
#define FAKE_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_MIXER_TYPE, FakeMixerClass))
#define IS_FAKE_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_MIXER_TYPE))
#define IS_FAKE_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_MIXER_TYPE))
#define FAKE_MIXER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_MIXER_TYPE, FakeMixerClass))
GType fake_mixer_get_type (void);
GstElement * fake_mixer_new (void);
typedef struct {
GstElement parent;
GstFlowReturn return_value;
} FakeSrc;
typedef struct {
GstElementClass parent;
} FakeSrcClass;
#define FAKE_SRC_TYPE (fake_src_get_type ())
#define FAKE_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_SRC_TYPE, FakeSrc))
#define FAKE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_SRC_TYPE, FakeSrcClass))
#define IS_FAKE_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_SRC_TYPE))
#define IS_FAKE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_SRC_TYPE))
#define FAKE_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_SRC_TYPE, FakeSrcClass))
GType fake_src_get_type (void);
GstElement * fake_src_new (void);
void fake_elements_register (void);
G_END_DECLS
#endif /* _GST_VALIDATE_TEST_UTILS */
@@ -0,0 +1,37 @@
#include <gst/check/gstcheck.h>
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-utils.h>
GST_START_TEST (test_resolve_variables)
{
GstStructure *s1 =
gst_structure_from_string ("vars, a=(string)1, b=(string)2", NULL);
GstStructure *s2 = gst_structure_from_string ("test, n=\"$(a)/$(b)\"", NULL);
gst_validate_structure_resolve_variables (NULL, s2, s1, 0);
fail_unless_equals_string (gst_structure_get_string (s2, "n"), "1/2");
gst_structure_free (s1);
gst_structure_free (s2);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("utilities");
TCase *tc_chain = tcase_create ("utilities");
suite_add_tcase (s, tc_chain);
if (atexit (gst_validate_deinit) != 0) {
GST_ERROR ("failed to set gst_validate_deinit as exit function");
}
gst_validate_init ();
tcase_add_test (tc_chain, test_resolve_variables);
gst_validate_deinit ();
return s;
}
GST_CHECK_MAIN (gst_validate);
@@ -0,0 +1,9 @@
meta,
args = {
"fakesrc num-buffers=1 ! fakesink",
},
expected-issues = {
"expected-issue, issue-id=scenario::not-ended",
}
set-property, target-element-factory-name=capsfilter, property-name=caps, property-value="video/x-raw,framerate=30/1,format=I420"
@@ -0,0 +1,54 @@
meta,
handles-states=true,
args = {
"videotestsrc pattern=blue ! compositor name=c ! video/x-raw,width=100,height=100,framerate=10/1 ! $(videosink) videotestsrc pattern=green ! c.",
}
# Start with the green stream on the top left corner and the blue on in the bottom right
set-timed-value-properties, timestamp=0.0, source-type=GstTriggerControlSource, binding-type=direct-absolute,
c.sink_0::xpos=50,
c.sink_0::ypos=50,
c.sink_0::width=50,
c.sink_0::height=50,
c.sink_1::xpos=0,
c.sink_1::ypos=0,
c.sink_1::width=50,
c.sink_1::height=50
# And invert it after 1 second of playback
set-timed-value-properties, timestamp=1.0, source-type=GstTriggerControlSource, binding-type=direct-absolute,
c.sink_0::xpos=0,
c.sink_0::ypos=0,
c.sink_1::xpos=50,
c.sink_1::ypos=50
play
crank-clock, expected-time=0.0
check-properties,
c.sink_0::xpos=50,
c.sink_0::ypos=50,
c.sink_1::xpos=0,
c.sink_1::ypos=0
crank-clock, repeat=5
check-position, expected-position=0.5
check-properties,
c.sink_0::xpos=50,
c.sink_0::ypos=50,
c.sink_1::xpos=0,
c.sink_1::ypos=0
crank-clock, repeat=5
check-position, expected-position=1.0
check-properties,
c.sink_0::xpos=0,
c.sink_0::ypos=0,
c.sink_1::xpos=50,
c.sink_1::ypos=50
set-properties, c.sink_0::xpos=50, c.sink_0::ypos=50, c.sink_1::xpos=0, c.sink_1::ypos=0
check-properties, c.sink_0::xpos=50, c.sink_0::ypos=50, c.sink_1::xpos=0, c.sink_1::ypos=0
set-properties, c::latency=50.0
check-properties, c::latency=50.0
stop
@@ -0,0 +1,49 @@
meta,
handles-states=true,
args = {
"videotestsrc pattern=ball animation-mode=frames num-buffers=30 ! video/x-raw,framerate=10/1 ! $(videosink) name=sink sync=true",
},
expected-issues = {
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Pipeline position doesn.t match expectations got 0:00:00.100000000 instead of.*",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Pipeline position doesn.t match expectations got 0:00:00.200000000 instead of.*",
],
}
pause;
foreach, n=[0, 2],
actions = {
[seek, start="$(position)+0.1", flags="accurate+flush"],
[check-position, expected-position="expr($(n)*0.01)"], # expected to fail
}
priv_check-action-type-calls, type=seek, n=2
priv_check-action-type-calls, type=check-position, n=2
foreach, n=[0, 6], actions = {
[seek, start="$(position)+0.1", flags="accurate+flush"],
[check-position, expected-position="expr((3 + $(n)) * 0.1)"],
}
priv_check-action-type-calls, type=seek, n=8
priv_check-action-type-calls, type=check-position, n=8
check-position, expected-position=0.8
foreach, n=[9, 11], actions = {
[seek, start="$(position)+0.1", flags="accurate+flush"],
[check-position, expected-position="expr($(n)*0.1)"],
}
priv_check-action-type-calls, type=seek, n=10
# We called it once manually
priv_check-action-type-calls, type=check-position, n=11
check-position, expected-position=1.0
stop
@@ -0,0 +1,24 @@
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
event caps: video/x-raw, format=(string)ABGR64_LE, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
event caps: video/x-raw, format=(string)ABGR64_LE, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
buffer: checksum=c2c3ac5edd6cd9060ffce7e1fc012b390ac135d7, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=c2c3ac5edd6cd9060ffce7e1fc012b390ac135d7, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
buffer: checksum=eb34fe4e12ed160eee179fe802b0a876a8df7489, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=eb34fe4e12ed160eee179fe802b0a876a8df7489, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
buffer: checksum=5ece74f070b26a2d2f81818ea0c788de8afb684c, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=5ece74f070b26a2d2f81818ea0c788de8afb684c, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
@@ -0,0 +1,33 @@
meta,
handles-states=true,
args = {
"videotestsrc pattern=ball name=s ! fakesink",
}
foreach, pattern=<green, blue>,
actions = {
[set-properties, s::pattern="$(pattern)"],
}
priv_check-action-type-calls, type=set-properties, n=2
check-properties, s::pattern="Blue"
foreach, pattern=<
# We can also pass int values (which works for enums)
1, 3, 5, # green
>,
actions = {
[set-properties, s::pattern="$(pattern)"],
}
priv_check-action-type-calls, type=set-properties, n=5
check-properties, s::pattern="Green"
foreach, pattern=<blue, white, black>,
actions = {
[set-properties, s::pattern="$(pattern)"],
}
priv_check-action-type-calls, type=set-properties, n=8
check-properties, s::pattern="100\%\ Black"
stop
@@ -0,0 +1,80 @@
meta,
handles-states=true,
args = {
"videotestsrc pattern=ball animation-mode=frames num-buffers=30 ! video/x-raw,framerate=10/1 ! $(videosink) name=sink sync=true",
},
expected-issues = {
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Pipeline position doesn.t match expectations got 0:00:00.100000000 instead of.*",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Pipeline position doesn.t match expectations got 0:00:00.200000000 instead of.*",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Expected subaction level 4, got 3",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Expected subaction level 4, got 3",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Expected subaction level 5, got 4",
],
[
expected-issue,
level=critical,
issue-id=scenario::execution-error,
details="Expected subaction level 5, got 4",
],
}
pause;
foreach, n=[0, 2],
actions={
[seek, start="$(position)+0.1", flags="accurate+flush"],
[check-position, expected-position="expr($(n)*0.01)"], # Expected failling subaction!
}
priv_check-action-type-calls, type=seek, n=2
priv_check-action-type-calls, type=check-position, n=2
foreach, i=[0, 2],
actions={
[seek, start="$(position)+0.1", flags="accurate+flush"],
[priv_check-subaction-level, level=1],
[foreach, j=[0, 1],
actions={
[priv_check-subaction-level, level=2],
[foreach, k=[0, 1],
actions={
[priv_check-subaction-level, level=4], # Failling... twice
[priv_check-subaction-level, level=3],
[foreach, l=[0, 1],
actions={
[priv_check-subaction-level, level=4],
[priv_check-subaction-level, level=5], # Failling... twice
},
],
},
],
},
],
}
priv_check-action-type-calls, type=seek, n=4
stop
@@ -0,0 +1,31 @@
meta,
handles-states=true,
args = {
"videotestsrc name=src pattern=ball animation-mode=frames num-buffers=30 ! video/x-raw,framerate=10/1 ! $(videosink) name=sink sync=true",
}
pause;
foreach, repeat="max(1, 2)",
actions = {
"seek, start=\"$(position)+0.1\", flags=\"accurate+flush\"",
"check-position, expected-position=\"expr((1+$(repeat))*0.1)\"",
}
priv_check-action-type-calls, type=seek, n=2
priv_check-action-type-calls, type=check-position, n=2
foreach,
repeat=2,
pattern=[0, 10, 5],
actions = {
"set-properties, src::horizontal-speed=\"$(pattern)\"",
"check-properties, src::horizontal-speed=\"$(pattern)\"",
}
check-properties, src::horizontal-speed=5
priv_check-action-type-calls, type=set-properties, n=4
priv_check-action-type-calls, type=check-properties, n=5
priv_check-action-type-calls, type=seek, n=2
priv_check-action-type-calls, type=check-position, n=2
stop
@@ -0,0 +1,15 @@
if launcher.found()
test_name = 'validate/launcher_tests'
env = environment()
env.set('GST_STATE_IGNORE_ELEMENTS', '')
env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '')
env.set('GST_PLUGIN_PATH_1_0', [meson.global_build_root()] + pluginsdirs)
env.set('GST_REGISTRY', '@0@/@1@.registry'.format(meson.current_build_dir(), test_name))
env.set('GST_PLUGIN_SCANNER_1_0', gst_plugin_scanner_path)
test(test_name, launcher, args: ['-o', meson.project_build_root() + '/validate-launcher-output/',
meson.current_source_dir() + '/test_validate.py', '--validate-tools-path',
join_paths(meson.current_build_dir(), '..', '..', 'tools')],
env: env)
endif
@@ -0,0 +1,7 @@
meta,
args = {
"audiotestsrc ! capsfilter caps=\"audio/x-raw,channels=2,channel-mask=(bitmask)0x67\" ! audioconvert ! capsfilter caps=\"audio/x-raw,channels=6,channel-mask=(bitmask)0x32\" name=capsfilter ! fakesink",
},
expected-issues = {
"expected-issue, level=critical, summary=\"a NOT NEGOTIATED message has been posted on the bus.\", details=\".*Caps negotiation failed at pad.*capsfilter:sink.*as it refused caps:.*\"",
}
@@ -0,0 +1,17 @@
meta,
args = {
"videotestsrc ! fakesink sync=true",
},
handles-states=true,
ignore-eos=true
run-command,
argv={
python3, -c, "import os; assert os.environ['ENVVAR_CHECK'] == 'set'",
},
env=[
vars,
ENVVAR_CHECK="set",
]
stop
@@ -0,0 +1,12 @@
meta,
handles-states=true,
args = {
"appsrc name=src ! typefind ! fakesink",
}
# Let push ourself into the pipeline :-)
appsrc-push, file-name="$(test_dir)/$(test_name).validatetest", target-element-name=src
priv_check-action-type-calls, type=appsrc-push, n=1
appsrc-eos, target-element-name=src
pause;
stop
@@ -0,0 +1,15 @@
meta,
handles-states=true,
args = {
"videotestsrc pattern=ball animation-mode=frames num-buffers=30 ! video/x-raw,framerate=10/1 ! $(videosink) name=sink sync=true",
},
configs = {
"$(validateflow), pad=sink:sink, buffers-checksum=true",
}
pause;
seek, start="$(position)+0.1", repeat=10, flags="accurate+flush"
priv_check-action-type-calls, type=seek, n=10
check-position, expected-position=1.0
priv_check-action-type-calls, type=check-position, n=1
stop
@@ -0,0 +1,88 @@
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
event caps: video/x-raw, format=(string)ABGR64_LE, framerate=(fraction)10/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
event caps: video/x-raw, format=(string)ABGR64_LE, framerate=(fraction)10/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
buffer: checksum=c2c3ac5edd6cd9060ffce7e1fc012b390ac135d7, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=c2c3ac5edd6cd9060ffce7e1fc012b390ac135d7, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
buffer: checksum=eb34fe4e12ed160eee179fe802b0a876a8df7489, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=eb34fe4e12ed160eee179fe802b0a876a8df7489, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
buffer: checksum=5ece74f070b26a2d2f81818ea0c788de8afb684c, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=5ece74f070b26a2d2f81818ea0c788de8afb684c, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.300000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.300000000, base=0:00:00.000000000, position=0:00:00.300000000
event segment: format=TIME, start=0:00:00.300000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.300000000, base=0:00:00.000000000, position=0:00:00.300000000
buffer: checksum=ddc4a73eb29e68413708e87409041161f0f5aed1, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=ddc4a73eb29e68413708e87409041161f0f5aed1, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.400000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.400000000, base=0:00:00.000000000, position=0:00:00.400000000
event segment: format=TIME, start=0:00:00.400000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.400000000, base=0:00:00.000000000, position=0:00:00.400000000
buffer: checksum=d6cd6db21d62bbcff2b8dbf959eb6db7bbf94862, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=d6cd6db21d62bbcff2b8dbf959eb6db7bbf94862, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.500000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.500000000, base=0:00:00.000000000, position=0:00:00.500000000
event segment: format=TIME, start=0:00:00.500000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.500000000, base=0:00:00.000000000, position=0:00:00.500000000
buffer: checksum=e6ea9c1f26d0867e6383e0c2bbac708555302599, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=e6ea9c1f26d0867e6383e0c2bbac708555302599, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.600000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.600000000, base=0:00:00.000000000, position=0:00:00.600000000
event segment: format=TIME, start=0:00:00.600000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.600000000, base=0:00:00.000000000, position=0:00:00.600000000
buffer: checksum=bf60199f505343f0477c4e0322e4a0c43222c773, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=bf60199f505343f0477c4e0322e4a0c43222c773, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.700000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.700000000, base=0:00:00.000000000, position=0:00:00.700000000
event segment: format=TIME, start=0:00:00.700000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.700000000, base=0:00:00.000000000, position=0:00:00.700000000
buffer: checksum=fdb66ab2ff08bcf781ec9847e0a88699924d8d9d, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=fdb66ab2ff08bcf781ec9847e0a88699924d8d9d, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.800000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.800000000, base=0:00:00.000000000, position=0:00:00.800000000
event segment: format=TIME, start=0:00:00.800000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.800000000, base=0:00:00.000000000, position=0:00:00.800000000
buffer: checksum=d64e8211923d80c6d63c8eef3c10c46ebcd5f7f2, pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=d64e8211923d80c6d63c8eef3c10c46ebcd5f7f2, pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:00.900000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.900000000, base=0:00:00.000000000, position=0:00:00.900000000
event segment: format=TIME, start=0:00:00.900000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.900000000, base=0:00:00.000000000, position=0:00:00.900000000
buffer: checksum=03a7dbed3959d21121dc658a6c372b3a88a73612, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=03a7dbed3959d21121dc658a6c372b3a88a73612, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
event flush-start: (no structure)
event flush-start: (no structure)
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
event segment: format=TIME, start=0:00:01.000000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:01.000000000, base=0:00:00.000000000, position=0:00:01.000000000
event segment: format=TIME, start=0:00:01.000000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:01.000000000, base=0:00:00.000000000, position=0:00:01.000000000
buffer: checksum=df0a7326f04e5b6620275fc47bd78f33fbbc380b, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
buffer: checksum=df0a7326f04e5b6620275fc47bd78f33fbbc380b, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
@@ -0,0 +1,64 @@
# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python
#
# Copyright (c) 2016,Thibault Saunier <thibault.saunier@osg.samsung.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
"""
The GstValidate default testsuite
"""
import os
from launcher.apps.gstvalidate import GstValidateSimpleTestsGenerator
TEST_MANAGER = "validate"
def get_pipelines(test_manager):
return [("not_negotiated.accept_caps_failure",
"audiotestsrc ! audio/x-raw,channels=2,channel-mask='(bitmask)0x67' "
"! audioconvert ! capsfilter caps=audio/x-raw,channels=6,channel-mask='(bitmask)0x32' "
" name=capsfilter ! fakesink",
{"expected-issues": [
{'returncode': 18},
{'level': 'critical', 'summary': 'a NOT NEGOTIATED message has been posted on the bus.',
'details': r'.*Caps negotiation failed at pad.*capsfilter:sink.*as it refused caps:.*'}]}),
("not_negotiated.caps_query_failure",
"\( \( audiotestsrc \) ! input-selector name=i \) ! capsfilter name=capsfilter caps=video/x-raw ! fakesink",
{"expected-issues": [
{'returncode': 18},
{'level': 'critical', 'summary': 'a NOT NEGOTIATED message has been posted on the bus.',
'details': 'Caps negotiation failed starting from pad \'capsfilter:sink\' as the '
'QUERY_CAPS returned EMPTY caps for the following possible reasons:'}]})]
def setup_tests(test_manager, options):
testsuite_dir = os.path.realpath(os.path.join(os.path.dirname(__file__)))
print("Setting up tests to test GstValidate")
# No restriction about scenarios that are potentially used
valid_scenarios = ["play_15s"]
test_manager.add_scenarios(valid_scenarios)
test_manager.add_generators(test_manager.GstValidatePipelineTestsGenerator
("test_validate", test_manager,
pipelines_descriptions=get_pipelines(test_manager),
valid_scenarios=valid_scenarios))
test_manager.add_generators(
GstValidateSimpleTestsGenerator("simple", test_manager,
os.path.join(testsuite_dir))
)
return True
@@ -0,0 +1,18 @@
pluginsdirs = [ ]
if gst_dep.type_name() == 'pkgconfig'
pbase = dependency('gstreamer-plugins-base-' + apiversion)
pluginsdirs = [gst_dep.get_variable('pluginsdir'),
pbase.get_variable('pluginsdir')]
gst_plugin_scanner_dir = gst_dep.get_variable('pluginscannerdir')
else
gst_plugin_scanner_dir = subproject('gstreamer').get_variable('gst_scanner_dir')
endif
gst_plugin_scanner_path = join_paths(gst_plugin_scanner_dir, 'gst-plugin-scanner')
# FIXME: make check work on windows
if host_machine.system() != 'windows' and gst_check_dep.found()
subdir('check')
endif
subdir('launcher_tests')