Initial support for test categories and fix the windows build ##test

This commit is contained in:
pancake 2020-03-31 11:29:57 +02:00 committed by radare
parent 2c40d164b5
commit 304bc367de
5 changed files with 54 additions and 25 deletions

View File

@ -6,7 +6,7 @@
#define LINEFMT "%s, line %"PFMT64u": " #define LINEFMT "%s, line %"PFMT64u": "
R_API R2RCmdTest *r2r_cmd_test_new() { R_API R2RCmdTest *r2r_cmd_test_new(void) {
return R_NEW0 (R2RCmdTest); return R_NEW0 (R2RCmdTest);
} }
@ -216,7 +216,7 @@ fail:
goto beach; goto beach;
} }
R_API R2RAsmTest *r2r_asm_test_new() { R_API R2RAsmTest *r2r_asm_test_new(void) {
return R_NEW0 (R2RAsmTest); return R_NEW0 (R2RAsmTest);
} }
@ -399,7 +399,7 @@ fail:
goto beach; goto beach;
} }
R_API R2RJsonTest *r2r_json_test_new() { R_API R2RJsonTest *r2r_json_test_new(void) {
return R_NEW0 (R2RJsonTest); return R_NEW0 (R2RJsonTest);
} }
@ -485,7 +485,7 @@ R_API void r2r_test_free(R2RTest *test) {
free (test); free (test);
} }
R_API R2RTestDatabase *r2r_test_database_new() { R_API R2RTestDatabase *r2r_test_database_new(void) {
R2RTestDatabase *db = R_NEW (R2RTestDatabase); R2RTestDatabase *db = R_NEW (R2RTestDatabase);
if (!db) { if (!db) {
return NULL; return NULL;

View File

@ -34,12 +34,13 @@ static void print_state(R2RState *state, ut64 prev_completed);
static void print_log(R2RState *state, ut64 prev_completed, ut64 prev_paths_completed); static void print_log(R2RState *state, ut64 prev_completed, ut64 prev_paths_completed);
static int help(bool verbose) { static int help(bool verbose) {
printf ("Usage: r2r [-vh] [-j threads] [test path]\n"); printf ("Usage: r2r [-vh] [-j threads] [test file/dir | @test-type]\n");
if (verbose) { if (verbose) {
printf ( printf (
" -h print this help\n" " -h print this help\n"
" -v show version\n" " -v show version\n"
" -V verbose\n" " -V verbose\n"
" -n do nothing (don't run any test, just load/parse them)\n"
" -L log mode (better printing for CI, logfiles, etc.)" " -L log mode (better printing for CI, logfiles, etc.)"
" -j [threads] how many threads to use for running tests concurrently (default is "WORKERS_DEFAULT_STR")\n" " -j [threads] how many threads to use for running tests concurrently (default is "WORKERS_DEFAULT_STR")\n"
" -r [radare2] path to radare2 executable (default is "RADARE2_CMD_DEFAULT")\n" " -r [radare2] path to radare2 executable (default is "RADARE2_CMD_DEFAULT")\n"
@ -47,6 +48,7 @@ static int help(bool verbose) {
" -f [file] file to use for json tests (default is "JSON_TEST_FILE_DEFAULT")\n" " -f [file] file to use for json tests (default is "JSON_TEST_FILE_DEFAULT")\n"
" -C [dir] chdir before running r2r (default follows executable symlink + test/new\n" " -C [dir] chdir before running r2r (default follows executable symlink + test/new\n"
"\n" "\n"
"Supported test types: @json @unit @fuzz @cmds\n"
"OS/Arch for archos tests: "R2R_ARCH_OS"\n"); "OS/Arch for archos tests: "R2R_ARCH_OS"\n");
} }
return 1; return 1;
@ -83,6 +85,10 @@ static bool r2r_chdir(const char *argv0) {
#endif #endif
} }
static void r2r_test_run_unit(void) {
system ("make -C ../unit all run");
}
static bool r2r_chdir_fromtest(const char *test_path) { static bool r2r_chdir_fromtest(const char *test_path) {
char *abs_test_path = r_file_abspath (test_path); char *abs_test_path = r_file_abspath (test_path);
if (!r_file_is_directory (abs_test_path)) { if (!r_file_is_directory (abs_test_path)) {
@ -140,7 +146,7 @@ int main(int argc, char **argv) {
ret = help (true); ret = help (true);
goto beach; goto beach;
case 'v': case 'v':
printf (""R2_VERSION"\n"); printf (R2_VERSION "\n");
return 0; return 0;
case 'V': case 'V':
verbose = true; verbose = true;
@ -184,12 +190,13 @@ int main(int argc, char **argv) {
if (r2r_dir) { if (r2r_dir) {
chdir (r2r_dir); chdir (r2r_dir);
} else { } else {
bool dir_found = (opt.ind < argc) bool dir_found = (opt.ind < argc && argv[opt.ind][0] != '.')
? r2r_chdir_fromtest (argv[opt.ind]) ? r2r_chdir_fromtest (argv[opt.ind])
: r2r_chdir (argv[0]); : r2r_chdir (argv[0]);
if (!dir_found) { if (!dir_found) {
eprintf ("Cannot find db/ directory related to the given test.\n"); eprintf ("Cannot find db/ directory related to the given test.\n");
return -1; return -1;
} }
} }
@ -225,7 +232,28 @@ int main(int argc, char **argv) {
// Manually specified path(s) // Manually specified path(s)
int i; int i;
for (i = opt.ind; i < argc; i++) { for (i = opt.ind; i < argc; i++) {
char *tf = (argv[i][0] == '/')? strdup (argv[i]): r_str_newf ("%s"R_SYS_DIR"%s", cwd, argv[i]); const char *arg = argv[i];
if (*arg == '@') {
arg++;
eprintf ("Category: %s\n", arg);
if (!strcmp (arg, "unit")) {
r2r_test_run_unit ();
continue;
} else if (!strcmp (arg, "fuzz")) {
eprintf (".fuzz: TODO\n");
continue;
} else if (!strcmp (arg, "json")) {
arg = "db/json";
} else if (!strcmp (arg, "dasm")) {
arg = "db/asm";
} else if (!strcmp (arg, "cmds")) {
arg = "db";
} else {
arg = r_str_newf ("db/%s", arg + 1);
}
}
char *tf = (*arg == '/')? strdup (arg)
: r_str_newf ("%s"R_SYS_DIR"%s", cwd, arg);
if (!r2r_test_database_load (state.db, tf)) { if (!r2r_test_database_load (state.db, tf)) {
eprintf ("Failed to load tests from \"%s\"\n", tf); eprintf ("Failed to load tests from \"%s\"\n", tf);
r2r_test_database_free (state.db); r2r_test_database_free (state.db);
@ -247,7 +275,7 @@ int main(int argc, char **argv) {
uint32_t loaded_tests = r_pvector_len (&state.db->tests); uint32_t loaded_tests = r_pvector_len (&state.db->tests);
printf ("Loaded %u tests.\n", loaded_tests); printf ("Loaded %u tests.\n", loaded_tests);
if (nothing) { if (nothing) {
return 0; goto coast;
} }
bool jq_available = r2r_check_jq_available (); bool jq_available = r2r_check_jq_available ();
@ -333,6 +361,7 @@ int main(int argc, char **argv) {
ret = 1; ret = 1;
} }
coast:
r_pvector_clear (&state.queue); r_pvector_clear (&state.queue);
r_pvector_clear (&state.results); r_pvector_clear (&state.results);
r_pvector_clear (&state.completed_paths); r_pvector_clear (&state.completed_paths);

View File

@ -141,26 +141,26 @@ typedef struct r2r_test_result_info_t {
}; };
} R2RTestResultInfo; } R2RTestResultInfo;
R_API R2RCmdTest *r2r_cmd_test_new(); R_API R2RCmdTest *r2r_cmd_test_new(void);
R_API void r2r_cmd_test_free(R2RCmdTest *test); R_API void r2r_cmd_test_free(R2RCmdTest *test);
R_API RPVector *r2r_load_cmd_test_file(const char *file); R_API RPVector *r2r_load_cmd_test_file(const char *file);
R_API R2RAsmTest *r2r_asm_test_new(); R_API R2RAsmTest *r2r_asm_test_new(void);
R_API void r2r_asm_test_free(R2RAsmTest *test); R_API void r2r_asm_test_free(R2RAsmTest *test);
R_API RPVector *r2r_load_asm_test_file(RStrConstPool *strpool, const char *file); R_API RPVector *r2r_load_asm_test_file(RStrConstPool *strpool, const char *file);
R_API R2RJsonTest *r2r_json_test_new(); R_API R2RJsonTest *r2r_json_test_new(void);
R_API void r2r_json_test_free(R2RJsonTest *test); R_API void r2r_json_test_free(R2RJsonTest *test);
R_API RPVector *r2r_load_json_test_file(const char *file); R_API RPVector *r2r_load_json_test_file(const char *file);
R_API R2RTestDatabase *r2r_test_database_new(); R_API R2RTestDatabase *r2r_test_database_new(void);
R_API void r2r_test_database_free(R2RTestDatabase *db); R_API void r2r_test_database_free(R2RTestDatabase *db);
R_API bool r2r_test_database_load(R2RTestDatabase *db, const char *path); R_API bool r2r_test_database_load(R2RTestDatabase *db, const char *path);
typedef struct r2r_subprocess_t R2RSubprocess; typedef struct r2r_subprocess_t R2RSubprocess;
R_API bool r2r_subprocess_init(); R_API bool r2r_subprocess_init(void);
R_API void r2r_subprocess_fini(); R_API void r2r_subprocess_fini(void);
R_API R2RSubprocess *r2r_subprocess_start( R_API R2RSubprocess *r2r_subprocess_start(
const char *file, const char *args[], size_t args_size, const char *file, const char *args[], size_t args_size,
const char *envvars[], const char *envvals[], size_t env_size); const char *envvars[], const char *envvals[], size_t env_size);
@ -173,7 +173,7 @@ typedef R2RProcessOutput *(*R2RCmdRunner)(const char *file, const char *args[],
R_API void r2r_process_output_free(R2RProcessOutput *out); R_API void r2r_process_output_free(R2RProcessOutput *out);
R_API R2RProcessOutput *r2r_run_cmd_test(R2RRunConfig *config, R2RCmdTest *test, R2RCmdRunner runner); R_API R2RProcessOutput *r2r_run_cmd_test(R2RRunConfig *config, R2RCmdTest *test, R2RCmdRunner runner);
R_API bool r2r_check_cmd_test(R2RProcessOutput *out, R2RCmdTest *test); R_API bool r2r_check_cmd_test(R2RProcessOutput *out, R2RCmdTest *test);
R_API bool r2r_check_jq_available(); R_API bool r2r_check_jq_available(void);
R_API R2RProcessOutput *r2r_run_json_test(R2RRunConfig *config, R2RJsonTest *test, R2RCmdRunner runner); R_API R2RProcessOutput *r2r_run_json_test(R2RRunConfig *config, R2RJsonTest *test, R2RCmdRunner runner);
R_API bool r2r_check_json_test(R2RProcessOutput *out, R2RJsonTest *test); R_API bool r2r_check_json_test(R2RProcessOutput *out, R2RJsonTest *test);

View File

@ -9,8 +9,8 @@ struct r2r_subprocess_t {
RStrBuf err; RStrBuf err;
}; };
R_API bool r2r_subprocess_init() { return true; } R_API bool r2r_subprocess_init(void) { return true; }
R_API void r2r_subprocess_fini() {} R_API void r2r_subprocess_fini(void) {}
R_API R2RSubprocess *r2r_subprocess_start( R_API R2RSubprocess *r2r_subprocess_start(
const char *file, const char *args[], size_t args_size, const char *file, const char *args[], size_t args_size,
@ -60,7 +60,7 @@ static RThreadLock *subprocs_mutex;
static int sigchld_pipe[2]; static int sigchld_pipe[2];
static RThread *sigchld_thread; static RThread *sigchld_thread;
static void handle_sigchld() { static void handle_sigchld(int sig) {
ut8 b = 1; ut8 b = 1;
write (sigchld_pipe[1], &b, 1); write (sigchld_pipe[1], &b, 1);
} }
@ -112,7 +112,7 @@ static RThreadFunctionRet sigchld_th(RThread *th) {
return R_TH_STOP; return R_TH_STOP;
} }
R_API bool r2r_subprocess_init() { R_API bool r2r_subprocess_init(void) {
r_pvector_init(&subprocs, NULL); r_pvector_init(&subprocs, NULL);
subprocs_mutex = r_th_lock_new (false); subprocs_mutex = r_th_lock_new (false);
if (!subprocs_mutex) { if (!subprocs_mutex) {
@ -139,7 +139,7 @@ R_API bool r2r_subprocess_init() {
return true; return true;
} }
R_API void r2r_subprocess_fini() { R_API void r2r_subprocess_fini(void) {
r_sys_signal (SIGCHLD, SIG_IGN); r_sys_signal (SIGCHLD, SIG_IGN);
close (sigchld_pipe [0]); close (sigchld_pipe [0]);
close (sigchld_pipe [1]); close (sigchld_pipe [1]);
@ -480,7 +480,7 @@ R_API bool r2r_check_cmd_test(R2RProcessOutput *out, R2RCmdTest *test) {
#define JQ_CMD "jq" #define JQ_CMD "jq"
R_API bool r2r_check_jq_available() { R_API bool r2r_check_jq_available(void) {
const char *invalid_json = "this is not json lol"; const char *invalid_json = "this is not json lol";
R2RSubprocess *proc = r2r_subprocess_start (JQ_CMD, NULL, 0, NULL, NULL, 0); R2RSubprocess *proc = r2r_subprocess_start (JQ_CMD, NULL, 0, NULL, NULL, 0);
r2r_subprocess_stdin_write (proc, (const ut8 *)invalid_json, strlen (invalid_json)); r2r_subprocess_stdin_write (proc, (const ut8 *)invalid_json, strlen (invalid_json));

View File

@ -12,7 +12,7 @@
.Op Fl j Ar threads .Op Fl j Ar threads
.Op Fl r Ar r2-path .Op Fl r Ar r2-path
.Op Fl m Ar rasm2-pth .Op Fl m Ar rasm2-pth
.Op Fl f Ar json-test-file .Op Fl f Ar bin-for-json-tests
.Op Fl C Ar chdir .Op Fl C Ar chdir
.Op [test-(dir|file) ...] .Op [test-(dir|file) ...]
.Sh DESCRIPTION .Sh DESCRIPTION
@ -39,8 +39,8 @@ Set path to radare2 executable
Set path to rasm2executable Set path to rasm2executable
.It Fl m Ar rasm2-path .It Fl m Ar rasm2-path
Set path to rasm2executable Set path to rasm2executable
.It Fl f Ar json-test-file .It Fl f Ar bin-for-json-tests
Run the given test file as json Load the given binary when running the JSON tests
.It Fl C Ar directory .It Fl C Ar directory
Early chdir before running any test Early chdir before running any test
.El .El