From 97abec11a2cff16c195590380703a9bbc0642ab7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Oct 2024 11:46:07 -0700 Subject: [PATCH] begin setting up tester for automated tests --- build.bat | 1 + project.4coder | 2 +- src/os/core/os_core.c | 41 ++++++++++++++ src/os/core/os_core.h | 6 ++ src/tester/tester_main.c | 116 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/tester/tester_main.c diff --git a/build.bat b/build.bat index 3448e77b..d021e5a1 100644 --- a/build.bat +++ b/build.bat @@ -104,6 +104,7 @@ if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_fr if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1 if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1 +if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1 if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1 if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 diff --git a/project.4coder b/project.4coder index 761e90ad..16f4c193 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "build rdi_from_pdb rdi_dump tester telemetry && pushd build && tester && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/os/core/os_core.c b/src/os/core/os_core.c index a6718e32..01b130dc 100644 --- a/src/os/core/os_core.c +++ b/src/os/core/os_core.c @@ -151,6 +151,47 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range) return result; } +//////////////////////////////// +//~ rjf: Process Launcher Helpers + +internal OS_Handle +os_cmd_line_launch(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + U8 split_chars[] = {' '}; + String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0); + OS_Handle handle = {0}; + if(parts.node_count != 0) + { + String8 exe = parts.first->string; + String8 exe_folder = str8_chop_last_slash(exe); + if(exe_folder.size == 0) + { + exe_folder = os_get_current_path(scratch.arena); + } + OS_ProcessLaunchParams params = {0}; + params.cmd_line = parts; + params.path = exe_folder; + params.inherit_env = 1; + handle = os_process_launch(¶ms); + } + scratch_end(scratch); + return handle; +} + +internal OS_Handle +os_cmd_line_launchf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + OS_Handle result = os_cmd_line_launch(string); + va_end(args); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: GUID Helpers (Helpers, Implemented Once) diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index c3f1fdc1..e062f5f5 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -165,6 +165,12 @@ internal OS_FileID os_id_from_file_path(String8 path); internal S64 os_file_id_compare(OS_FileID a, OS_FileID b); internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range); +//////////////////////////////// +//~ rjf: Process Launcher Helpers + +internal OS_Handle os_cmd_line_launch(String8 string); +internal OS_Handle os_cmd_line_launchf(char *fmt, ...); + //////////////////////////////// //~ rjf: GUID Helpers (Helpers, Implemented Once) diff --git a/src/tester/tester_main.c b/src/tester/tester_main.c new file mode 100644 index 00000000..576acc0e --- /dev/null +++ b/src/tester/tester_main.c @@ -0,0 +1,116 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Build Options + +#define BUILD_VERSION_MAJOR 0 +#define BUILD_VERSION_MINOR 9 +#define BUILD_VERSION_PATCH 12 +#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA" +#define BUILD_TITLE "tester" +#define BUILD_CONSOLE_INTERFACE 1 +#define OS_FEATURE_GRAPHICAL 1 + +//////////////////////////////// +//~ rjf: Includes + +//- rjf: [h] +#include "base/base_inc.h" +#include "os/os_inc.h" +#include "path/path.h" +#include "hash_store/hash_store.h" + +//- rjf: [c] +#include "base/base_inc.c" +#include "os/os_inc.c" +#include "path/path.c" +#include "hash_store/hash_store.c" + +//////////////////////////////// +//~ rjf: Entry Points + +internal B32 frame(void) { return 0; } + +internal void +entry_point(CmdLine *cmdline) +{ + Arena *arena = arena_alloc(); + + ////////////////////////////// + //- rjf: PDB -> RDI determinism + // + String8 name = {0}; + B32 good = 1; + String8List out = {0}; + { + name = str8_lit("PDB -> RDI determinism"); + OS_HandleList processes = {0}; + String8List rdi_paths = {0}; + U64 num_repeats_per_pdb = 4; + String8 pdb_paths[] = + { + str8_lit_comp("odintest/test.pdb"), + }; + for EachElement(pdb_idx, pdb_paths) + { + String8 pdb_path = path_normalized_from_string(arena, pdb_paths[pdb_idx]); + String8 pdb_folder = str8_chop_last_slash(pdb_path); + String8 repeat_folder = push_str8f(arena, "%S/pdb2rdi_determinism", pdb_folder); + os_make_directory(repeat_folder); + for EachIndex(repeat_idx, num_repeats_per_pdb) + { + String8 rdi_path = push_str8f(arena, "%S/repeat_%I64u.rdi", repeat_folder, repeat_idx); + str8_list_push(arena, &rdi_paths, rdi_path); + os_handle_list_push(arena, &processes, os_cmd_line_launchf("rdi_from_pdb --pdb:%S --out:%S", pdb_path, rdi_path)); + } + }; + for(OS_HandleNode *n = processes.first; n != 0; n = n->next) + { + os_process_join(n->v, max_U64); + } + U64 hashes_count = rdi_paths.node_count; + U128 *hashes = push_array(arena, U128, hashes_count); + String8 *paths = push_array(arena, String8, hashes_count); + { + U64 idx = 0; + for(String8Node *n = rdi_paths.first; n != 0; n = n->next, idx += 1) + { + String8 path = n->string; + String8 data = os_data_from_file_path(arena, path); + hashes[idx] = hs_hash_from_data(data); + paths[idx] = path; + } + } + B32 matches = 1; + for EachIndex(idx, hashes_count) + { + if(!u128_match(hashes[idx], hashes[0])) + { + matches = 0; + break; + } + } + if(!matches) + { + good = 0; + for EachIndex(idx, hashes_count) + { + str8_list_pushf(arena, &out, " [%I64u] (%S): 0x%I64x:%I64x\n", idx, paths[idx], hashes[idx].u64[0], hashes[idx].u64[1]); + } + } + } + + ////////////////////////////// + //- rjf: dump results + // + fprintf(stderr, "[%s] %.*s\n", good ? "." : "X", str8_varg(name)); + if(!good) + { + for(String8Node *n = out.first; n != 0; n = n->next) + { + fprintf(stderr, "%.*s", str8_varg(n->string)); + } + } + +}