validate: Implement fault_injection as a Gs(tValidate)Plugin
authorThibault Saunier <tsaunier@gnome.org>
Wed, 4 Feb 2015 13:30:05 +0000 (14:30 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Sat, 14 Feb 2015 15:32:11 +0000 (16:32 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=743994

validate/configure.ac
validate/fault_injection/Makefile.am
validate/fault_injection/socket_interposer.c
validate/fault_injection/socket_interposer.h
validate/gst/validate/Makefile.am
validate/gst/validate/gst-validate-scenario.c
validate/gst/validate/validate.c

index ea310bf..ca34dc8 100644 (file)
@@ -188,8 +188,15 @@ GST_LICENSE="LGPL"
 AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license])
 AC_SUBST(GST_LICENSE)
 
-dnl set location of plugin directory
-AG_GST_SET_PLUGINDIR
+dnl define location of plugin directory
+AS_AC_EXPAND(PLUGINDIR, ${libdir}/gstreamer-$GST_API_VERSION/validate)
+AC_DEFINE_UNQUOTED(PLUGINDIR, "$PLUGINDIR",
+[directory where GstValidate plugins are located])
+AC_MSG_NOTICE([Using $PLUGINDIR 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)
 
 # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above
 dnl make sure it doesn't complain about unused variables if debugging is disabled
@@ -235,10 +242,6 @@ GST_CFLAGS="$GST_CFLAGS \$(GST_OPTION_CFLAGS)"
 AC_SUBST(GST_CFLAGS)
 AC_SUBST(GST_LIBS)
 
-dnl Tiny library overriding calls such as socket recv / send
-FAULTINJECTION_LIBS="-L\$(top_srcdir)/fault_injection/ -lfaultinjection-$GST_API_VERSION"
-AC_SUBST([FAULTINJECTION_LIBS])
-
 dnl GST_ALL_*
 dnl vars common to for all internal objects (core libs, elements, applications)
 dnl CFLAGS:
index dbfe5be..8a43028 100644 (file)
@@ -1,13 +1,13 @@
-libfaultinjection_@GST_API_VERSION@_la_SOURCES = \
+plugin_LTLIBRARIES = libfaultinjection.la
+
+libfaultinjection_la_SOURCES = \
        socket_interposer.c
 
-libfaultinjection_@GST_API_VERSION@include_HEADERS = \
+noinst_HEADERS = \
        socket_interposer.h
 
-lib_LTLIBRARIES = libfaultinjection-@GST_API_VERSION@.la
-
-libfaultinjection_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)
-libfaultinjection_@GST_API_VERSION@_la_LIBADD = $(GST_ALL_LIBS)
-libfaultinjection_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/faultinjection
+libfaultinjection_la_CFLAGS = $(GST_ALL_CFLAGS)
+libfaultinjection_la_LIBADD = $(GST_ALL_LIBS) $(top_builddir)/gst/validate/libgstvalidate-@GST_API_VERSION@.la
+libfaultinjection_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_ALL_LDFLAGS)
 
 CLEANFILES =
index 1d80287..6e027d5 100644 (file)
 
 #define _GNU_SOURCE
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "socket_interposer.h"
-#include <gst/validate/gst-validate-scenario.h>
+#include <gst/gst.h>
+#include "../gst/validate/gst-validate-scenario.h"
 
 #if defined(__gnu_linux__) && !defined(__ANDROID__) && !defined (ANDROID)
 
@@ -329,8 +334,8 @@ _execute_corrupt_socket_recv (GstValidateScenario * scenario,
   return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
 }
 
-void
-socket_interposer_init (void)
+static gboolean
+socket_interposer_init (GstPlugin * plugin)
 {
   gst_validate_register_action_type ("corrupt-socket-recv", "fault-injector",
       _execute_corrupt_socket_recv, ((GstValidateActionParameter[]) {
@@ -347,13 +352,23 @@ socket_interposer_init (void)
             NULL}
           }),
       "corrupt the next socket receive", GST_VALIDATE_ACTION_TYPE_ASYNC);
+
+  return TRUE;
 }
 
 #else /* No LD_PRELOAD tricks on Windows */
 
-void
-socket_interposer_init (void)
+static gboolean
+socket_interposer_init (GstPlugin * plugin)
 {
+  return TRUE;
 }
 
 #endif
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    faultinjector,
+    "Fault injector plugin for GstValidate",
+    socket_interposer_init, VERSION, "LGPL", GST_PACKAGE_NAME,
+    GST_PACKAGE_ORIGIN)
index 9bd3bd6..bc08578 100644 (file)
@@ -24,6 +24,4 @@
 #ifndef _SOCKET_INTERPOSER_H_
 #define _SOCKET_INTERPOSER_H_
 
-extern void socket_interposer_init(void);
-
 #endif /* _SOCKET_INTERPOSER_H_ */
index 7cdcddf..e8e35c9 100644 (file)
@@ -46,14 +46,13 @@ noinst_HEADERS =            \
 
 lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la
 libgstvalidate_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\
-       $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) -I$(top_srcdir)/fault_injection
+       $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS)
 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 = \
        $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
        $(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \
-       $(GLIB_LIBS) $(LIBM)\
-       $(FAULTINJECTION_LIBS)
+       $(GLIB_LIBS) $(LIBM)
 
 libgstvalidate_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate
 
@@ -116,7 +115,6 @@ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
                --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
                --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-controller-@GST_API_VERSION@` \
                --includedir=`$(PKG_CONFIG) --variable=girdir gio-2.0` \
-               --shared-library=faultinjection-@GST_API_VERSION@ \
                $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
 endif
 
index e45850e..adc2656 100644 (file)
@@ -45,7 +45,6 @@
 #include "gst-validate-utils.h"
 #include <gst/validate/gst-validate-override.h>
 #include <gst/validate/gst-validate-override-registry.h>
-#include <socket_interposer.h>
 
 #define GST_VALIDATE_SCENARIO_GET_PRIVATE(o) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_VALIDATE_SCENARIO, GstValidateScenarioPrivate))
@@ -2653,6 +2652,4 @@ init_scenarios (void)
       GST_VALIDATE_ACTION_TYPE_NONE);
   /*  *INDENT-ON* */
 
-  socket_interposer_init ();
-  /*  *INDENT-ON* */
 }
index 1a0376c..479ea2e 100644 (file)
 #  include "config.h"
 #endif
 
+/* For g_stat () */
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 #include "validate.h"
 #include "gst-validate-internal.h"
 
 GST_DEBUG_CATEGORY (gstvalidate_debug);
 
+static gboolean
+gst_validate_scan_path_for_plugins (const gchar * path)
+{
+  GDir *dir;
+  const gchar *dirent;
+  gchar *filename;
+  GstPlugin *plugin;
+  gboolean changed = FALSE;
+
+  dir = g_dir_open (path, 0, NULL);
+  if (!dir)
+    return FALSE;
+
+  while ((dirent = g_dir_read_name (dir))) {
+    GStatBuf file_status;
+
+    filename = g_build_filename (path, dirent, NULL);
+    if (g_stat (filename, &file_status) < 0) {
+      /* Plugin will be removed from cache after the scan completes if it
+       * is still marked 'cached' */
+      g_free (filename);
+      continue;
+    }
+
+    if (!(file_status.st_mode & S_IFREG)) {
+      g_free (filename);
+      continue;
+    }
+    if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX)) {
+      GST_TRACE ("extension is not recognized as module file, ignoring file %s",
+          filename);
+      g_free (filename);
+      continue;
+    }
+
+    plugin = gst_plugin_load_file (filename, NULL);
+    if (plugin) {
+      GST_DEBUG ("Plugin %s loaded", filename);
+      gst_object_unref (plugin);
+    }
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+
+  return changed;
+
+}
+
+
+static void
+gst_validate_init_plugins (void)
+{
+  const gchar *plugin_path;
+
+  plugin_path = g_getenv ("GST_VALIDATE_PLUGIN_PATH");
+  if (plugin_path) {
+    char **list;
+    int i;
+
+    GST_DEBUG ("GST_VALIDATE_PLUGIN_PATH set to %s", plugin_path);
+    list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
+    for (i = 0; list[i]; i++) {
+      gst_validate_scan_path_for_plugins (list[i]);
+    }
+    g_strfreev (list);
+  } else {
+    GST_DEBUG ("GST_VALIDATE_PLUGIN_PATH not set");
+  }
+
+  if (plugin_path == NULL) {
+    char *home_plugins;
+
+    /* plugins in the user's home directory take precedence over
+     * system-installed ones */
+    home_plugins = g_build_filename (g_get_user_data_dir (),
+        "gstreamer-" GST_API_VERSION, "plugins", NULL);
+
+    GST_DEBUG ("scanning home plugins %s", home_plugins);
+    gst_validate_scan_path_for_plugins (home_plugins);
+    g_free (home_plugins);
+
+    /* add the main (installed) library path */
+
+#ifdef G_OS_WIN32
+    {
+      char *base_dir;
+      char *dir;
+
+      base_dir =
+          g_win32_get_package_installation_directory_of_module
+          (_priv_gst_dll_handle);
+
+      dir = g_build_filename (base_dir,
+#ifdef _DEBUG
+          "debug"
+#endif
+          "lib", "gstreamer-" GST_API_VERSION, NULL);
+      GST_DEBUG ("scanning DLL dir %s", dir);
+
+      gst_validate_scan_path_for_plugins (dir);
+
+      g_free (dir);
+      g_free (base_dir);
+    }
+#else
+    gst_validate_scan_path_for_plugins (PLUGINDIR);
+#endif
+  }
+}
+
 /**
  * gst_validate_init:
  *
@@ -55,4 +173,6 @@ gst_validate_init (void)
 
   /* Ensure we load overrides before any use of a monitor */
   gst_validate_override_registry_preload ();
+
+  gst_validate_init_plugins ();
 }