-
-
Notifications
You must be signed in to change notification settings - Fork 327
/
rz_test.h
218 lines (188 loc) · 6.4 KB
/
rz_test.h
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// SPDX-FileCopyrightText: 2020 thestr4ng3r <info@florianmaerkl.de>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef RIZIN_RZTEST_H
#define RIZIN_RZTEST_H
#include <rz_util.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define RZ_TEST_OS "freebsd"
#elif defined(__linux__)
#define RZ_TEST_OS "linux"
#elif defined(__APPLE__)
#define RZ_TEST_OS "darwin"
#elif __WINDOWS__
#define RZ_TEST_OS "windows"
#else
#define RZ_TEST_OS "unknown"
#endif
#if __i386__
#define RZ_TEST_ARCH "x86"
#elif __x86_64__
#define RZ_TEST_ARCH "x64"
#elif __arm__
#define RZ_TEST_ARCH "arm"
#elif __arm64__
#define RZ_TEST_ARCH "arm64"
#else
#define RZ_TEST_ARCH "unknown"
#endif
#define RZ_TEST_ARCH_OS RZ_TEST_OS "-" RZ_TEST_ARCH
typedef struct rz_test_cmd_test_string_record {
char *value;
ut64 line_begin; // inclusive
ut64 line_end; // exclusive
} RzCmdTestStringRecord;
typedef struct rz_test_cmd_test_bool_record {
bool value;
ut64 line; // bools are always oneliners (e.g. BROKEN=1)
bool set;
} RzCmdTestBoolRecord;
typedef struct rz_test_cmd_test_num_record {
ut64 value;
ut64 line; // nums are always oneliners (e.g. TIMEOUT=10)
bool set;
} RzCmdTestNumRecord;
typedef struct rz_test_cmd_test_t {
RzCmdTestStringRecord name;
RzCmdTestStringRecord file;
RzCmdTestStringRecord args;
RzCmdTestStringRecord source;
RzCmdTestStringRecord cmds;
RzCmdTestStringRecord expect;
RzCmdTestStringRecord expect_err;
RzCmdTestStringRecord regexp_out;
RzCmdTestStringRecord regexp_err;
RzCmdTestBoolRecord broken;
RzCmdTestNumRecord timeout;
ut64 run_line;
bool load_plugins;
} RzCmdTest;
// A temporary workaround while clang-format bug is not fixed:
// https://bugs.llvm.org/show_bug.cgi?id=46240
// clang-format off
#define RZ_CMD_TEST_FOREACH_RECORD_NOP(name, field)
#define RZ_CMD_TEST_FOREACH_RECORD(macro_str, macro_bool, macro_int) \
macro_str ("NAME", name) \
macro_str ("FILE", file) \
macro_str ("ARGS", args) \
macro_int ("TIMEOUT", timeout) \
macro_str ("SOURCE", source) \
macro_str ("CMDS", cmds) \
macro_str ("EXPECT", expect) \
macro_str ("EXPECT_ERR", expect_err) \
macro_str ("REGEXP_FILTER_OUT", regexp_out) \
macro_str ("REGEXP_FILTER_ERR", regexp_err) \
macro_bool ("BROKEN", broken)
// clang-format on
typedef enum rz_test_asm_test_mode_t {
RZ_ASM_TEST_MODE_ASSEMBLE = 1,
RZ_ASM_TEST_MODE_DISASSEMBLE = (1 << 1),
RZ_ASM_TEST_MODE_BIG_ENDIAN = (1 << 2),
RZ_ASM_TEST_MODE_BROKEN = (1 << 3)
} RzAsmTestMode;
typedef struct rz_test_asm_test_t {
ut64 line;
const char *arch;
const char *cpu;
int bits;
int mode;
ut64 offset;
RZ_NONNULL char *disasm;
RZ_NONNULL ut8 *bytes;
size_t bytes_size;
RZ_NULLABLE char *il;
} RzAsmTest;
typedef struct rz_test_json_test_t {
ut64 line;
char *cmd;
bool broken;
bool load_plugins;
} RzJsonTest;
typedef struct rz_test_fuzz_test_t {
char *file;
} RzFuzzTest;
typedef enum rz_test_test_type_t {
RZ_TEST_TYPE_CMD,
RZ_TEST_TYPE_ASM,
RZ_TEST_TYPE_JSON,
RZ_TEST_TYPE_FUZZ
} RzTestType;
typedef struct rz_test_test_t {
const char *path;
RzTestType type;
union {
RzCmdTest *cmd_test;
RzAsmTest *asm_test;
RzJsonTest *json_test;
RzFuzzTest *fuzz_test;
};
} RzTest;
typedef struct rz_test_test_database_t {
RzPVector /*<RzTest *>*/ tests;
RzStrConstPool strpool;
} RzTestDatabase;
typedef struct rz_test_run_config_t {
const char *rz_cmd;
const char *rz_asm_cmd;
const char *json_test_file;
ut64 timeout_ms;
} RzTestRunConfig;
typedef struct rz_test_asm_test_output_t {
char *disasm;
ut8 *bytes;
size_t bytes_size;
char *il;
char *il_report;
bool il_failed;
bool as_timeout;
bool disas_timeout;
bool il_timeout;
} RzAsmTestOutput;
typedef enum rz_test_test_result_t {
RZ_TEST_RESULT_OK,
RZ_TEST_RESULT_FAILED,
RZ_TEST_RESULT_BROKEN,
RZ_TEST_RESULT_FIXED
} RzTestResult;
typedef struct rz_test_test_result_info_t {
RzTest *test;
RzTestResult result;
bool timeout;
bool run_failed; // something went seriously wrong (e.g. rizin not found)
ut64 time_elapsed;
union {
RzSubprocessOutput *proc_out; // for test->type == RZ_TEST_TYPE_CMD, RZ_TEST_TYPE_JSON or RZ_TEST_TYPE_FUZZ
RzAsmTestOutput *asm_out; // for test->type == RZ_TEST_TYPE_ASM
};
} RzTestResultInfo;
RZ_API RzCmdTest *rz_test_cmd_test_new(void);
RZ_API void rz_test_cmd_test_free(RzCmdTest *test);
RZ_API RzPVector /*<RzCmdTest *>*/ *rz_test_load_cmd_test_file(const char *file);
RZ_API RzAsmTest *rz_test_asm_test_new(void);
RZ_API void rz_test_asm_test_free(RzAsmTest *test);
RZ_API RzPVector /*<RzAsmTest *>*/ *rz_test_load_asm_test_file(RzStrConstPool *strpool, const char *file);
RZ_API RzJsonTest *rz_test_json_test_new(void);
RZ_API void rz_test_json_test_free(RzJsonTest *test);
RZ_API RzPVector /*<RzJsonTest *>*/ *rz_test_load_json_test_file(const char *file);
RZ_API RzTestDatabase *rz_test_test_database_new(void);
RZ_API void rz_test_test_database_free(RzTestDatabase *db);
RZ_API bool rz_test_test_database_load(RzTestDatabase *db, const char *path);
RZ_API bool rz_test_test_database_load_fuzz(RzTestDatabase *db, const char *path);
typedef RzSubprocessOutput *(*RzTestCmdRunner)(const char *file, const char *args[], size_t args_size,
const char *envvars[], const char *envvals[], size_t env_size, ut64 timeout_ms, void *user);
RZ_API RzSubprocessOutput *rz_test_run_cmd_test(RzTestRunConfig *config, RzCmdTest *test, RzTestCmdRunner runner, void *user);
RZ_API bool rz_test_check_cmd_test(RzSubprocessOutput *out, RzCmdTest *test);
RZ_API bool rz_test_cmp_cmd_output(const char *output, const char *expect, const char *regexp);
RZ_API bool rz_test_check_jq_available(void);
RZ_API RzSubprocessOutput *rz_test_run_json_test(RzTestRunConfig *config, RzJsonTest *test, RzTestCmdRunner runner, void *user);
RZ_API bool rz_test_check_json_test(RzSubprocessOutput *out, RzJsonTest *test);
RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest *test);
RZ_API bool rz_test_check_asm_test(RzAsmTestOutput *out, RzAsmTest *test);
RZ_API void rz_test_asm_test_output_free(RzAsmTestOutput *out);
RZ_API RzSubprocessOutput *rz_test_run_fuzz_test(RzTestRunConfig *config, RzFuzzTest *test, RzTestCmdRunner runner, void *user);
RZ_API bool rz_test_check_fuzz_test(RzSubprocessOutput *out);
RZ_API void rz_test_test_free(RzTest *test);
RZ_API char *rz_test_test_name(RzTest *test);
RZ_API bool rz_test_test_broken(RzTest *test);
RZ_API RzTestResultInfo *rz_test_run_test(RzTestRunConfig *config, RzTest *test);
RZ_API void rz_test_test_result_info_free(RzTestResultInfo *result);
#endif // RIZIN_RZTEST_H