registry: Add registry helper phase 1
[platform/upstream/gstreamer.git] / tests / check / gst / gstregistry.c
1 /* GStreamer unit tests for the plugin registry
2  *
3  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <gst/check/gstcheck.h>
26 #include <string.h>
27
28 static gint
29 plugin_name_cmp (GstPlugin * a, GstPlugin * b)
30 {
31   const gchar *name_a = gst_plugin_get_name (a);
32   const gchar *name_b = gst_plugin_get_name (b);
33
34   return strcmp (name_a, name_b);
35 }
36
37 static gint
38 plugin_ptr_cmp (GstPlugin * a, GstPlugin * b)
39 {
40   return (a == b) ? 0 : 1;
41 }
42
43 static void
44 print_plugin (const gchar * marker, GstRegistry * registry, GstPlugin * plugin)
45 {
46   const gchar *name;
47   GList *features, *f;
48
49   name = gst_plugin_get_name (plugin);
50
51   GST_DEBUG ("%s: plugin %p %d %s file: %s", marker, plugin,
52       GST_OBJECT_REFCOUNT (plugin), name,
53       GST_STR_NULL (gst_plugin_get_filename (plugin)));
54
55   features = gst_registry_get_feature_list_by_plugin (registry, name);
56   for (f = features; f != NULL; f = f->next) {
57     GstPluginFeature *feature;
58
59     feature = GST_PLUGIN_FEATURE (f->data);
60
61     GST_LOG ("%s:    feature: %p %s", marker, feature,
62         gst_plugin_feature_get_name (feature));
63   }
64   gst_plugin_feature_list_free (features);
65 }
66
67 GST_START_TEST (test_registry_update)
68 {
69   GstPluginFeature *old_identity, *new_identity;
70   GstPluginFeature *old_pipeline, *new_pipeline;
71   GstRegistry *registry;
72   GList *plugins_before, *plugins_after, *l;
73
74   registry = gst_registry_get_default ();
75   fail_unless (registry != NULL);
76   ASSERT_OBJECT_REFCOUNT (registry, "default registry", 1);
77
78   /* refcount should still be 1 the second time */
79   registry = gst_registry_get_default ();
80   fail_unless (registry != NULL);
81   ASSERT_OBJECT_REFCOUNT (registry, "default registry", 1);
82
83   old_identity = gst_registry_lookup_feature (registry, "identity");
84   fail_unless (old_identity != NULL, "Can't find plugin feature 'identity'");
85
86   old_pipeline = gst_registry_lookup_feature (registry, "pipeline");
87   fail_unless (old_pipeline != NULL, "Can't find plugin feature 'pipeline'");
88
89   /* plugins should have a refcount of 2: the registry holds one reference,
90    * and the other one is ours for the list */
91   plugins_before = gst_registry_get_plugin_list (registry);
92   for (l = plugins_before; l; l = l->next) {
93     GstPlugin *plugin;
94
95     plugin = GST_PLUGIN (l->data);
96
97     print_plugin ("before1", registry, plugin);
98
99     ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 2);
100   }
101
102   fail_unless (gst_update_registry () != FALSE, "registry update failed");
103
104   GST_LOG (" -----------------------------------");
105   GST_LOG ("          registry updated          ");
106   GST_LOG (" -----------------------------------");
107
108   /* static plugins should have the same refcount as before (ie. 2), whereas
109    * file-based plugins *may* have been replaced by a newly-created object
110    * if the on-disk file changed (and was not yet loaded). There should be
111    * only one reference left for those, and that's ours */
112   for (l = plugins_before; l; l = l->next) {
113     GstPlugin *plugin;
114
115     plugin = GST_PLUGIN (l->data);
116
117     print_plugin ("before2", registry, plugin);
118
119     if (gst_plugin_get_filename (plugin)) {
120       /* file-based plugin. */
121       ASSERT_OBJECT_REFCOUNT_BETWEEN (plugin, "plugin", 1, 2);
122     } else {
123       /* static plugin */
124       ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 2);
125     }
126   }
127
128   GST_LOG (" -----------------------------------");
129
130   plugins_after = gst_registry_get_plugin_list (registry);
131   for (l = plugins_after; l; l = l->next) {
132     GstPlugin *plugin = GST_PLUGIN (l->data);
133
134     print_plugin ("after  ", registry, plugin);
135
136     /* file-based plugins should have a refcount of 2 (one for the registry,
137      * one for us for the list) or 3 (one for the registry, one for the before
138      * list, one for the after list), static plugins should have one of 3
139      * (one for the registry, one for the new list and one for the old list).
140      * This implicitly also makes sure that all static plugins are the same
141      * objects as they were before. Non-static ones may or may not have been
142      * replaced by new objects */
143     if (gst_plugin_get_filename (plugin)) {
144       if (g_list_find_custom (plugins_before, plugin,
145               (GCompareFunc) plugin_ptr_cmp) != NULL) {
146         /* Same plugin existed in the before list. Refcount must be 3 */
147         ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 3);
148       } else {
149         /* This plugin is newly created, so should only exist in the after list
150          * and the registry: Refcount must be 2 */
151         ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 2);
152       }
153     } else {
154       ASSERT_OBJECT_REFCOUNT (plugin, "plugin", 3);
155     }
156   }
157
158   /* check that we still have all plugins in the new list that we had before */
159   for (l = plugins_after; l; l = l->next) {
160     GstPlugin *plugin;
161
162     plugin = GST_PLUGIN (l->data);
163
164     fail_unless (g_list_find_custom (plugins_before, plugin,
165             (GCompareFunc) plugin_name_cmp) != NULL,
166         "Plugin %s is in new list but not in old one?!",
167         gst_plugin_get_name (plugin));
168   }
169   for (l = plugins_before; l; l = l->next) {
170     GstPlugin *plugin;
171
172     plugin = GST_PLUGIN (l->data);
173     fail_unless (g_list_find_custom (plugins_after, plugin,
174             (GCompareFunc) plugin_name_cmp) != NULL,
175         "Plugin %s is in old list but not in new one?!",
176         gst_plugin_get_name (plugin));
177   }
178
179   new_identity = gst_registry_lookup_feature (registry, "identity");
180   fail_unless (new_identity != NULL, "Can't find plugin feature 'identity'");
181 #if 0
182   fail_unless (old_identity != new_identity, "Old and new 'identity' feature "
183       "should be different but are the same object");
184
185   ASSERT_OBJECT_REFCOUNT (old_identity, "old identity feature after update", 1);
186 #endif
187
188   new_pipeline = gst_registry_lookup_feature (registry, "pipeline");
189   fail_unless (new_pipeline != NULL, "Can't find plugin feature 'pipeline'");
190 #if 0
191   fail_unless (old_pipeline == new_pipeline, "Old and new 'pipeline' feature "
192       "objects should be the same, but are different objects");
193 #endif
194
195   gst_plugin_list_free (plugins_before);
196   plugins_before = NULL;
197   gst_plugin_list_free (plugins_after);
198   plugins_after = NULL;
199   registry = NULL;
200
201   gst_object_unref (old_identity);
202   gst_object_unref (new_identity);
203   gst_object_unref (old_pipeline);
204   gst_object_unref (new_pipeline);
205 }
206
207 GST_END_TEST;
208
209 static Suite *
210 registry_suite (void)
211 {
212   Suite *s = suite_create ("registry");
213   TCase *tc_chain = tcase_create ("general");
214
215   suite_add_tcase (s, tc_chain);
216
217   tcase_add_test (tc_chain, test_registry_update);
218
219   return s;
220 }
221
222 GST_CHECK_MAIN (registry);