Update
This commit is contained in:
@@ -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);
|
||||
+9
@@ -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"
|
||||
+54
@@ -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
|
||||
+24
@@ -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
|
||||
+7
@@ -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:.*\"",
|
||||
}
|
||||
+17
@@ -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
|
||||
+12
@@ -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
|
||||
+88
@@ -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')
|
||||
Reference in New Issue
Block a user