mirror of
https://github.com/troglobit/libite.git
synced 2026-10-28 12:20:45 +00:00
New unit test framework, first test pidfile funcs
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
dedcaf92d5
commit
61fb7aeca2
6 files changed
+157
-127
No files matched your search
@@ -16,6 +16,7 @@ pkgconfigdir = $(libdir)/pkgconfig
|
|||||||
pkgconfig_DATA = libite.pc
|
pkgconfig_DATA = libite.pc
|
||||||
doc_DATA = README.md LICENSE
|
doc_DATA = README.md LICENSE
|
||||||
EXTRA_DIST = README.md LICENSE ChangeLog.md
|
EXTRA_DIST = README.md LICENSE ChangeLog.md
|
||||||
|
SUBDIRS = tests
|
||||||
|
|
||||||
## Generate MD5 checksum file
|
## Generate MD5 checksum file
|
||||||
MD5 = md5sum
|
MD5 = md5sum
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ AM_SILENT_RULES([yes])
|
|||||||
|
|
||||||
AC_CONFIG_SRCDIR(lite.h)
|
AC_CONFIG_SRCDIR(lite.h)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
AC_CONFIG_FILES([Makefile libite.pc])
|
AC_CONFIG_FILES([Makefile tests/Makefile libite.pc])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
|||||||
-126
@@ -21,7 +21,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
extern char *__pidfile_name;
|
|
||||||
extern char *chomp(char *str);
|
extern char *chomp(char *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,131 +117,6 @@ int pidfile_signal(const char *pidfile, int signal)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************* UNIT TESTS ************************************/
|
|
||||||
#ifdef UNITTEST
|
|
||||||
#include <paths.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "lite.h"
|
|
||||||
|
|
||||||
extern char *__progname;
|
|
||||||
static char PIDFILE[42];
|
|
||||||
static int verbose = 0;
|
|
||||||
static struct stat before, after;
|
|
||||||
|
|
||||||
static int test(int result, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
char buf[80];
|
|
||||||
size_t len;
|
|
||||||
va_list ap;
|
|
||||||
const char success[] = " \e[1m[ OK ]\e[0m\n";
|
|
||||||
const char failure[] = " \e[7m[FAIL]\e[0m\n";
|
|
||||||
const char dots[] = " .....................................................................";
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
write(STDERR_FILENO, buf, len);
|
|
||||||
write(STDERR_FILENO, dots, 60 - len); /* pad with dots. */
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
write(STDERR_FILENO, success, strlen(success));
|
|
||||||
else
|
|
||||||
write(STDERR_FILENO, failure, strlen(failure));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int timespec_newer(const struct timespec *a, const struct timespec *b)
|
|
||||||
{
|
|
||||||
if (a->tv_sec != b->tv_sec)
|
|
||||||
return a->tv_sec > b->tv_sec;
|
|
||||||
|
|
||||||
return a->tv_nsec > b->tv_nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *timespec2str(struct timespec *ts, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
size_t ret, pos;
|
|
||||||
struct tm t;
|
|
||||||
|
|
||||||
memset(buf, 0, len);
|
|
||||||
|
|
||||||
tzset();
|
|
||||||
if (localtime_r(&(ts->tv_sec), &t) == NULL)
|
|
||||||
return buf;
|
|
||||||
|
|
||||||
ret = strftime(buf, len, "%F %T", &t);
|
|
||||||
if (ret == 0)
|
|
||||||
return buf;
|
|
||||||
len -= ret - 1;
|
|
||||||
|
|
||||||
pos = strlen(buf);
|
|
||||||
len -= pos;
|
|
||||||
snprintf(&buf[pos], len, ".%09ld", ts->tv_nsec);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sigterm_handler(int UNUSED(signo))
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
printf("Exiting ...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sigalrm_handler(int UNUSED(signo))
|
|
||||||
{
|
|
||||||
pidfile(NULL);
|
|
||||||
if (!fexist(PIDFILE))
|
|
||||||
err(1, "failed creating %s", PIDFILE);
|
|
||||||
stat(PIDFILE, &before);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mtime()
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
/* Must sleep a while here otherwise we execute too fast => no mtime change :-( */
|
|
||||||
usleep(10000);
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
printf("Calling pidfile() again to update mtime ...\n");
|
|
||||||
pidfile(NULL);
|
|
||||||
stat(PIDFILE, &after);
|
|
||||||
|
|
||||||
ret = timespec_newer(&after.st_mtim, &before.st_mtim);
|
|
||||||
if (verbose) {
|
|
||||||
printf("Before: %s\n", timespec2str(&before.st_mtim, buf, sizeof(buf)));
|
|
||||||
printf("After : %s\n", timespec2str(&after.st_mtim, buf, sizeof(buf)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return !ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (argc > 1 && !strcmp(argv[1], "-v"))
|
|
||||||
verbose = 1;
|
|
||||||
|
|
||||||
snprintf(PIDFILE, sizeof(PIDFILE), "%s%s.pid", _PATH_VARRUN, __progname);
|
|
||||||
|
|
||||||
signal(SIGTERM, sigterm_handler);
|
|
||||||
signal(SIGALRM, sigalrm_handler);
|
|
||||||
alarm(1);
|
|
||||||
|
|
||||||
return test(pidfile_poll(PIDFILE) != getpid(), "Testing pidfile_poll()")
|
|
||||||
|| test(strcmp(__pidfile_name, PIDFILE), "Testing __pidfile_name vs guessed PID filename")
|
|
||||||
|| test(mtime(), "Testing mtime update of followup pidfile() call")
|
|
||||||
|| test(pidfile_signal(PIDFILE, SIGTERM), "Testing signalling ourselves")
|
|
||||||
;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* UNITTEST */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* compile-command: "make V=1 -f pidfilefn.mk"
|
* compile-command: "make V=1 -f pidfilefn.mk"
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
EXTRA_DIST = check.h
|
||||||
|
CLEANFILES = *~
|
||||||
|
|
||||||
|
TESTS =
|
||||||
|
TESTS += pidfile_func
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
# Ignore warnings about unused result, in e.g. write()
|
||||||
|
CFLAGS = -Wno-unused-result
|
||||||
|
LDADD = -L../ ../libite.la
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#ifndef LITE_TESTS_CHECK_H_
|
||||||
|
#define LITE_TESTS_CHECK_H_
|
||||||
|
|
||||||
|
#include "../lite.h"
|
||||||
|
|
||||||
|
#define fail_unless(test) \
|
||||||
|
do { \
|
||||||
|
if (!(test)) { \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"----------------------------------------------\n" \
|
||||||
|
"%s:%d: test FAILED:\nFailed test: %s\n" \
|
||||||
|
"----------------------------------------------\n", \
|
||||||
|
__FILE__, __LINE__, #test); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline int test(int result, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[80];
|
||||||
|
size_t len;
|
||||||
|
va_list ap;
|
||||||
|
const char success[] = " \e[1m[ OK ]\e[0m\n";
|
||||||
|
const char failure[] = " \e[7m[FAIL]\e[0m\n";
|
||||||
|
const char dots[] = " .....................................................................";
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
write(STDERR_FILENO, buf, len);
|
||||||
|
write(STDERR_FILENO, dots, 60 - len); /* pad with dots. */
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
write(STDERR_FILENO, success, strlen(success));
|
||||||
|
else
|
||||||
|
write(STDERR_FILENO, failure, strlen(failure));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int timespec_newer(const struct timespec *a, const struct timespec *b)
|
||||||
|
{
|
||||||
|
if (a->tv_sec != b->tv_sec)
|
||||||
|
return a->tv_sec > b->tv_sec;
|
||||||
|
|
||||||
|
return a->tv_nsec > b->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *timespec2str(struct timespec *ts, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t ret, pos;
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
|
memset(buf, 0, len);
|
||||||
|
|
||||||
|
tzset();
|
||||||
|
if (localtime_r(&(ts->tv_sec), &t) == NULL)
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
ret = strftime(buf, len, "%F %T", &t);
|
||||||
|
if (ret == 0)
|
||||||
|
return buf;
|
||||||
|
len -= ret - 1;
|
||||||
|
|
||||||
|
pos = strlen(buf);
|
||||||
|
len -= pos;
|
||||||
|
snprintf(&buf[pos], len, ".%09ld", ts->tv_nsec);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LITE_TESTS_CHECK_H_ */
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#include <paths.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "check.h"
|
||||||
|
|
||||||
|
extern char *__progname;
|
||||||
|
extern char *__pidfile_name;
|
||||||
|
extern char *__pidfile_path;
|
||||||
|
|
||||||
|
static char PIDFILE[42];
|
||||||
|
static int verbose = 0;
|
||||||
|
static struct stat before, after;
|
||||||
|
|
||||||
|
static void sigterm_handler(int UNUSED(signo))
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
printf("Exiting ...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sigalrm_handler(int UNUSED(signo))
|
||||||
|
{
|
||||||
|
pidfile(NULL);
|
||||||
|
if (!fexist(PIDFILE))
|
||||||
|
err(1, "failed creating %s", PIDFILE);
|
||||||
|
stat(PIDFILE, &before);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mtime()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
/* Must sleep a while here otherwise we execute too fast => no mtime change :-( */
|
||||||
|
usleep(10000);
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printf("Calling pidfile() again to update mtime ...\n");
|
||||||
|
pidfile(NULL);
|
||||||
|
stat(PIDFILE, &after);
|
||||||
|
|
||||||
|
ret = timespec_newer(&after.st_mtim, &before.st_mtim);
|
||||||
|
if (verbose) {
|
||||||
|
printf("Before: %s\n", timespec2str(&before.st_mtim, buf, sizeof(buf)));
|
||||||
|
printf("After : %s\n", timespec2str(&after.st_mtim, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc > 1 && !strcmp(argv[1], "-v"))
|
||||||
|
verbose = 1;
|
||||||
|
|
||||||
|
/* Override default _PATH_VARRUN in pidfile() */
|
||||||
|
__pidfile_path = _PATH_TMP;
|
||||||
|
snprintf(PIDFILE, sizeof(PIDFILE), "%s%s.pid", __pidfile_path, __progname);
|
||||||
|
|
||||||
|
signal(SIGTERM, sigterm_handler);
|
||||||
|
signal(SIGALRM, sigalrm_handler);
|
||||||
|
alarm(1);
|
||||||
|
|
||||||
|
return test(pidfile_poll(PIDFILE) != getpid(), "Testing pidfile_poll()")
|
||||||
|
|| test(strcmp(__pidfile_name, PIDFILE), "Testing __pidfile_name vs guessed PID filename")
|
||||||
|
|| test(mtime(), "Testing mtime update of followup pidfile() call")
|
||||||
|
|| test(pidfile_signal(PIDFILE, SIGTERM), "Testing signalling ourselves")
|
||||||
|
;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user