From a4a8840fbeb3bb29ee1cd8bcc9b6f6cc626054df Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Thu, 7 Feb 2019 09:47:47 +0100 Subject: [PATCH] tests: introduce common helper file At this chance, change the installation directory for tests to $prefix/tests. --- config.mk | 1 + tests/Makefile | 29 +++++++---- tests/helpers.c | 64 +++++++++++++++++++++++ tests/helpers.h | 131 ++++++++++++++++++++++++++++++------------------ 4 files changed, 165 insertions(+), 60 deletions(-) create mode 100644 tests/helpers.c diff --git a/config.mk b/config.mk index 4e48cb2..735e0f5 100644 --- a/config.mk +++ b/config.mk @@ -23,6 +23,7 @@ MKDIR_P := mkdir -p libdir ?= lib includedir ?= include bindir ?= bin +testdir ?= tests export ARCH CROSS_COMPILE CC LD AR UAPI CFLAGS LDFLAGS DESTDIR diff --git a/tests/Makefile b/tests/Makefile index 9e9411c..b1d14f0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,14 +3,16 @@ include ../config.mk include ../libversion.mk -TESTFILES := $(wildcard *.c) -BINARIES = $(TESTFILES:%.c=%) -TARGETS = $(TESTFILES:%.c=$(O_DIR)/%) -DEPFILES = $(TESTFILES:%.c=$(O_DIR)/%.d) +ALLSRC := $(wildcard *.c) +HELPSRC := helpers.c +HELPOBJ := $(O_DIR)/helpers.o +TESTSRC := $(filter-out $(HELPSRC),$(ALLSRC)) +TARGETS = $(TESTSRC:%.c=$(O_DIR)/%) +DEPFILES = $(ALLSRC:%.c=$(O_DIR)/%.d) -TEST_CPPFLAGS := $(BASE_CPPFLAGS) \ - -I. \ - -I../include \ +TEST_CPPFLAGS := $(BASE_CPPFLAGS) \ + -I. \ + -I../include \ -I$(O_DIR)/../include TEST_CFLAGS := $(TEST_CPPFLAGS) $(BASE_CFLAGS) @@ -21,15 +23,20 @@ override LDFLAGS := $(TEST_LDFLAGS) $(LDFLAGS) all: $(TARGETS) +$(TARGETS): $(HELPOBJ) + install: all - $(Q)for bin in $(BINARIES); do \ - $(INSTALL) -D $(O_DIR)/$$bin $(DESTDIR)/$(bindir)/$$bin; \ + $(Q)for bin in $(TESTSRC:%.c=%); do \ + $(INSTALL) -D $(O_DIR)/$$bin $(DESTDIR)/$(testdir)/$$bin; \ done clean clobber mrproper: - $(Q)$(RM) -f $(TARGETS) $(DEPFILES) + $(Q)$(RM) -f $(TARGETS) $(DEPFILES) $(HELPOBJ) + +$(O_DIR)/%.o: %.c + $(call cc-cmd,$@,$(Q)$(CC) -o $(@) $< -c $(CFLAGS)) $(O_DIR)/%: %.c - $(call ccld-cmd,$@,$(Q)$(CC) -o $(@) $< $(CFLAGS) $(LDFLAGS)) + $(call ccld-cmd,$@,$(Q)$(CC) -o $(@) $< $(HELPOBJ) $(CFLAGS) $(LDFLAGS)) -include $(DEPFILES) diff --git a/tests/helpers.c b/tests/helpers.c new file mode 100644 index 0000000..f0d51ce --- /dev/null +++ b/tests/helpers.c @@ -0,0 +1,64 @@ +/* + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "helpers.h" + +char *get_unique_name_and_path(const char *type, + int serial, char **ppath) +{ + char *path; + int ret; + + ret = asprintf(&path, "/dev/evenless/%s/test%d.%d", + type, getpid(), serial); + if (ret < 0) + error(1, ENOMEM, "malloc"); + + if (ppath) + *ppath = path; + + return strrchr(path, '/') + 1; +} + +int new_thread(pthread_t *tid, int policy, int prio, + void *(*fn)(void *), void *arg) +{ + struct sched_param param; + pthread_attr_t attr; + int ret; + + pthread_attr_init(&attr); + param.sched_priority = prio; + pthread_attr_setschedpolicy(&attr, policy); + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + __Tcall(ret, pthread_create(tid, &attr, fn, arg)); + + return ret; +} + +void timespec_add_ns(struct timespec *__restrict r, + const struct timespec *__restrict t, + long ns) +{ + long s, rem; + + s = ns / 1000000000; + rem = ns - s * 1000000000; + r->tv_sec = t->tv_sec + s; + r->tv_nsec = t->tv_nsec + rem; + if (r->tv_nsec >= 1000000000) { + r->tv_sec++; + r->tv_nsec -= 1000000000; + } +} diff --git a/tests/helpers.h b/tests/helpers.h index 8b00030..878f163 100644 --- a/tests/helpers.h +++ b/tests/helpers.h @@ -5,52 +5,70 @@ #ifndef _EVENLESS_TESTS_HELPERS_H #define _EVENLESS_TESTS_HELPERS_H -#include -#include -#include -#include #include +#include #include +#include +#include #define __stringify_1(x...) #x #define __stringify(x...) __stringify_1(x) #define warn_failed(__fmt, __args...) \ - fprintf(stderr, "FAILED: " __fmt, ##__args) + fprintf(stderr, "%s:%d: FAILED: " __fmt "\n", __FILE__, __LINE__, ##__args) -#define __T(__ret, __action) \ - ({ \ - (__ret) = (__action); \ - if (__ret < 0) { \ - (__ret) = -(__ret); \ - warn_failed("%s (=%s)", \ - __stringify(__action), \ - strerror(__ret)); \ - } \ - (__ret) >= 0; \ +#define abort_test() exit(1) + +#define __Tcall(__ret, __call) \ + ({ \ + (__ret) = (__call); \ + if (__ret < 0) { \ + warn_failed("%s (=%s)", \ + __stringify(__call), \ + strerror(-(__ret))); \ + } \ + (__ret) >= 0; \ }) -#define __F(__ret, __action) \ - ({ \ - (__ret) = (__action); \ - if ((__ret) >= 0) \ - warn_failed("%s (%d >= 0)", \ - __stringify(__action), \ - __ret); \ - (__ret) < 0; \ +#define __Tcall_assert(__ret, __call) \ + do { \ + if (!__Tcall(__ret, __call)) \ + abort_test(); \ + } while (0) + +#define __Fcall(__ret, __call) \ + ({ \ + (__ret) = (__call); \ + if ((__ret) >= 0) \ + warn_failed("%s (%d >= 0)", \ + __stringify(__call), \ + __ret); \ + (__ret) < 0; \ }) -#define __Terrno(__ret, __action) \ - ({ \ - (__ret) = (__action); \ - if (__ret) \ - warn_failed("%s (=%s)", \ - __stringify(__action), \ - strerror(errno)); \ - (__ret) == 0; \ +#define __Fcall_assert(__ret, __call) \ + do { \ + if (!__Fcall(__ret, __call)) \ + abort_test(); \ + } while (0) + +#define __Tcall_errno(__ret, __call) \ + ({ \ + (__ret) = (__call); \ + if (__ret) \ + warn_failed("%s (=%s)", \ + __stringify(__call), \ + strerror(errno)); \ + (__ret) == 0; \ }) -#define __Tassert(__expr) \ +#define __Tcall_errno_assert(__ret, __call) \ + do { \ + if (!__Tcall_errno(__ret, __call)) \ + abort_test(); \ + } while (0) + +#define __Texpr(__expr) \ ({ \ int __ret = !!(__expr); \ if (!__ret) \ @@ -59,26 +77,41 @@ __ret; \ }) -#define __Fassert(__expr) \ - ({ \ - int __ret = (__expr); \ - if (__ret) \ - warn_failed("%s (=true)", \ - __stringify(__expr)); \ - !__ret; \ +#define __Texpr_assert(__expr) \ + do { \ + if (!__Texpr(__expr)) \ + abort_test(); \ + } while (0) + +#define __Fexpr(__expr) \ + ({ \ + int __ret = (__expr); \ + if (__ret) \ + warn_failed("%s (=true)", \ + __stringify(__expr)); \ + !__ret; \ }) -static inline -char *get_unique_name(const char *type, int serial, char **ppath) +#define __Fexpr_assert(__expr) \ + do { \ + if (!__Fexpr(__expr)) \ + abort_test(); \ + } while (0) + +char *get_unique_name_and_path(const char *type, + int serial, char **ppath); + +static inline char *get_unique_name(const char *type, + int serial) { - int ret; - - ret = asprintf(ppath, "/dev/evenless/%s/test%d.%d", - type, getpid(), serial); - if (ret < 0) - error(1, ENOMEM, "malloc"); - - return strrchr(*ppath, '/') + 1; + return get_unique_name_and_path(type, serial, NULL); } +int new_thread(pthread_t *tid, int policy, int prio, + void *(*fn)(void *), void *arg); + +void timespec_add_ns(struct timespec *__restrict r, + const struct timespec *__restrict t, + long ns); + #endif /* !_EVENLESS_TESTS_HELPERS_H */