tests: info: add test case to reproduce infinite loop
[platform/upstream/gstreamer.git] / tests / check / gst / gstinfo.c
1 /* GStreamer
2  *
3  * Unit tests for GstInfo
4  *
5  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 #include <string.h>
26
27 #ifndef GST_DISABLE_GST_DEBUG
28
29 static GList *messages;         /* NULL */
30 static gboolean save_messages;  /* FALSE */
31
32 static void
33 printf_extension_log_func (GstDebugCategory * category,
34     GstDebugLevel level, const gchar * file, const gchar * function,
35     gint line, GObject * object, GstDebugMessage * message, gpointer unused)
36 {
37   const gchar *dbg_msg;
38
39   dbg_msg = gst_debug_message_get (message);
40   fail_unless (dbg_msg != NULL);
41
42   if (save_messages && g_str_equal (category->name, "check"))
43     messages = g_list_append (messages, g_strdup (dbg_msg));
44
45   /* g_print ("%s\n", dbg_msg); */
46
47   /* quick hack to still get stuff to show if GST_DEBUG is set */
48   if (g_getenv ("GST_DEBUG")) {
49     gst_debug_log_default (category, level, file, function, line, object,
50         message, unused);
51   }
52 }
53
54 /* check our GST_PTR_FORMAT printf extension stuff */
55 GST_START_TEST (info_ptr_format_printf_extension)
56 {
57   /* set up our own log function to make sure the code in gstinfo is actually
58    * executed without GST_DEBUG being set or it being output to stdout */
59   gst_debug_remove_log_function (gst_debug_log_default);
60   gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
61
62   gst_debug_set_default_threshold (GST_LEVEL_LOG);
63
64   /* NULL object */
65   GST_LOG ("NULL: %" GST_PTR_FORMAT, (gpointer) NULL);
66
67   /* structure */
68   {
69     GstStructure *s;
70
71     s = gst_structure_new ("foo/bar", "number", G_TYPE_INT, 1,
72         "string", G_TYPE_STRING, "s", "float-number", G_TYPE_DOUBLE,
73         (gdouble) 424242.42, NULL);
74
75     GST_LOG ("STRUCTURE: %" GST_PTR_FORMAT, s);
76     gst_structure_free (s);
77   }
78
79   /* message */
80   {
81     GstMessage *msg;
82
83     msg = gst_message_new_element (NULL,
84         gst_structure_new ("redirect", "new-location", G_TYPE_STRING,
85             "http://foobar.com/r0x0r.ogg", "minimum-bitrate", G_TYPE_INT,
86             56000, NULL));
87
88     GST_LOG ("MESSAGE: %" GST_PTR_FORMAT, msg);
89     gst_message_unref (msg);
90   }
91
92 #if 0
93   /* TODO: GObject */
94   {
95     GST_LOG ("GOBJECT: %" GST_PTR_FORMAT, obj);
96   }
97
98   /* TODO: GstObject */
99   {
100     GST_LOG ("GSTOBJECT: %" GST_PTR_FORMAT, obj);
101   }
102
103   /* TODO: GstPad */
104   {
105     GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
106   }
107
108   /* TODO: GstCaps */
109   {
110     GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
111   }
112 #endif
113
114   /* clean up */
115   gst_debug_set_default_threshold (GST_LEVEL_NONE);
116   gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
117   gst_debug_remove_log_function (printf_extension_log_func);
118 }
119
120 GST_END_TEST;
121
122 /* check our GST_SEGMENT_FORMAT printf extension stuff */
123 GST_START_TEST (info_segment_format_printf_extension)
124 {
125   /* set up our own log function to make sure the code in gstinfo is actually
126    * executed without GST_DEBUG being set or it being output to stdout */
127   gst_debug_remove_log_function (gst_debug_log_default);
128   gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
129
130   gst_debug_set_default_threshold (GST_LEVEL_LOG);
131
132   /* TIME segment */
133   {
134     GstSegment segment;
135
136     gst_segment_init (&segment, GST_FORMAT_TIME);
137
138     segment.rate = 1.0;
139     segment.applied_rate = 2.0;
140     segment.start = 0;
141     segment.stop = 5 * 60 * GST_SECOND;
142     segment.time = 0;
143
144     segment.position = 2 * GST_SECOND;
145     segment.duration = 90 * 60 * GST_SECOND;
146
147     GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
148   }
149
150   /* BYTE segment */
151   {
152     GstSegment segment;
153
154     gst_segment_init (&segment, GST_FORMAT_BYTES);
155
156     segment.rate = 1.0;
157     segment.applied_rate = 1.0;
158     segment.start = 0;
159     segment.stop = 9999999;
160     segment.time = 0;
161
162     GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
163   }
164
165   /* UNKNOWN format segment (format numbers are consecutive from 0) */
166   {
167     GstSegment segment;
168
169     gst_segment_init (&segment, 98765432);
170
171     segment.rate = 1.0;
172     segment.applied_rate = 1.0;
173     segment.start = 0;
174     segment.stop = 987654321;
175     segment.time = 0;
176
177     GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
178   }
179
180   /* UNDEFINED format segment */
181   {
182     GstSegment segment;
183
184     gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
185
186     GST_LOG ("UNDEFINED: %" GST_SEGMENT_FORMAT, &segment);
187   }
188
189   /* NULL segment */
190   GST_LOG ("NULL: %" GST_SEGMENT_FORMAT, (GstSegment *) NULL);
191
192   /* clean up */
193   gst_debug_set_default_threshold (GST_LEVEL_NONE);
194   gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
195   gst_debug_remove_log_function (printf_extension_log_func);
196 }
197
198 GST_END_TEST;
199
200 GST_START_TEST (info_log_handler)
201 {
202   guint removed;
203
204   removed = gst_debug_remove_log_function (gst_debug_log_default);
205   fail_unless (removed == 1);
206 }
207
208 GST_END_TEST;
209
210 GST_START_TEST (info_dump_mem)
211 {
212   GstDebugCategory *cat = NULL;
213   GstElement *e;
214
215   const guint8 data[] = { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
216     0x71, 0x74, 0x20, 0x20, 0x20, 0x05, 0x03, 0x00, 0x71, 0x74, 0x20, 0x20,
217     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218     0x00, 0x00, 0xef, 0xe1, 0x6d, 0x6f, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x6c,
219     0x6d, 0x76, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xd1, 0x00, 0x1d,
220     0xbf, 0xd1, 0x00, 0x1e, 0x00, 0x00, 0x0b, 0xb5, 0x00, 0x04, 0x59, 0xc5,
221     0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, '%', 's', '%', 's'
223   };
224
225   e = gst_element_factory_make ("fakesink", NULL);
226   GST_DEBUG_CATEGORY_INIT (cat, "dumpcat", 0, "data dump debug category");
227   GST_MEMDUMP ("quicktime header", data, sizeof (data));
228   GST_MEMDUMP (NULL, data, sizeof (data));
229   GST_CAT_MEMDUMP (cat, "quicktime header", data, sizeof (data));
230   GST_MEMDUMP_OBJECT (e, "object stuff", data, sizeof (data));
231   GST_CAT_MEMDUMP_OBJECT (cat, e, "object/cat stuff", data, sizeof (data));
232   gst_object_unref (e);
233 }
234
235 GST_END_TEST;
236
237 GST_START_TEST (info_fixme)
238 {
239   GstDebugCategory *cat = NULL;
240   GstElement *e;
241
242   e = gst_element_factory_make ("fakesink", NULL);
243   GST_DEBUG_CATEGORY_INIT (cat, "fixcat", 0, "FIXME debug category");
244   GST_FIXME ("fix %s thing", "this");
245   GST_FIXME_OBJECT (e, "fix %s object", "this");
246   GST_CAT_FIXME (cat, "fix some%s in this category", "thing");
247   GST_CAT_FIXME_OBJECT (cat, e, "fix some%s in this cat and object", "thing");
248   gst_object_unref (e);
249 }
250
251 GST_END_TEST;
252
253 /* need this indirection so the compiler doesn't check the printf format
254  * like it would if we used GST_INFO directly (it would complain) */
255 static void
256 call_GST_INFO (const gchar * format, ...)
257 {
258   va_list var_args;
259
260   va_start (var_args, format);
261   gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_INFO, __FILE__, GST_FUNCTION,
262       __LINE__, NULL, format, var_args);
263   va_end (var_args);
264 }
265
266 GST_START_TEST (info_old_printf_extensions)
267 {
268   GstSegment segment;
269   GstCaps *caps;
270   gchar *str;
271
272   /* set up our own log function to make sure the code in gstinfo is actually
273    * executed without GST_DEBUG being set or it being output to stdout */
274   gst_debug_remove_log_function (gst_debug_log_default);
275   gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
276
277   gst_debug_set_default_threshold (GST_LEVEL_LOG);
278
279   save_messages = TRUE;
280
281   fail_unless (messages == NULL);
282
283   gst_segment_init (&segment, GST_FORMAT_TIME);
284   caps = gst_caps_new_simple ("foo/bar", "width", G_TYPE_INT, 4096,
285       "framerate", GST_TYPE_FRACTION, 50, 1, "format", G_TYPE_STRING, "ARGB",
286       NULL);
287   call_GST_INFO ("Segment %Q, caps are %P", &segment, caps);
288   gst_caps_unref (caps);
289
290   fail_unless_equals_int (g_list_length (messages), 1);
291   str = (gchar *) messages->data;
292   fail_unless (str != NULL);
293
294   GST_INFO ("str = '%s'", str);
295
296   fail_unless (strstr (str, "time") != NULL);
297   fail_unless (strstr (str, "start=0:00:00.000000000") != NULL);
298   fail_unless (strstr (str, "stop=99:99:99.999999999") != NULL);
299   fail_unless (strstr (str, "applied_rate=1.000000") != NULL);
300
301   fail_unless (strstr (str, " caps are ") != NULL);
302   fail_unless (strstr (str, "foo/bar") != NULL);
303   fail_unless (strstr (str, "width=(int)4096") != NULL);
304   fail_unless (strstr (str, "framerate=(fraction)50/1") != NULL);
305   fail_unless (strstr (str, "ARGB") != NULL);
306
307   /* clean up */
308   gst_debug_set_default_threshold (GST_LEVEL_NONE);
309   gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
310   gst_debug_remove_log_function (printf_extension_log_func);
311   save_messages = FALSE;
312   g_list_foreach (messages, (GFunc) g_free, NULL);
313   messages = NULL;
314 }
315
316 GST_END_TEST;
317
318 GST_START_TEST (info_register_same_debug_category_twice)
319 {
320   GstDebugCategory *cat1 = NULL, *cat2 = NULL;
321
322   GST_DEBUG_CATEGORY_INIT (cat1, "dupli-cat", 0, "Going once");
323   GST_DEBUG_CATEGORY_INIT (cat2, "dupli-cat", 0, "Going twice");
324
325   fail_unless_equals_pointer (cat1, cat2);
326
327   fail_unless_equals_string (gst_debug_category_get_name (cat1), "dupli-cat");
328   fail_unless_equals_string (gst_debug_category_get_description (cat1),
329       "Going once");
330 }
331
332 GST_END_TEST;
333
334 GST_START_TEST (info_set_and_unset_single)
335 {
336   GstDebugLevel orig = gst_debug_get_default_threshold ();
337   GstDebugLevel cat1, cat2;
338   GstDebugCategory *states;
339
340   GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
341   fail_unless (states != NULL);
342
343   gst_debug_set_default_threshold (GST_LEVEL_WARNING);
344
345   gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
346   cat1 = gst_debug_category_get_threshold (states);
347   gst_debug_unset_threshold_for_name ("GST_STATES");
348   cat2 = gst_debug_category_get_threshold (states);
349
350   gst_debug_set_default_threshold (orig);
351   fail_unless (cat1 = GST_LEVEL_DEBUG);
352   fail_unless (cat2 = GST_LEVEL_WARNING);
353 }
354
355 GST_END_TEST;
356
357 GST_START_TEST (info_set_and_unset_multiple)
358 {
359   GstDebugLevel orig = gst_debug_get_default_threshold ();
360   GstDebugLevel cat1, cat2, cat3;
361   GstDebugCategory *states;
362   GstDebugCategory *caps;
363
364   GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
365   GST_DEBUG_CATEGORY_GET (caps, "GST_CAPS");
366   fail_unless (states != NULL);
367   fail_unless (caps != NULL);
368
369   gst_debug_set_default_threshold (GST_LEVEL_WARNING);
370
371   gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
372   gst_debug_set_threshold_for_name ("GST_CAPS", GST_LEVEL_DEBUG);
373   cat1 = gst_debug_category_get_threshold (states);
374   gst_debug_unset_threshold_for_name ("GST_STATES");
375   gst_debug_unset_threshold_for_name ("GST_CAPS");
376   cat2 = gst_debug_category_get_threshold (states);
377   cat3 = gst_debug_category_get_threshold (caps);
378
379   gst_debug_set_default_threshold (orig);
380
381   fail_unless (cat1 = GST_LEVEL_DEBUG);
382   fail_unless (cat2 = GST_LEVEL_WARNING);
383   fail_unless (cat3 = GST_LEVEL_WARNING);
384 }
385
386 GST_END_TEST;
387 #endif
388
389 GST_START_TEST (info_fourcc)
390 {
391   gchar *res;
392   const gchar *cmp;
393
394   cmp = "abcd";
395   res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x64636261));
396   fail_unless_equals_string (res, cmp);
397   g_free (res);
398
399   cmp = ".bcd";
400   res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x646362a9));
401   fail_unless_equals_string (res, cmp);
402 }
403
404 GST_END_TEST;
405
406 static Suite *
407 gst_info_suite (void)
408 {
409   Suite *s = suite_create ("GstInfo");
410   TCase *tc_chain = tcase_create ("info");
411
412   tcase_set_timeout (tc_chain, 30);
413
414   suite_add_tcase (s, tc_chain);
415   tcase_add_test (tc_chain, info_fourcc);
416 #ifndef GST_DISABLE_GST_DEBUG
417   tcase_add_test (tc_chain, info_segment_format_printf_extension);
418   tcase_add_test (tc_chain, info_ptr_format_printf_extension);
419   tcase_add_test (tc_chain, info_log_handler);
420   tcase_add_test (tc_chain, info_dump_mem);
421   tcase_add_test (tc_chain, info_fixme);
422   tcase_add_test (tc_chain, info_old_printf_extensions);
423   tcase_add_test (tc_chain, info_register_same_debug_category_twice);
424   tcase_add_test (tc_chain, info_set_and_unset_single);
425   tcase_add_test (tc_chain, info_set_and_unset_multiple);
426 #endif
427
428   return s;
429 }
430
431 GST_CHECK_MAIN (gst_info);