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