validate: Turn GstValidateRunner into a GstTracer
authorThibault Saunier <tsaunier@gnome.org>
Sat, 24 Oct 2015 07:28:51 +0000 (09:28 +0200)
committerThibault Saunier <thibault.saunier@collabora.com>
Tue, 23 Feb 2016 10:46:32 +0000 (11:46 +0100)
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

20 files changed:
validate/configure.ac
validate/gst/Makefile.am
validate/gst/preload/Makefile.am [deleted file]
validate/gst/preload/gst-validate-monitor-preload.c [deleted file]
validate/gst/validate/Makefile.am
validate/gst/validate/gst-validate-internal.h
validate/gst/validate/gst-validate-monitor.c
validate/gst/validate/gst-validate-runner.c
validate/gst/validate/gst-validate-runner.h
validate/gst/validate/validate.c
validate/plugins/fault_injection/Makefile.am
validate/plugins/gapplication/Makefile.am
validate/plugins/gtk/Makefile.am
validate/plugins/ssim/Makefile.am
validate/tests/check/validate/monitoring.c
validate/tests/check/validate/overrides.c
validate/tests/check/validate/padmonitor.c
validate/tests/check/validate/reporting.c
validate/tools/gst-validate-transcoding.c
validate/tools/gst-validate.c

index 9acd38d63e707548c76279b5f5e2f42c4b5c98f3..7bf1c9f846fbd1ea833033c54d5d2b88340e3f5b 100644 (file)
@@ -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
index 7e449719565ca7991ef962fe2a53c9bb51ba3673..c5e508e5cd69453f834f59381f3b2e8b5a17b4b6 100644 (file)
@@ -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 (file)
index 66faee0..0000000
+++ /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 (file)
index 370a94e..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* 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;
-}
index 84e601c60cbacbc5104ae5c84ee376e9c9214faa..df29f1173fb907ef4ffc44592e5234c4f7790964 100644 (file)
@@ -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
index adabd2146657a28a4edff18efc3706e908d78fc6..362c9399f114503dc2b3f79cd9f29a8ba0826119 100644 (file)
@@ -24,6 +24,7 @@
 
 #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
@@ -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
index 03e9c26b738122e764234a08de60644cc3e6eb00..ddd115db47c46539bc29f329095658963e08f162 100644 (file)
@@ -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"));
+}
index e0af7724ce877e06cfaf4ead25146aa109f89f31..90ba38d29f942a3d493bbbc4b657b797f28a30ba 100644 (file)
@@ -1,7 +1,8 @@
 /* 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
@@ -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 */
index 3c9b31d13f613ca70ccb0501fb4ea6a0e408ad4b..3c6a5c8623931a0ba08f6020b9a6356d44138421 100644 (file)
@@ -25,6 +25,8 @@
 #include <glib-object.h>
 #include <gst/gst.h>
 
+#include <gst/gsttracer.h>
+
 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;
 
   /* <private> */
   GstValidateRunnerPrivate *priv;
@@ -65,7 +67,7 @@ struct _GstValidateRunner {
  * GStreamer Validate Runner object class.
  */
 struct _GstValidateRunnerClass {
-  GObjectClass parent_class;
+  GstTracerClass       parent_class;
 };
 
 /* normal GObject stuff */
index 726c43168df3d97854fbcb1fcff899361b0e0f2a..0103a19ba5a3a29007f8da2ce2a6a0d96237f4a1 100644 (file)
@@ -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;
index 3a181ffdc021d592d777d078c23b4b3416770c66..631ed24a1628f5a988b9e6e23e565c8c34ba4b86 100644 (file)
@@ -1,4 +1,4 @@
-plugin_LTLIBRARIES = libgstvalidatefaultinjection.la
+validateplugin_LTLIBRARIES = libgstvalidatefaultinjection.la
 
 libgstvalidatefaultinjection_la_SOURCES = \
        socket_interposer.c
index 20ce6a0c5280d0934c039ab67982055833a1a55c..9baf9292e313adade922097b415b171c470cc1cd 100644 (file)
@@ -1,4 +1,4 @@
-plugin_LTLIBRARIES = libgstvalidategapplication.la
+validateplugin_LTLIBRARIES = libgstvalidategapplication.la
 
 libgstvalidategapplication_la_SOURCES = \
        gstvalidategapplication.c
index f049a270b1d399e355b31eb9519e32f29d7dd3d7..2d47a61db50c5944288aaaaed7b4b5c0f034c0d2 100644 (file)
@@ -1,4 +1,4 @@
-plugin_LTLIBRARIES = libgstvalidategtk.la
+validateplugin_LTLIBRARIES = libgstvalidategtk.la
 
 libgstvalidategtk_la_SOURCES = gstvalidategtk.c
 
index 71618ce9d7b4144b6e7fd83eaf6daf924a5f9512..55a96811b6f33528f0851e494543c87e1898743b 100644 (file)
@@ -1,4 +1,4 @@
-plugin_LTLIBRARIES = libgstvalidatessim.la
+validateplugin_LTLIBRARIES = libgstvalidatessim.la
 
 libgstvalidatessim_la_SOURCES = gstvalidatessim.c
 
index 0bc6849a56b4d6b811333974e87f50b8bda6f485..12cf8f4d13bcced60f05b01be4877281cd5f7fa9 100644 (file)
@@ -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;
 }
 
index 9683ddb3ffb223891d082c1ee444f0fc127f7854..d4467d30dfe61633d6a9923e45a1bc502e0bc20f 100644 (file)
@@ -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;
 }
 
index 19f12fb2b52a0cca6881126a9b277bcd1d20a317..52134dd9c7f48aadd1fbb1a3e3d6169abe1e719a 100644 (file)
@@ -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;
 }
 
index ca7a92b0ab7502dd7ba2e45dec5dc3ab7b8cd8e4..7f1b69bd9d0c5b12de56a3c0fcd76b7783b8b98b 100644 (file)
 #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,
@@ -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;
 }
 
index fd8c5f93da5c53b9b70936f4545294d4dbfd3115..d0d2bc78be9f9f41e81e055fbd892106b06b93c2 100644 (file)
@@ -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);
index 8a7693709186383daa0a896640995083a05f997d..bff03fc79f0c43531959f162bff2a733132f0d6c 100644 (file)
@@ -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));