1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (c) 2021 Google LLC
4 */
5
6 #ifndef _TEST_FRAMEWORK_H
7 #define _TEST_FRAMEWORK_H
8
9 #include <stdbool.h>
10 #include <stdio.h>
11
12 #ifdef __ANDROID__
13 static int test_case_pass;
14 static int test_case_fail;
15 #define ksft_print_msg printf
16 #define ksft_test_result_pass(...) ({test_case_pass++; printf(__VA_ARGS__); })
17 #define ksft_test_result_fail(...) ({test_case_fail++; printf(__VA_ARGS__); })
18 #define ksft_exit_fail_msg(...) printf(__VA_ARGS__)
19 #define ksft_print_header()
20 #define ksft_set_plan(cnt)
21 #define ksft_get_fail_cnt() test_case_fail
22 #define ksft_exit_pass() 0
23 #define ksft_exit_fail() 1
24 #else
25 #include <kselftest.h>
26 #endif
27
28 #define TEST_FAILURE 1
29 #define TEST_SUCCESS 0
30
31 #define ptr_to_u64(p) ((__u64)p)
32
33 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
34 #define le16_to_cpu(x) (x)
35 #define le32_to_cpu(x) (x)
36 #define le64_to_cpu(x) (x)
37 #else
38 #error Big endian not supported!
39 #endif
40
41 struct _test_options {
42 int file;
43 bool verbose;
44 };
45
46 extern struct _test_options test_options;
47
48 #define TESTCOND(condition) \
49 do { \
50 if (!(condition)) { \
51 ksft_print_msg("%s failed %d\n", \
52 __func__, __LINE__); \
53 goto out; \
54 } else if (test_options.verbose) \
55 ksft_print_msg("%s succeeded %d\n", \
56 __func__, __LINE__); \
57 } while (false)
58
59 #define TESTCONDERR(condition) \
60 do { \
61 if (!(condition)) { \
62 ksft_print_msg("%s failed %d\n", \
63 __func__, __LINE__); \
64 ksft_print_msg("Error %d (\"%s\")\n", \
65 errno, strerror(errno)); \
66 goto out; \
67 } else if (test_options.verbose) \
68 ksft_print_msg("%s succeeded %d\n", \
69 __func__, __LINE__); \
70 } while (false)
71
72 #define TEST(statement, condition) \
73 do { \
74 statement; \
75 TESTCOND(condition); \
76 } while (false)
77
78 #define TESTERR(statement, condition) \
79 do { \
80 statement; \
81 TESTCONDERR(condition); \
82 } while (false)
83
84 enum _operator {
85 _eq,
86 _ne,
87 _ge,
88 };
89
90 static const char * const _operator_name[] = {
91 "==",
92 "!=",
93 ">=",
94 };
95
96 #define _TEST_OPERATOR(name, _type, format_specifier) \
97 static inline int _test_operator_##name(const char *func, int line, \
98 _type a, _type b, enum _operator o) \
99 { \
100 bool pass; \
101 switch (o) { \
102 case _eq: pass = a == b; break; \
103 case _ne: pass = a != b; break; \
104 case _ge: pass = a >= b; break; \
105 } \
106 \
107 if (!pass) \
108 ksft_print_msg("Failed: %s at line %d, " \
109 format_specifier " %s " \
110 format_specifier "\n", \
111 func, line, a, _operator_name[o], b); \
112 else if (test_options.verbose) \
113 ksft_print_msg("Passed: %s at line %d, " \
114 format_specifier " %s " \
115 format_specifier "\n", \
116 func, line, a, _operator_name[o], b); \
117 \
118 return pass ? TEST_SUCCESS : TEST_FAILURE; \
119 }
120
121 _TEST_OPERATOR(i, int, "%d")
122 _TEST_OPERATOR(ui, unsigned int, "%u")
123 _TEST_OPERATOR(lui, unsigned long, "%lu")
124 _TEST_OPERATOR(ss, ssize_t, "%zd")
125 _TEST_OPERATOR(vp, void *, "%px")
126 _TEST_OPERATOR(cp, char *, "%px")
127
128 #define _CALL_TO(_type, name, a, b, o) \
129 _type:_test_operator_##name(__func__, __LINE__, \
130 (_type) (long long) (a), \
131 (_type) (long long) (b), o)
132
133 #define TESTOPERATOR(a, b, o) \
134 do { \
135 if (_Generic((a), \
136 _CALL_TO(int, i, a, b, o), \
137 _CALL_TO(unsigned int, ui, a, b, o), \
138 _CALL_TO(unsigned long, lui, a, b, o), \
139 _CALL_TO(ssize_t, ss, a, b, o), \
140 _CALL_TO(void *, vp, a, b, o), \
141 _CALL_TO(char *, cp, a, b, o) \
142 )) \
143 goto out; \
144 } while (false)
145
146 #define TESTEQUAL(a, b) TESTOPERATOR(a, b, _eq)
147 #define TESTNE(a, b) TESTOPERATOR(a, b, _ne)
148 #define TESTGE(a, b) TESTOPERATOR(a, b, _ge)
149
150 /* For testing a syscall that returns 0 on success and sets errno otherwise */
151 #define TESTSYSCALL(statement) TESTCONDERR((statement) == 0)
152
153 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
154
print_bytes(const void * data,size_t size)155 static inline void print_bytes(const void *data, size_t size)
156 {
157 const char *bytes = data;
158 int i;
159
160 for (i = 0; i < size; ++i) {
161 if (i % 0x10 == 0)
162 printf("%08x:", i);
163 printf("%02x ", (unsigned int) (unsigned char) bytes[i]);
164 if (i % 0x10 == 0x0f)
165 printf("\n");
166 }
167
168 if (i % 0x10 != 0)
169 printf("\n");
170 }
171
172
173
174 #endif
175