logger: add -DTEST_LOGGER

"make test_logger" now compiles logger(1) test program
to overwrite system datetime stuff, hostname and PID, for example:

   export TZ=GMT
   export LOGGER_TEST_TIMEOFDAY=1234567890.123456
   export LOGGER_TEST_HOSTNAME=foo
   export LOGGER_TEST_GETPID=123

   ./test_logger --rfc5424 --no-act --stderr -i --tag MyTag mesg
   <13>1 2009-02-13T23:31:30.123456+00:00 foo MyTag 123 - [timeQuality tzKnown="1" isSynced="0"] mesg

if the LOGGER_TEST_* variables are not specified then default to
standard logger(1) behavior.

Note that it would be possible to use for example "unshare --utc" to
make hostname stable and portable, but LOGGER_TEST_* variables allow
to keep the tests less complex.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2015-03-16 13:26:52 +01:00
parent fd343a0572
commit ef5fb28001
3 changed files with 56 additions and 6 deletions

View File

@ -26,6 +26,11 @@ if HAVE_SYSTEMD
logger_LDADD = $(SYSTEMD_LIBS) $(SYSTEMD_DAEMON_LIBS) $(SYSTEMD_JOURNAL_LIBS)
logger_CFLAGS = $(SYSTEMD_CFLAGS) $(SYSTEMD_DAEMON_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS)
endif
check_PROGRAMS += test_logger
test_logger_SOURCES = $(logger_SOURCES)
test_logger_LDADD = $(logger_LDADD)
test_logger_CFLAGS = -DTEST_LOGGER $(logger_CFLAGS)
endif # BUILD_LOGGER

View File

@ -119,6 +119,50 @@ struct logger_ctl {
skip_empty_lines:1; /* do not send empty lines when processing files */
};
/*
* For tests we want to be able to control datetime outputs
*/
#ifdef TEST_LOGGER
static inline int logger_gettimeofday(struct timeval *tv, struct timezone *tz)
{
char *str = getenv("LOGGER_TEST_TIMEOFDAY");
uintmax_t sec, usec;
if (str && sscanf(str, "%ju.%ju", &sec, &usec) == 2) {
tv->tv_sec = sec;
tv->tv_usec = usec;
return tv->tv_sec == sec && tv->tv_usec == usec;
}
return gettimeofday(tv, tz);
}
static inline char *logger_xgethostname(void)
{
char *str = getenv("LOGGER_TEST_HOSTNAME");
return str ? xstrdup(str) : xgethostname();
}
static inline pid_t logger_getpid(void)
{
char *str = getenv("LOGGER_TEST_GETPID");
unsigned int pid;
if (str && sscanf(str, "%u", &pid) == 1)
return pid;
return getpid();
}
#undef HAVE_NTP_GETTIME /* force to default non-NTP */
#else /* !TEST_LOGGER */
# define logger_gettimeofday(x, y) gettimeofday(x, y)
# define logger_xgethostname xgethostname
# define logger_getpid getpid
#endif
static int decode(const char *name, CODE *codetab)
{
register CODE *c;
@ -319,7 +363,7 @@ static const char *rfc3164_current_time(void)
"Sep", "Oct", "Nov", "Dec"
};
gettimeofday(&tv, NULL);
logger_gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
snprintf(time, sizeof(time),"%s %2d %2.2d:%2.2d:%2.2d",
monthnames[tm->tm_mon], tm->tm_mday,
@ -367,7 +411,7 @@ static void syslog_rfc3164_header(struct logger_ctl *const ctl)
if (ctl->pid)
snprintf(pid, sizeof(pid), "[%d]", ctl->pid);
if ((hostname = xgethostname())) {
if ((hostname = logger_xgethostname())) {
char *dot = strchr(hostname, '.');
if (dot)
*dot = '\0';
@ -416,7 +460,7 @@ static void syslog_rfc5424_header(struct logger_ctl *const ctl)
struct timeval tv;
struct tm *tm;
gettimeofday(&tv, NULL);
logger_gettimeofday(&tv, NULL);
if ((tm = localtime(&tv.tv_sec)) != NULL) {
char fmt[64];
const size_t i = strftime(fmt, sizeof(fmt),
@ -432,7 +476,7 @@ static void syslog_rfc5424_header(struct logger_ctl *const ctl)
time = xstrdup(NILVALUE);
if (ctl->rfc5424_host) {
if (!(hostname = xgethostname()))
if (!(hostname = logger_xgethostname()))
hostname = xstrdup(NILVALUE);
/* Arbitrary looking 'if (var < strlen()) checks originate from
* RFC 5424 - 6 Syslog Message Format definition. */
@ -764,7 +808,7 @@ int main(int argc, char **argv)
ctl.skip_empty_lines = 1;
break;
case 'i': /* log process id also */
ctl.pid = getpid();
ctl.pid = logger_getpid();
break;
case OPT_ID:
if (optarg) {
@ -774,7 +818,7 @@ int main(int argc, char **argv)
p++;
ctl.pid = strtoul_or_err(optarg, _("failed to parse id"));
} else
ctl.pid = getpid();
ctl.pid = logger_getpid();
break;
case 'p': /* priority */
ctl.pri = pencode(optarg);

View File

@ -17,6 +17,7 @@ TS_HELPER_LIBMOUNT_DEBUG="$top_builddir/test_mount_debug"
TS_HELPER_PYLIBMOUNT_CONTEXT="$top_srcdir/libmount/python/test_mount_context.py"
TS_HELPER_PYLIBMOUNT_TAB="$top_srcdir/libmount/python/test_mount_tab.py"
TS_HELPER_PYLIBMOUNT_UPDATE="$top_srcdir/libmount/python/test_mount_tab_update.py"
TS_HELPER_LOGGER="$top_builddir/test_logger"
TS_HELPER_LOGINDEFS="$top_builddir/test_logindefs"
TS_HELPER_MD5="$top_builddir/test_md5"
TS_HELPER_MORE=${TS_HELPER_MORE-"$top_builddir/test_more"}