3 * Unit tests for GstInfo
5 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
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.
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.
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.
26 #include <gst/check/gstcheck.h>
30 #ifndef GST_DISABLE_GST_DEBUG
32 static GList *messages; /* NULL */
33 static gboolean save_messages; /* FALSE */
36 printf_extension_log_func (GstDebugCategory * category,
37 GstDebugLevel level, const gchar * file, const gchar * function,
38 gint line, GObject * object, GstDebugMessage * message, gpointer unused)
42 dbg_msg = gst_debug_message_get (message);
43 fail_unless (dbg_msg != NULL);
45 if (save_messages && g_str_equal (category->name, "check"))
46 messages = g_list_append (messages, g_strdup (dbg_msg));
48 /* g_print ("%s\n", dbg_msg); */
50 /* quick hack to still get stuff to show if GST_DEBUG is set */
51 if (g_getenv ("GST_DEBUG")) {
52 gst_debug_log_default (category, level, file, function, line, object,
57 /* check our GST_PTR_FORMAT printf extension stuff */
58 GST_START_TEST (info_ptr_format_printf_extension)
60 /* set up our own log function to make sure the code in gstinfo is actually
61 * executed without GST_DEBUG being set or it being output to stdout */
62 gst_debug_remove_log_function (gst_debug_log_default);
63 gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
65 gst_debug_set_default_threshold (GST_LEVEL_LOG);
68 GST_LOG ("NULL: %" GST_PTR_FORMAT, (gpointer) NULL);
74 s = gst_structure_new ("foo/bar", "number", G_TYPE_INT, 1,
75 "string", G_TYPE_STRING, "s", "float-number", G_TYPE_DOUBLE,
76 (gdouble) 424242.42, NULL);
78 GST_LOG ("STRUCTURE: %" GST_PTR_FORMAT, s);
79 gst_structure_free (s);
86 msg = gst_message_new_element (NULL,
87 gst_structure_new ("redirect", "new-location", G_TYPE_STRING,
88 "http://foobar.com/r0x0r.ogg", "minimum-bitrate", G_TYPE_INT,
91 GST_LOG ("MESSAGE: %" GST_PTR_FORMAT, msg);
92 gst_message_unref (msg);
95 /* buffer and buffer list */
100 buf = gst_buffer_new_allocate (NULL, 42, NULL);
101 GST_BUFFER_PTS (buf) = 5 * GST_SECOND;
102 GST_BUFFER_DURATION (buf) = GST_SECOND;
103 GST_LOG ("BUFFER: %" GST_PTR_FORMAT, buf);
105 list = gst_buffer_list_new ();
106 gst_buffer_list_add (list, buf);
107 buf = gst_buffer_new_allocate (NULL, 58, NULL);
108 gst_buffer_list_add (list, buf);
109 GST_LOG ("BUFFERLIST: %" GST_PTR_FORMAT, list);
110 gst_buffer_list_unref (list);
116 GST_LOG ("GOBJECT: %" GST_PTR_FORMAT, obj);
119 /* TODO: GstObject */
121 GST_LOG ("GSTOBJECT: %" GST_PTR_FORMAT, obj);
126 GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
131 GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
136 gst_debug_set_default_threshold (GST_LEVEL_NONE);
137 gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
138 gst_debug_remove_log_function (printf_extension_log_func);
143 /* check our GST_SEGMENT_FORMAT printf extension stuff */
144 GST_START_TEST (info_segment_format_printf_extension)
146 /* set up our own log function to make sure the code in gstinfo is actually
147 * executed without GST_DEBUG being set or it being output to stdout */
148 gst_debug_remove_log_function (gst_debug_log_default);
149 gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
151 gst_debug_set_default_threshold (GST_LEVEL_LOG);
157 gst_segment_init (&segment, GST_FORMAT_TIME);
160 segment.applied_rate = 2.0;
162 segment.stop = 5 * 60 * GST_SECOND;
165 segment.position = 2 * GST_SECOND;
166 segment.duration = 90 * 60 * GST_SECOND;
168 GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
175 gst_segment_init (&segment, GST_FORMAT_BYTES);
178 segment.applied_rate = 1.0;
180 segment.stop = 9999999;
183 GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
186 /* UNKNOWN format segment (format numbers are consecutive from 0) */
190 gst_segment_init (&segment, 98765432);
193 segment.applied_rate = 1.0;
195 segment.stop = 987654321;
198 GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
201 /* UNDEFINED format segment */
205 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
207 GST_LOG ("UNDEFINED: %" GST_SEGMENT_FORMAT, &segment);
211 GST_LOG ("NULL: %" GST_SEGMENT_FORMAT, (GstSegment *) NULL);
214 gst_debug_set_default_threshold (GST_LEVEL_NONE);
215 gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
216 gst_debug_remove_log_function (printf_extension_log_func);
221 GST_START_TEST (info_log_handler)
225 removed = gst_debug_remove_log_function (gst_debug_log_default);
226 fail_unless_equals_int (removed, 1);
231 GST_START_TEST (info_dump_mem)
233 GstDebugCategory *cat = NULL;
236 const guint8 data[] = { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
237 0x71, 0x74, 0x20, 0x20, 0x20, 0x05, 0x03, 0x00, 0x71, 0x74, 0x20, 0x20,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0xef, 0xe1, 0x6d, 0x6f, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x6c,
240 0x6d, 0x76, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xd1, 0x00, 0x1d,
241 0xbf, 0xd1, 0x00, 0x1e, 0x00, 0x00, 0x0b, 0xb5, 0x00, 0x04, 0x59, 0xc5,
242 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, '%', 's', '%', 's'
246 e = gst_pipeline_new ("pipeline");
247 GST_DEBUG_CATEGORY_INIT (cat, "dumpcat", 0, "data dump debug category");
248 GST_MEMDUMP ("quicktime header", data, sizeof (data));
249 GST_MEMDUMP (NULL, data, sizeof (data));
250 GST_CAT_MEMDUMP (cat, "quicktime header", data, sizeof (data));
251 GST_MEMDUMP_OBJECT (e, "object stuff", data, sizeof (data));
252 GST_CAT_MEMDUMP_OBJECT (cat, e, "object/cat stuff", data, sizeof (data));
253 gst_object_unref (e);
258 GST_START_TEST (info_fixme)
260 GstDebugCategory *cat = NULL;
263 e = gst_pipeline_new ("pipeline");
264 GST_DEBUG_CATEGORY_INIT (cat, "fixcat", 0, "FIXME debug category");
265 GST_FIXME ("fix %s thing", "this");
266 GST_FIXME_OBJECT (e, "fix %s object", "this");
267 GST_CAT_FIXME (cat, "fix some%s in this category", "thing");
268 GST_CAT_FIXME_OBJECT (cat, e, "fix some%s in this cat and object", "thing");
269 gst_object_unref (e);
274 /* need this indirection so the compiler doesn't check the printf format
275 * like it would if we used GST_INFO directly (it would complain) */
277 call_GST_INFO (const gchar * format, ...)
281 va_start (var_args, format);
282 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_INFO, __FILE__, GST_FUNCTION,
283 __LINE__, NULL, format, var_args);
287 GST_START_TEST (info_old_printf_extensions)
293 /* set up our own log function to make sure the code in gstinfo is actually
294 * executed without GST_DEBUG being set or it being output to stdout */
295 gst_debug_remove_log_function (gst_debug_log_default);
296 gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
298 gst_debug_set_default_threshold (GST_LEVEL_LOG);
300 save_messages = TRUE;
302 fail_unless (messages == NULL);
304 gst_segment_init (&segment, GST_FORMAT_TIME);
305 caps = gst_caps_new_simple ("foo/bar", "width", G_TYPE_INT, 4096,
306 "framerate", GST_TYPE_FRACTION, 50, 1, "format", G_TYPE_STRING, "ARGB",
308 call_GST_INFO ("Segment %Q, caps are %P", &segment, caps);
309 gst_caps_unref (caps);
311 fail_unless_equals_int (g_list_length (messages), 1);
312 str = (gchar *) messages->data;
313 fail_unless (str != NULL);
315 GST_INFO ("str = '%s'", str);
317 fail_unless (strstr (str, "time") != NULL);
318 fail_unless (strstr (str, "start=0:00:00.000000000") != NULL);
319 fail_unless (strstr (str, "stop=99:99:99.999999999") != NULL);
320 fail_unless (strstr (str, "applied_rate=1.000000") != NULL);
322 fail_unless (strstr (str, " caps are ") != NULL);
323 fail_unless (strstr (str, "foo/bar") != NULL);
324 fail_unless (strstr (str, "width=(int)4096") != NULL);
325 fail_unless (strstr (str, "framerate=(fraction)50/1") != NULL);
326 fail_unless (strstr (str, "ARGB") != NULL);
329 gst_debug_set_default_threshold (GST_LEVEL_NONE);
330 gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
331 gst_debug_remove_log_function (printf_extension_log_func);
332 save_messages = FALSE;
333 g_list_free_full (messages, (GDestroyNotify) g_free);
339 GST_START_TEST (info_register_same_debug_category_twice)
341 GstDebugCategory *cat1 = NULL, *cat2 = NULL;
343 GST_DEBUG_CATEGORY_INIT (cat1, "dupli-cat", 0, "Going once");
344 GST_DEBUG_CATEGORY_INIT (cat2, "dupli-cat", 0, "Going twice");
346 fail_unless_equals_pointer (cat1, cat2);
348 fail_unless_equals_string (gst_debug_category_get_name (cat1), "dupli-cat");
349 fail_unless_equals_string (gst_debug_category_get_description (cat1),
355 GST_START_TEST (info_set_and_unset_single)
357 GstDebugLevel orig = gst_debug_get_default_threshold ();
358 GstDebugLevel cat1, cat2;
359 GstDebugCategory *states;
361 GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
362 fail_unless (states != NULL);
364 gst_debug_set_default_threshold (GST_LEVEL_WARNING);
366 gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
367 cat1 = gst_debug_category_get_threshold (states);
368 gst_debug_unset_threshold_for_name ("GST_STATES");
369 cat2 = gst_debug_category_get_threshold (states);
371 gst_debug_set_default_threshold (orig);
372 fail_unless_equals_int (cat1, GST_LEVEL_DEBUG);
373 fail_unless_equals_int (cat2, GST_LEVEL_WARNING);
378 GST_START_TEST (info_set_and_unset_multiple)
380 GstDebugLevel orig = gst_debug_get_default_threshold ();
381 GstDebugLevel cat1, cat2, cat3;
382 GstDebugCategory *states;
383 GstDebugCategory *caps;
385 GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
386 GST_DEBUG_CATEGORY_GET (caps, "GST_CAPS");
387 fail_unless (states != NULL);
388 fail_unless (caps != NULL);
390 gst_debug_set_default_threshold (GST_LEVEL_WARNING);
392 gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
393 gst_debug_set_threshold_for_name ("GST_CAPS", GST_LEVEL_DEBUG);
394 cat1 = gst_debug_category_get_threshold (states);
395 gst_debug_unset_threshold_for_name ("GST_STATES");
396 gst_debug_unset_threshold_for_name ("GST_CAPS");
397 cat2 = gst_debug_category_get_threshold (states);
398 cat3 = gst_debug_category_get_threshold (caps);
400 gst_debug_set_default_threshold (orig);
402 fail_unless_equals_int (cat1, GST_LEVEL_DEBUG);
403 fail_unless_equals_int (cat2, GST_LEVEL_WARNING);
404 fail_unless_equals_int (cat3, GST_LEVEL_WARNING);
410 GST_START_TEST (info_fourcc)
416 res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x64636261));
417 fail_unless_equals_string (res, cmp);
421 res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x646362a9));
422 fail_unless_equals_string (res, cmp);
428 /* Here we're testing adding debug categories after gst_init() and making
429 * sure that this doesn't incur exponential costs. Previously this would
430 * reparse the debug string and re-add the parsed category/levels to the
431 * list, thus doubling the list to pattern match a category against for
432 * every category added. And we would also re-evaluate all existing categories
433 * against that list. This test makes sure the overhead of registering debug
434 * categories late is very small. This test would time out before the fix. */
435 GST_START_TEST (info_post_gst_init_category_registration)
437 GstDebugCategory *cats[10000] = { NULL, };
440 /* Note: before the fixes this wouldn't work to trigger the problem because
441 * only a pattern set via GST_DEBUG before gst_init would be picked up
443 gst_debug_set_threshold_from_string ("*a*b:6,*b*0:6,*c:3,d*:2,xyz*:9,ax:1",
446 fail_unless_equals_int (GST_LEVEL_DEFAULT,
447 gst_debug_get_default_threshold ());
449 for (i = 0; i < G_N_ELEMENTS (cats); ++i) {
450 gchar *name = g_strdup_printf ("%s-%x", (i % 2 == 0) ? "cat" : "dog", i);
451 GST_DEBUG_CATEGORY_INIT (cats[i], name, 0, "none");
455 /* These checks will only work if no one else set anything externally */
456 if (g_getenv ("GST_DEBUG") == NULL) {
458 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0]),
461 fail_unless_equals_int (gst_debug_category_get_threshold (cats[1]),
464 fail_unless_equals_int (gst_debug_category_get_threshold (cats[2]),
467 fail_unless_equals_int (gst_debug_category_get_threshold (cats[3]),
470 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xc]),
473 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0x4c]),
475 /* *a*b:6 and d*:2, but d*:2 takes priority here as cat name is "dog-a1b"
476 * and order matters: items listed later override earlier ones. */
477 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xa1b]),
480 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xb10]),
488 gst_info_suite (void)
490 Suite *s = suite_create ("GstInfo");
491 TCase *tc_chain = tcase_create ("info");
493 tcase_set_timeout (tc_chain, 30);
495 suite_add_tcase (s, tc_chain);
496 tcase_add_test (tc_chain, info_fourcc);
497 #ifndef GST_DISABLE_GST_DEBUG
498 tcase_add_test (tc_chain, info_segment_format_printf_extension);
499 tcase_add_test (tc_chain, info_ptr_format_printf_extension);
500 tcase_add_test (tc_chain, info_log_handler);
501 tcase_add_test (tc_chain, info_dump_mem);
502 tcase_add_test (tc_chain, info_fixme);
503 tcase_add_test (tc_chain, info_old_printf_extensions);
504 tcase_add_test (tc_chain, info_register_same_debug_category_twice);
505 tcase_add_test (tc_chain, info_set_and_unset_single);
506 tcase_add_test (tc_chain, info_set_and_unset_multiple);
507 tcase_add_test (tc_chain, info_post_gst_init_category_registration);
513 GST_CHECK_MAIN (gst_info);