1 /* GStreamer
2 *
3 * unit test for state changes on all elements
4 *
5 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <unistd.h>
28
29 #include <glib.h>
30 #include <glib/gprintf.h>
31 #include <gmodule.h>
32 #include <gst/check/gstcheck.h>
33
34 static GList *elements = NULL;
35
36 static void
setup(void)37 setup (void)
38 {
39 GList *features, *f;
40 GList *plugins, *p;
41 gchar **ignorelist = NULL;
42 const gchar *STATE_IGNORE_ELEMENTS = NULL;
43
44 GST_DEBUG ("getting elements for package %s", PACKAGE);
45 STATE_IGNORE_ELEMENTS = g_getenv ("GST_STATE_IGNORE_ELEMENTS");
46 if (!g_getenv ("GST_NO_STATE_IGNORE_ELEMENTS") && STATE_IGNORE_ELEMENTS) {
47 GST_DEBUG ("Will ignore element factories: '%s'", STATE_IGNORE_ELEMENTS);
48 ignorelist = g_strsplit (STATE_IGNORE_ELEMENTS, " ", 0);
49 }
50
51 plugins = gst_registry_get_plugin_list (gst_registry_get ());
52
53 for (p = plugins; p; p = p->next) {
54 GstPlugin *plugin = p->data;
55
56 if (strcmp (gst_plugin_get_source (plugin), PACKAGE) != 0)
57 continue;
58
59 features =
60 gst_registry_get_feature_list_by_plugin (gst_registry_get (),
61 gst_plugin_get_name (plugin));
62
63 for (f = features; f; f = f->next) {
64 GstPluginFeature *feature = f->data;
65 const gchar *name = gst_plugin_feature_get_name (feature);
66 gboolean ignore = FALSE;
67
68 if (!GST_IS_ELEMENT_FACTORY (feature))
69 continue;
70
71 if (ignorelist) {
72 gchar **s;
73
74 for (s = ignorelist; s && *s; ++s) {
75 if (g_str_has_prefix (name, *s)) {
76 GST_DEBUG ("ignoring element %s", name);
77 ignore = TRUE;
78 }
79 }
80 if (ignore)
81 continue;
82 }
83
84 GST_DEBUG ("adding element %s", name);
85 elements = g_list_prepend (elements, (gpointer) g_strdup (name));
86 }
87 gst_plugin_feature_list_free (features);
88 }
89 gst_plugin_list_free (plugins);
90 g_strfreev (ignorelist);
91 }
92
93 static void
teardown(void)94 teardown (void)
95 {
96 GList *e;
97
98 for (e = elements; e; e = e->next) {
99 g_free (e->data);
100 }
101 g_list_free (elements);
102 elements = NULL;
103 }
104
105
GST_START_TEST(test_state_changes_up_and_down_seq)106 GST_START_TEST (test_state_changes_up_and_down_seq)
107 {
108 GstElement *element;
109 GstStateChangeReturn sret;
110 GList *e;
111
112 for (e = elements; e; e = e->next) {
113 const gchar *name = e->data;
114
115 GST_DEBUG ("testing element %s", name);
116 element = gst_element_factory_make (name, name);
117 fail_if (element == NULL, "Could not make element from factory %s", name);
118
119 if (GST_IS_PIPELINE (element)) {
120 GST_DEBUG ("element %s is a pipeline", name);
121 }
122
123 sret = gst_element_set_state (element, GST_STATE_READY);
124 if (sret != GST_STATE_CHANGE_FAILURE) {
125 gst_element_set_state (element, GST_STATE_PAUSED);
126 gst_element_set_state (element, GST_STATE_PLAYING);
127 gst_element_set_state (element, GST_STATE_PAUSED);
128 gst_element_set_state (element, GST_STATE_READY);
129 gst_element_set_state (element, GST_STATE_NULL);
130
131 gst_element_set_state (element, GST_STATE_PAUSED);
132 gst_element_set_state (element, GST_STATE_READY);
133 gst_element_set_state (element, GST_STATE_PLAYING);
134 gst_element_set_state (element, GST_STATE_PAUSED);
135 gst_element_set_state (element, GST_STATE_NULL);
136 }
137 gst_object_unref (GST_OBJECT (element));
138 }
139 }
140
141 GST_END_TEST;
142
GST_START_TEST(test_state_changes_up_seq)143 GST_START_TEST (test_state_changes_up_seq)
144 {
145 GstElement *element;
146 GstStateChangeReturn sret;
147 GList *e;
148
149 for (e = elements; e; e = e->next) {
150 const gchar *name = e->data;
151
152 GST_DEBUG ("testing element %s", name);
153 element = gst_element_factory_make (name, name);
154 fail_if (element == NULL, "Could not make element from factory %s", name);
155
156 if (GST_IS_PIPELINE (element)) {
157 GST_DEBUG ("element %s is a pipeline", name);
158 }
159
160 sret = gst_element_set_state (element, GST_STATE_READY);
161 if (sret != GST_STATE_CHANGE_FAILURE) {
162 gst_element_set_state (element, GST_STATE_PAUSED);
163 gst_element_set_state (element, GST_STATE_READY);
164
165 gst_element_set_state (element, GST_STATE_PAUSED);
166 gst_element_set_state (element, GST_STATE_PLAYING);
167 gst_element_set_state (element, GST_STATE_PAUSED);
168 gst_element_set_state (element, GST_STATE_READY);
169
170 gst_element_set_state (element, GST_STATE_NULL);
171 }
172 gst_object_unref (GST_OBJECT (element));
173 }
174 }
175
176 GST_END_TEST;
177
GST_START_TEST(test_state_changes_down_seq)178 GST_START_TEST (test_state_changes_down_seq)
179 {
180 GstElement *element;
181 GstStateChangeReturn sret;
182 GList *e;
183
184 for (e = elements; e; e = e->next) {
185 const gchar *name = e->data;
186
187 GST_DEBUG ("testing element %s", name);
188 element = gst_element_factory_make (name, name);
189 fail_if (element == NULL, "Could not make element from factory %s", name);
190
191 if (GST_IS_PIPELINE (element)) {
192 GST_DEBUG ("element %s is a pipeline", name);
193 }
194
195 sret = gst_element_set_state (element, GST_STATE_READY);
196 if (sret != GST_STATE_CHANGE_FAILURE) {
197 gst_element_set_state (element, GST_STATE_PAUSED);
198 gst_element_set_state (element, GST_STATE_PLAYING);
199
200 gst_element_set_state (element, GST_STATE_PAUSED);
201 gst_element_set_state (element, GST_STATE_PLAYING);
202
203 gst_element_set_state (element, GST_STATE_PAUSED);
204 gst_element_set_state (element, GST_STATE_READY);
205 gst_element_set_state (element, GST_STATE_PAUSED);
206 gst_element_set_state (element, GST_STATE_PLAYING);
207
208 gst_element_set_state (element, GST_STATE_PAUSED);
209 gst_element_set_state (element, GST_STATE_READY);
210 gst_element_set_state (element, GST_STATE_NULL);
211 }
212 gst_object_unref (GST_OBJECT (element));
213 }
214 }
215
216 GST_END_TEST;
217
218
219 static Suite *
states_suite(void)220 states_suite (void)
221 {
222 Suite *s = suite_create ("states_bad");
223 TCase *tc_chain = tcase_create ("general");
224
225 #if defined(HAVE_LADSPA) || defined(HAVE_LV2)
226 /* timeout after 60s, not the default 3
227 * we have wrapper plugins enabled
228 */
229 tcase_set_timeout (tc_chain, 60);
230 #endif
231
232 suite_add_tcase (s, tc_chain);
233 tcase_add_checked_fixture (tc_chain, setup, teardown);
234 tcase_add_test (tc_chain, test_state_changes_up_and_down_seq);
235 tcase_add_test (tc_chain, test_state_changes_up_seq);
236 tcase_add_test (tc_chain, test_state_changes_down_seq);
237
238 return s;
239 }
240
241 int
main(int argc,char ** argv)242 main (int argc, char **argv)
243 {
244 Suite *s;
245 GModule *libx11;
246
247 libx11 =
248 g_module_open ("libX11.so.6", G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY);
249 if (libx11) {
250 void (*xinitthreads) (void);
251 if (g_module_symbol (libx11, "XInitThreads", (gpointer *) & xinitthreads)) {
252 xinitthreads ();
253 }
254 g_module_close (libx11);
255 }
256 gst_check_init (&argc, &argv);
257 s = states_suite ();
258 return gst_check_run_suite (s, "states_bad", __FILE__);
259 }
260