From 8af1d67bd3e8a1766cb9984b3771162cc4c19669 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 10 Aug 2012 14:07:29 +0200 Subject: Split the library into a linkable and an LD_PRELOAD-able part In order to satisfy the desire of using libumberlog, specifically ul_format(), without having to worry about syslog() & friends being overridden, split the library into two parts: A linkable library, which provides the new API, but does not override the legacy syslog() functions; and a new, LD_PRELOAD-able part, which does override the old ones. Signed-off-by: Gergely Nagy --- t/test_umberlog_preload.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 t/test_umberlog_preload.c (limited to 't/test_umberlog_preload.c') diff --git a/t/test_umberlog_preload.c b/t/test_umberlog_preload.c new file mode 100644 index 0000000..e931210 --- /dev/null +++ b/t/test_umberlog_preload.c @@ -0,0 +1,340 @@ +#define _GNU_SOURCE 1 + +#include "umberlog.h" +#include "config.h" +#include "test-common.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +START_TEST (test_simple) +{ + char *msg; + struct json_object *jo; + char host[_POSIX_HOST_NAME_MAX + 1]; + + openlog ("umberlog/test_simple", 0, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "hello, I'm %s!", __FUNCTION__, NULL); + jo = parse_msg (msg); + free (msg); + + gethostname (host, _POSIX_HOST_NAME_MAX); + + verify_value (jo, "msg", "hello, I'm test_simple!"); + verify_value (jo, "facility", "local0"); + verify_value (jo, "priority", "debug"); + verify_value (jo, "program", "umberlog/test_simple"); + verify_value_exists (jo, "pid"); + verify_value_exists (jo, "uid"); + verify_value_exists (jo, "gid"); + verify_value_exists (jo, "timestamp"); + verify_value (jo, "host", host); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_no_discover) +{ + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_no_discover", LOG_UL_NODISCOVER, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "hello, I'm %s!", __FUNCTION__, NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "msg", "hello, I'm test_no_discover!"); + verify_value_missing (jo, "facility"); + verify_value_missing (jo, "priority"); + verify_value_missing (jo, "program"); + verify_value_missing (jo, "pid"); + verify_value_missing (jo, "uid"); + verify_value_missing (jo, "gid"); + verify_value_missing (jo, "host"); + verify_value_missing (jo, "timestamp"); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_additional_fields) +{ + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_additional_fields", 0, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "testing 1, 2, 3...", + "random_number", "%d", 42, + "random_string", "fourty-two", + NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "msg", "testing 1, 2, 3..."); + verify_value (jo, "random_number", "42"); + verify_value (jo, "random_string", "fourty-two"); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_discover_priority) +{ + char *msg, *pid; + struct json_object *jo; + + openlog ("umberlog/test_discover_priority", 0, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "testing 1, 2, 3...", + "pid", "%d", getpid () + 42, + NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "msg", "testing 1, 2, 3..."); + + if (asprintf (&pid, "%d", getpid ()) == -1) + abort (); + verify_value (jo, "pid", pid); + free (pid); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_no_timestamp) +{ + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_no_timestamp", LOG_UL_NOTIME, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "hello, I'm %s!", __FUNCTION__, NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "msg", "hello, I'm test_no_timestamp!"); + verify_value (jo, "facility", "local0"); + verify_value (jo, "priority", "debug"); + verify_value (jo, "program", "umberlog/test_no_timestamp"); + verify_value_exists (jo, "pid"); + verify_value_exists (jo, "uid"); + verify_value_exists (jo, "gid"); + verify_value_missing (jo, "timestamp"); + verify_value_exists (jo, "host"); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_json_escape) +{ + static const char control_chars[] = + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20"; + + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_json_escape", LOG_UL_NODISCOVER, LOG_LOCAL0); + + msg = ul_format (LOG_DEBUG, "%s", __FUNCTION__, + "quotes", "Hi, \"quoted value\" speaking!", + "\"really\"", "yeah", + "control", "foo\nbar", + "utf8", "Árvíztűrő tükörfúrógép", + "junk", "\013foo", + "all_control", control_chars, + NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "quotes", "Hi, \"quoted value\" speaking!"); + verify_value (jo, "\"really\"", "yeah"); + verify_value (jo, "control", "foo\nbar"); + verify_value (jo, "utf8", "Árvíztűrő tükörfúrógép"); + verify_value (jo, "junk", "\013foo"); + verify_value (jo, "all_control", control_chars); + + json_object_put (jo); + + closelog (); +} +END_TEST + +START_TEST (test_facprio) +{ + char *msg; + struct json_object *jo; + + msg = ul_format (LOG_LOCAL1 | LOG_DEBUG, "%s", __FUNCTION__, + NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "facility", "local1"); + verify_value (jo, "priority", "debug"); + + json_object_put (jo); +} +END_TEST + +START_TEST (test_closelog) +{ + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_closelog", LOG_UL_NODISCOVER, LOG_LOCAL0); + closelog (); + + msg = ul_format (LOG_DEBUG, "%s", __FUNCTION__, NULL); + jo = parse_msg (msg); + free (msg); + + verify_value_missing (jo, "facility"); + + json_object_put (jo); + + openlog ("umberlog/test_closelog", 0, LOG_LOCAL0); + closelog (); + + msg = ul_format (LOG_DEBUG, "%s", __FUNCTION__, NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "facility", "local0"); +#ifdef HAVE_PROGRAM_INVOCATION_SHORT_NAME + verify_value (jo, "program", "test_umberlog_preload"); +#else + verify_value_missing (jo, "program"); +#endif + verify_value_differs (jo, "pid", "0"); + if (getuid () != 0) + verify_value_differs (jo, "uid", "0"); + if (getgid () != 0) + verify_value_differs (jo, "gid", "0"); + verify_value_differs (jo, "host", ""); + + json_object_put (jo); +} +END_TEST + +#ifdef HAVE_PARSE_PRINTF_FORMAT +START_TEST (test_positional_params) +{ + char *msg; + struct json_object *jo; + + openlog ("umberlog/test_positional_params", LOG_UL_NOTIME, LOG_LOCAL0); + +#define COMPLEX_FORMAT \ + "%3$*5$.*2$hhd , %1$Lf , %4$.3s , %4$s", 1.0L, 5, (char)100, "prefix", -8 +#define COMPLEX_RESULT "00100 , 1.000000 , pre , prefix" + msg = ul_format (LOG_DEBUG, COMPLEX_FORMAT, + "simple1", "value1", + "complex", COMPLEX_FORMAT, + "simple2", "value2", + NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "msg", COMPLEX_RESULT); + verify_value (jo, "simple1", "value1"); + verify_value (jo, "complex", COMPLEX_RESULT); + verify_value (jo, "simple2", "value2"); + + json_object_put (jo); + + closelog (); +} +END_TEST +#endif + +/* This must be the first test! */ +START_TEST (test_openlog_defaults) +{ + char *msg; + struct json_object *jo; + + /* No openlog */ + + msg = ul_format (LOG_ALERT, "message", NULL); + jo = parse_msg (msg); + free (msg); + + verify_value (jo, "facility", "user"); +#ifdef HAVE_PROGRAM_INVOCATION_SHORT_NAME + verify_value (jo, "program", "test_umberlog_preload"); +#else + verify_value_missing (jo, "program"); +#endif + verify_value_differs (jo, "pid", "0"); + if (getuid () != 0) + verify_value_differs (jo, "uid", "0"); + if (getgid () != 0) + verify_value_differs (jo, "gid", "0"); + verify_value_differs (jo, "host", ""); + json_object_put (jo); + + closelog (); +} +END_TEST + +int +main (void) +{ + Suite *s; + SRunner *sr; + TCase *ft, *bt; + int nfailed; + + s = suite_create ("Umberlog (LD_PRELOAD) functional testsuite"); + + ft = tcase_create ("Basic tests"); + tcase_add_test (ft, test_openlog_defaults); + tcase_add_test (ft, test_simple); + tcase_add_test (ft, test_no_discover); + tcase_add_test (ft, test_additional_fields); + tcase_add_test (ft, test_discover_priority); + tcase_add_test (ft, test_no_timestamp); +#ifdef HAVE_PARSE_PRINTF_FORMAT + tcase_add_test (ft, test_positional_params); +#endif + suite_add_tcase (s, ft); + + bt = tcase_create ("Bug tests"); + tcase_add_test (bt, test_json_escape); + tcase_add_test (bt, test_facprio); + tcase_add_test (bt, test_closelog); + suite_add_tcase (s, bt); + + sr = srunner_create (s); + + srunner_run_all (sr, CK_ENV); + nfailed = srunner_ntests_failed (sr); + srunner_free (sr); + + return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} -- cgit