1 #include <stdlib.h>
2 #include <string.h>
3 #define G_LOG_USE_STRUCTURED 1
4 #include <glib.h>
5
6 #ifdef G_OS_WIN32
7 #define LINE_END "\r\n"
8 #else
9 #define LINE_END "\n"
10 #endif
11
12 /* Test g_warn macros */
13 static void
14 test_warnings (void)
15 {
16 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
17 "*test_warnings*should not be reached*");
18 g_warn_if_reached ();
19 g_test_assert_expected_messages ();
20
21 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
22 "*test_warnings*runtime check failed*");
23 g_warn_if_fail (FALSE);
24 g_test_assert_expected_messages ();
25 }
26
27 static guint log_count = 0;
28
29 static void
30 log_handler (const gchar *log_domain,
31 GLogLevelFlags log_level,
32 const gchar *message,
33 gpointer user_data)
34 {
35 g_assert_cmpstr (log_domain, ==, "bu");
36 g_assert_cmpint (log_level, ==, G_LOG_LEVEL_INFO);
37
38 log_count++;
39 }
40
41 /* test that custom log handlers only get called for
42 * their domain and level
43 */
44 static void
45 test_set_handler (void)
46 {
47 guint id;
48
49 id = g_log_set_handler ("bu", G_LOG_LEVEL_INFO, log_handler, NULL);
50
51 g_log ("bu", G_LOG_LEVEL_DEBUG, "message");
52 g_log ("ba", G_LOG_LEVEL_DEBUG, "message");
53 g_log ("bu", G_LOG_LEVEL_INFO, "message");
54 g_log ("ba", G_LOG_LEVEL_INFO, "message");
55
56 g_assert_cmpint (log_count, ==, 1);
57
58 g_log_remove_handler ("bu", id);
59 }
60
61 static void
62 test_default_handler_error (void)
63 {
64 g_log_set_default_handler (g_log_default_handler, NULL);
65 g_error ("message1");
66 exit (0);
67 }
68
69 static void
70 test_default_handler_error_stderr (void)
71 {
72 g_log_writer_default_set_use_stderr (FALSE);
73 g_log_set_default_handler (g_log_default_handler, NULL);
74 g_error ("message1");
75 exit (0);
76 }
77
78 static void
79 test_default_handler_critical_stderr (void)
80 {
81 g_log_writer_default_set_use_stderr (TRUE);
82 g_log_set_default_handler (g_log_default_handler, NULL);
83 g_critical ("message2");
84 exit (0);
85 }
86
87 static void
88 test_default_handler_critical (void)
89 {
90 g_log_writer_default_set_use_stderr (FALSE);
91 g_log_set_default_handler (g_log_default_handler, NULL);
92 g_critical ("message2");
93 exit (0);
94 }
95
96 static void
97 test_default_handler_warning_stderr (void)
98 {
99 g_log_writer_default_set_use_stderr (TRUE);
100 g_log_set_default_handler (g_log_default_handler, NULL);
101 g_warning ("message3");
102 exit (0);
103 }
104
105 static void
106 test_default_handler_warning (void)
107 {
108 g_log_writer_default_set_use_stderr (FALSE);
109 g_log_set_default_handler (g_log_default_handler, NULL);
110 g_warning ("message3");
111 exit (0);
112 }
113
114 static void
115 test_default_handler_message (void)
116 {
117 g_log_writer_default_set_use_stderr (FALSE);
118 g_log_set_default_handler (g_log_default_handler, NULL);
119 g_message ("message4");
120 exit (0);
121 }
122
123 static void
124 test_default_handler_message_stderr (void)
125 {
126 g_log_writer_default_set_use_stderr (TRUE);
127 g_log_set_default_handler (g_log_default_handler, NULL);
128 g_message ("message4");
129 exit (0);
130 }
131
132 static void
133 test_default_handler_info (void)
134 {
135 g_log_writer_default_set_use_stderr (FALSE);
136 g_log_set_default_handler (g_log_default_handler, NULL);
137 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5");
138 exit (0);
139 }
140
141 static void
142 test_default_handler_info_stderr (void)
143 {
144 g_log_writer_default_set_use_stderr (TRUE);
145 g_log_set_default_handler (g_log_default_handler, NULL);
146 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5");
147 exit (0);
148 }
149
150 static void
151 test_default_handler_bar_info (void)
152 {
153 g_log_writer_default_set_use_stderr (FALSE);
154 g_log_set_default_handler (g_log_default_handler, NULL);
155
156 g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
157
158 g_log ("bar", G_LOG_LEVEL_INFO, "message5");
159 exit (0);
160 }
161
162 static void
163 test_default_handler_baz_debug (void)
164 {
165 g_log_writer_default_set_use_stderr (FALSE);
166 g_log_set_default_handler (g_log_default_handler, NULL);
167
168 g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
169
170 g_log ("baz", G_LOG_LEVEL_DEBUG, "message6");
171 exit (0);
172 }
173
174 static void
175 test_default_handler_debug (void)
176 {
177 g_log_writer_default_set_use_stderr (FALSE);
178 g_log_set_default_handler (g_log_default_handler, NULL);
179
180 g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
181
182 g_log ("foo", G_LOG_LEVEL_DEBUG, "6");
183 g_log ("bar", G_LOG_LEVEL_DEBUG, "6");
184 g_log ("baz", G_LOG_LEVEL_DEBUG, "6");
185
186 exit (0);
187 }
188
189 static void
190 test_default_handler_debug_stderr (void)
191 {
192 g_log_writer_default_set_use_stderr (TRUE);
193 g_log_set_default_handler (g_log_default_handler, NULL);
194
195 g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
196
197 g_log ("foo", G_LOG_LEVEL_DEBUG, "6");
198 g_log ("bar", G_LOG_LEVEL_DEBUG, "6");
199 g_log ("baz", G_LOG_LEVEL_DEBUG, "6");
200
201 exit (0);
202 }
203
204 static void
205 test_default_handler_would_drop_env5 (void)
206 {
207 g_setenv ("G_MESSAGES_DEBUG", "foobar", TRUE);
208
209 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
210 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
211 }
212
213 static void
214 test_default_handler_would_drop_env4 (void)
215 {
216 g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
217
218 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
219 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
220 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
221 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
222 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
223 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
224 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
225 }
226
227 static void
228 test_default_handler_would_drop_env3 (void)
229 {
230 g_setenv ("G_MESSAGES_DEBUG", "foo bar", TRUE);
231
232 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
233 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
234 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
235 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
236 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
237 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
238 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
239 }
240
241 static void
242 test_default_handler_would_drop_env2 (void)
243 {
244 g_setenv ("G_MESSAGES_DEBUG", " bar baz ", TRUE);
245
246 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
247 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
248 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
249 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
250 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
251 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
252 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
253 }
254
255 static void
256 test_default_handler_would_drop_env1 (void)
257 {
258 g_unsetenv ("G_MESSAGES_DEBUG");
259
260 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
261 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
262 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
263 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
264 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
265 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
266 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
267 }
268
269 static void
270 test_default_handler_would_drop (void)
271 {
272 g_unsetenv ("G_MESSAGES_DEBUG");
273
274 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
275 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
276 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
277 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
278 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
279 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
280 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
281
282 /* Expected to have no effect */
283 g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
284
285 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
286 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
287 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
288 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
289 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
290 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
291 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
292
293 {
294 const gchar *domains[] = { "all", NULL };
295 g_log_writer_default_set_debug_domains (domains);
296
297 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
298 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
299 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
300 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
301 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
302 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
303 g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
304 }
305
306 {
307 const gchar *domains[] = { "foobar", NULL };
308 g_log_writer_default_set_debug_domains (domains);
309
310 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
311 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
312 }
313
314 {
315 const gchar *domains[] = { "foobar", "bar", NULL };
316 g_log_writer_default_set_debug_domains (domains);
317
318 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
319 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
320 }
321
322 {
323 const gchar *domains[] = { "foobar", "bar", "barfoo", NULL };
324 g_log_writer_default_set_debug_domains (domains);
325
326 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
327 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
328 }
329
330 {
331 const gchar *domains[] = { "", NULL };
332 g_log_writer_default_set_debug_domains (domains);
333
334 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
335 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
336 }
337
338 {
339 const gchar *domains[] = { "foobar", "bar", "foo", "barfoo", NULL };
340 g_log_writer_default_set_debug_domains (domains);
341
342 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
343 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
344 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "baz"));
345 }
346
347 {
348 const gchar *domains[] = { "foo", "bar", "baz", NULL };
349 g_log_writer_default_set_debug_domains (domains);
350
351 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
352 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
353 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "baz"));
354 }
355
356
357 {
358 const gchar *domains[] = { "foo", NULL };
359 g_log_writer_default_set_debug_domains (domains);
360
361 g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
362 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
363 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foobarbaz"));
364 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "barfoobaz"));
365 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "barbazfoo"));
366 }
367
368 {
369 const gchar *domains[] = {NULL};
370 g_log_writer_default_set_debug_domains (domains);
371
372 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
373 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
374 }
375
376 g_log_writer_default_set_debug_domains (NULL);
377 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
378 g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
379
380 exit (0);
381 }
382
383 static const gchar *
384 test_would_drop_robustness_random_domain (void)
385 {
386 static const gchar *domains[] = { "foo", "bar", "baz", NULL };
387 return domains[g_random_int_range (0, G_N_ELEMENTS (domains))];
388 }
389
390 static gboolean test_would_drop_robustness_stopping;
391
392 static gpointer
393 test_would_drop_robustness_thread (gpointer data)
394 {
395 while (!g_atomic_int_get (&test_would_drop_robustness_stopping))
396 {
397 gsize i;
398 const gchar *domains[4] = { 0 };
399
400 for (i = 0; i < G_N_ELEMENTS (domains) - 1; i++)
401 domains[i] = test_would_drop_robustness_random_domain ();
402
403 domains[G_N_ELEMENTS (domains) - 1] = 0;
404
405 g_log_writer_default_set_debug_domains (domains);
406 }
407 return NULL;
408 }
409
410 static void
411 test_default_handler_would_drop_robustness (void)
412 {
413 GThread *threads[2];
414 gsize i;
415 guint counter = 1024 * 128;
416 g_log_writer_default_set_debug_domains (NULL);
417
418 for (i = 0; i < G_N_ELEMENTS (threads); i++)
419 threads[i] = g_thread_new (NULL, test_would_drop_robustness_thread, NULL);
420
421 while (counter-- > 0)
422 g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, test_would_drop_robustness_random_domain ());
423
424 g_atomic_int_set (&test_would_drop_robustness_stopping, TRUE);
425 for (i = 0; i < G_N_ELEMENTS (threads); i++)
426 g_thread_join (threads[i]);
427 }
428
429 static void
430 test_default_handler_0x400 (void)
431 {
432 g_log_writer_default_set_use_stderr (FALSE);
433 g_log_set_default_handler (g_log_default_handler, NULL);
434 g_log (G_LOG_DOMAIN, 1<<10, "message7");
435 exit (0);
436 }
437
438 static void
439 test_default_handler (void)
440 {
441 g_test_trap_subprocess ("/logging/default-handler/subprocess/error", 0,
442 G_TEST_SUBPROCESS_DEFAULT);
443 g_test_trap_assert_failed ();
444 g_test_trap_assert_stderr ("*ERROR*message1*");
445
446 g_test_trap_subprocess ("/logging/default-handler/subprocess/error-stderr", 0,
447 G_TEST_SUBPROCESS_DEFAULT);
448 g_test_trap_assert_failed ();
449 g_test_trap_assert_stderr ("*ERROR*message1*");
450
451 g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0,
452 G_TEST_SUBPROCESS_DEFAULT);
453 g_test_trap_assert_failed ();
454 g_test_trap_assert_stderr ("*CRITICAL*message2*");
455
456 g_test_trap_subprocess ("/logging/default-handler/subprocess/critical-stderr", 0,
457 G_TEST_SUBPROCESS_DEFAULT);
458 g_test_trap_assert_failed ();
459 g_test_trap_assert_stderr ("*CRITICAL*message2*");
460
461 g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0,
462 G_TEST_SUBPROCESS_DEFAULT);
463 g_test_trap_assert_failed ();
464 g_test_trap_assert_stderr ("*WARNING*message3*");
465
466 g_test_trap_subprocess ("/logging/default-handler/subprocess/warning-stderr", 0,
467 G_TEST_SUBPROCESS_DEFAULT);
468 g_test_trap_assert_failed ();
469 g_test_trap_assert_stderr ("*WARNING*message3*");
470
471 g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0,
472 G_TEST_SUBPROCESS_DEFAULT);
473 g_test_trap_assert_passed ();
474 g_test_trap_assert_stderr ("*Message*message4*");
475
476 g_test_trap_subprocess ("/logging/default-handler/subprocess/message-stderr", 0,
477 G_TEST_SUBPROCESS_DEFAULT);
478 g_test_trap_assert_passed ();
479 g_test_trap_assert_stderr ("*Message*message4*");
480
481 g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0,
482 G_TEST_SUBPROCESS_DEFAULT);
483 g_test_trap_assert_passed ();
484 g_test_trap_assert_stdout_unmatched ("*INFO*message5*");
485
486 g_test_trap_subprocess ("/logging/default-handler/subprocess/info-stderr", 0,
487 G_TEST_SUBPROCESS_DEFAULT);
488 g_test_trap_assert_passed ();
489 g_test_trap_assert_stderr_unmatched ("*INFO*message5*");
490
491 g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0,
492 G_TEST_SUBPROCESS_DEFAULT);
493 g_test_trap_assert_passed ();
494 g_test_trap_assert_stdout ("*INFO*message5*");
495
496 g_test_trap_subprocess ("/logging/default-handler/subprocess/baz-debug", 0,
497 G_TEST_SUBPROCESS_DEFAULT);
498 g_test_trap_assert_passed ();
499 g_test_trap_assert_stdout ("*DEBUG*message6*");
500
501 g_test_trap_subprocess ("/logging/default-handler/subprocess/debug", 0,
502 G_TEST_SUBPROCESS_DEFAULT);
503 g_test_trap_assert_passed ();
504 g_test_trap_assert_stdout ("*DEBUG*6*6*6*");
505
506 g_test_trap_subprocess ("/logging/default-handler/subprocess/debug-stderr", 0,
507 G_TEST_SUBPROCESS_DEFAULT);
508 g_test_trap_assert_passed ();
509 g_test_trap_assert_stdout_unmatched ("DEBUG");
510 g_test_trap_assert_stderr ("*DEBUG*6*6*6*");
511
512 g_test_trap_subprocess ("/logging/default-handler/subprocess/0x400", 0,
513 G_TEST_SUBPROCESS_DEFAULT);
514 g_test_trap_assert_passed ();
515 g_test_trap_assert_stdout ("*LOG-0x400*message7*");
516
517 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop", 0,
518 G_TEST_SUBPROCESS_DEFAULT);
519 g_test_trap_assert_passed ();
520 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-env1", 0,
521 G_TEST_SUBPROCESS_DEFAULT);
522 g_test_trap_assert_passed ();
523 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-env2", 0,
524 G_TEST_SUBPROCESS_DEFAULT);
525 g_test_trap_assert_passed ();
526 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-env3", 0,
527 G_TEST_SUBPROCESS_DEFAULT);
528 g_test_trap_assert_passed ();
529 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-env4", 0,
530 G_TEST_SUBPROCESS_DEFAULT);
531 g_test_trap_assert_passed ();
532 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-env5", 0,
533 G_TEST_SUBPROCESS_DEFAULT);
534 g_test_trap_assert_passed ();
535 g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop-robustness", 0,
536 G_TEST_SUBPROCESS_DEFAULT);
537 g_test_trap_assert_passed ();
538 }
539
540 static void
541 test_fatal_log_mask (void)
542 {
543 if (g_test_subprocess ())
544 {
545 g_log_set_fatal_mask ("bu", G_LOG_LEVEL_INFO);
546 g_log ("bu", G_LOG_LEVEL_INFO, "fatal");
547 return;
548 }
549 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
550 g_test_trap_assert_failed ();
551 /* G_LOG_LEVEL_INFO isn't printed by default */
552 g_test_trap_assert_stdout_unmatched ("*fatal*");
553 }
554
555 static gint my_print_count = 0;
556 static void
557 my_print_handler (const gchar *text)
558 {
559 my_print_count++;
560 }
561
562 static void
563 test_print_handler (void)
564 {
565 GPrintFunc old_print_handler;
566
567 old_print_handler = g_set_print_handler (my_print_handler);
568 g_assert_nonnull (old_print_handler);
569
570 my_print_count = 0;
571 g_print ("bu ba");
572 g_assert_cmpint (my_print_count, ==, 1);
573
574 if (g_test_subprocess ())
575 {
576 g_set_print_handler (NULL);
577 old_print_handler ("default handler\n");
578 g_print ("bu ba\n");
579 return;
580 }
581
582 g_set_print_handler (old_print_handler);
583 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
584 g_test_trap_assert_stdout ("*default handler" LINE_END "*");
585 g_test_trap_assert_stdout ("*bu ba" LINE_END "*");
586 g_test_trap_assert_stdout_unmatched ("*# default handler" LINE_END "*");
587 g_test_trap_assert_stdout_unmatched ("*# bu ba" LINE_END "*");
588 g_test_trap_has_passed ();
589 }
590
591 static void
592 test_printerr_handler (void)
593 {
594 GPrintFunc old_printerr_handler;
595
596 old_printerr_handler = g_set_printerr_handler (my_print_handler);
597 g_assert_nonnull (old_printerr_handler);
598
599 my_print_count = 0;
600 g_printerr ("bu ba");
601 g_assert_cmpint (my_print_count, ==, 1);
602
603 if (g_test_subprocess ())
604 {
605 g_set_printerr_handler (NULL);
606 old_printerr_handler ("default handler\n");
607 g_printerr ("bu ba\n");
608 return;
609 }
610
611 g_set_printerr_handler (old_printerr_handler);
612 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
613 g_test_trap_assert_stderr ("*default handler" LINE_END "*");
614 g_test_trap_assert_stderr ("*bu ba" LINE_END "*");
615 g_test_trap_has_passed ();
616 }
617
618 static char *fail_str = "foo";
619 static char *log_str = "bar";
620
621 static gboolean
622 good_failure_handler (const gchar *log_domain,
623 GLogLevelFlags log_level,
624 const gchar *msg,
625 gpointer user_data)
626 {
627 g_test_message ("The Good Fail Message Handler\n");
628 g_assert ((char *)user_data != log_str);
629 g_assert ((char *)user_data == fail_str);
630
631 return FALSE;
632 }
633
634 static gboolean
635 bad_failure_handler (const gchar *log_domain,
636 GLogLevelFlags log_level,
637 const gchar *msg,
638 gpointer user_data)
639 {
640 g_test_message ("The Bad Fail Message Handler\n");
641 g_assert ((char *)user_data == log_str);
642 g_assert ((char *)user_data != fail_str);
643
644 return FALSE;
645 }
646
647 static void
648 test_handler (const gchar *log_domain,
649 GLogLevelFlags log_level,
650 const gchar *msg,
651 gpointer user_data)
652 {
653 g_test_message ("The Log Message Handler\n");
654 g_assert ((char *)user_data != fail_str);
655 g_assert ((char *)user_data == log_str);
656 }
657
658 static void
659 bug653052 (void)
660 {
661 g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=653052");
662
663 g_test_log_set_fatal_handler (good_failure_handler, fail_str);
664 g_log_set_default_handler (test_handler, log_str);
665
666 g_return_if_fail (0);
667
668 g_test_log_set_fatal_handler (bad_failure_handler, fail_str);
669 g_log_set_default_handler (test_handler, log_str);
670
671 g_return_if_fail (0);
672 }
673
674 static void
675 test_gibberish (void)
676 {
677 if (g_test_subprocess ())
678 {
679 g_warning ("bla bla \236\237\190");
680 return;
681 }
682 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
683 g_test_trap_assert_failed ();
684 g_test_trap_assert_stderr ("*bla bla \\x9e\\x9f\\u000190*");
685 }
686
687 static GLogWriterOutput
688 null_log_writer (GLogLevelFlags log_level,
689 const GLogField *fields,
690 gsize n_fields,
691 gpointer user_data)
692 {
693 log_count++;
694 return G_LOG_WRITER_HANDLED;
695 }
696
697 typedef struct {
698 const GLogField *fields;
699 gsize n_fields;
700 } ExpectedMessage;
701
702 static gboolean
703 compare_field (const GLogField *f1, const GLogField *f2)
704 {
705 if (strcmp (f1->key, f2->key) != 0)
706 return FALSE;
707 if (f1->length != f2->length)
708 return FALSE;
709
710 if (f1->length == -1)
711 return strcmp (f1->value, f2->value) == 0;
712 else
713 return memcmp (f1->value, f2->value, f1->length) == 0;
714 }
715
716 static gboolean
717 compare_fields (const GLogField *f1, gsize n1, const GLogField *f2, gsize n2)
718 {
719 gsize i, j;
720
721 for (i = 0; i < n1; i++)
722 {
723 for (j = 0; j < n2; j++)
724 {
725 if (compare_field (&f1[i], &f2[j]))
726 break;
727 }
728 if (j == n2)
729 return FALSE;
730 }
731
732 return TRUE;
733 }
734
735 static GSList *expected_messages = NULL;
736 static const guchar binary_field[] = {1, 2, 3, 4, 5};
737
738
739 static GLogWriterOutput
740 expect_log_writer (GLogLevelFlags log_level,
741 const GLogField *fields,
742 gsize n_fields,
743 gpointer user_data)
744 {
745 ExpectedMessage *expected = expected_messages->data;
746
747 if (compare_fields (fields, n_fields, expected->fields, expected->n_fields))
748 {
749 expected_messages = g_slist_delete_link (expected_messages, expected_messages);
750 }
751 else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG)
752 {
753 char *str;
754
755 str = g_log_writer_format_fields (log_level, fields, n_fields, FALSE);
756 g_test_fail_printf ("Unexpected message: %s", str);
757 g_free (str);
758 }
759
760 return G_LOG_WRITER_HANDLED;
761 }
762
763 static void
764 test_structured_logging_no_state (void)
765 {
766 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
767 * can only be called once per process. */
768 if (g_test_subprocess ())
769 {
770 gpointer some_pointer = GUINT_TO_POINTER (0x100);
771 guint some_integer = 123;
772
773 log_count = 0;
774 g_log_set_writer_func (null_log_writer, NULL, NULL);
775
776 g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
777 "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e",
778 "MY_APPLICATION_CUSTOM_FIELD", "some debug string",
779 "MESSAGE", "This is a debug message about pointer %p and integer %u.",
780 some_pointer, some_integer);
781
782 g_assert_cmpint (log_count, ==, 1);
783 }
784 else
785 {
786 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
787 g_test_trap_assert_passed ();
788 }
789 }
790
791 static void
792 test_structured_logging_some_state (void)
793 {
794 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
795 * can only be called once per process. */
796 if (g_test_subprocess ())
797 {
798 gpointer state_object = NULL; /* this must not be dereferenced */
799 const GLogField fields[] = {
800 { "MESSAGE", "This is a debug message.", -1 },
801 { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
802 { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
803 { "MY_APPLICATION_STATE", state_object, 0 },
804 };
805
806 log_count = 0;
807 g_log_set_writer_func (null_log_writer, NULL, NULL);
808
809 g_log_structured_array (G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields));
810
811 g_assert_cmpint (log_count, ==, 1);
812 }
813 else
814 {
815 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
816 g_test_trap_assert_passed ();
817 }
818 }
819
820 static void
821 test_structured_logging_robustness (void)
822 {
823 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
824 * can only be called once per process. */
825 if (g_test_subprocess ())
826 {
827 log_count = 0;
828 g_log_set_writer_func (null_log_writer, NULL, NULL);
829
830 /* NULL log_domain shouldn't crash */
831 g_log (NULL, G_LOG_LEVEL_MESSAGE, "Test");
832 g_log_structured (NULL, G_LOG_LEVEL_MESSAGE, "MESSAGE", "Test");
833
834 g_assert_cmpint (log_count, ==, 2);
835 }
836 else
837 {
838 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
839 g_test_trap_assert_passed ();
840 }
841 }
842
843 static void
844 test_structured_logging_roundtrip1 (void)
845 {
846 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
847 * can only be called once per process. */
848 if (g_test_subprocess ())
849 {
850 gpointer some_pointer = GUINT_TO_POINTER (0x100);
851 gint some_integer = 123;
852 gchar message[200];
853 GLogField fields[] = {
854 { "GLIB_DOMAIN", "some-domain", -1 },
855 { "PRIORITY", "5", -1 },
856 { "MESSAGE", "String assigned using g_snprintf() below", -1 },
857 { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
858 { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }
859 };
860 ExpectedMessage expected = { fields, 5 };
861
862 /* %p format is implementation defined and depends on the platform */
863 g_snprintf (message, sizeof (message),
864 "This is a debug message about pointer %p and integer %u.",
865 some_pointer, some_integer);
866 fields[2].value = message;
867
868 expected_messages = g_slist_append (NULL, &expected);
869 g_log_set_writer_func (expect_log_writer, NULL, NULL);
870
871 g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
872 "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893",
873 "MY_APPLICATION_CUSTOM_FIELD", "some debug string",
874 "MESSAGE", "This is a debug message about pointer %p and integer %u.",
875 some_pointer, some_integer);
876
877 if (expected_messages != NULL)
878 {
879 char *str;
880 ExpectedMessage *msg = expected_messages->data;
881
882 str = g_log_writer_format_fields (0, msg->fields, msg->n_fields, FALSE);
883 g_test_fail_printf ("Unexpected message: %s", str);
884 g_free (str);
885 }
886 }
887 else
888 {
889 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
890 g_test_trap_assert_passed ();
891 }
892 }
893
894 static void
895 test_structured_logging_roundtrip2 (void)
896 {
897 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
898 * can only be called once per process. */
899 if (g_test_subprocess ())
900 {
901 const gchar *some_string = "abc";
902 const GLogField fields[] = {
903 { "GLIB_DOMAIN", "some-domain", -1 },
904 { "PRIORITY", "5", -1 },
905 { "MESSAGE", "This is a debug message about string 'abc'.", -1 },
906 { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
907 { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }
908 };
909 ExpectedMessage expected = { fields, 5 };
910
911 expected_messages = g_slist_append (NULL, &expected);
912 g_log_set_writer_func (expect_log_writer, NULL, NULL);
913
914 g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
915 "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893",
916 "MY_APPLICATION_CUSTOM_FIELD", "some debug string",
917 "MESSAGE", "This is a debug message about string '%s'.",
918 some_string);
919
920 g_assert (expected_messages == NULL);
921 }
922 else
923 {
924 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
925 g_test_trap_assert_passed ();
926 }
927 }
928
929 static void
930 test_structured_logging_roundtrip3 (void)
931 {
932 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
933 * can only be called once per process. */
934 if (g_test_subprocess ())
935 {
936 const GLogField fields[] = {
937 { "GLIB_DOMAIN", "some-domain", -1 },
938 { "PRIORITY", "4", -1 },
939 { "MESSAGE", "Test test test.", -1 }
940 };
941 ExpectedMessage expected = { fields, 3 };
942
943 expected_messages = g_slist_append (NULL, &expected);
944 g_log_set_writer_func (expect_log_writer, NULL, NULL);
945
946 g_log_structured ("some-domain", G_LOG_LEVEL_WARNING,
947 "MESSAGE", "Test test test.");
948
949 g_assert (expected_messages == NULL);
950 }
951 else
952 {
953 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
954 g_test_trap_assert_passed ();
955 }
956 }
957
958 static GVariant *
959 create_variant_fields (void)
960 {
961 GVariant *binary;
962 GVariantBuilder builder;
963
964 binary = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, binary_field, G_N_ELEMENTS (binary_field), sizeof (binary_field[0]));
965
966 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
967 g_variant_builder_add (&builder, "{sv}", "MESSAGE_ID", g_variant_new_string ("06d4df59e6c24647bfe69d2c27ef0b4e"));
968 g_variant_builder_add (&builder, "{sv}", "MESSAGE", g_variant_new_string ("This is a debug message"));
969 g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD", g_variant_new_string ("some debug string"));
970 g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary);
971
972 return g_variant_builder_end (&builder);
973 }
974
975 static void
976 test_structured_logging_variant1 (void)
977 {
978 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
979 * can only be called once per process. */
980 if (g_test_subprocess ())
981 {
982 GVariant *v = create_variant_fields ();
983
984 log_count = 0;
985 g_log_set_writer_func (null_log_writer, NULL, NULL);
986
987 g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v);
988 g_variant_unref (v);
989 g_assert_cmpint (log_count, ==, 1);
990 }
991 else
992 {
993 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
994 g_test_trap_assert_passed ();
995 }
996 }
997
998 static void
999 test_structured_logging_variant2 (void)
1000 {
1001 /* Test has to run in a subprocess as it calls g_log_set_writer_func(), which
1002 * can only be called once per process. */
1003 if (g_test_subprocess ())
1004 {
1005 const GLogField fields[] = {
1006 { "GLIB_DOMAIN", "some-domain", -1 },
1007 { "PRIORITY", "5", -1 },
1008 { "MESSAGE", "This is a debug message", -1 },
1009 { "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e", -1 },
1010 { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
1011 { "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary_field, sizeof (binary_field) }
1012 };
1013 ExpectedMessage expected = { fields, 6 };
1014 GVariant *v = create_variant_fields ();
1015
1016 expected_messages = g_slist_append (NULL, &expected);
1017 g_log_set_writer_func (expect_log_writer, NULL, NULL);
1018
1019 g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v);
1020 g_variant_unref (v);
1021 g_assert (expected_messages == NULL);
1022 }
1023 else
1024 {
1025 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1026 g_test_trap_assert_passed ();
1027 }
1028 }
1029
1030 static void
1031 test_structured_logging_set_writer_func_twice (void)
1032 {
1033 /* Test has to run in a subprocess as it calls g_log_set_writer_func() and
1034 * causes an error. */
1035 if (g_test_subprocess ())
1036 {
1037 g_log_set_writer_func (null_log_writer, NULL, NULL);
1038 g_log_set_writer_func (expect_log_writer, NULL, NULL);
1039 }
1040 else
1041 {
1042 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1043 g_test_trap_assert_failed ();
1044 }
1045 }
1046
1047 int
1048 main (int argc, char *argv[])
1049 {
1050 g_unsetenv ("G_MESSAGES_DEBUG");
1051
1052 g_test_init (&argc, &argv, NULL);
1053
1054 g_test_add_func ("/logging/default-handler", test_default_handler);
1055 g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error);
1056 g_test_add_func ("/logging/default-handler/subprocess/error-stderr", test_default_handler_error_stderr);
1057 g_test_add_func ("/logging/default-handler/subprocess/critical", test_default_handler_critical);
1058 g_test_add_func ("/logging/default-handler/subprocess/critical-stderr", test_default_handler_critical_stderr);
1059 g_test_add_func ("/logging/default-handler/subprocess/warning", test_default_handler_warning);
1060 g_test_add_func ("/logging/default-handler/subprocess/warning-stderr", test_default_handler_warning_stderr);
1061 g_test_add_func ("/logging/default-handler/subprocess/message", test_default_handler_message);
1062 g_test_add_func ("/logging/default-handler/subprocess/message-stderr", test_default_handler_message_stderr);
1063 g_test_add_func ("/logging/default-handler/subprocess/info", test_default_handler_info);
1064 g_test_add_func ("/logging/default-handler/subprocess/info-stderr", test_default_handler_info_stderr);
1065 g_test_add_func ("/logging/default-handler/subprocess/bar-info", test_default_handler_bar_info);
1066 g_test_add_func ("/logging/default-handler/subprocess/baz-debug", test_default_handler_baz_debug);
1067 g_test_add_func ("/logging/default-handler/subprocess/debug", test_default_handler_debug);
1068 g_test_add_func ("/logging/default-handler/subprocess/debug-stderr", test_default_handler_debug_stderr);
1069 g_test_add_func ("/logging/default-handler/subprocess/0x400", test_default_handler_0x400);
1070 g_test_add_func ("/logging/default-handler/subprocess/would-drop", test_default_handler_would_drop);
1071 g_test_add_func ("/logging/default-handler/subprocess/would-drop-env1", test_default_handler_would_drop_env1);
1072 g_test_add_func ("/logging/default-handler/subprocess/would-drop-env2", test_default_handler_would_drop_env2);
1073 g_test_add_func ("/logging/default-handler/subprocess/would-drop-env3", test_default_handler_would_drop_env3);
1074 g_test_add_func ("/logging/default-handler/subprocess/would-drop-env4", test_default_handler_would_drop_env4);
1075 g_test_add_func ("/logging/default-handler/subprocess/would-drop-env5", test_default_handler_would_drop_env5);
1076 g_test_add_func ("/logging/default-handler/subprocess/would-drop-robustness", test_default_handler_would_drop_robustness);
1077 g_test_add_func ("/logging/warnings", test_warnings);
1078 g_test_add_func ("/logging/fatal-log-mask", test_fatal_log_mask);
1079 g_test_add_func ("/logging/set-handler", test_set_handler);
1080 g_test_add_func ("/logging/print-handler", test_print_handler);
1081 g_test_add_func ("/logging/printerr-handler", test_printerr_handler);
1082 g_test_add_func ("/logging/653052", bug653052);
1083 g_test_add_func ("/logging/gibberish", test_gibberish);
1084 g_test_add_func ("/structured-logging/no-state", test_structured_logging_no_state);
1085 g_test_add_func ("/structured-logging/some-state", test_structured_logging_some_state);
1086 g_test_add_func ("/structured-logging/robustness", test_structured_logging_robustness);
1087 g_test_add_func ("/structured-logging/roundtrip1", test_structured_logging_roundtrip1);
1088 g_test_add_func ("/structured-logging/roundtrip2", test_structured_logging_roundtrip2);
1089 g_test_add_func ("/structured-logging/roundtrip3", test_structured_logging_roundtrip3);
1090 g_test_add_func ("/structured-logging/variant1", test_structured_logging_variant1);
1091 g_test_add_func ("/structured-logging/variant2", test_structured_logging_variant2);
1092 g_test_add_func ("/structured-logging/set-writer-func-twice", test_structured_logging_set_writer_func_twice);
1093
1094 return g_test_run ();
1095 }