test.h: update to yshui/test.h@9e5fc7b
Fix unit tests on *BSD systems Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
2d1621aee4
commit
065f9ffd4d
|
@ -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 {
|
||||||
|
@ -33,57 +40,55 @@ struct test_file_metadata {
|
||||||
|
|
||||||
struct test_file_metadata __attribute__((weak)) * test_file_head;
|
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) \
|
||||||
do { \
|
do { \
|
||||||
if ((a) != (b)) { \
|
if ((a) != (b)) { \
|
||||||
SET_FAILURE(#a " != " #b); \
|
SET_FAILURE(#a " != " #b); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_TRUE(a) \
|
#define TEST_TRUE(a) \
|
||||||
do { \
|
do { \
|
||||||
if (!(a)) { \
|
if (!(a)) { \
|
||||||
SET_FAILURE(#a " is not true"); \
|
SET_FAILURE(#a " is not true"); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_STREQUAL(a, b) \
|
#define TEST_STREQUAL(a, b) \
|
||||||
do { \
|
do { \
|
||||||
if (strcmp(a, b) != 0) { \
|
if (strcmp(a, b) != 0) { \
|
||||||
SET_FAILURE(#a " != " #b); \
|
SET_FAILURE(#a " != " #b); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_CASE(_name) \
|
#define TEST_CASE(_name) \
|
||||||
static void __test_h_##_name(struct test_case_metadata *, \
|
static void __test_h_##_name(struct test_case_metadata *, \
|
||||||
struct test_file_metadata *); \
|
struct test_file_metadata *); \
|
||||||
static struct test_file_metadata __test_h_file; \
|
static struct test_file_metadata __test_h_file; \
|
||||||
static struct test_case_metadata __test_h_meta_##_name = { \
|
static struct test_case_metadata __test_h_meta_##_name = { \
|
||||||
.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) { \
|
__test_h_file.name = __FILE__; \
|
||||||
__test_h_file.name = __FILE__; \
|
__test_h_file.next = test_file_head; \
|
||||||
__test_h_file.next = test_file_head; \
|
test_file_head = &__test_h_file; \
|
||||||
test_file_head = &__test_h_file; \
|
__test_h_file.registered = true; \
|
||||||
__test_h_file.registered = true; \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
static void __test_h_##_name( \
|
||||||
static void __test_h_##_name( \
|
struct test_case_metadata *metadata __attribute__((unused)), \
|
||||||
struct test_case_metadata *metadata __attribute__((unused)), \
|
|
||||||
struct test_file_metadata *file_metadata __attribute__((unused)))
|
struct test_file_metadata *file_metadata __attribute__((unused)))
|
||||||
|
|
||||||
extern void __attribute__((weak)) (*test_h_unittest_setup)(void);
|
extern void __attribute__((weak)) (*test_h_unittest_setup)(void);
|
||||||
|
@ -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");
|
||||||
|
@ -147,12 +171,12 @@ static inline void __attribute__((constructor(102))) run_tests(void) {
|
||||||
|
|
||||||
#define TEST_CASE(name) static void __attribute__((unused)) __test_h_##name(void)
|
#define TEST_CASE(name) static void __attribute__((unused)) __test_h_##name(void)
|
||||||
|
|
||||||
#define TEST_EQUAL(a, b) \
|
#define TEST_EQUAL(a, b) \
|
||||||
(void)(a); \
|
(void)(a); \
|
||||||
(void)(b)
|
(void)(b)
|
||||||
#define TEST_TRUE(a) (void)(a)
|
#define TEST_TRUE(a) (void)(a)
|
||||||
#define TEST_STREQUAL(a, b) \
|
#define TEST_STREQUAL(a, b) \
|
||||||
(void)(a); \
|
(void)(a); \
|
||||||
(void)(b)
|
(void)(b)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue