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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <gst/check/gstcheck.h>
27
28 #include <string.h>
29
30 #ifndef GST_DISABLE_GST_DEBUG
31
32 static GList *messages; /* NULL */
33 static gboolean save_messages; /* FALSE */
34
35 static void
printf_extension_log_func(GstDebugCategory * category,GstDebugLevel level,const gchar * file,const gchar * function,gint line,GObject * object,GstDebugMessage * message,gpointer unused)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)
39 {
40 const gchar *dbg_msg;
41
42 dbg_msg = gst_debug_message_get (message);
43 fail_unless (dbg_msg != NULL);
44
45 if (save_messages && g_str_equal (category->name, "check"))
46 messages = g_list_append (messages, g_strdup (dbg_msg));
47
48 /* g_print ("%s\n", dbg_msg); */
49
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,
53 message, unused);
54 }
55 }
56
57 /* check our GST_PTR_FORMAT printf extension stuff */
GST_START_TEST(info_ptr_format_printf_extension)58 GST_START_TEST (info_ptr_format_printf_extension)
59 {
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);
64
65 gst_debug_set_default_threshold (GST_LEVEL_LOG);
66
67 /* NULL object */
68 GST_LOG ("NULL: %" GST_PTR_FORMAT, (gpointer) NULL);
69
70 /* structure */
71 {
72 GstStructure *s;
73
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);
77
78 GST_LOG ("STRUCTURE: %" GST_PTR_FORMAT, s);
79 gst_structure_free (s);
80 }
81
82 /* message */
83 {
84 GstMessage *msg;
85
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,
89 56000, NULL));
90
91 GST_LOG ("MESSAGE: %" GST_PTR_FORMAT, msg);
92 gst_message_unref (msg);
93 }
94
95 /* buffer and buffer list */
96 {
97 GstBufferList *list;
98 GstBuffer *buf;
99
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);
104
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);
111 }
112
113 #if 0
114 /* TODO: GObject */
115 {
116 GST_LOG ("GOBJECT: %" GST_PTR_FORMAT, obj);
117 }
118
119 /* TODO: GstObject */
120 {
121 GST_LOG ("GSTOBJECT: %" GST_PTR_FORMAT, obj);
122 }
123
124 /* TODO: GstPad */
125 {
126 GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
127 }
128
129 /* TODO: GstCaps */
130 {
131 GST_LOG ("PAD: %" GST_PTR_FORMAT, pad);
132 }
133 #endif
134
135 /* clean up */
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);
139 }
140
141 GST_END_TEST;
142
143 /* check our GST_SEGMENT_FORMAT printf extension stuff */
GST_START_TEST(info_segment_format_printf_extension)144 GST_START_TEST (info_segment_format_printf_extension)
145 {
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);
150
151 gst_debug_set_default_threshold (GST_LEVEL_LOG);
152
153 /* TIME segment */
154 {
155 GstSegment segment;
156
157 gst_segment_init (&segment, GST_FORMAT_TIME);
158
159 segment.rate = 1.0;
160 segment.applied_rate = 2.0;
161 segment.start = 0;
162 segment.stop = 5 * 60 * GST_SECOND;
163 segment.time = 0;
164
165 segment.position = 2 * GST_SECOND;
166 segment.duration = 90 * 60 * GST_SECOND;
167
168 GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
169 }
170
171 /* BYTE segment */
172 {
173 GstSegment segment;
174
175 gst_segment_init (&segment, GST_FORMAT_BYTES);
176
177 segment.rate = 1.0;
178 segment.applied_rate = 1.0;
179 segment.start = 0;
180 segment.stop = 9999999;
181 segment.time = 0;
182
183 GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
184 }
185
186 /* UNKNOWN format segment (format numbers are consecutive from 0) */
187 {
188 GstSegment segment;
189
190 gst_segment_init (&segment, 98765432);
191
192 segment.rate = 1.0;
193 segment.applied_rate = 1.0;
194 segment.start = 0;
195 segment.stop = 987654321;
196 segment.time = 0;
197
198 GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
199 }
200
201 /* UNDEFINED format segment */
202 {
203 GstSegment segment;
204
205 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
206
207 GST_LOG ("UNDEFINED: %" GST_SEGMENT_FORMAT, &segment);
208 }
209
210 /* NULL segment */
211 GST_LOG ("NULL: %" GST_SEGMENT_FORMAT, (GstSegment *) NULL);
212
213 /* clean up */
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);
217 }
218
219 GST_END_TEST;
220
GST_START_TEST(info_log_handler)221 GST_START_TEST (info_log_handler)
222 {
223 guint removed;
224
225 removed = gst_debug_remove_log_function (gst_debug_log_default);
226 fail_unless_equals_int (removed, 1);
227 }
228
229 GST_END_TEST;
230
231 static void
compare_gst_log_func(GstDebugCategory * category,GstDebugLevel level,const gchar * file,const gchar * function,gint line,GObject * object,GstDebugMessage * message,gpointer user_data)232 compare_gst_log_func (GstDebugCategory * category, GstDebugLevel level,
233 const gchar * file, const gchar * function, gint line, GObject * object,
234 GstDebugMessage * message, gpointer user_data)
235 {
236 gboolean match;
237 gchar *log_line;
238
239 fail_unless_equals_pointer (user_data, NULL);
240
241 log_line = gst_debug_log_get_line (category, level, file, function, line,
242 object, message);
243
244 match = g_pattern_match_simple ("*:*:*.*0*DEBUG*check*gstinfo.c:*"
245 ":info_log_handler_get_line: test message\n", log_line);
246 fail_unless_equals_int (match, TRUE);
247 g_free (log_line);
248 }
249
GST_START_TEST(info_log_handler_get_line)250 GST_START_TEST (info_log_handler_get_line)
251 {
252 gst_debug_remove_log_function (gst_debug_log_default);
253 gst_debug_add_log_function (compare_gst_log_func, NULL, NULL);
254
255 gst_debug_set_default_threshold (GST_LEVEL_LOG);
256 GST_DEBUG ("test message");
257
258 /* clean up */
259 gst_debug_set_default_threshold (GST_LEVEL_NONE);
260 gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
261 gst_debug_remove_log_function (compare_gst_log_func);
262 }
263
264 GST_END_TEST;
265
GST_START_TEST(info_dump_mem)266 GST_START_TEST (info_dump_mem)
267 {
268 GstDebugCategory *cat = NULL;
269 GstElement *e;
270
271 const guint8 data[] = { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
272 0x71, 0x74, 0x20, 0x20, 0x20, 0x05, 0x03, 0x00, 0x71, 0x74, 0x20, 0x20,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0xef, 0xe1, 0x6d, 0x6f, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x6c,
275 0x6d, 0x76, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xd1, 0x00, 0x1d,
276 0xbf, 0xd1, 0x00, 0x1e, 0x00, 0x00, 0x0b, 0xb5, 0x00, 0x04, 0x59, 0xc5,
277 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, '%', 's', '%', 's'
279 };
280
281 e = gst_pipeline_new ("pipeline");
282 GST_DEBUG_CATEGORY_INIT (cat, "dumpcat", 0, "data dump debug category");
283 GST_MEMDUMP ("quicktime header", data, sizeof (data));
284 GST_MEMDUMP (NULL, data, sizeof (data));
285 GST_CAT_MEMDUMP (cat, "quicktime header", data, sizeof (data));
286 GST_MEMDUMP_OBJECT (e, "object stuff", data, sizeof (data));
287 GST_CAT_MEMDUMP_OBJECT (cat, e, "object/cat stuff", data, sizeof (data));
288 gst_object_unref (e);
289 }
290
291 GST_END_TEST;
292
GST_START_TEST(info_fixme)293 GST_START_TEST (info_fixme)
294 {
295 GstDebugCategory *cat = NULL;
296 GstElement *e;
297
298 e = gst_pipeline_new ("pipeline");
299 GST_DEBUG_CATEGORY_INIT (cat, "fixcat", 0, "FIXME debug category");
300 GST_FIXME ("fix %s thing", "this");
301 GST_FIXME_OBJECT (e, "fix %s object", "this");
302 GST_CAT_FIXME (cat, "fix some%s in this category", "thing");
303 GST_CAT_FIXME_OBJECT (cat, e, "fix some%s in this cat and object", "thing");
304 gst_object_unref (e);
305 }
306
307 GST_END_TEST;
308
309 /* need this indirection so the compiler doesn't check the printf format
310 * like it would if we used GST_INFO directly (it would complain) */
311 static void
call_GST_INFO(const gchar * format,...)312 call_GST_INFO (const gchar * format, ...)
313 {
314 va_list var_args;
315
316 va_start (var_args, format);
317 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_INFO, __FILE__, GST_FUNCTION,
318 __LINE__, NULL, format, var_args);
319 va_end (var_args);
320 }
321
GST_START_TEST(info_old_printf_extensions)322 GST_START_TEST (info_old_printf_extensions)
323 {
324 GstSegment segment;
325 GstCaps *caps;
326 gchar *str;
327
328 /* set up our own log function to make sure the code in gstinfo is actually
329 * executed without GST_DEBUG being set or it being output to stdout */
330 gst_debug_remove_log_function (gst_debug_log_default);
331 gst_debug_add_log_function (printf_extension_log_func, NULL, NULL);
332
333 gst_debug_set_default_threshold (GST_LEVEL_LOG);
334
335 save_messages = TRUE;
336
337 fail_unless (messages == NULL);
338
339 gst_segment_init (&segment, GST_FORMAT_TIME);
340 caps = gst_caps_new_simple ("foo/bar", "width", G_TYPE_INT, 4096,
341 "framerate", GST_TYPE_FRACTION, 50, 1, "format", G_TYPE_STRING, "ARGB",
342 NULL);
343 call_GST_INFO ("Segment %Q, caps are %P", &segment, caps);
344 gst_caps_unref (caps);
345
346 fail_unless_equals_int (g_list_length (messages), 1);
347 str = (gchar *) messages->data;
348 fail_unless (str != NULL);
349
350 GST_INFO ("str = '%s'", str);
351
352 fail_unless (strstr (str, "time") != NULL);
353 fail_unless (strstr (str, "start=0:00:00.000000000") != NULL);
354 fail_unless (strstr (str, "stop=99:99:99.999999999") != NULL);
355 fail_unless (strstr (str, "applied_rate=1.000000") != NULL);
356
357 fail_unless (strstr (str, " caps are ") != NULL);
358 fail_unless (strstr (str, "foo/bar") != NULL);
359 fail_unless (strstr (str, "width=(int)4096") != NULL);
360 fail_unless (strstr (str, "framerate=(fraction)50/1") != NULL);
361 fail_unless (strstr (str, "ARGB") != NULL);
362
363 /* clean up */
364 gst_debug_set_default_threshold (GST_LEVEL_NONE);
365 gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
366 gst_debug_remove_log_function (printf_extension_log_func);
367 save_messages = FALSE;
368 g_list_free_full (messages, (GDestroyNotify) g_free);
369 messages = NULL;
370 }
371
372 GST_END_TEST;
373
GST_START_TEST(info_register_same_debug_category_twice)374 GST_START_TEST (info_register_same_debug_category_twice)
375 {
376 GstDebugCategory *cat1 = NULL, *cat2 = NULL;
377
378 GST_DEBUG_CATEGORY_INIT (cat1, "dupli-cat", 0, "Going once");
379 GST_DEBUG_CATEGORY_INIT (cat2, "dupli-cat", 0, "Going twice");
380
381 fail_unless_equals_pointer (cat1, cat2);
382
383 fail_unless_equals_string (gst_debug_category_get_name (cat1), "dupli-cat");
384 fail_unless_equals_string (gst_debug_category_get_description (cat1),
385 "Going once");
386 }
387
388 GST_END_TEST;
389
GST_START_TEST(info_set_and_unset_single)390 GST_START_TEST (info_set_and_unset_single)
391 {
392 GstDebugLevel orig = gst_debug_get_default_threshold ();
393 GstDebugLevel cat1, cat2;
394 GstDebugCategory *states;
395
396 GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
397 fail_unless (states != NULL);
398
399 gst_debug_set_default_threshold (GST_LEVEL_WARNING);
400
401 gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
402 cat1 = gst_debug_category_get_threshold (states);
403 gst_debug_unset_threshold_for_name ("GST_STATES");
404 cat2 = gst_debug_category_get_threshold (states);
405
406 gst_debug_set_default_threshold (orig);
407 fail_unless_equals_int (cat1, GST_LEVEL_DEBUG);
408 fail_unless_equals_int (cat2, GST_LEVEL_WARNING);
409 }
410
411 GST_END_TEST;
412
GST_START_TEST(info_set_and_unset_multiple)413 GST_START_TEST (info_set_and_unset_multiple)
414 {
415 GstDebugLevel orig = gst_debug_get_default_threshold ();
416 GstDebugLevel cat1, cat2, cat3;
417 GstDebugCategory *states;
418 GstDebugCategory *caps;
419
420 GST_DEBUG_CATEGORY_GET (states, "GST_STATES");
421 GST_DEBUG_CATEGORY_GET (caps, "GST_CAPS");
422 fail_unless (states != NULL);
423 fail_unless (caps != NULL);
424
425 gst_debug_set_default_threshold (GST_LEVEL_WARNING);
426
427 gst_debug_set_threshold_for_name ("GST_STATES", GST_LEVEL_DEBUG);
428 gst_debug_set_threshold_for_name ("GST_CAPS", GST_LEVEL_DEBUG);
429 cat1 = gst_debug_category_get_threshold (states);
430 gst_debug_unset_threshold_for_name ("GST_STATES");
431 gst_debug_unset_threshold_for_name ("GST_CAPS");
432 cat2 = gst_debug_category_get_threshold (states);
433 cat3 = gst_debug_category_get_threshold (caps);
434
435 gst_debug_set_default_threshold (orig);
436
437 fail_unless_equals_int (cat1, GST_LEVEL_DEBUG);
438 fail_unless_equals_int (cat2, GST_LEVEL_WARNING);
439 fail_unless_equals_int (cat3, GST_LEVEL_WARNING);
440 }
441
442 GST_END_TEST;
443 #endif
444
GST_START_TEST(info_fourcc)445 GST_START_TEST (info_fourcc)
446 {
447 gchar *res;
448 const gchar *cmp;
449
450 cmp = "abcd";
451 res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x64636261));
452 fail_unless_equals_string (res, cmp);
453 g_free (res);
454
455 cmp = ".bcd";
456 res = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (0x646362a9));
457 fail_unless_equals_string (res, cmp);
458 g_free (res);
459 }
460
461 GST_END_TEST;
462
463 /* Here we're testing adding debug categories after gst_init() and making
464 * sure that this doesn't incur exponential costs. Previously this would
465 * reparse the debug string and re-add the parsed category/levels to the
466 * list, thus doubling the list to pattern match a category against for
467 * every category added. And we would also re-evaluate all existing categories
468 * against that list. This test makes sure the overhead of registering debug
469 * categories late is very small. This test would time out before the fix. */
GST_START_TEST(info_post_gst_init_category_registration)470 GST_START_TEST (info_post_gst_init_category_registration)
471 {
472 GstDebugCategory *cats[10000] = { NULL, };
473 guint i;
474
475 /* Note: before the fixes this wouldn't work to trigger the problem because
476 * only a pattern set via GST_DEBUG before gst_init would be picked up
477 * (another bug) */
478 gst_debug_set_threshold_from_string ("*a*b:6,*b*0:6,*c:3,d*:2,xyz*:9,ax:1",
479 TRUE);
480
481 fail_unless_equals_int (GST_LEVEL_DEFAULT,
482 gst_debug_get_default_threshold ());
483
484 for (i = 0; i < G_N_ELEMENTS (cats); ++i) {
485 gchar *name = g_strdup_printf ("%s-%x", (i % 2 == 0) ? "cat" : "dog", i);
486 GST_DEBUG_CATEGORY_INIT (cats[i], name, 0, "none");
487 g_free (name);
488 }
489
490 /* These checks will only work if no one else set anything externally */
491 if (g_getenv ("GST_DEBUG") == NULL) {
492 /* none */
493 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0]),
494 GST_LEVEL_DEFAULT);
495 /* d*:2 */
496 fail_unless_equals_int (gst_debug_category_get_threshold (cats[1]),
497 GST_LEVEL_WARNING);
498 /* none */
499 fail_unless_equals_int (gst_debug_category_get_threshold (cats[2]),
500 GST_LEVEL_DEFAULT);
501 /* d*:2 */
502 fail_unless_equals_int (gst_debug_category_get_threshold (cats[3]),
503 GST_LEVEL_WARNING);
504 /* *c:3 */
505 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xc]),
506 GST_LEVEL_FIXME);
507 /* *c:3 */
508 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0x4c]),
509 GST_LEVEL_FIXME);
510 /* *a*b:6 and d*:2, but d*:2 takes priority here as cat name is "dog-a1b"
511 * and order matters: items listed later override earlier ones. */
512 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xa1b]),
513 GST_LEVEL_WARNING);
514 /* *a*0:6 */
515 fail_unless_equals_int (gst_debug_category_get_threshold (cats[0xb10]),
516 GST_LEVEL_LOG);
517 }
518 }
519
520 GST_END_TEST;
521
522 static Suite *
gst_info_suite(void)523 gst_info_suite (void)
524 {
525 Suite *s = suite_create ("GstInfo");
526 TCase *tc_chain = tcase_create ("info");
527
528 tcase_set_timeout (tc_chain, 30);
529
530 suite_add_tcase (s, tc_chain);
531 tcase_add_test (tc_chain, info_fourcc);
532 #ifndef GST_DISABLE_GST_DEBUG
533 tcase_add_test (tc_chain, info_segment_format_printf_extension);
534 tcase_add_test (tc_chain, info_ptr_format_printf_extension);
535 tcase_add_test (tc_chain, info_log_handler);
536 tcase_add_test (tc_chain, info_log_handler_get_line);
537 tcase_add_test (tc_chain, info_dump_mem);
538 tcase_add_test (tc_chain, info_fixme);
539 tcase_add_test (tc_chain, info_old_printf_extensions);
540 tcase_add_test (tc_chain, info_register_same_debug_category_twice);
541 tcase_add_test (tc_chain, info_set_and_unset_single);
542 tcase_add_test (tc_chain, info_set_and_unset_multiple);
543 tcase_add_test (tc_chain, info_post_gst_init_category_registration);
544 #endif
545
546 return s;
547 }
548
549 GST_CHECK_MAIN (gst_info);
550