move check stuff to its own library to be used by other modules
[platform/upstream/gstreamer.git] / tests / check / libs / controller.c
1 /* GStreamer
2  *
3  * unit test for the controller library
4  *
5  * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dor net>
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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "config.h"
24 #include <gst/check/gstcheck.h>
25 #include <gst/controller/gst-controller.h>
26
27 /* LOCAL TEST ELEMENT */
28
29 enum
30 {
31   ARG_ULONG = 1,
32   ARG_DOUBLE,
33   ARG_BOOLEAN,
34   ARG_COUNT
35 };
36
37 #define GST_TYPE_TEST_MONO_SOURCE            (gst_test_mono_source_get_type ())
38 #define GST_TEST_MONO_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSource))
39 #define GST_TEST_MONO_SOURCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
40 #define GST_IS_TEST_MONO_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_MONO_SOURCE))
41 #define GST_IS_TEST_MONO_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_MONO_SOURCE))
42 #define GST_TEST_MONO_SOURCE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
43
44 typedef struct _GstTestMonoSource GstTestMonoSource;
45 typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass;
46
47 struct _GstTestMonoSource
48 {
49   GstElement parent;
50   gulong val_ulong;
51   gdouble val_double;
52   gboolean val_bool;
53 };
54 struct _GstTestMonoSourceClass
55 {
56   GstElementClass parent_class;
57 };
58
59 GType gst_test_mono_source_get_type (void);
60
61 static void
62 gst_test_mono_source_get_property (GObject * object,
63     guint property_id, GValue * value, GParamSpec * pspec)
64 {
65   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
66
67   switch (property_id) {
68     case ARG_ULONG:
69       g_value_set_ulong (value, self->val_ulong);
70       break;
71     case ARG_DOUBLE:
72       g_value_set_double (value, self->val_double);
73       break;
74     default:
75       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
76       break;
77   }
78 }
79
80 static void
81 gst_test_mono_source_set_property (GObject * object,
82     guint property_id, const GValue * value, GParamSpec * pspec)
83 {
84   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
85
86   switch (property_id) {
87     case ARG_ULONG:
88       self->val_ulong = g_value_get_ulong (value);
89       break;
90     case ARG_DOUBLE:
91       self->val_double = g_value_get_double (value);
92       break;
93     default:
94       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
95       break;
96   }
97 }
98
99 static void
100 gst_test_mono_source_class_init (GstTestMonoSourceClass * klass)
101 {
102   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
103
104   gobject_class->set_property = gst_test_mono_source_set_property;
105   gobject_class->get_property = gst_test_mono_source_get_property;
106
107   g_object_class_install_property (gobject_class, ARG_ULONG,
108       g_param_spec_ulong ("ulong",
109           "ulong prop",
110           "ulong number parameter for the test_mono_source",
111           0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
112
113   g_object_class_install_property (gobject_class, ARG_DOUBLE,
114       g_param_spec_double ("double",
115           "double prop",
116           "double number parameter for the test_mono_source",
117           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
118 }
119
120 static void
121 gst_test_mono_source_base_init (GstTestMonoSourceClass * klass)
122 {
123   static const GstElementDetails details = {
124     "Monophonic source for unit tests",
125     "Source/Audio/MonoSource",
126     "Use in unit tests",
127     "Stefan Kost <ensonic@users.sf.net>"
128   };
129   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
130
131   gst_element_class_set_details (element_class, &details);
132 }
133
134 GType
135 gst_test_mono_source_get_type (void)
136 {
137   static GType type = 0;
138
139   if (type == 0) {
140     static const GTypeInfo info = {
141       (guint16) sizeof (GstTestMonoSourceClass),
142       (GBaseInitFunc) gst_test_mono_source_base_init,   // base_init
143       NULL,                     // base_finalize
144       (GClassInitFunc) gst_test_mono_source_class_init, // class_init
145       NULL,                     // class_finalize
146       NULL,                     // class_data
147       (guint16) sizeof (GstTestMonoSource),
148       0,                        // n_preallocs
149       NULL,                     // instance_init
150       NULL                      // value_table
151     };
152     type =
153         g_type_register_static (GST_TYPE_ELEMENT, "GstTestMonoSource", &info,
154         0);
155   }
156   return type;
157 }
158
159 static gboolean
160 gst_test_plugin_init (GstPlugin * plugin)
161 {
162   gst_element_register (plugin, "testmonosource", GST_RANK_NONE,
163       GST_TYPE_TEST_MONO_SOURCE);
164   return TRUE;
165 }
166
167 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
168     GST_VERSION_MINOR,
169     "gst-test",
170     "controller test plugin - several unit test support elements",
171     gst_test_plugin_init, VERSION, "LGPL", PACKAGE_NAME,
172     "http://gstreamer.freedesktop.org")
173
174 /* TESTS */
175 /* double init should not harm */
176     GST_START_TEST (controller_init)
177 {
178   gst_controller_init (NULL, NULL);
179 }
180
181 GST_END_TEST;
182
183 /* tests for an element with no controlled params */
184 GST_START_TEST (controller_new_fail)
185 {
186   GstController *ctrl;
187   GstElement *elem;
188
189   elem = gst_element_factory_make ("fakesrc", "test_source");
190
191   /* that property should not exist */
192   ctrl = gst_controller_new (G_OBJECT (elem), "_schrompf_", NULL);
193   fail_unless (ctrl == NULL, NULL);
194
195   g_object_unref (elem);
196 }
197
198 GST_END_TEST;
199
200 /* tests for an element with controlled params */
201 GST_START_TEST (controller_new_okay1)
202 {
203   GstController *ctrl;
204   GstElement *elem;
205
206   elem = gst_element_factory_make ("testmonosource", "test_source");
207
208   /* that property should exist and should be controllable */
209   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
210   fail_unless (ctrl != NULL, NULL);
211
212   g_object_unref (ctrl);
213   g_object_unref (elem);
214 }
215
216 GST_END_TEST;
217
218 /* controlling several params should return the same controller */
219 GST_START_TEST (controller_new_okay2)
220 {
221   GstController *ctrl1, *ctrl2;
222   GstElement *elem;
223
224   elem = gst_element_factory_make ("testmonosource", "test_source");
225
226   /* that property should exist and should be controllable */
227   ctrl1 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
228   fail_unless (ctrl1 != NULL, NULL);
229
230   /* that property should exist and should be controllable */
231   ctrl2 = gst_controller_new (G_OBJECT (elem), "double", NULL);
232   fail_unless (ctrl2 != NULL, NULL);
233   fail_unless (ctrl1 == ctrl2, NULL);
234
235   g_object_unref (ctrl2);
236   g_object_unref (ctrl1);
237   g_object_unref (elem);
238 }
239
240 GST_END_TEST;
241
242 /* controlling a params twice should be handled */
243 GST_START_TEST (controller_param_twice)
244 {
245   GstController *ctrl;
246   GstElement *elem;
247   gboolean res;
248
249   elem = gst_element_factory_make ("testmonosource", "test_source");
250
251   /* that property should exist and should be controllable */
252   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "ulong", NULL);
253   fail_unless (ctrl != NULL, NULL);
254
255   /* it should have been added at least once, let remove it */
256   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
257   fail_unless (res, NULL);
258
259   /* removing it agian should not work */
260   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
261   fail_unless (!res, NULL);
262
263   g_object_unref (ctrl);
264   g_object_unref (elem);
265 }
266
267 GST_END_TEST;
268
269 /* tests if we cleanup properly */
270 GST_START_TEST (controller_finalize)
271 {
272   GstController *ctrl;
273   GstElement *elem;
274
275   elem = gst_element_factory_make ("testmonosource", "test_source");
276
277   /* that property should exist and should be controllable */
278   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
279   fail_unless (ctrl != NULL, NULL);
280
281   /* free the controller */
282   g_object_unref (ctrl);
283
284   /* object shouldn't have a controller anymore */
285   ctrl = gst_object_get_controller (G_OBJECT (elem));
286   fail_unless (ctrl == NULL, NULL);
287
288   g_object_unref (elem);
289 }
290
291 GST_END_TEST;
292
293 /* test timed value handling without interpolation */
294 GST_START_TEST (controller_interpolate_none)
295 {
296   GstController *ctrl;
297   GstElement *elem;
298   gboolean res;
299   GValue val_ulong = { 0, };
300
301   elem = gst_element_factory_make ("testmonosource", "test_source");
302
303   /* that property should exist and should be controllable */
304   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
305   fail_unless (ctrl != NULL, NULL);
306
307   /* set interpolation mode */
308   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
309
310   /* set control values */
311   g_value_init (&val_ulong, G_TYPE_ULONG);
312   g_value_set_ulong (&val_ulong, 0);
313   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
314   fail_unless (res, NULL);
315   g_value_set_ulong (&val_ulong, 100);
316   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
317   fail_unless (res, NULL);
318
319   /* now pull in values for some timestamps */
320   gst_controller_sink_values (ctrl, 0 * GST_SECOND);
321   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
322   gst_controller_sink_values (ctrl, 1 * GST_SECOND);
323   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
324   gst_controller_sink_values (ctrl, 2 * GST_SECOND);
325   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
326
327   g_object_unref (ctrl);
328   g_object_unref (elem);
329 }
330
331 GST_END_TEST;
332
333 /* @TODO write more tests (using an internal element that has controlable params)
334  */
335 Suite *
336 gst_controller_suite (void)
337 {
338   Suite *s = suite_create ("Controller");
339   TCase *tc = tcase_create ("general");
340
341   suite_add_tcase (s, tc);
342   tcase_add_test (tc, controller_init);
343   tcase_add_test (tc, controller_new_fail);
344   tcase_add_test (tc, controller_new_okay1);
345   tcase_add_test (tc, controller_new_okay2);
346   tcase_add_test (tc, controller_param_twice);
347   tcase_add_test (tc, controller_finalize);
348   tcase_add_test (tc, controller_interpolate_none);
349
350   return s;
351 }
352
353 int
354 main (int argc, char **argv)
355 {
356   int nf;
357
358   Suite *s = gst_controller_suite ();
359   SRunner *sr = srunner_create (s);
360
361   gst_check_init (&argc, &argv);
362   gst_controller_init (NULL, NULL);
363
364   srunner_run_all (sr, CK_NORMAL);
365   nf = srunner_ntests_failed (sr);
366   srunner_free (sr);
367
368   return nf;
369 }