From c890b806d5689d071684436ec338c6d15c53d768 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 21 Jun 2026 20:13:44 -0700 Subject: [PATCH] pull out test input/exemplar path formation helpers to base; fix torture crash --- src/base/base_test.c | 23 +++++++++- src/base/base_test.h | 49 +++++++++++---------- src/raddbg/tests/raddbg_tests.c | 11 +---- src/rdi_from_pdb/tests/rdi_from_pdb_tests.c | 25 +---------- src/torture/torture.c | 4 +- 5 files changed, 54 insertions(+), 58 deletions(-) diff --git a/src/base/base_test.c b/src/base/base_test.c index 5a2e302f..28b67153 100644 --- a/src/base/base_test.c +++ b/src/base/base_test.c @@ -3,6 +3,27 @@ #if BUILD_TESTS +internal String8 +test_input_path(Arena *arena, TestCtx *ctx, String8 name) +{ + String8 path = str8f(arena, "%S/%S", ctx->input_data_path, name); + return path; +} + +internal String8 +test_input_exe_path(Arena *arena, TestCtx *ctx, String8 name) +{ + String8 path = str8f(arena, "%S/%S%S", ctx->input_data_path, name, program_ext_postfix_from_os(OperatingSystem_CURRENT, 1)); + return path; +} + +internal String8 +test_exemplar_path(Arena *arena, TestCtx *ctx, String8 name) +{ + String8 path = str8f(arena, "%S/%S", ctx->exemplars_path, name); + return path; +} + internal void base_register_test(char *func_name_cstr, TestFunctionType *fn, char *file_path_cstr, int line, int skip) { @@ -10,7 +31,7 @@ base_register_test(char *func_name_cstr, TestFunctionType *fn, char *file_path_c U64 src_min = str8_find_needle(file_path, 0, s("src/"), StringMatchFlag_SlashInsensitive); U64 src_max = src_min + str8_lit("src/").size; U64 layer_slash_max = str8_find_needle(file_path, src_max, s("/"), StringMatchFlag_SlashInsensitive); - + TestInfo *t = &test_infos[test_infos_count++]; t->layer = str8_substr(file_path, r1u64(src_max, layer_slash_max)); t->label = str8_cstring(func_name_cstr); diff --git a/src/base/base_test.h b/src/base/base_test.h index f17c8f1c..827c59bb 100644 --- a/src/base/base_test.h +++ b/src/base/base_test.h @@ -17,20 +17,20 @@ TestStatus; typedef struct TestResult TestResult; struct TestResult { - TestStatus status; - char *fail_file; - int fail_line; - char *fail_cond; + TestStatus status; + char *fail_file; + int fail_line; + char *fail_cond; }; typedef struct TestCtx TestCtx; struct TestCtx { - CmdLine *cmdline; - String8 exemplars_path; - String8 artifacts_path; - String8 input_data_path; - TestResult *result_out; + CmdLine *cmdline; + String8 exemplars_path; + String8 artifacts_path; + String8 input_data_path; + TestResult *result_out; String8List *test_out; }; @@ -41,10 +41,10 @@ typedef TEST_FUNCTION_SIG(TestFunctionType); typedef struct TestInfo TestInfo; struct TestInfo { - String8 layer; - String8 label; - S64 decl_line; - B32 skip; + String8 layer; + String8 label; + S64 decl_line; + B32 skip; TestFunctionType *test_fn; }; @@ -54,18 +54,21 @@ struct TestInfo global U16 test_infos_count = 0; global TestInfo test_infos[0xffff] = {0}; +internal String8 test_input_path(Arena *arena, TestCtx *ctx, String8 name); +internal String8 test_input_exe_path(Arena *arena, TestCtx *ctx, String8 name); +internal String8 test_exemplar_path(Arena *arena, TestCtx *ctx, String8 name); internal void base_register_test(char *func_name, TestFunctionType *fn, char *file_path, int line, int skip); #define AddTest(name, file_path, line, skip_, ...) \ - TEST_FUNCTION_DEF(name); \ - __VA_ARGS__ void add_test__##name(void) { base_register_test(Stringify(name), test__##name, file_path, line, skip_); } +TEST_FUNCTION_DEF(name); \ +__VA_ARGS__ void add_test__##name(void) { base_register_test(Stringify(name), test__##name, file_path, line, skip_); } # if COMPILER_MSVC # pragma section(".CRT$XCU", read) # define DeclareTest(name, skip) \ - /* register test */ AddTest(name, __FILE__, __LINE__, (skip)) \ - /* alloc function pointer */ __declspec(allocate(".CRT$XCU")) void (*add_test_ptr__##name)(void) = add_test__##name; \ - /* do not GC test caller */ __pragma(comment(linker, "/include:" Stringify(add_test_ptr__##name))) +/* register test */ AddTest(name, __FILE__, __LINE__, (skip)) \ +/* alloc function pointer */ __declspec(allocate(".CRT$XCU")) void (*add_test_ptr__##name)(void) = add_test__##name; \ +/* do not GC test caller */ __pragma(comment(linker, "/include:" Stringify(add_test_ptr__##name))) # elif COMPILER_GCC || COMPILER_CLANG // clang and gcc allocate memory for the function pointer automatically # define DeclareTest(name, skip) AddTest(name, __FILE__, __LINE__, (skip), __attribute__((constructor))) @@ -80,14 +83,14 @@ internal void base_register_test(char *func_name, TestFunctionType *fn, char *fi #define SkippedTest(name) DeclareTest(name, 1) TEST_FUNCTION_DEF(name) #define TestCheck(c) do { if (!(c)) { \ - /* record failed check */ ctx->result_out[0] = (TestResult){ .fail_file = __FILE__, .fail_line = __LINE__, .fail_cond = Stringify(c) }; \ - /* under debugger? -> trap */ if(debugger_is_attached()) { Trap(); } \ - /* exit test */ return; \ +/* record failed check */ ctx->result_out[0] = (TestResult){ .fail_file = __FILE__, .fail_line = __LINE__, .fail_cond = Stringify(c) }; \ +/* under debugger? -> trap */ if(debugger_is_attached()) { Trap(); } \ +/* exit test */ return; \ } } while(0) #define TestSkip() do { \ - ctx->result_out[0] = (TestResult){ .status = TestStatus_Skip }; \ - return; \ +ctx->result_out[0] = (TestResult){ .status = TestStatus_Skip }; \ +return; \ } while(0) // test log diff --git a/src/raddbg/tests/raddbg_tests.c b/src/raddbg/tests/raddbg_tests.c index 394853ef..231eb0a2 100644 --- a/src/raddbg/tests/raddbg_tests.c +++ b/src/raddbg/tests/raddbg_tests.c @@ -4,13 +4,6 @@ //////////////////////////////// //~ rjf: Debugger Testing IPC Driving Helpers -internal String8 -rd_test__test_binary_path(Arena *arena, TestCtx *ctx, String8 name) -{ - String8 path = str8f(arena, "%S/%S/%S%S", ctx->input_data_path, name, name, program_ext_postfix_from_os(OperatingSystem_CURRENT, 1)); - return path; -} - internal String8 rd_test__raddbg_path(Arena *arena, CmdLine *cmdline) { @@ -114,7 +107,7 @@ rd_test__stepping_regressions(Arena *arena, TestCtx *ctx, String8 target_binary, String8List test_log_strings = {0}; // rjf: get binary path - String8 binary_path = rd_test__test_binary_path(arena, ctx, target_binary); + String8 binary_path = test_input_exe_path(arena, ctx, str8f(scratch.arena, "%S/%S", target_binary, target_binary)); B32 binary_exists_locally = (properties_from_file_path(binary_path).modified != 0); // rjf: if binary does not exist -> skip this test, @@ -233,7 +226,7 @@ rd_test__eval_regressions(Arena *arena, TestCtx *ctx, String8 target_binary, Str String8List test_log_strings = {0}; // rjf: get binary path - String8 binary_path = rd_test__test_binary_path(arena, ctx, target_binary); + String8 binary_path = test_input_exe_path(arena, ctx, str8f(scratch.arena, "%S/%S", target_binary, target_binary)); B32 binary_exists_locally = (properties_from_file_path(binary_path).modified != 0); // rjf: if binary does not exist -> skip this test, diff --git a/src/rdi_from_pdb/tests/rdi_from_pdb_tests.c b/src/rdi_from_pdb/tests/rdi_from_pdb_tests.c index 34c09dc2..2005a726 100644 --- a/src/rdi_from_pdb/tests/rdi_from_pdb_tests.c +++ b/src/rdi_from_pdb/tests/rdi_from_pdb_tests.c @@ -1,36 +1,15 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal String8 -p2r_test__test_path(Arena *arena, TestCtx *ctx, String8 id, String8 name) -{ - String8 path = str8f(arena, "%S/%S/%S", ctx->input_data_path, id, name); - return path; -} - Test(p2r_determinism) { U64 num_repeats_per_pdb = 16; String8 pdb_paths[] = { - p2r_test__test_path(arena, ctx, s("mule_main_9ff1e58f"), s("mule_main.pdb")), - p2r_test__test_path(arena, ctx, s("mule_main_9ff1e58f"), s("mule_module.pdb")), + test_input_path(arena, ctx, s("mule_main_9ff1e58f/mule_main.pdb")), + test_input_path(arena, ctx, s("mule_main_9ff1e58f/mule_module.pdb")), }; - B32 all_pdbs_exist_locally = 1; for EachElement(pdb_idx, pdb_paths) - { - String8 pdb_path = pdb_paths[pdb_idx]; - if(properties_from_file_path(pdb_path).modified == 0) - { - all_pdbs_exist_locally = 0; - break; - } - } - if(!all_pdbs_exist_locally) - { - TestSkip(); - } - else for EachElement(pdb_idx, pdb_paths) { // rjf: unpack paths, make output directory String8 pdb_path = pdb_paths[pdb_idx]; diff --git a/src/torture/torture.c b/src/torture/torture.c index e9d15efb..70a77111 100644 --- a/src/torture/torture.c +++ b/src/torture/torture.c @@ -1382,14 +1382,14 @@ t_entry_point(CmdLine *cmdline) if (slow_count > 1) { U64 label_max = 0; U64 layer_max = 0; - for EachElement(i, slowest) { + for EachIndex(i, slow_count) { Slowest s = slowest[i]; label_max = Max(g_sorted_test_infos[s.target_idx]->label.size, label_max); layer_max = Max(g_sorted_test_infos[s.target_idx]->layer.size, layer_max); } fprintf(stderr, " \nSlow Tests\n"); - for EachElement(i, slowest) { + for EachIndex(i, slow_count) { Slowest s = slowest[i]; if (s.target_idx >= test_infos_count) { break; }