check/: Add test
authorDavid Schleef <ds@schleef.org>
Thu, 15 Sep 2005 23:51:24 +0000 (23:51 +0000)
committerDavid Schleef <ds@schleef.org>
Thu, 15 Sep 2005 23:51:24 +0000 (23:51 +0000)
Original commit message from CVS:
* check/Makefile.am:
* check/gst/gstplugin.c: Add test
* gst/gstplugin.c: Fix problems noticed by testsuite
* gst/gstplugin.h:
* gst/gstregistry.c:
* gst/gstregistry.h:

ChangeLog
check/Makefile.am
check/gst/gstplugin.c [new file with mode: 0644]
gst/gstplugin.c
gst/gstplugin.h
gst/gstregistry.c
gst/gstregistry.h
tests/check/Makefile.am
tests/check/gst/gstplugin.c [new file with mode: 0644]

index 021a196a27491e95d67942c581683ee2088ff2cd..5d4a445b5e00da4c7d57f5369e727c5b122938e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-09-15  David Schleef  <ds@schleef.org>
+
+       * check/Makefile.am:
+       * check/gst/gstplugin.c: Add test
+       * gst/gstplugin.c: Fix problems noticed by testsuite
+       * gst/gstplugin.h:
+       * gst/gstregistry.c: 
+       * gst/gstregistry.h:
+
 2005-09-15  David Schleef  <ds@schleef.org>
 
        * gst/gstplugin.c: Implement semi-decent recounting and locking
index 14e02f8cbf1d94dafc1ac41af1954b23468d40e1..d8fd6001136b942f67849bb0b47aa4a8bb6ec188 100644 (file)
@@ -39,6 +39,7 @@ check_PROGRAMS =                              \
        gst/gstobject                           \
        gst/gstpad                              \
        gst/gstpipeline                         \
+       gst/gstplugin                           \
        gst/gstsystemclock                      \
        gst/gststructure                        \
        gst/gsttag                              \
diff --git a/check/gst/gstplugin.c b/check/gst/gstplugin.c
new file mode 100644 (file)
index 0000000..e2ae667
--- /dev/null
@@ -0,0 +1,166 @@
+/* GStreamer
+ *
+ * unit test for GstPlugin
+ *
+ * Copyright 2004 Thomas Vander Stichele <thomas at apestaart dot org>
+ * Copyright 2005 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gst/check/gstcheck.h>
+
+static gboolean
+register_check_elements (GstPlugin * plugin)
+{
+  return TRUE;
+}
+
+static GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "check elements",
+  "check elements",
+  register_check_elements,
+  VERSION,
+  GST_LICENSE,
+  PACKAGE,
+  GST_PACKAGE,
+  GST_ORIGIN,
+
+  GST_PADDING_INIT
+};
+
+GST_START_TEST (test_register_static)
+{
+  GstPlugin *plugin;
+
+  _gst_plugin_register_static (&plugin_desc);
+
+  plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
+
+  gst_object_unref (plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_load_gstelements)
+{
+  GstPlugin *unloaded_plugin;
+  GstPlugin *loaded_plugin;
+
+  unloaded_plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (unloaded_plugin == NULL, "Failed to find gstelements plugin");
+  fail_if (unloaded_plugin->object.refcount != 2,
+      "Refcount of unloaded plugin in registry initially should be 2");
+
+  gst_object_ref (unloaded_plugin);
+  loaded_plugin = gst_plugin_load (unloaded_plugin);
+  fail_if (loaded_plugin == NULL, "Failed to load plugin");
+
+  fail_if (loaded_plugin->object.refcount != 2,
+      "Refcount of loaded plugin in registry should be 2");
+  fail_if (unloaded_plugin->object.refcount != 1,
+      "Refcount of replaced plugin in registry should be 1");
+
+  gst_object_unref (unloaded_plugin);
+  gst_object_unref (loaded_plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_registry_get_plugin_list)
+{
+  GList *list;
+  GstPlugin *plugin;
+
+  plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in registry should be 2");
+
+  list = gst_registry_get_plugin_list (gst_registry_get_default ());
+
+  fail_if (plugin->object.refcount != 3,
+      "Refcount of plugin in registry+list should be 3");
+
+  gst_plugin_list_free (list);
+
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in after list free should be 2");
+
+  gst_object_unref (plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_find_feature)
+{
+  GstPlugin *plugin;
+  GstPluginFeature *feature;
+
+  plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in registry should be 2");
+
+  feature = gst_registry_find_feature (gst_registry_get_default (),
+      "identity", GST_TYPE_ELEMENT_FACTORY);
+  fail_if (feature == NULL, "Failed to find identity element factory");
+  fail_if (feature->plugin != plugin,
+      "Expected indentity to be from gstelements plugin");
+
+  fail_if (plugin->object.refcount != 3,
+      "Refcount of plugin in registry+feature should be 3");
+
+  gst_object_unref (feature->plugin);
+
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in after list free should be 2");
+
+  gst_object_unref (plugin);
+}
+GST_END_TEST Suite * gst_plugin_suite (void)
+{
+  Suite *s = suite_create ("GstPlugin");
+  TCase *tc_chain = tcase_create ("general");
+
+  /* turn off timeout */
+  tcase_set_timeout (tc_chain, 60);
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_register_static);
+  tcase_add_test (tc_chain, test_load_gstelements);
+  tcase_add_test (tc_chain, test_registry_get_plugin_list);
+  tcase_add_test (tc_chain, test_find_feature);
+
+  return s;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = gst_plugin_suite ();
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_VERBOSE);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
index adfc78a5840d8e64a11fc5520dba98973141a79d..7d10169b935d4804ee21e534ef074524a48dccb5 100644 (file)
@@ -402,6 +402,7 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
   _gst_plugin_fault_handler_filename = NULL;
   GST_INFO ("plugin \"%s\" loaded", plugin->filename);
 
+  gst_object_ref (plugin);
   gst_default_registry_add_plugin (plugin);
 
   g_static_mutex_unlock (&gst_plugin_loading_mutex);
@@ -857,6 +858,7 @@ GstPlugin *
 gst_plugin_load (GstPlugin * plugin)
 {
   GError *error = NULL;
+  GstPlugin *newplugin;
 
   if (gst_plugin_is_loaded (plugin)) {
     return plugin;
@@ -866,12 +868,26 @@ gst_plugin_load (GstPlugin * plugin)
     return plugin;
   }
 
-  plugin = gst_plugin_load_file (plugin->filename, &error);
-  if (!plugin) {
+  newplugin = gst_plugin_load_file (plugin->filename, &error);
+  if (newplugin == NULL) {
     GST_WARNING ("load_plugin error: %s\n", error->message);
     g_error_free (error);
+    gst_object_unref (plugin);
     return NULL;
   }
 
-  return plugin;
+  gst_object_unref (plugin);
+
+  return newplugin;
+}
+
+void
+gst_plugin_list_free (GList * list)
+{
+  GList *g;
+
+  for (g = list; g; g = g->next) {
+    gst_object_unref (GST_PLUGIN (g->data));
+  }
+  g_list_free (list);
 }
index bfae206c46521a96399db5e68343f2c505484013..dbd1db8375615c9b0a9d5e9db8d104a05e3ce426 100644 (file)
@@ -150,9 +150,6 @@ typedef gboolean        (*GstPluginFilter)              (GstPlugin *plugin,
 
 GType                   gst_plugin_get_type             (void);
 
-GstPlugin *             gst_plugin_new                  (void);
-void                    gst_plugin_free                 (GstPlugin *plugin);
-
 void                   _gst_plugin_initialize          (void);
 void                   _gst_plugin_register_static     (GstPluginDesc *desc);
 
@@ -175,6 +172,7 @@ GList*                      gst_plugin_list_feature_filter  (GList *list,
                                                         GstPluginFeatureFilter filter,
                                                         gboolean first,
                                                         gpointer user_data);
+void gst_plugin_list_free (GList *list);
 gboolean               gst_plugin_name_filter          (GstPlugin *plugin, const gchar *name);
 
 GList*                 gst_plugin_get_feature_list     (GstPlugin *plugin);
index b72560ee061d607b8ff7d1371538d8da3f6060bc..286b439d61daf696ba40b4dd4a070551d819d72e 100644 (file)
@@ -117,10 +117,12 @@ enum
 static void gst_registry_class_init (GstRegistryClass * klass);
 static void gst_registry_init (GstRegistry * registry);
 
-static GObjectClass *parent_class = NULL;
 static guint gst_registry_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GstRegistry, gst_registry, G_TYPE_OBJECT);
+static GstPlugin *gst_registry_lookup_locked (GstRegistry * registry,
+    const char *filename);
+
+G_DEFINE_TYPE (GstRegistry, gst_registry, GST_TYPE_OBJECT);
 
 static void
 gst_registry_class_init (GstRegistryClass * klass)
@@ -129,8 +131,6 @@ gst_registry_class_init (GstRegistryClass * klass)
 
   gobject_class = (GObjectClass *) klass;
 
-  parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
   gst_registry_signals[PLUGIN_ADDED] =
       g_signal_new ("plugin-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRegistryClass, plugin_added), NULL,
@@ -176,13 +176,16 @@ gst_registry_add_path (GstRegistry * registry, const gchar * path)
     return;
   }
 
+  GST_LOCK (registry);
   if (g_list_find_custom (registry->paths, path, (GCompareFunc) strcmp)) {
     g_warning ("path %s already added to registry", path);
+    GST_UNLOCK (registry);
     return;
   }
 
   GST_INFO ("Adding plugin path: \"%s\"", path);
   registry->paths = g_list_append (registry->paths, g_strdup (path));
+  GST_UNLOCK (registry);
 }
 
 /**
@@ -196,29 +199,20 @@ gst_registry_add_path (GstRegistry * registry, const gchar * path)
 GList *
 gst_registry_get_path_list (GstRegistry * registry)
 {
-  g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
-
-  return g_list_copy (registry->paths);
-}
+  GList *list;
 
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
 
-/**
- * gst_registry_clear_paths:
- * @registry: the registry to clear the paths of
- *
- * Clear the paths of the given registry
- */
-void
-gst_registry_clear_paths (GstRegistry * registry)
-{
-  g_return_if_fail (GST_IS_REGISTRY (registry));
-
-  g_list_foreach (registry->paths, (GFunc) g_free, NULL);
-  g_list_free (registry->paths);
+  GST_LOCK (registry);
+  /* We don't need to copy the strings, because they won't be deleted
+   * as long as the GstRegistry is around */
+  list = g_list_copy (registry->paths);
+  GST_UNLOCK (registry);
 
-  registry->paths = NULL;
+  return list;
 }
 
+
 /**
  * gst_registry_add_plugin:
  * @registry: the registry to add the plugin to
@@ -235,26 +229,27 @@ gst_registry_add_plugin (GstRegistry * registry, GstPlugin * plugin)
 
   g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
 
-  existing_plugin = gst_registry_lookup (registry, plugin->filename);
+  GST_LOCK (registry);
+  existing_plugin = gst_registry_lookup_locked (registry, plugin->filename);
   if (existing_plugin) {
-    GST_DEBUG ("Replacing existing plugin for filename \"%s\"",
-        plugin->filename);
+    GST_DEBUG ("Replacing existing plugin %p for filename \"%s\"",
+        existing_plugin, plugin->filename);
     registry->plugins = g_list_remove (registry->plugins, existing_plugin);
     gst_object_unref (existing_plugin);
   }
 
+  GST_DEBUG ("Adding plugin %p for filename \"%s\"", plugin, plugin->filename);
+
   registry->plugins = g_list_prepend (registry->plugins, plugin);
 
   gst_object_ref (plugin);
   gst_object_sink (plugin);
+  GST_UNLOCK (registry);
 
   GST_DEBUG ("emitting plugin-added for filename %s", plugin->filename);
   g_signal_emit (G_OBJECT (registry), gst_registry_signals[PLUGIN_ADDED], 0,
       plugin);
 
-  /* FIXME hack to fix unref later */
-  gst_object_ref (plugin);
-
   return TRUE;
 }
 
@@ -270,7 +265,10 @@ gst_registry_remove_plugin (GstRegistry * registry, GstPlugin * plugin)
 {
   g_return_if_fail (GST_IS_REGISTRY (registry));
 
+  GST_LOCK (registry);
   registry->plugins = g_list_remove (registry->plugins, plugin);
+  GST_UNLOCK (registry);
+  gst_object_unref (plugin);
 }
 
 /**
@@ -284,16 +282,26 @@ gst_registry_remove_plugin (GstRegistry * registry, GstPlugin * plugin)
  * the results. If the first flag is set, only the first match is
  * returned (as a list with a single object).
  *
- * Returns: a GList of plugins, g_list_free after use.
+ * Returns: a GList of plugins, gst_plugin_list_free after use.
  */
 GList *
 gst_registry_plugin_filter (GstRegistry * registry,
     GstPluginFilter filter, gboolean first, gpointer user_data)
 {
+  GList *list;
+  GList *g;
+
   g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
 
-  return gst_filter_run (registry->plugins, (GstFilterFunc) filter, first,
+  GST_LOCK (registry);
+  list = gst_filter_run (registry->plugins, (GstFilterFunc) filter, first,
       user_data);
+  for (g = list; g; g = g->next) {
+    gst_object_ref (GST_PLUGIN (g->data));
+  }
+  GST_UNLOCK (registry);
+
+  return list;
 }
 
 /**
@@ -308,16 +316,22 @@ gst_registry_plugin_filter (GstRegistry * registry,
  * If the first flag is set, only the first match is
  * returned (as a list with a single object).
  *
- * Returns: a GList of plugin features, g_list_free after use.
+ * Returns: a GList of plugin features, gst_plugin_feature_list_free after use.
  */
 GList *
 gst_registry_feature_filter (GstRegistry * registry,
     GstPluginFeatureFilter filter, gboolean first, gpointer user_data)
 {
+  GList *list;
+
   g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
 
-  return gst_plugin_list_feature_filter (registry->plugins, filter, first,
+  GST_LOCK (registry);
+  list = gst_plugin_list_feature_filter (registry->plugins, filter, first,
       user_data);
+  GST_UNLOCK (registry);
+
+  return list;
 }
 
 /**
@@ -343,7 +357,8 @@ gst_registry_find_plugin (GstRegistry * registry, const gchar * name)
   if (walk)
     result = GST_PLUGIN (walk->data);
 
-  g_list_free (walk);
+  gst_object_ref (result);
+  gst_plugin_list_free (walk);
 
   return result;
 }
@@ -380,7 +395,8 @@ gst_registry_find_feature (GstRegistry * registry, const gchar * name,
   if (walk)
     feature = GST_PLUGIN_FEATURE (walk->data);
 
-  g_list_free (walk);
+  gst_object_ref (feature->plugin);
+  gst_plugin_feature_list_free (walk);
 
   return feature;
 }
@@ -401,15 +417,28 @@ gst_registry_get_feature_list (GstRegistry * registry, GType type)
 GList *
 gst_registry_get_plugin_list (GstRegistry * registry)
 {
-  return g_list_copy (registry->plugins);
+  GList *list;
+  GList *g;
+
+  GST_LOCK (registry);
+  list = g_list_copy (registry->plugins);
+  for (g = list; g; g = g->next) {
+    gst_object_ref (GST_PLUGIN (g->data));
+  }
+  GST_UNLOCK (registry);
+
+  return list;
 }
 
-GstPlugin *
-gst_registry_lookup (GstRegistry * registry, const char *filename)
+static GstPlugin *
+gst_registry_lookup_locked (GstRegistry * registry, const char *filename)
 {
   GList *g;
   GstPlugin *plugin;
 
+  if (filename == NULL)
+    return NULL;
+
   for (g = registry->plugins; g; g = g_list_next (g)) {
     plugin = GST_PLUGIN (g->data);
     if (plugin->filename && strcmp (filename, plugin->filename) == 0) {
@@ -420,6 +449,18 @@ gst_registry_lookup (GstRegistry * registry, const char *filename)
   return NULL;
 }
 
+GstPlugin *
+gst_registry_lookup (GstRegistry * registry, const char *filename)
+{
+  GstPlugin *plugin;
+
+  GST_LOCK (registry);
+  plugin = gst_registry_lookup_locked (registry, filename);
+  GST_UNLOCK (registry);
+
+  return plugin;
+}
+
 static void
 gst_registry_scan_path_level (GstRegistry * registry, const gchar * path,
     int level)
index c22659d6e4d95ed1dcb807dc5c47a8cad9312963..5db5e170dd589d3dc6bc676dac4e8544ea0f9b96 100644 (file)
@@ -39,7 +39,7 @@ typedef struct _GstRegistry GstRegistry;
 typedef struct _GstRegistryClass GstRegistryClass;
 
 struct _GstRegistry {
-  GObject       object;
+  GstObject     object;
 
   GList                *plugins;
 
@@ -52,7 +52,7 @@ struct _GstRegistry {
 };
 
 struct _GstRegistryClass {
-  GObjectClass         parent_class;
+  GstObjectClass       parent_class;
 
   /* signals */
   void                         (*plugin_added)         (GstRegistry *registry, GstPlugin *plugin);
@@ -68,7 +68,6 @@ GstRegistry *           gst_registry_get_default        (void);
 
 void                   gst_registry_scan_path          (GstRegistry *registry, const gchar *path);
 GList*                 gst_registry_get_path_list      (GstRegistry *registry);
-void                   gst_registry_clear_paths        (GstRegistry *registry);
 
 gboolean               gst_registry_add_plugin         (GstRegistry *registry, GstPlugin *plugin);
 void                   gst_registry_remove_plugin      (GstRegistry *registry, GstPlugin *plugin);
index 14e02f8cbf1d94dafc1ac41af1954b23468d40e1..d8fd6001136b942f67849bb0b47aa4a8bb6ec188 100644 (file)
@@ -39,6 +39,7 @@ check_PROGRAMS =                              \
        gst/gstobject                           \
        gst/gstpad                              \
        gst/gstpipeline                         \
+       gst/gstplugin                           \
        gst/gstsystemclock                      \
        gst/gststructure                        \
        gst/gsttag                              \
diff --git a/tests/check/gst/gstplugin.c b/tests/check/gst/gstplugin.c
new file mode 100644 (file)
index 0000000..e2ae667
--- /dev/null
@@ -0,0 +1,166 @@
+/* GStreamer
+ *
+ * unit test for GstPlugin
+ *
+ * Copyright 2004 Thomas Vander Stichele <thomas at apestaart dot org>
+ * Copyright 2005 David Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gst/check/gstcheck.h>
+
+static gboolean
+register_check_elements (GstPlugin * plugin)
+{
+  return TRUE;
+}
+
+static GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "check elements",
+  "check elements",
+  register_check_elements,
+  VERSION,
+  GST_LICENSE,
+  PACKAGE,
+  GST_PACKAGE,
+  GST_ORIGIN,
+
+  GST_PADDING_INIT
+};
+
+GST_START_TEST (test_register_static)
+{
+  GstPlugin *plugin;
+
+  _gst_plugin_register_static (&plugin_desc);
+
+  plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
+
+  gst_object_unref (plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_load_gstelements)
+{
+  GstPlugin *unloaded_plugin;
+  GstPlugin *loaded_plugin;
+
+  unloaded_plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (unloaded_plugin == NULL, "Failed to find gstelements plugin");
+  fail_if (unloaded_plugin->object.refcount != 2,
+      "Refcount of unloaded plugin in registry initially should be 2");
+
+  gst_object_ref (unloaded_plugin);
+  loaded_plugin = gst_plugin_load (unloaded_plugin);
+  fail_if (loaded_plugin == NULL, "Failed to load plugin");
+
+  fail_if (loaded_plugin->object.refcount != 2,
+      "Refcount of loaded plugin in registry should be 2");
+  fail_if (unloaded_plugin->object.refcount != 1,
+      "Refcount of replaced plugin in registry should be 1");
+
+  gst_object_unref (unloaded_plugin);
+  gst_object_unref (loaded_plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_registry_get_plugin_list)
+{
+  GList *list;
+  GstPlugin *plugin;
+
+  plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in registry should be 2");
+
+  list = gst_registry_get_plugin_list (gst_registry_get_default ());
+
+  fail_if (plugin->object.refcount != 3,
+      "Refcount of plugin in registry+list should be 3");
+
+  gst_plugin_list_free (list);
+
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in after list free should be 2");
+
+  gst_object_unref (plugin);
+}
+
+GST_END_TEST
+GST_START_TEST (test_find_feature)
+{
+  GstPlugin *plugin;
+  GstPluginFeature *feature;
+
+  plugin = gst_default_registry_find_plugin ("gstelements");
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in registry should be 2");
+
+  feature = gst_registry_find_feature (gst_registry_get_default (),
+      "identity", GST_TYPE_ELEMENT_FACTORY);
+  fail_if (feature == NULL, "Failed to find identity element factory");
+  fail_if (feature->plugin != plugin,
+      "Expected indentity to be from gstelements plugin");
+
+  fail_if (plugin->object.refcount != 3,
+      "Refcount of plugin in registry+feature should be 3");
+
+  gst_object_unref (feature->plugin);
+
+  fail_if (plugin->object.refcount != 2,
+      "Refcount of plugin in after list free should be 2");
+
+  gst_object_unref (plugin);
+}
+GST_END_TEST Suite * gst_plugin_suite (void)
+{
+  Suite *s = suite_create ("GstPlugin");
+  TCase *tc_chain = tcase_create ("general");
+
+  /* turn off timeout */
+  tcase_set_timeout (tc_chain, 60);
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_register_static);
+  tcase_add_test (tc_chain, test_load_gstelements);
+  tcase_add_test (tc_chain, test_registry_get_plugin_list);
+  tcase_add_test (tc_chain, test_find_feature);
+
+  return s;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = gst_plugin_suite ();
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_VERBOSE);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}