1 | #include <stdlib.h> |
2 | #include <string.h> |
3 | #define G_LOG_USE_STRUCTURED 1 |
4 | #include <glib.h> |
5 | |
6 | /* Test g_warn macros */ |
7 | static void |
8 | test_warnings (void) |
9 | { |
10 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
11 | pattern: "*test_warnings*should not be reached*" ); |
12 | g_warn_if_reached (); |
13 | g_test_assert_expected_messages (); |
14 | |
15 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
16 | pattern: "*test_warnings*runtime check failed*" ); |
17 | g_warn_if_fail (FALSE); |
18 | g_test_assert_expected_messages (); |
19 | } |
20 | |
21 | static guint log_count = 0; |
22 | |
23 | static void |
24 | log_handler (const gchar *log_domain, |
25 | GLogLevelFlags log_level, |
26 | const gchar *message, |
27 | gpointer user_data) |
28 | { |
29 | g_assert_cmpstr (log_domain, ==, "bu" ); |
30 | g_assert_cmpint (log_level, ==, G_LOG_LEVEL_INFO); |
31 | |
32 | log_count++; |
33 | } |
34 | |
35 | /* test that custom log handlers only get called for |
36 | * their domain and level |
37 | */ |
38 | static void |
39 | test_set_handler (void) |
40 | { |
41 | guint id; |
42 | |
43 | id = g_log_set_handler (log_domain: "bu" , log_levels: G_LOG_LEVEL_INFO, log_func: log_handler, NULL); |
44 | |
45 | g_log (log_domain: "bu" , log_level: G_LOG_LEVEL_DEBUG, format: "message" ); |
46 | g_log (log_domain: "ba" , log_level: G_LOG_LEVEL_DEBUG, format: "message" ); |
47 | g_log (log_domain: "bu" , log_level: G_LOG_LEVEL_INFO, format: "message" ); |
48 | g_log (log_domain: "ba" , log_level: G_LOG_LEVEL_INFO, format: "message" ); |
49 | |
50 | g_assert_cmpint (log_count, ==, 1); |
51 | |
52 | g_log_remove_handler (log_domain: "bu" , handler_id: id); |
53 | } |
54 | |
55 | static void |
56 | test_default_handler_error (void) |
57 | { |
58 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
59 | g_error ("message1" ); |
60 | exit (status: 0); |
61 | } |
62 | |
63 | static void |
64 | test_default_handler_critical (void) |
65 | { |
66 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
67 | g_critical ("message2" ); |
68 | exit (status: 0); |
69 | } |
70 | |
71 | static void |
72 | test_default_handler_warning (void) |
73 | { |
74 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
75 | g_warning ("message3" ); |
76 | exit (status: 0); |
77 | } |
78 | |
79 | static void |
80 | test_default_handler_message (void) |
81 | { |
82 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
83 | g_message ("message4" ); |
84 | exit (status: 0); |
85 | } |
86 | |
87 | static void |
88 | test_default_handler_info (void) |
89 | { |
90 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
91 | g_log (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_INFO, format: "message5" ); |
92 | exit (status: 0); |
93 | } |
94 | |
95 | static void |
96 | test_default_handler_bar_info (void) |
97 | { |
98 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
99 | |
100 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "foo bar baz" , TRUE); |
101 | |
102 | g_log (log_domain: "bar" , log_level: G_LOG_LEVEL_INFO, format: "message5" ); |
103 | exit (status: 0); |
104 | } |
105 | |
106 | static void |
107 | test_default_handler_baz_debug (void) |
108 | { |
109 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
110 | |
111 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "foo bar baz" , TRUE); |
112 | |
113 | g_log (log_domain: "baz" , log_level: G_LOG_LEVEL_DEBUG, format: "message6" ); |
114 | exit (status: 0); |
115 | } |
116 | |
117 | static void |
118 | test_default_handler_debug (void) |
119 | { |
120 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
121 | |
122 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "all" , TRUE); |
123 | |
124 | g_log (log_domain: "foo" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
125 | g_log (log_domain: "bar" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
126 | g_log (log_domain: "baz" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
127 | |
128 | exit (status: 0); |
129 | } |
130 | |
131 | static void |
132 | test_default_handler_debug_stderr (void) |
133 | { |
134 | g_log_writer_default_set_use_stderr (TRUE); |
135 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
136 | |
137 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "all" , TRUE); |
138 | |
139 | g_log (log_domain: "foo" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
140 | g_log (log_domain: "bar" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
141 | g_log (log_domain: "baz" , log_level: G_LOG_LEVEL_DEBUG, format: "6" ); |
142 | |
143 | exit (status: 0); |
144 | } |
145 | |
146 | static void |
147 | test_default_handler_would_drop (void) |
148 | { |
149 | g_unsetenv (variable: "G_MESSAGES_DEBUG" ); |
150 | |
151 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo" )); |
152 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo" )); |
153 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo" )); |
154 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo" )); |
155 | g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo" )); |
156 | g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo" )); |
157 | g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo" )); |
158 | |
159 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "bar baz" , TRUE); |
160 | |
161 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo" )); |
162 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo" )); |
163 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo" )); |
164 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo" )); |
165 | g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo" )); |
166 | g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo" )); |
167 | g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo" )); |
168 | |
169 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "foo bar" , TRUE); |
170 | |
171 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo" )); |
172 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo" )); |
173 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo" )); |
174 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo" )); |
175 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo" )); |
176 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo" )); |
177 | g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo" )); |
178 | |
179 | g_setenv (variable: "G_MESSAGES_DEBUG" , value: "all" , TRUE); |
180 | |
181 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo" )); |
182 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo" )); |
183 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo" )); |
184 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo" )); |
185 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo" )); |
186 | g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo" )); |
187 | g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo" )); |
188 | |
189 | exit (status: 0); |
190 | } |
191 | |
192 | static void |
193 | test_default_handler_0x400 (void) |
194 | { |
195 | g_log_set_default_handler (log_func: g_log_default_handler, NULL); |
196 | g_log (G_LOG_DOMAIN, log_level: 1<<10, format: "message7" ); |
197 | exit (status: 0); |
198 | } |
199 | |
200 | static void |
201 | test_default_handler (void) |
202 | { |
203 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/error" , usec_timeout: 0, test_flags: 0); |
204 | g_test_trap_assert_failed (); |
205 | g_test_trap_assert_stderr ("*ERROR*message1*" ); |
206 | |
207 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/critical" , usec_timeout: 0, test_flags: 0); |
208 | g_test_trap_assert_failed (); |
209 | g_test_trap_assert_stderr ("*CRITICAL*message2*" ); |
210 | |
211 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/warning" , usec_timeout: 0, test_flags: 0); |
212 | g_test_trap_assert_failed (); |
213 | g_test_trap_assert_stderr ("*WARNING*message3*" ); |
214 | |
215 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/message" , usec_timeout: 0, test_flags: 0); |
216 | g_test_trap_assert_passed (); |
217 | g_test_trap_assert_stderr ("*Message*message4*" ); |
218 | |
219 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/info" , usec_timeout: 0, test_flags: 0); |
220 | g_test_trap_assert_passed (); |
221 | g_test_trap_assert_stdout_unmatched ("*INFO*message5*" ); |
222 | |
223 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/bar-info" , usec_timeout: 0, test_flags: 0); |
224 | g_test_trap_assert_passed (); |
225 | g_test_trap_assert_stdout ("*INFO*message5*" ); |
226 | |
227 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/baz-debug" , usec_timeout: 0, test_flags: 0); |
228 | g_test_trap_assert_passed (); |
229 | g_test_trap_assert_stdout ("*DEBUG*message6*" ); |
230 | |
231 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/debug" , usec_timeout: 0, test_flags: 0); |
232 | g_test_trap_assert_passed (); |
233 | g_test_trap_assert_stdout ("*DEBUG*6*6*6*" ); |
234 | |
235 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/debug-stderr" , usec_timeout: 0, test_flags: 0); |
236 | g_test_trap_assert_passed (); |
237 | g_test_trap_assert_stdout_unmatched ("DEBUG" ); |
238 | g_test_trap_assert_stderr ("*DEBUG*6*6*6*" ); |
239 | |
240 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/0x400" , usec_timeout: 0, test_flags: 0); |
241 | g_test_trap_assert_passed (); |
242 | g_test_trap_assert_stdout ("*LOG-0x400*message7*" ); |
243 | |
244 | g_test_trap_subprocess (test_path: "/logging/default-handler/subprocess/would-drop" , usec_timeout: 0, test_flags: 0); |
245 | g_test_trap_assert_passed (); |
246 | } |
247 | |
248 | static void |
249 | test_fatal_log_mask (void) |
250 | { |
251 | if (g_test_subprocess ()) |
252 | { |
253 | g_log_set_fatal_mask (log_domain: "bu" , fatal_mask: G_LOG_LEVEL_INFO); |
254 | g_log (log_domain: "bu" , log_level: G_LOG_LEVEL_INFO, format: "fatal" ); |
255 | return; |
256 | } |
257 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
258 | g_test_trap_assert_failed (); |
259 | /* G_LOG_LEVEL_INFO isn't printed by default */ |
260 | g_test_trap_assert_stdout_unmatched ("*fatal*" ); |
261 | } |
262 | |
263 | static gint my_print_count = 0; |
264 | static void |
265 | my_print_handler (const gchar *text) |
266 | { |
267 | my_print_count++; |
268 | } |
269 | |
270 | static void |
271 | test_print_handler (void) |
272 | { |
273 | GPrintFunc old_print_handler; |
274 | |
275 | old_print_handler = g_set_print_handler (func: my_print_handler); |
276 | g_assert (old_print_handler == NULL); |
277 | |
278 | my_print_count = 0; |
279 | g_print (format: "bu ba" ); |
280 | g_assert_cmpint (my_print_count, ==, 1); |
281 | |
282 | g_set_print_handler (NULL); |
283 | } |
284 | |
285 | static void |
286 | test_printerr_handler (void) |
287 | { |
288 | GPrintFunc old_printerr_handler; |
289 | |
290 | old_printerr_handler = g_set_printerr_handler (func: my_print_handler); |
291 | g_assert (old_printerr_handler == NULL); |
292 | |
293 | my_print_count = 0; |
294 | g_printerr (format: "bu ba" ); |
295 | g_assert_cmpint (my_print_count, ==, 1); |
296 | |
297 | g_set_printerr_handler (NULL); |
298 | } |
299 | |
300 | static char *fail_str = "foo" ; |
301 | static char *log_str = "bar" ; |
302 | |
303 | static gboolean |
304 | good_failure_handler (const gchar *log_domain, |
305 | GLogLevelFlags log_level, |
306 | const gchar *msg, |
307 | gpointer user_data) |
308 | { |
309 | g_test_message (format: "The Good Fail Message Handler\n" ); |
310 | g_assert ((char *)user_data != log_str); |
311 | g_assert ((char *)user_data == fail_str); |
312 | |
313 | return FALSE; |
314 | } |
315 | |
316 | static gboolean |
317 | bad_failure_handler (const gchar *log_domain, |
318 | GLogLevelFlags log_level, |
319 | const gchar *msg, |
320 | gpointer user_data) |
321 | { |
322 | g_test_message (format: "The Bad Fail Message Handler\n" ); |
323 | g_assert ((char *)user_data == log_str); |
324 | g_assert ((char *)user_data != fail_str); |
325 | |
326 | return FALSE; |
327 | } |
328 | |
329 | static void |
330 | test_handler (const gchar *log_domain, |
331 | GLogLevelFlags log_level, |
332 | const gchar *msg, |
333 | gpointer user_data) |
334 | { |
335 | g_test_message (format: "The Log Message Handler\n" ); |
336 | g_assert ((char *)user_data != fail_str); |
337 | g_assert ((char *)user_data == log_str); |
338 | } |
339 | |
340 | static void |
341 | bug653052 (void) |
342 | { |
343 | g_test_bug (bug_uri_snippet: "653052" ); |
344 | |
345 | g_test_log_set_fatal_handler (log_func: good_failure_handler, user_data: fail_str); |
346 | g_log_set_default_handler (log_func: test_handler, user_data: log_str); |
347 | |
348 | g_return_if_fail (0); |
349 | |
350 | g_test_log_set_fatal_handler (log_func: bad_failure_handler, user_data: fail_str); |
351 | g_log_set_default_handler (log_func: test_handler, user_data: log_str); |
352 | |
353 | g_return_if_fail (0); |
354 | } |
355 | |
356 | static void |
357 | test_gibberish (void) |
358 | { |
359 | if (g_test_subprocess ()) |
360 | { |
361 | g_warning ("bla bla \236\237\190" ); |
362 | return; |
363 | } |
364 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
365 | g_test_trap_assert_failed (); |
366 | g_test_trap_assert_stderr ("*bla bla \\x9e\\x9f\\u000190*" ); |
367 | } |
368 | |
369 | static GLogWriterOutput |
370 | null_log_writer (GLogLevelFlags log_level, |
371 | const GLogField *fields, |
372 | gsize n_fields, |
373 | gpointer user_data) |
374 | { |
375 | log_count++; |
376 | return G_LOG_WRITER_HANDLED; |
377 | } |
378 | |
379 | typedef struct { |
380 | const GLogField *fields; |
381 | gsize n_fields; |
382 | } ExpectedMessage; |
383 | |
384 | static gboolean |
385 | compare_field (const GLogField *f1, const GLogField *f2) |
386 | { |
387 | if (strcmp (s1: f1->key, s2: f2->key) != 0) |
388 | return FALSE; |
389 | if (f1->length != f2->length) |
390 | return FALSE; |
391 | |
392 | if (f1->length == -1) |
393 | return strcmp (s1: f1->value, s2: f2->value) == 0; |
394 | else |
395 | return memcmp (s1: f1->value, s2: f2->value, n: f1->length) == 0; |
396 | } |
397 | |
398 | static gboolean |
399 | compare_fields (const GLogField *f1, gsize n1, const GLogField *f2, gsize n2) |
400 | { |
401 | gsize i, j; |
402 | |
403 | for (i = 0; i < n1; i++) |
404 | { |
405 | for (j = 0; j < n2; j++) |
406 | { |
407 | if (compare_field (f1: &f1[i], f2: &f2[j])) |
408 | break; |
409 | } |
410 | if (j == n2) |
411 | return FALSE; |
412 | } |
413 | |
414 | return TRUE; |
415 | } |
416 | |
417 | static GSList *expected_messages = NULL; |
418 | static const guchar binary_field[] = {1, 2, 3, 4, 5}; |
419 | |
420 | |
421 | static GLogWriterOutput |
422 | expect_log_writer (GLogLevelFlags log_level, |
423 | const GLogField *fields, |
424 | gsize n_fields, |
425 | gpointer user_data) |
426 | { |
427 | ExpectedMessage *expected = expected_messages->data; |
428 | |
429 | if (compare_fields (f1: fields, n1: n_fields, f2: expected->fields, n2: expected->n_fields)) |
430 | { |
431 | expected_messages = g_slist_delete_link (list: expected_messages, link_: expected_messages); |
432 | } |
433 | else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG) |
434 | { |
435 | char *str; |
436 | |
437 | str = g_log_writer_format_fields (log_level, fields, n_fields, FALSE); |
438 | g_test_message (format: "Unexpected message: %s" , str); |
439 | g_free (mem: str); |
440 | g_test_fail (); |
441 | } |
442 | |
443 | return G_LOG_WRITER_HANDLED; |
444 | } |
445 | |
446 | static void |
447 | test_structured_logging_no_state (void) |
448 | { |
449 | gpointer some_pointer = GUINT_TO_POINTER (0x100); |
450 | guint some_integer = 123; |
451 | |
452 | log_count = 0; |
453 | g_log_set_writer_func (func: null_log_writer, NULL, NULL); |
454 | |
455 | g_log_structured (log_domain: "some-domain" , log_level: G_LOG_LEVEL_MESSAGE, |
456 | "MESSAGE_ID" , "06d4df59e6c24647bfe69d2c27ef0b4e" , |
457 | "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , |
458 | "MESSAGE" , "This is a debug message about pointer %p and integer %u." , |
459 | some_pointer, some_integer); |
460 | |
461 | g_assert_cmpint (log_count, ==, 1); |
462 | } |
463 | |
464 | static void |
465 | test_structured_logging_some_state (void) |
466 | { |
467 | gpointer state_object = NULL; /* this must not be dereferenced */ |
468 | const GLogField fields[] = { |
469 | { "MESSAGE" , "This is a debug message." , -1 }, |
470 | { "MESSAGE_ID" , "fcfb2e1e65c3494386b74878f1abf893" , -1 }, |
471 | { "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , -1 }, |
472 | { "MY_APPLICATION_STATE" , state_object, 0 }, |
473 | }; |
474 | |
475 | log_count = 0; |
476 | g_log_set_writer_func (func: null_log_writer, NULL, NULL); |
477 | |
478 | g_log_structured_array (log_level: G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields)); |
479 | |
480 | g_assert_cmpint (log_count, ==, 1); |
481 | } |
482 | |
483 | static void |
484 | test_structured_logging_robustness (void) |
485 | { |
486 | log_count = 0; |
487 | g_log_set_writer_func (func: null_log_writer, NULL, NULL); |
488 | |
489 | /* NULL log_domain shouldn't crash */ |
490 | g_log (NULL, log_level: G_LOG_LEVEL_MESSAGE, format: "Test" ); |
491 | g_log_structured (NULL, log_level: G_LOG_LEVEL_MESSAGE, "MESSAGE" , "Test" ); |
492 | |
493 | g_assert_cmpint (log_count, ==, 1); |
494 | } |
495 | |
496 | static void |
497 | test_structured_logging_roundtrip1 (void) |
498 | { |
499 | gpointer some_pointer = GUINT_TO_POINTER (0x100); |
500 | gint some_integer = 123; |
501 | gchar message[200]; |
502 | GLogField fields[] = { |
503 | { "GLIB_DOMAIN" , "some-domain" , -1 }, |
504 | { "PRIORITY" , "5" , -1 }, |
505 | { "MESSAGE" , "String assigned using g_snprintf() below" , -1 }, |
506 | { "MESSAGE_ID" , "fcfb2e1e65c3494386b74878f1abf893" , -1 }, |
507 | { "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , -1 } |
508 | }; |
509 | ExpectedMessage expected = { fields, 5 }; |
510 | |
511 | /* %p format is implementation defined and depends on the platform */ |
512 | g_snprintf (string: message, n: sizeof (message), |
513 | format: "This is a debug message about pointer %p and integer %u." , |
514 | some_pointer, some_integer); |
515 | fields[2].value = message; |
516 | |
517 | expected_messages = g_slist_append (NULL, data: &expected); |
518 | g_log_set_writer_func (func: expect_log_writer, NULL, NULL); |
519 | |
520 | g_log_structured (log_domain: "some-domain" , log_level: G_LOG_LEVEL_MESSAGE, |
521 | "MESSAGE_ID" , "fcfb2e1e65c3494386b74878f1abf893" , |
522 | "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , |
523 | "MESSAGE" , "This is a debug message about pointer %p and integer %u." , |
524 | some_pointer, some_integer); |
525 | |
526 | if (expected_messages != NULL) |
527 | { |
528 | char *str; |
529 | ExpectedMessage *expected = expected_messages->data; |
530 | |
531 | str = g_log_writer_format_fields (log_level: 0, fields: expected->fields, n_fields: expected->n_fields, FALSE); |
532 | g_test_message (format: "Unexpected message: %s" , str); |
533 | g_free (mem: str); |
534 | g_test_fail (); |
535 | } |
536 | } |
537 | |
538 | static void |
539 | test_structured_logging_roundtrip2 (void) |
540 | { |
541 | const gchar *some_string = "abc" ; |
542 | const GLogField fields[] = { |
543 | { "GLIB_DOMAIN" , "some-domain" , -1 }, |
544 | { "PRIORITY" , "5" , -1 }, |
545 | { "MESSAGE" , "This is a debug message about string 'abc'." , -1 }, |
546 | { "MESSAGE_ID" , "fcfb2e1e65c3494386b74878f1abf893" , -1 }, |
547 | { "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , -1 } |
548 | }; |
549 | ExpectedMessage expected = { fields, 5 }; |
550 | |
551 | expected_messages = g_slist_append (NULL, data: &expected); |
552 | g_log_set_writer_func (func: expect_log_writer, NULL, NULL); |
553 | |
554 | g_log_structured (log_domain: "some-domain" , log_level: G_LOG_LEVEL_MESSAGE, |
555 | "MESSAGE_ID" , "fcfb2e1e65c3494386b74878f1abf893" , |
556 | "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , |
557 | "MESSAGE" , "This is a debug message about string '%s'." , |
558 | some_string); |
559 | |
560 | g_assert (expected_messages == NULL); |
561 | } |
562 | |
563 | static void |
564 | test_structured_logging_roundtrip3 (void) |
565 | { |
566 | const GLogField fields[] = { |
567 | { "GLIB_DOMAIN" , "some-domain" , -1 }, |
568 | { "PRIORITY" , "4" , -1 }, |
569 | { "MESSAGE" , "Test test test." , -1 } |
570 | }; |
571 | ExpectedMessage expected = { fields, 3 }; |
572 | |
573 | expected_messages = g_slist_append (NULL, data: &expected); |
574 | g_log_set_writer_func (func: expect_log_writer, NULL, NULL); |
575 | |
576 | g_log_structured (log_domain: "some-domain" , log_level: G_LOG_LEVEL_WARNING, |
577 | "MESSAGE" , "Test test test." ); |
578 | |
579 | g_assert (expected_messages == NULL); |
580 | } |
581 | |
582 | static GVariant * |
583 | create_variant_fields (void) |
584 | { |
585 | GVariant *binary; |
586 | GVariantBuilder builder; |
587 | |
588 | binary = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, elements: binary_field, G_N_ELEMENTS (binary_field), element_size: sizeof (binary_field[0])); |
589 | |
590 | g_variant_builder_init (builder: &builder, G_VARIANT_TYPE ("a{sv}" )); |
591 | g_variant_builder_add (builder: &builder, format_string: "{sv}" , "MESSAGE_ID" , g_variant_new_string (string: "06d4df59e6c24647bfe69d2c27ef0b4e" )); |
592 | g_variant_builder_add (builder: &builder, format_string: "{sv}" , "MESSAGE" , g_variant_new_string (string: "This is a debug message" )); |
593 | g_variant_builder_add (builder: &builder, format_string: "{sv}" , "MY_APPLICATION_CUSTOM_FIELD" , g_variant_new_string (string: "some debug string" )); |
594 | g_variant_builder_add (builder: &builder, format_string: "{sv}" , "MY_APPLICATION_CUSTOM_FIELD_BINARY" , binary); |
595 | |
596 | return g_variant_builder_end (builder: &builder); |
597 | } |
598 | |
599 | static void |
600 | test_structured_logging_variant1 (void) |
601 | { |
602 | GVariant *v = create_variant_fields (); |
603 | |
604 | log_count = 0; |
605 | g_log_set_writer_func (func: null_log_writer, NULL, NULL); |
606 | |
607 | g_log_variant (log_domain: "some-domain" , log_level: G_LOG_LEVEL_MESSAGE, fields: v); |
608 | g_variant_unref (value: v); |
609 | g_assert_cmpint (log_count, ==, 1); |
610 | } |
611 | |
612 | static void |
613 | test_structured_logging_variant2 (void) |
614 | { |
615 | const GLogField fields[] = { |
616 | { "GLIB_DOMAIN" , "some-domain" , -1 }, |
617 | { "PRIORITY" , "5" , -1 }, |
618 | { "MESSAGE" , "This is a debug message" , -1 }, |
619 | { "MESSAGE_ID" , "06d4df59e6c24647bfe69d2c27ef0b4e" , -1 }, |
620 | { "MY_APPLICATION_CUSTOM_FIELD" , "some debug string" , -1 }, |
621 | { "MY_APPLICATION_CUSTOM_FIELD_BINARY" , binary_field, sizeof (binary_field) } |
622 | }; |
623 | ExpectedMessage expected = { fields, 6 }; |
624 | GVariant *v = create_variant_fields (); |
625 | |
626 | expected_messages = g_slist_append (NULL, data: &expected); |
627 | g_log_set_writer_func (func: expect_log_writer, NULL, NULL); |
628 | |
629 | g_log_variant (log_domain: "some-domain" , log_level: G_LOG_LEVEL_MESSAGE, fields: v); |
630 | g_variant_unref (value: v); |
631 | g_assert (expected_messages == NULL); |
632 | } |
633 | |
634 | int |
635 | main (int argc, char *argv[]) |
636 | { |
637 | g_unsetenv (variable: "G_MESSAGES_DEBUG" ); |
638 | |
639 | g_test_init (argc: &argc, argv: &argv, NULL); |
640 | g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/" ); |
641 | |
642 | g_test_add_func (testpath: "/logging/default-handler" , test_func: test_default_handler); |
643 | g_test_add_func (testpath: "/logging/default-handler/subprocess/error" , test_func: test_default_handler_error); |
644 | g_test_add_func (testpath: "/logging/default-handler/subprocess/critical" , test_func: test_default_handler_critical); |
645 | g_test_add_func (testpath: "/logging/default-handler/subprocess/warning" , test_func: test_default_handler_warning); |
646 | g_test_add_func (testpath: "/logging/default-handler/subprocess/message" , test_func: test_default_handler_message); |
647 | g_test_add_func (testpath: "/logging/default-handler/subprocess/info" , test_func: test_default_handler_info); |
648 | g_test_add_func (testpath: "/logging/default-handler/subprocess/bar-info" , test_func: test_default_handler_bar_info); |
649 | g_test_add_func (testpath: "/logging/default-handler/subprocess/baz-debug" , test_func: test_default_handler_baz_debug); |
650 | g_test_add_func (testpath: "/logging/default-handler/subprocess/debug" , test_func: test_default_handler_debug); |
651 | g_test_add_func (testpath: "/logging/default-handler/subprocess/debug-stderr" , test_func: test_default_handler_debug_stderr); |
652 | g_test_add_func (testpath: "/logging/default-handler/subprocess/0x400" , test_func: test_default_handler_0x400); |
653 | g_test_add_func (testpath: "/logging/default-handler/subprocess/would-drop" , test_func: test_default_handler_would_drop); |
654 | g_test_add_func (testpath: "/logging/warnings" , test_func: test_warnings); |
655 | g_test_add_func (testpath: "/logging/fatal-log-mask" , test_func: test_fatal_log_mask); |
656 | g_test_add_func (testpath: "/logging/set-handler" , test_func: test_set_handler); |
657 | g_test_add_func (testpath: "/logging/print-handler" , test_func: test_print_handler); |
658 | g_test_add_func (testpath: "/logging/printerr-handler" , test_func: test_printerr_handler); |
659 | g_test_add_func (testpath: "/logging/653052" , test_func: bug653052); |
660 | g_test_add_func (testpath: "/logging/gibberish" , test_func: test_gibberish); |
661 | g_test_add_func (testpath: "/structured-logging/no-state" , test_func: test_structured_logging_no_state); |
662 | g_test_add_func (testpath: "/structured-logging/some-state" , test_func: test_structured_logging_some_state); |
663 | g_test_add_func (testpath: "/structured-logging/robustness" , test_func: test_structured_logging_robustness); |
664 | g_test_add_func (testpath: "/structured-logging/roundtrip1" , test_func: test_structured_logging_roundtrip1); |
665 | g_test_add_func (testpath: "/structured-logging/roundtrip2" , test_func: test_structured_logging_roundtrip2); |
666 | g_test_add_func (testpath: "/structured-logging/roundtrip3" , test_func: test_structured_logging_roundtrip3); |
667 | g_test_add_func (testpath: "/structured-logging/variant1" , test_func: test_structured_logging_variant1); |
668 | g_test_add_func (testpath: "/structured-logging/variant2" , test_func: test_structured_logging_variant2); |
669 | |
670 | return g_test_run (); |
671 | } |
672 | |