Fix unit tests on *BSD systems

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-10-12 14:56:59 +01:00
parent 2d1621aee4
commit 065f9ffd4d
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
1 changed files with 74 additions and 50 deletions

View File

@ -8,6 +8,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
defined(__NetBSD__) || defined(__OpenBSD__)
#define USE_SYSCTL_FOR_ARGS 1
#include <sys/sysctl.h>
#include <unistd.h> // getpid
#endif
struct test_file_metadata; struct test_file_metadata;
struct test_failure { struct test_failure {
@ -35,8 +42,7 @@ struct test_file_metadata __attribute__((weak)) * test_file_head;
#define SET_FAILURE(_message) \ #define SET_FAILURE(_message) \
metadata->failure = (struct test_failure) { \ metadata->failure = (struct test_failure) { \
.message = _message, .file = __FILE__, .line = __LINE__, \ .message = _message, .file = __FILE__, .line = __LINE__, .present = true, \
.present = true, \
} }
#define TEST_EQUAL(a, b) \ #define TEST_EQUAL(a, b) \
@ -71,8 +77,7 @@ struct test_file_metadata __attribute__((weak)) * test_file_head;
.name = #_name, \ .name = #_name, \
.fn = __test_h_##_name, \ .fn = __test_h_##_name, \
}; \ }; \
static void __attribute__((constructor(101))) \ static void __attribute__((constructor(101))) __test_h_##_name##_register(void) { \
__test_h_##_name##_register(void) { \
__test_h_meta_##_name.next = __test_h_file.tests; \ __test_h_meta_##_name.next = __test_h_file.tests; \
__test_h_file.tests = &__test_h_meta_##_name; \ __test_h_file.tests = &__test_h_meta_##_name; \
if (!__test_h_file.registered) { \ if (!__test_h_file.registered) { \
@ -91,11 +96,31 @@ extern void __attribute__((weak)) (*test_h_unittest_setup)(void);
/// @param[out] tests_run if not NULL, set to whether tests were run /// @param[out] tests_run if not NULL, set to whether tests were run
static inline void __attribute__((constructor(102))) run_tests(void) { static inline void __attribute__((constructor(102))) run_tests(void) {
bool should_run = false; bool should_run = false;
#ifdef USE_SYSCTL_FOR_ARGS
int mib[] = {
CTL_KERN,
#if defined(__NetBSD__) || defined(__OpenBSD__)
KERN_PROC_ARGS,
getpid(),
KERN_PROC_ARGV,
#else
KERN_PROC,
KERN_PROC_ARGS,
getpid(),
#endif
};
char *arg = NULL;
size_t arglen;
sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &arglen, NULL, 0);
arg = malloc(arglen);
sysctl(mib, sizeof(mib) / sizeof(mib[0]), arg, &arglen, NULL, 0);
#else
FILE *cmdlinef = fopen("/proc/self/cmdline", "r"); FILE *cmdlinef = fopen("/proc/self/cmdline", "r");
char *arg = NULL; char *arg = NULL;
int arglen; int arglen;
fscanf(cmdlinef, "%ms%n", &arg, &arglen); fscanf(cmdlinef, "%ms%n", &arg, &arglen);
fclose(cmdlinef); fclose(cmdlinef);
#endif
for (char *pos = arg; pos < arg + arglen; pos += strlen(pos) + 1) { for (char *pos = arg; pos < arg + arglen; pos += strlen(pos) + 1) {
if (strcmp(pos, "--unittest") == 0) { if (strcmp(pos, "--unittest") == 0) {
should_run = true; should_run = true;
@ -122,9 +147,8 @@ static inline void __attribute__((constructor(102))) run_tests(void) {
j->failure.present = false; j->failure.present = false;
j->fn(j, i); j->fn(j, i);
if (j->failure.present) { if (j->failure.present) {
fprintf(stderr, "failed (%s at %s:%d)\n", fprintf(stderr, "failed (%s at %s:%d)\n", j->failure.message,
j->failure.message, j->failure.file, j->failure.file, j->failure.line);
j->failure.line);
failed++; failed++;
} else { } else {
fprintf(stderr, "passed\n"); fprintf(stderr, "passed\n");