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
data/scenarios/Makefile
gst/Makefile
gst/validate/Makefile
-gst/preload/Makefile
gst/overrides/Makefile
plugins/Makefile
plugins/fault_injection/Makefile
SUBDIRS = validate overrides
-
-if HAVE_LD_PRELOAD
-SUBDIRS += preload
-endif
+++ /dev/null
-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 =
+++ /dev/null
-/* GStreamer
- *
- * Copyright (C) 2013 Collabora Ltd.
- * Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>
- *
- * 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 <gst/gst.h>
-#include <string.h>
-#include <stdlib.h>
-#include <gst/validate/validate.h>
-
-#define __USE_GNU
-#include <dlfcn.h>
-
-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;
-}
-libgstvalidate_@GST_API_VERSION@_la_SOURCES = \
+source_c = \
gst-validate-runner.c \
gst-validate-reporter.c \
gst-validate-monitor.c \
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 \
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 = \
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
#include <gst/gst.h>
#include "gst-validate-scenario.h"
+#include "gst-validate-monitor.h"
GST_DEBUG_CATEGORY_EXTERN (gstvalidate_debug);
#define GST_CAT_DEFAULT gstvalidate_debug
* 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
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"));
+}
/* GStreamer
*
- * Copyright (C) 2013 Collabora Ltd.
+ * Copyright (C) 2013-2016 Collabora Ltd.
* Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>
+ * Author: Thibault Saunier <thibault.saunier@collabora.com>
*
* gst-validate-runner.c - Validate Runner class
*
# 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
/* 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 */
} 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
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)
}
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
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,
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));
}
/**
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;
}
/*
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 */
#include <glib-object.h>
#include <gst/gst.h>
+#include <gst/gsttracer.h>
+
typedef struct _GstValidateRunner GstValidateRunner;
typedef struct _GstValidateRunnerClass GstValidateRunnerClass;
* Class that manages a Validate test run for some pipeline
*/
struct _GstValidateRunner {
- GObject object;
+ GstTracer object;
/* <private> */
GstValidateRunnerPrivate *priv;
* GStreamer Validate Runner object class.
*/
struct _GstValidateRunnerClass {
- GObjectClass parent_class;
+ GstTracerClass parent_class;
};
/* normal GObject stuff */
validate_initialized = TRUE;
gst_validate_init_plugins ();
+ gst_validate_init_runner ();
}
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;
-plugin_LTLIBRARIES = libgstvalidatefaultinjection.la
+validateplugin_LTLIBRARIES = libgstvalidatefaultinjection.la
libgstvalidatefaultinjection_la_SOURCES = \
socket_interposer.c
-plugin_LTLIBRARIES = libgstvalidategapplication.la
+validateplugin_LTLIBRARIES = libgstvalidategapplication.la
libgstvalidategapplication_la_SOURCES = \
gstvalidategapplication.c
-plugin_LTLIBRARIES = libgstvalidategtk.la
+validateplugin_LTLIBRARIES = libgstvalidategtk.la
libgstvalidategtk_la_SOURCES = gstvalidategtk.c
-plugin_LTLIBRARIES = libgstvalidatessim.la
+validateplugin_LTLIBRARIES = libgstvalidatessim.la
libgstvalidatessim_la_SOURCES = gstvalidatessim.c
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;
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;
}
"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);
"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);
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");
/* 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);
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;
}
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);
}
_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;
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)
{
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;
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,
.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,
.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,
.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,
.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,
.num_issues = 1
},
{ NULL}
- });
+ }));
/* *INDENT-ON* */
-}
-
-GST_END_TEST;
GST_START_TEST (caps_events)
{
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;
}
#include <gst/check/gstcheck.h>
#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,
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 (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",
"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 */
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)
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;
}
}
/* Create the pipeline */
+ runner = gst_validate_runner_new ();
create_transcoding_pipeline (argv[1], argv[2]);
#ifdef G_OS_UNIX
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);
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));
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)) {
_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));