From 8c760b0a0e80cb0a1cc5062f7d19a0569bf05474 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Sat, 24 Oct 2015 09:28:51 +0200 Subject: [PATCH] validate: Turn GstValidateRunner into a GstTracer This way we do not need the LD_PRELOAD hack anymore Add a new libgstvalidateplugin GStreamer plugin, making sure it shares the exact same code as the library (exposing only the wanted symbols). Fix the way we set where to install GstValidate plugins Try to keep backward compatibility even if tracers should never be instantiated after an GstElement has been instantiated. Differential Revision: https://phabricator.freedesktop.org/D459 --- validate/configure.ac | 14 +- validate/gst/Makefile.am | 4 - validate/gst/preload/Makefile.am | 15 -- .../gst/preload/gst-validate-monitor-preload.c | 164 ---------------- validate/gst/validate/Makefile.am | 24 ++- validate/gst/validate/gst-validate-internal.h | 7 +- validate/gst/validate/gst-validate-monitor.c | 6 + validate/gst/validate/gst-validate-runner.c | 218 ++++++++++++++++++++- validate/gst/validate/gst-validate-runner.h | 6 +- validate/gst/validate/validate.c | 6 +- validate/plugins/fault_injection/Makefile.am | 2 +- validate/plugins/gapplication/Makefile.am | 2 +- validate/plugins/gtk/Makefile.am | 2 +- validate/plugins/ssim/Makefile.am | 2 +- validate/tests/check/validate/monitoring.c | 7 +- validate/tests/check/validate/overrides.c | 23 +-- validate/tests/check/validate/padmonitor.c | 163 ++++++++------- validate/tests/check/validate/reporting.c | 174 ++++++++-------- validate/tools/gst-validate-transcoding.c | 2 +- validate/tools/gst-validate.c | 14 +- 20 files changed, 441 insertions(+), 414 deletions(-) delete mode 100644 validate/gst/preload/Makefile.am delete mode 100644 validate/gst/preload/gst-validate-monitor-preload.c diff --git a/validate/configure.ac b/validate/configure.ac index 9acd38d..7bf1c9f 100644 --- a/validate/configure.ac +++ b/validate/configure.ac @@ -214,14 +214,17 @@ AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license]) AC_SUBST(GST_LICENSE) dnl define location of plugin directory -AS_AC_EXPAND(PLUGINDIR, ${libdir}/gstreamer-$GST_API_VERSION/validate) -AC_DEFINE_UNQUOTED(PLUGINDIR, "$PLUGINDIR", +AS_AC_EXPAND(VALIDATEPLUGINDIR, ${libdir}/gstreamer-$GST_API_VERSION/validate) +AC_DEFINE_UNQUOTED(VALIDATEPLUGINDIR, "$VALIDATEPLUGINDIR", [directory where GstValidate plugins are located]) -AC_MSG_NOTICE([Using $PLUGINDIR as the plugin install location for GstValidate]) +AC_MSG_NOTICE([Using $VALIDATEPLUGINDIR as the plugin install location for GstValidate]) dnl plugin directory configure-time variable for use in Makefile.am -plugindir="\$(libdir)/gstreamer-$GST_API_VERSION/validate" -AC_SUBST(plugindir) +validateplugindir="\$(libdir)/gstreamer-$GST_API_VERSION/validate" +AC_SUBST(validateplugindir) + +dnl set location of plugin directory +AG_GST_SET_PLUGINDIR # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above dnl make sure it doesn't complain about unused variables if debugging is disabled @@ -317,7 +320,6 @@ data/Makefile data/scenarios/Makefile gst/Makefile gst/validate/Makefile -gst/preload/Makefile gst/overrides/Makefile plugins/Makefile plugins/fault_injection/Makefile diff --git a/validate/gst/Makefile.am b/validate/gst/Makefile.am index 7e44971..c5e508e 100644 --- a/validate/gst/Makefile.am +++ b/validate/gst/Makefile.am @@ -1,5 +1 @@ SUBDIRS = validate overrides - -if HAVE_LD_PRELOAD -SUBDIRS += preload -endif diff --git a/validate/gst/preload/Makefile.am b/validate/gst/preload/Makefile.am deleted file mode 100644 index 66faee0..0000000 --- a/validate/gst/preload/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -libgstvalidate_preload_@GST_API_VERSION@_la_SOURCES = \ - gst-validate-monitor-preload.c - -libgstvalidate_preload_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS) -libgstvalidate_preload_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \ - $(GST_LT_LDFLAGS) $(top_builddir)/gst/validate/libgstvalidate-1.0.la -libgstvalidate_preload_@GST_API_VERSION@_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \ - $(GST_ALL_LIBS) -libgstvalidate_preload_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate -libgstvalidate_preload_@GST_API_VERSION@include_HEADERS = - -lib_LTLIBRARIES = libgstvalidate_preload-@GST_API_VERSION@.la - -CLEANFILES = diff --git a/validate/gst/preload/gst-validate-monitor-preload.c b/validate/gst/preload/gst-validate-monitor-preload.c deleted file mode 100644 index 370a94e..0000000 --- a/validate/gst/preload/gst-validate-monitor-preload.c +++ /dev/null @@ -1,164 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2013 Collabora Ltd. - * Author: Thiago Sousa Santos - * - * gst-validate-monitor-preload.c - Validate Element monitors preload functions - * - * 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.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include - -#define __USE_GNU -#include - -static GstValidateRunner *runner = NULL; - -static void -exit_report_printer (void) -{ - if (runner) - gst_validate_runner_exit (runner, TRUE); -} - -/* - * Functions that wrap object creation so gst-validate can be used - * to monitor 'standard' applications - */ - -static void -gst_validate_preload_wrap (GstElement * element) -{ - if (runner == NULL) { - gst_validate_init (); - runner = gst_validate_runner_new (); - atexit (exit_report_printer); - } - - /* the reference to the monitor is lost */ - gst_validate_monitor_factory_create (GST_OBJECT_CAST (element), runner, NULL); -} - -GstElement * -gst_element_factory_make (const gchar * element_name, const gchar * name) -{ - static GstElement *(*gst_element_factory_make_real) (const gchar *, - const gchar *) = NULL; - GstElement *element; - - if (!gst_element_factory_make_real) - gst_element_factory_make_real = - dlsym (RTLD_NEXT, "gst_element_factory_make"); - - element = gst_element_factory_make_real (element_name, name); - - if (GST_IS_PIPELINE (element)) { - gst_validate_preload_wrap (element); - } - return element; -} - -GstElement * -gst_pipeline_new (const gchar * name) -{ - static GstElement *(*gst_pipeline_new_real) (const gchar *) = NULL; - GstElement *element; - - if (!gst_pipeline_new_real) - gst_pipeline_new_real = dlsym (RTLD_NEXT, "gst_pipeline_new"); - - element = gst_pipeline_new_real (name); - gst_validate_preload_wrap (element); - return element; -} - -GstElement * -gst_parse_launchv (const gchar ** argv, GError ** error) -{ - static GstElement *(*gst_parse_launchv_real) (const gchar **, GError **) = - NULL; - GstElement *element; - - if (!gst_parse_launchv_real) - gst_parse_launchv_real = dlsym (RTLD_NEXT, "gst_parse_launchv"); - - element = gst_parse_launchv_real (argv, error); - if (GST_IS_PIPELINE (element)) { - gst_validate_preload_wrap (element); - } - return element; -} - -GstElement * -gst_parse_launchv_full (const gchar ** argv, GstParseContext * context, - GstParseFlags flags, GError ** error) -{ - static GstElement *(*gst_parse_launchv_full_real) (const gchar **, - GstParseContext *, GstParseFlags, GError **) = NULL; - GstElement *element; - - if (!gst_parse_launchv_full_real) - gst_parse_launchv_full_real = dlsym (RTLD_NEXT, "gst_parse_launchv_full"); - - element = gst_parse_launchv_full_real (argv, context, flags, error); - if (GST_IS_PIPELINE (element)) { - gst_validate_preload_wrap (element); - } - return element; -} - -GstElement * -gst_parse_launch (const gchar * pipeline_description, GError ** error) -{ - static GstElement *(*gst_parse_launch_real) (const gchar *, GError **) = NULL; - GstElement *element; - - if (!gst_parse_launch_real) - gst_parse_launch_real = dlsym (RTLD_NEXT, "gst_parse_launch"); - - element = gst_parse_launch_real (pipeline_description, error); - if (GST_IS_PIPELINE (element)) { - gst_validate_preload_wrap (element); - } - return element; -} - -GstElement * -gst_parse_launch_full (const gchar * pipeline_description, - GstParseContext * context, GstParseFlags flags, GError ** error) -{ - static GstElement *(*gst_parse_launch_full_real) (const gchar *, - GstParseContext *, GstParseFlags, GError **) = NULL; - GstElement *element; - - if (!gst_parse_launch_full_real) - gst_parse_launch_full_real = dlsym (RTLD_NEXT, "gst_parse_launch_full"); - - element = - gst_parse_launch_full_real (pipeline_description, context, flags, error); - if (GST_IS_PIPELINE (element)) { - gst_validate_preload_wrap (element); - } - return element; -} diff --git a/validate/gst/validate/Makefile.am b/validate/gst/validate/Makefile.am index 84e601c..df29f11 100644 --- a/validate/gst/validate/Makefile.am +++ b/validate/gst/validate/Makefile.am @@ -1,4 +1,4 @@ -libgstvalidate_@GST_API_VERSION@_la_SOURCES = \ +source_c = \ gst-validate-runner.c \ gst-validate-reporter.c \ gst-validate-monitor.c \ @@ -18,7 +18,7 @@ libgstvalidate_@GST_API_VERSION@_la_SOURCES = \ gst-validate-media-info.c \ validate.c -libgstvalidate_@GST_API_VERSION@include_HEADERS = \ +source_h = \ validate.h \ gst-validate-types.h \ gst-validate-bin-monitor.h \ @@ -45,9 +45,13 @@ noinst_HEADERS = \ gst-validate-i18n-lib.h \ gst-validate-internal.h +# GstValidate library lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la +libgstvalidate_@GST_API_VERSION@_la_SOURCES = $(source_c) +libgstvalidate_@GST_API_VERSION@include_HEADERS = $(source_h) libgstvalidate_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\ - $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) + $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) \ + -DGST_USE_UNSTABLE_API libgstvalidate_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \ $(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS) libgstvalidate_@GST_API_VERSION@_la_LIBADD = \ @@ -57,6 +61,20 @@ libgstvalidate_@GST_API_VERSION@_la_LIBADD = \ libgstvalidate_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate +# GstValidate GStreamer plugin +plugin_LTLIBRARIES = libgstvalidateplugin-@GST_API_VERSION@.la +libgstvalidateplugin_@GST_API_VERSION@_la_SOURCES = $(source_c) +libgstvalidateplugin_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\ + $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) \ + -DGST_USE_UNSTABLE_API \ + -D__GST_VALIDATE_PLUGIN +libgstvalidateplugin_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \ + $(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS) +libgstvalidateplugin_@GST_API_VERSION@_la_LIBADD = \ + $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \ + $(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \ + $(GLIB_LIBS) $(LIBM) + CLEANFILES = if HAVE_INTROSPECTION diff --git a/validate/gst/validate/gst-validate-internal.h b/validate/gst/validate/gst-validate-internal.h index adabd21..362c939 100644 --- a/validate/gst/validate/gst-validate-internal.h +++ b/validate/gst/validate/gst-validate-internal.h @@ -24,6 +24,7 @@ #include #include "gst-validate-scenario.h" +#include "gst-validate-monitor.h" GST_DEBUG_CATEGORY_EXTERN (gstvalidate_debug); #define GST_CAT_DEFAULT gstvalidate_debug @@ -43,6 +44,10 @@ void init_scenarios (void); * and this is done by the scenario itself now */ GST_EXPORT gboolean _action_check_and_set_printed (GstValidateAction *action); GST_EXPORT gboolean gst_validate_action_is_subaction (GstValidateAction *action); -void _priv_validate_override_registry_deinit (void); +GST_EXPORT void _priv_validate_override_registry_deinit (void); + +G_GNUC_INTERNAL GstValidateMonitor * gst_validate_get_monitor (GObject *object); +G_GNUC_INTERNAL void gst_validate_init_runner (void); +G_GNUC_INTERNAL void gst_validate_deinit_runner (void); #endif diff --git a/validate/gst/validate/gst-validate-monitor.c b/validate/gst/validate/gst-validate-monitor.c index 03e9c26..ddd115d 100644 --- a/validate/gst/validate/gst-validate-monitor.c +++ b/validate/gst/validate/gst-validate-monitor.c @@ -411,3 +411,9 @@ gst_validate_monitor_set_media_descriptor (GstValidateMonitor * monitor, if (klass->set_media_descriptor) klass->set_media_descriptor (monitor, media_descriptor); } + +GstValidateMonitor * +gst_validate_get_monitor (GObject * object) +{ + return GST_VALIDATE_MONITOR (g_object_get_data (object, "validate-monitor")); +} diff --git a/validate/gst/validate/gst-validate-runner.c b/validate/gst/validate/gst-validate-runner.c index e0af772..90ba38d 100644 --- a/validate/gst/validate/gst-validate-runner.c +++ b/validate/gst/validate/gst-validate-runner.c @@ -1,7 +1,8 @@ /* GStreamer * - * Copyright (C) 2013 Collabora Ltd. + * Copyright (C) 2013-2016 Collabora Ltd. * Author: Thiago Sousa Santos + * Author: Thibault Saunier * * gst-validate-runner.c - Validate Runner class * @@ -28,12 +29,22 @@ # include "config.h" #endif +#include "validate.h" #include "gst-validate-internal.h" #include "gst-validate-report.h" #include "gst-validate-monitor-factory.h" #include "gst-validate-override-registry.h" #include "gst-validate-runner.h" +static gboolean element_created = FALSE; + +/* We create a GstValidateRunner on _init () + * so that we keep backward compatibility when + * the user create a Runner after creating the pipeline + * but the runner was actually already ready to be used. + */ +static GstValidateRunner *first_runner = NULL; + /** * SECTION:gst-validate-runner * @short_description: Class that runs Gst Validate tests for a pipeline @@ -68,6 +79,12 @@ struct _GstValidateRunnerPrivate /* A list of PatternLevel */ GList *report_pattern_levels; + + /* Whether the runner was create with GST_TRACERS=validate or not) */ + gboolean user_created; + + gchar *pipeline_names; + gchar **pipeline_names_strv; }; /* Describes the reporting level to apply to a name pattern */ @@ -92,7 +109,7 @@ typedef struct _PatternLevel } G_STMT_END #define gst_validate_runner_parent_class parent_class -G_DEFINE_TYPE (GstValidateRunner, gst_validate_runner, G_TYPE_OBJECT); +G_DEFINE_TYPE (GstValidateRunner, gst_validate_runner, GST_TYPE_TRACER); /* signals */ enum @@ -103,7 +120,62 @@ enum LAST_SIGNAL }; -static guint _signals[LAST_SIGNAL] = { 0 }; +enum +{ + PROP_0, + PROP_PARAMS, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static guint _signals[LAST_SIGNAL] = { NULL, }; + +static gboolean +gst_validate_runner_should_monitor (GstValidateRunner * self, + GstElement * element) +{ + gint i; + GstValidateMonitor *monitor; + + if (!GST_IS_PIPELINE (element)) { + return FALSE; + } + + if (self->priv->user_created) + return FALSE; + + if (!self->priv->pipeline_names_strv) + return TRUE; + + monitor = gst_validate_get_monitor (G_OBJECT (element)); + + if (monitor) { + GST_ERROR_OBJECT (self, "Pipeline %" GST_PTR_FORMAT " is already" + " monitored by %" GST_PTR_FORMAT " using runner: %" GST_PTR_FORMAT + " NOT monitoring again.", + element, monitor, + gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor))); + } + + for (i = 0; self->priv->pipeline_names_strv[i]; i++) { + if (g_pattern_match_simple (self->priv->pipeline_names_strv[i], + GST_OBJECT_NAME (element))) + return TRUE; + } + + return FALSE; +} + +static void +do_element_new (GstValidateRunner * self, guint64 ts, GstElement * element) +{ + element_created = TRUE; + if (gst_validate_runner_should_monitor (self, element)) { + /* the reference to the monitor is lost */ + gst_validate_monitor_factory_create (GST_OBJECT_CAST (element), self, NULL); + } +} static gboolean _parse_reporting_level (gchar * str, GstValidateReportingDetails * level) @@ -233,21 +305,95 @@ _unref_report_list (gpointer unused, GList * reports, gpointer unused_too) } static void -gst_validate_runner_dispose (GObject * object) +gst_validate_runner_finalize (GObject * object) { GstValidateRunner *runner = GST_VALIDATE_RUNNER_CAST (object); + if (!runner->priv->user_created) + gst_validate_runner_exit (runner, TRUE); + g_list_free_full (runner->priv->reports, (GDestroyNotify) gst_validate_report_unref); + g_list_free_full (runner->priv->report_pattern_levels, (GDestroyNotify) _free_report_pattern_level); g_mutex_clear (&runner->priv->mutex); + g_free (runner->priv->pipeline_names); + g_strfreev (runner->priv->pipeline_names_strv); + g_hash_table_foreach (runner->priv->reports_by_type, (GHFunc) _unref_report_list, NULL); g_hash_table_destroy (runner->priv->reports_by_type); - G_OBJECT_CLASS (parent_class)->dispose (object); + + G_OBJECT_CLASS (parent_class)->finalize (object); + + if (!runner->priv->user_created) + gst_validate_deinit (); +} + +static GObject * +gst_validate_runner_constructor (GType type, guint n_construct_params, + GObjectConstructParam * construct_params) +{ + GObject *runner = G_OBJECT_CLASS (parent_class)->constructor (type, + n_construct_params, construct_params); + + if (!gst_validate_is_initialized ()) { + first_runner = GST_VALIDATE_RUNNER (runner); + gst_validate_init (); + first_runner = NULL; + + return runner; + } + + return runner; +} + + +static void +gst_validate_runner_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstValidateRunner *runner; + + runner = GST_VALIDATE_RUNNER (object); + switch (prop_id) { + case PROP_PARAMS: + { + g_value_set_string (value, runner->priv->pipeline_names); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_validate_runner_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstValidateRunner *runner; + + runner = GST_VALIDATE_RUNNER (object); + switch (prop_id) { + case PROP_PARAMS: + { + g_free (runner->priv->pipeline_names); + g_strfreev (runner->priv->pipeline_names_strv); + + runner->priv->pipeline_names = g_value_dup_string (value); + if (runner->priv->pipeline_names) + runner->priv->pipeline_names_strv = + g_strsplit (runner->priv->pipeline_names, ",", -1); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -257,10 +403,20 @@ gst_validate_runner_class_init (GstValidateRunnerClass * klass) gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = gst_validate_runner_dispose; + gobject_class->finalize = gst_validate_runner_finalize; + + gobject_class->set_property = gst_validate_runner_set_property; + gobject_class->get_property = gst_validate_runner_get_property; + gobject_class->constructor = gst_validate_runner_constructor; g_type_class_add_private (klass, sizeof (GstValidateRunnerPrivate)); + properties[PROP_PARAMS] = + g_param_spec_string ("params", "Params", "Extra configuration parameters", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, PROP_LAST, properties); + _signals[REPORT_ADDED_SIGNAL] = g_signal_new ("report-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, @@ -283,6 +439,9 @@ gst_validate_runner_init (GstValidateRunner * runner) runner->priv->default_level = GST_VALIDATE_SHOW_DEFAULT; _init_report_levels (runner); + + gst_tracing_register_hook (GST_TRACER (runner), "element-new", + G_CALLBACK (do_element_new)); } /** @@ -295,7 +454,22 @@ gst_validate_runner_init (GstValidateRunner * runner) GstValidateRunner * gst_validate_runner_new (void) { - return g_object_new (GST_TYPE_VALIDATE_RUNNER, NULL); + GstValidateRunner *runner; + + if (first_runner) { + runner = first_runner; + first_runner = NULL; + } else if (element_created) { + g_error ("Should never create a GstValidateRunner after a GstElement" + "has been created in the same process."); + + return NULL; + } else { + runner = g_object_new (GST_TYPE_VALIDATE_RUNNER, NULL); + runner->priv->user_created = TRUE; + } + + return runner; } /* @@ -537,3 +711,33 @@ gst_validate_runner_exit (GstValidateRunner * runner, gboolean print_result) return ret; } + +void +gst_validate_init_runner (void) +{ + if (!first_runner) { + first_runner = g_object_new (GST_TYPE_VALIDATE_RUNNER, NULL); + first_runner->priv->user_created = TRUE; + } /* else the first runner has been created through the GST_TRACERS system */ +} + +void +gst_validate_deinit_runner (void) +{ + g_clear_object (&first_runner); +} + +#ifdef __GST_VALIDATE_PLUGIN +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_tracer_register (plugin, "validate", GST_TYPE_VALIDATE_RUNNER)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, validatetracer, + "GStreamer Validate tracers", plugin_init, VERSION, GST_LICENSE, + GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); +#endif /* __GST_VALIDATE_PLUGIN */ diff --git a/validate/gst/validate/gst-validate-runner.h b/validate/gst/validate/gst-validate-runner.h index 3c9b31d..3c6a5c8 100644 --- a/validate/gst/validate/gst-validate-runner.h +++ b/validate/gst/validate/gst-validate-runner.h @@ -25,6 +25,8 @@ #include #include +#include + typedef struct _GstValidateRunner GstValidateRunner; typedef struct _GstValidateRunnerClass GstValidateRunnerClass; @@ -52,7 +54,7 @@ typedef struct _GstValidateRunnerPrivate GstValidateRunnerPrivate; * Class that manages a Validate test run for some pipeline */ struct _GstValidateRunner { - GObject object; + GstTracer object; /* */ GstValidateRunnerPrivate *priv; @@ -65,7 +67,7 @@ struct _GstValidateRunner { * GStreamer Validate Runner object class. */ struct _GstValidateRunnerClass { - GObjectClass parent_class; + GstTracerClass parent_class; }; /* normal GObject stuff */ diff --git a/validate/gst/validate/validate.c b/validate/gst/validate/validate.c index 726c431..0103a19 100644 --- a/validate/gst/validate/validate.c +++ b/validate/gst/validate/validate.c @@ -261,6 +261,7 @@ gst_validate_init (void) validate_initialized = TRUE; gst_validate_init_plugins (); + gst_validate_init_runner (); } void @@ -268,8 +269,9 @@ gst_validate_deinit (void) { g_mutex_lock (&_gst_validate_registry_mutex); _free_plugin_config (core_config); - gst_object_unref (_gst_validate_registry_default); - _gst_validate_registry_default = NULL; + gst_validate_deinit_runner (); + + g_clear_object (&_gst_validate_registry_default); _priv_validate_override_registry_deinit (); core_config = NULL; diff --git a/validate/plugins/fault_injection/Makefile.am b/validate/plugins/fault_injection/Makefile.am index 3a181ff..631ed24 100644 --- a/validate/plugins/fault_injection/Makefile.am +++ b/validate/plugins/fault_injection/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvalidatefaultinjection.la +validateplugin_LTLIBRARIES = libgstvalidatefaultinjection.la libgstvalidatefaultinjection_la_SOURCES = \ socket_interposer.c diff --git a/validate/plugins/gapplication/Makefile.am b/validate/plugins/gapplication/Makefile.am index 20ce6a0..9baf929 100644 --- a/validate/plugins/gapplication/Makefile.am +++ b/validate/plugins/gapplication/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvalidategapplication.la +validateplugin_LTLIBRARIES = libgstvalidategapplication.la libgstvalidategapplication_la_SOURCES = \ gstvalidategapplication.c diff --git a/validate/plugins/gtk/Makefile.am b/validate/plugins/gtk/Makefile.am index f049a27..2d47a61 100644 --- a/validate/plugins/gtk/Makefile.am +++ b/validate/plugins/gtk/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvalidategtk.la +validateplugin_LTLIBRARIES = libgstvalidategtk.la libgstvalidategtk_la_SOURCES = gstvalidategtk.c diff --git a/validate/plugins/ssim/Makefile.am b/validate/plugins/ssim/Makefile.am index 71618ce..55a9681 100644 --- a/validate/plugins/ssim/Makefile.am +++ b/validate/plugins/ssim/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvalidatessim.la +validateplugin_LTLIBRARIES = libgstvalidatessim.la libgstvalidatessim_la_SOURCES = gstvalidatessim.c diff --git a/validate/tests/check/validate/monitoring.c b/validate/tests/check/validate/monitoring.c index 0bc6849..12cf8f4 100644 --- a/validate/tests/check/validate/monitoring.c +++ b/validate/tests/check/validate/monitoring.c @@ -85,8 +85,8 @@ GST_START_TEST (monitors_cleanup) g_object_get_data ((GObject *) src->srcpads->data, "validate-monitor"); pmonitor2 = g_object_get_data ((GObject *) sink->sinkpads->data, "validate-monitor"); - check_destroyed (monitor, pmonitor1, pmonitor2, NULL); - check_destroyed (pipeline, src, sink, NULL); + gst_check_objects_destroyed_on_unref (monitor, pmonitor1, pmonitor2, NULL); + gst_check_objects_destroyed_on_unref (pipeline, src, sink, NULL); } GST_END_TEST; @@ -99,12 +99,9 @@ gst_validate_suite (void) TCase *tc_chain = tcase_create ("monitoring"); suite_add_tcase (s, tc_chain); - gst_validate_init (); - tcase_add_test (tc_chain, monitors_added); tcase_add_test (tc_chain, monitors_cleanup); - gst_validate_deinit (); return s; } diff --git a/validate/tests/check/validate/overrides.c b/validate/tests/check/validate/overrides.c index 9683ddb..d4467d3 100644 --- a/validate/tests/check/validate/overrides.c +++ b/validate/tests/check/validate/overrides.c @@ -27,17 +27,16 @@ static const gchar *some_overrides = "change-severity, issue-id=buffer::not-expected-one, new-severity=warning, element-factory-name=queue"; static void -_check_message_level (const gchar * factoryname, GstValidateReportLevel level, - const gchar * message_id) +_check_message_level (GstValidateRunner * runner, + gint previous_reports, const gchar * factoryname, + GstValidateReportLevel level, const gchar * message_id) { GList *reports; GstElement *element; - GstValidateRunner *runner; GstValidateMonitor *monitor; element = gst_element_factory_make (factoryname, NULL); fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); - runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (element), runner, NULL); @@ -45,8 +44,9 @@ _check_message_level (const gchar * factoryname, GstValidateReportLevel level, "Just some fakery"); reports = gst_validate_runner_get_reports (runner); - fail_unless_equals_int (g_list_length (reports), 1); - fail_unless_equals_int (((GstValidateReport *) reports->data)->level, level); + 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); @@ -56,6 +56,7 @@ _check_message_level (const gchar * factoryname, GstValidateReportLevel level, 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"); @@ -76,13 +77,13 @@ GST_START_TEST (check_text_overrides) /* Check that with a queue, the level of a * buffer::not-expected-one is WARNING */ - _check_message_level ("queue", GST_VALIDATE_REPORT_LEVEL_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 ("identity", GST_VALIDATE_REPORT_LEVEL_CRITICAL, - "buffer::not-expected-one"); + _check_message_level (runner, 1, "identity", + GST_VALIDATE_REPORT_LEVEL_CRITICAL, "buffer::not-expected-one"); g_remove (override_filename); g_free (override_filename); @@ -98,11 +99,11 @@ gst_validate_suite (void) TCase *tc_chain = tcase_create ("registry"); suite_add_tcase (s, tc_chain); + g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE); gst_validate_init (); - tcase_add_test (tc_chain, check_text_overrides); - gst_validate_deinit (); + return s; } diff --git a/validate/tests/check/validate/padmonitor.c b/validate/tests/check/validate/padmonitor.c index 19f12fb..52134dd 100644 --- a/validate/tests/check/validate/padmonitor.c +++ b/validate/tests/check/validate/padmonitor.c @@ -50,7 +50,7 @@ _stop_monitoring_bin (GstBin * bin, GstValidateRunner * runner) gst_object_unref (bin); ASSERT_OBJECT_REFCOUNT (monitor, "monitor", 1); gst_object_unref (monitor); - ASSERT_OBJECT_REFCOUNT (runner, "runner", 1); + ASSERT_OBJECT_REFCOUNT (runner, "runner", 2); gst_object_unref (runner); } @@ -144,9 +144,10 @@ GST_START_TEST (buffer_before_segment) _check_reports_refcount (srcpad, 2); gst_object_unref (srcpad); - check_destroyed (src, srcpad, NULL); - check_destroyed (sink, NULL, NULL); - check_destroyed (runner, NULL, NULL); + gst_check_objects_destroyed_on_unref (src, srcpad, NULL); + gst_check_object_destroyed_on_unref (sink); + ASSERT_OBJECT_REFCOUNT (runner, "runner", 2); + gst_object_unref (runner); } GST_END_TEST; @@ -338,34 +339,26 @@ _test_flow_aggregation (GstFlowReturn flow, GstFlowReturn flow1, gst_object_unref (demuxer); ASSERT_OBJECT_REFCOUNT (pmonitor, "plop", 1); gst_object_unref (pmonitor); -} -GST_START_TEST (flow_aggregation) -{ - /* Check the GstFlowCombiner to find the rules */ - - /* Failling cases: */ - _test_flow_aggregation (GST_FLOW_OK, GST_FLOW_OK, - GST_FLOW_ERROR, GST_FLOW_OK, TRUE); - _test_flow_aggregation (GST_FLOW_EOS, GST_FLOW_EOS, - GST_FLOW_EOS, GST_FLOW_OK, TRUE); - _test_flow_aggregation (GST_FLOW_FLUSHING, GST_FLOW_OK, - GST_FLOW_OK, GST_FLOW_OK, TRUE); - _test_flow_aggregation (GST_FLOW_NOT_NEGOTIATED, GST_FLOW_OK, - GST_FLOW_OK, GST_FLOW_OK, TRUE); - - /* Passing cases: */ - _test_flow_aggregation (GST_FLOW_EOS, GST_FLOW_EOS, - GST_FLOW_EOS, GST_FLOW_EOS, FALSE); - _test_flow_aggregation (GST_FLOW_EOS, GST_FLOW_EOS, - GST_FLOW_OK, GST_FLOW_OK, FALSE); - _test_flow_aggregation (GST_FLOW_OK, GST_FLOW_OK, - GST_FLOW_OK, GST_FLOW_EOS, FALSE); - _test_flow_aggregation (GST_FLOW_NOT_NEGOTIATED, GST_FLOW_OK, - GST_FLOW_OK, GST_FLOW_NOT_NEGOTIATED, FALSE); } -GST_END_TEST; +#define FLOW_TEST(name, flow1, flow2, flow3, demux_flow, fails) \ +GST_START_TEST(flow_aggregation_##name) { \ + _test_flow_aggregation (GST_FLOW_##flow1, GST_FLOW_##flow2, \ + GST_FLOW_##flow3, GST_FLOW_##demux_flow, fails); \ +} GST_END_TEST + +FLOW_TEST (ok_ok_error_ok, OK, OK, ERROR, OK, TRUE); +FLOW_TEST (eos_eos_eos_ok, EOS, EOS, EOS, OK, TRUE); +FLOW_TEST (flushing_ok_ok_ok, FLUSHING, OK, OK, OK, TRUE); +FLOW_TEST (not_neg_ok_ok_ok, NOT_NEGOTIATED, OK, OK, OK, TRUE); +/*[> Passing cases: <]*/ +FLOW_TEST (eos_eos_eos_eos, EOS, EOS, EOS, EOS, FALSE); +FLOW_TEST (eos_eos_ok_ok, EOS, EOS, OK, OK, FALSE); +FLOW_TEST (ok_ok_ok_eos, OK, OK, OK, EOS, FALSE); +FLOW_TEST (not_neg_ok_ok_not_neg, NOT_NEGOTIATED, OK, OK, NOT_NEGOTIATED, + FALSE); +#undef FLOW_TEST GST_START_TEST (issue_concatenation) { @@ -492,11 +485,13 @@ GST_START_TEST (issue_concatenation) gst_object_unref (sinkpad); gst_object_unref (fakemixer_sink1); gst_object_unref (fakemixer_sink2); - check_destroyed (fakemixer, fakemixer_sink1, fakemixer_sink2, NULL); - check_destroyed (src1, srcpad1, NULL); - check_destroyed (src2, srcpad2, NULL); - check_destroyed (sink, sinkpad, NULL); - check_destroyed (runner, NULL, NULL); + gst_check_objects_destroyed_on_unref (fakemixer, fakemixer_sink1, + fakemixer_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); + ASSERT_OBJECT_REFCOUNT (runner, "runner", 2); + gst_object_unref (runner); } GST_END_TEST; @@ -629,18 +624,25 @@ _check_media_info (GstSegment * segment, BufferDesc * bufs) GST_STATE_CHANGE_SUCCESS); gst_object_unref (srcpad); - check_destroyed (decoder, sinkpad, NULL); - check_destroyed (runner, NULL, NULL); + gst_check_objects_destroyed_on_unref (decoder, sinkpad, NULL); + ASSERT_OBJECT_REFCOUNT (runner, "runner", 2); + gst_object_unref (runner); } -GST_START_TEST (check_media_info) -{ - GstSegment segment; - +#define MEDIA_INFO_TEST(name,segment_start,bufs) \ +GST_START_TEST(media_info_##name) { \ + if (segment_start >= 0) { \ + GstSegment segment; \ + gst_segment_init (&segment, GST_FORMAT_TIME); \ + segment.start = segment_start; \ + _check_media_info (&segment, (bufs)); \ + } else \ + _check_media_info (NULL, (bufs)); \ +} GST_END_TEST /* *INDENT-OFF* */ - _check_media_info (NULL, - (BufferDesc []) { +MEDIA_INFO_TEST (1, -1, + ((BufferDesc []) { { .content = "buffer1", .pts = 0, @@ -674,16 +676,11 @@ GST_START_TEST (check_media_info) .num_issues = 1 }, { NULL} - }); -/* *INDENT-ON* */ - - gst_segment_init (&segment, GST_FORMAT_TIME); - /* Segment start is 2, the first buffer is expected (first Keyframe) */ - segment.start = 2; + })); -/* *INDENT-OFF* */ - _check_media_info (&segment, - (BufferDesc []) { +/* Segment start is 2, the first buffer is expected (first Keyframe) */ +MEDIA_INFO_TEST (2, 2, + ((BufferDesc []) { { .content = "buffer2", /* Wrong checksum */ .pts = 0, @@ -693,16 +690,11 @@ GST_START_TEST (check_media_info) .num_issues = 1 }, { NULL} - }); -/* *INDENT-ON* */ - - gst_segment_init (&segment, GST_FORMAT_TIME); - /* Segment start is 2, the first buffer is expected (first Keyframe) */ - segment.start = 2; + })); -/* *INDENT-OFF* */ - _check_media_info (&segment, - (BufferDesc []) { +/* Segment start is 2, the first buffer is expected (first Keyframe) */ +MEDIA_INFO_TEST (3, 2, + ((BufferDesc []) { { /* The right first buffer */ .content = "buffer1", .pts = 0, @@ -712,16 +704,11 @@ GST_START_TEST (check_media_info) .num_issues = 0 }, { NULL} - }); -/* *INDENT-ON* */ - - gst_segment_init (&segment, GST_FORMAT_TIME); - /* Segment start is 6, the 4th buffer is expected (first Keyframe) */ - segment.start = 6; + })); -/* *INDENT-OFF* */ - _check_media_info (&segment, - (BufferDesc []) { +/* Segment start is 6, the 4th buffer is expected (first Keyframe) */ +MEDIA_INFO_TEST (4, 6, + ((BufferDesc []) { { /* The right fourth buffer */ .content = "buffer4", .pts = 4, @@ -731,16 +718,11 @@ GST_START_TEST (check_media_info) .num_issues = 0 }, { NULL} - }); -/* *INDENT-ON* */ + })); - gst_segment_init (&segment, GST_FORMAT_TIME); - /* Segment start is 6, the 4th buffer is expected (first Keyframe) */ - segment.start = 6; - -/* *INDENT-OFF* */ - _check_media_info (&segment, - (BufferDesc []) { +/* Segment start is 6, the 4th buffer is expected (first Keyframe) */ +MEDIA_INFO_TEST (5, 6, + ((BufferDesc []) { { /* The sixth buffer... all wrong! */ .content = "buffer6", .pts = 6, @@ -750,11 +732,8 @@ GST_START_TEST (check_media_info) .num_issues = 1 }, { NULL} - }); + })); /* *INDENT-ON* */ -} - -GST_END_TEST; GST_START_TEST (caps_events) { @@ -1046,21 +1025,33 @@ gst_validate_suite (void) TCase *tc_chain = tcase_create ("padmonitor"); suite_add_tcase (s, tc_chain); - gst_validate_init (); fake_elements_register (); tcase_add_test (tc_chain, buffer_before_segment); tcase_add_test (tc_chain, buffer_outside_segment); tcase_add_test (tc_chain, buffer_timestamp_out_of_received_range); - tcase_add_test (tc_chain, flow_aggregation); + + tcase_add_test (tc_chain, media_info_1); + tcase_add_test (tc_chain, media_info_2); + tcase_add_test (tc_chain, media_info_3); + tcase_add_test (tc_chain, media_info_4); + tcase_add_test (tc_chain, media_info_5); + + tcase_add_test (tc_chain, flow_aggregation_ok_ok_error_ok); + tcase_add_test (tc_chain, flow_aggregation_eos_eos_eos_ok); + tcase_add_test (tc_chain, flow_aggregation_flushing_ok_ok_ok); + tcase_add_test (tc_chain, flow_aggregation_not_neg_ok_ok_ok); + tcase_add_test (tc_chain, flow_aggregation_eos_eos_eos_eos); + tcase_add_test (tc_chain, flow_aggregation_eos_eos_ok_ok); + tcase_add_test (tc_chain, flow_aggregation_ok_ok_ok_eos); + tcase_add_test (tc_chain, flow_aggregation_not_neg_ok_ok_not_neg); + tcase_add_test (tc_chain, issue_concatenation); - tcase_add_test (tc_chain, check_media_info); tcase_add_test (tc_chain, eos_without_segment); tcase_add_test (tc_chain, caps_events); tcase_add_test (tc_chain, flow_error_without_message); tcase_add_test (tc_chain, flow_error_with_message); - gst_validate_deinit (); return s; } diff --git a/validate/tests/check/validate/reporting.c b/validate/tests/check/validate/reporting.c index ca7a92b..7f1b69b 100644 --- a/validate/tests/check/validate/reporting.c +++ b/validate/tests/check/validate/reporting.c @@ -21,14 +21,9 @@ #include #include "test-utils.h" -GST_START_TEST (test_report_levels) +GST_START_TEST (test_report_levels_all) { GstValidateRunner *runner; - GstObject *pipeline; - GError *error = NULL; - GstElement *element; - GstValidateMonitor *monitor, *pipeline_monitor; - GstPad *pad; /* FIXME: for now the only interface to set the reporting level is through an * environment variable parsed at the time of the runner initialization, @@ -42,6 +37,14 @@ GST_START_TEST (test_report_levels) 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 */ @@ -50,6 +53,13 @@ GST_START_TEST (test_report_levels) 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", @@ -63,6 +73,18 @@ GST_START_TEST (test_report_levels) "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 */ @@ -190,92 +212,40 @@ _create_issues (GstValidateRunner * runner) check_destroyed (sink, sinkpad, NULL); } -GST_START_TEST (test_global_levels) -{ - GstValidateRunner *runner; - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "none", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* None shall pass */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 0); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "synthetic", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* Two reports of the same type */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 1); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "monitor", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* One report for each pad monitor */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 6); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* One report for each pad monitor, plus one for fakemixer src and fakesink sink */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 8); - g_object_unref (runner); -} - -GST_END_TEST; - -GST_START_TEST (test_specific_levels) -{ - GstValidateRunner *runner; - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", - "none,fakesrc1:synthetic", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* One issue should go through the none filter */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 1); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "monitor,sink:none", - TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* 5 issues because all pads will report their own issues separately, except - * for the sink which will not report an issue */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 5); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", - "subchain,sink:monitor", TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* 3 issues because both fake sources will have subsequent subchains of - * issues, and the sink will report its issue separately */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 3); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", - "synthetic,fakesrc1:subchain,fakesrc2:subchain,fakemixer*::src*:monitor", - TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* 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 */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 4); - g_object_unref (runner); - - fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "none,fakesink*:all", - TRUE)); - runner = gst_validate_runner_new (); - _create_issues (runner); - /* 2 issues repeated on the fakesink's sink */ - fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 2); - g_object_unref (runner); -} - -GST_END_TEST; +#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); + +#undef TEST_LEVELS static Suite * gst_validate_suite (void) @@ -284,14 +254,24 @@ gst_validate_suite (void) TCase *tc_chain = tcase_create ("reporting"); suite_add_tcase (s, tc_chain); - gst_validate_init (); fake_elements_register (); - tcase_add_test (tc_chain, test_report_levels); - tcase_add_test (tc_chain, test_global_levels); - tcase_add_test (tc_chain, test_specific_levels); + 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); - gst_validate_deinit (); return s; } diff --git a/validate/tools/gst-validate-transcoding.c b/validate/tools/gst-validate-transcoding.c index fd8c5f9..d0d2bc7 100644 --- a/validate/tools/gst-validate-transcoding.c +++ b/validate/tools/gst-validate-transcoding.c @@ -925,6 +925,7 @@ main (int argc, gchar ** argv) } /* Create the pipeline */ + runner = gst_validate_runner_new (); create_transcoding_pipeline (argv[1], argv[2]); #ifdef G_OS_UNIX @@ -932,7 +933,6 @@ main (int argc, gchar ** argv) g_unix_signal_add (SIGINT, (GSourceFunc) intr_handler, pipeline); #endif - runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline), runner, NULL); diff --git a/validate/tools/gst-validate.c b/validate/tools/gst-validate.c index 8a76937..bff03fc 100644 --- a/validate/tools/gst-validate.c +++ b/validate/tools/gst-validate.c @@ -537,6 +537,12 @@ main (int argc, gchar ** argv) g_option_context_free (ctx); + runner = gst_validate_runner_new (); + if (!runner) { + g_printerr ("Failed to setup Validate Runner\n"); + exit (1); + } + /* Create the pipeline */ argvn = g_new0 (char *, argc); memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); @@ -546,6 +552,8 @@ main (int argc, gchar ** argv) g_print ("Failed to create pipeline: %s\n", err ? err->message : "unknown reason"); g_clear_error (&err); + g_object_unref (runner); + exit (1); } if (!GST_IS_PIPELINE (pipeline)) { @@ -565,12 +573,6 @@ main (int argc, gchar ** argv) _register_playbin_actions (); } - runner = gst_validate_runner_new (); - if (!runner) { - g_printerr ("Failed to setup Validate Runner\n"); - exit (1); - } - monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline), runner, NULL); gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor)); -- 2.7.4