[go: up one dir, main page]

File: unittest.h

package info (click to toggle)
uftrace 0.13-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,212 kB
  • sloc: ansic: 53,313; python: 9,846; makefile: 838; asm: 703; cpp: 602; sh: 560; javascript: 191
file content (143 lines) | stat: -rw-r--r-- 8,764 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef UFTRACE_UNIT_TEST_H
#define UFTRACE_UNIT_TEST_H

#include <stdio.h>
#include <string.h>

enum {
	TEST_OK = 0, /* success */
	TEST_NG, /* failed */
	TEST_SKIP, /* skipped */
	TEST_SIG, /* signal caught */
	TEST_BAD, /* unknown result */
	TEST_MAX,
};

#define stringify(s) __stringify(s)
#define __stringify(s) #s

extern int debug;

#define __TEST_NG(file, line, test, name_a, a, name_b, b)                                          \
	({                                                                                         \
		if (debug) {                                                                       \
			printf("test failed at %s:%d: %s\n", file, line, test);                    \
			printf("  %-16s = %ld\n", name_a, (long)a);                                \
			printf("  %-16s = %ld\n", name_b, (long)b);                                \
			fflush(stdout);                                                            \
		}                                                                                  \
		return TEST_NG;                                                                    \
	})

#define __TEST_OP(a, op, b, file, line)                                                            \
	({                                                                                         \
		const char *name_a;                                                                \
		const char *name_b;                                                                \
		__typeof__(a) __a = (a);                                                           \
		__typeof__(b) __b = (b);                                                           \
                                                                                                   \
		if (__builtin_constant_p(a))                                                       \
			name_a = "value_1";                                                        \
		else                                                                               \
			name_a = stringify(a);                                                     \
                                                                                                   \
		if (__builtin_constant_p(b))                                                       \
			name_b = "value_2";                                                        \
		else                                                                               \
			name_b = stringify(b);                                                     \
                                                                                                   \
		if (!(__a op __b))                                                                 \
			__TEST_NG(file, line, stringify(a op b), name_a, __a, name_b, __b);        \
		TEST_OK;                                                                           \
	})

#define TEST_EQ(a, b) __TEST_OP(a, ==, b, __FILE__, __LINE__)
#define TEST_NE(a, b) __TEST_OP(a, !=, b, __FILE__, __LINE__)
#define TEST_GT(a, b) __TEST_OP(a, >, b, __FILE__, __LINE__)
#define TEST_GE(a, b) __TEST_OP(a, >=, b, __FILE__, __LINE__)
#define TEST_LT(a, b) __TEST_OP(a, <, b, __FILE__, __LINE__)
#define TEST_LE(a, b) __TEST_OP(a, <=, b, __FILE__, __LINE__)

#define __TEST_STRNG(file, line, test, name_a, a, name_b, b)                                       \
	({                                                                                         \
		if (debug) {                                                                       \
			printf("test failed at %s:%d: %s\n", file, line, test);                    \
			printf("  %-16s = %s\n", name_a, a);                                       \
			printf("  %-16s = %s\n", name_b, b);                                       \
		}                                                                                  \
		return TEST_NG;                                                                    \
	})

#define __TEST_STREQ(a, b, file, line)                                                             \
	({                                                                                         \
		const char *name_a;                                                                \
		const char *name_b;                                                                \
		const char *__a = (a);                                                             \
		const char *__b = (b);                                                             \
                                                                                                   \
		if (__builtin_constant_p(a))                                                       \
			name_a = "expected";                                                       \
		else                                                                               \
			name_a = stringify(a);                                                     \
                                                                                                   \
		if (__builtin_constant_p(b))                                                       \
			name_b = "actual";                                                         \
		else                                                                               \
			name_b = stringify(b);                                                     \
                                                                                                   \
		if (strcmp(__a, __b))                                                              \
			__TEST_STRNG(file, line, stringify(a == b), name_a, __a, name_b, __b);     \
		TEST_OK;                                                                           \
	})
#define TEST_STREQ(a, b) __TEST_STREQ(a, b, __FILE__, __LINE__)

#define __TEST_MEMEQ(a, b, sz, file, line)                                                         \
	({                                                                                         \
		const void *__a = (a);                                                             \
		const void *__b = (b);                                                             \
                                                                                                   \
		if (memcmp(__a, __b, (sz)))                                                        \
			__TEST_NG(file, line, stringify(a == b), stringify(a), __a, stringify(b),  \
				  __b);                                                            \
		TEST_OK;                                                                           \
	})
#define TEST_MEMEQ(a, b, sz) __TEST_MEMEQ((a), (b), (sz), __FILE__, __LINE__)

#define TEST_SECTION "uftrace.unit_test"

struct uftrace_unit_test {
	const char *name;
	int (*func)(void);
};

#ifdef __clang__
#define TEST_CASE(t)                                                                               \
	extern int func_##t(void);                                                                 \
                                                                                                   \
	__attribute__((section(TEST_SECTION), used, no_sanitize("address")))                       \
	const struct uftrace_unit_test test_##t = {                                                \
		.name = stringify(t),                                                              \
		.func = func_##t,                                                                  \
	};                                                                                         \
                                                                                                   \
	int func_##t(void)
#else /* #ifdef __clang__ */
#define TEST_CASE(t)                                                                               \
	extern int func_##t(void);                                                                 \
                                                                                                   \
	__attribute__((section(TEST_SECTION), used)) const struct uftrace_unit_test test_##t = {   \
		.name = stringify(t),                                                              \
		.func = func_##t,                                                                  \
	};                                                                                         \
                                                                                                   \
	int func_##t(void)
#endif /* #ifdef __clang__ */

#define TERM_COLOR_NORMAL ""
#define TERM_COLOR_RESET "\033[0m"
#define TERM_COLOR_BOLD "\033[1m"
#define TERM_COLOR_RED "\033[91m"
#define TERM_COLOR_GREEN "\033[32m"
#define TERM_COLOR_YELLOW "\033[33m"

#endif /* UFTRACE_UNIT_TEST_H */