diff --git a/tests/test_main.c b/tests/test_main.c index 6ede15bb7..0aa3bebc2 100644 --- a/tests/test_main.c +++ b/tests/test_main.c @@ -42,6 +42,7 @@ int tf_deselected_count = 0; #include #include /* #798 follow-up: socket-isolation re-exec probe */ #include +#include "foundation/win_utf8.h" /* cbm_module_path_utf8 — the runner's own image */ #else #include #ifdef __APPLE__ @@ -1891,11 +1892,33 @@ extern int tf_maybe_run_subprocess_stdout_probe(int argc, char **argv); extern void tf_test_impact_runner_filter_set_binary(const char *path); extern int tf_maybe_run_git_facts_diff_probe(int argc, char **argv); +/* The runner's own image, for the tests that start or copy it again. argv[0] + * is the caller's spelling, and a Windows parent that found the runner by + * search (the native python scheduler, scripts/run-test-wave.py) passes it + * without ".exe", which an exact spawn or copy of that path cannot open. */ +const char *tf_runner_image(int argc, char **argv); +const char *tf_runner_image(int argc, char **argv) { +#ifdef _WIN32 + static char image[4096]; + if (!image[0]) { + char *module = cbm_module_path_utf8(); + if (module && strlen(module) < sizeof(image)) { + memcpy(image, module, strlen(module) + 1); + } + free(module); + } + if (image[0]) { + return image; + } +#endif + return argc > 0 && argv ? argv[0] : NULL; +} + int main(int argc, char **argv) { /* #2003: never let a caller's GIT_DIR/GIT_INDEX_FILE/... redirect fixture * git commands at the caller's real repository. */ th_clear_git_repo_env(); - tf_test_impact_runner_filter_set_binary(argc > 0 && argv ? argv[0] : NULL); + tf_test_impact_runner_filter_set_binary(tf_runner_image(argc, argv)); #ifdef CBM_TEST_COVERAGE tf_coverage_process_init(); #ifndef _WIN32 diff --git a/tests/test_subprocess.c b/tests/test_subprocess.c index 0ca7b0d39..8df9fe92f 100644 --- a/tests/test_subprocess.c +++ b/tests/test_subprocess.c @@ -1507,12 +1507,13 @@ static void sp_stdout_payload(unsigned char bytes[SP_STDOUT_BYTES]) { /* Called before normal harness setup. Normal entry remembers argv[0], whose * storage lasts through main; the private exact argv grammar never runs suites. */ static int sp_stdin_probe(int argc, char **argv); +const char *tf_runner_image(int argc, char **argv); /* test_main.c */ int tf_maybe_run_subprocess_stdout_probe(int argc, char **argv); int tf_maybe_run_subprocess_stdout_probe(int argc, char **argv) { if (argc >= 2 && argv && strcmp(argv[1], "__cbm_subprocess_stdin_probe") == 0) return sp_stdin_probe(argc, argv); if (argc < 2 || !argv || strcmp(argv[1], "__cbm_subprocess_stdout_probe") != 0) { - sp_stdout_test_binary = argc > 0 && argv ? argv[0] : NULL; + sp_stdout_test_binary = tf_runner_image(argc, argv); return -1; } if (argc != 4 || (strcmp(argv[2], "binary") != 0 && strcmp(argv[2], "text") != 0 && diff --git a/tests/test_test_impact_git.c b/tests/test_test_impact_git.c index ed8483de5..5828a99e4 100644 --- a/tests/test_test_impact_git.c +++ b/tests/test_test_impact_git.c @@ -53,6 +53,7 @@ static bool gf_write(const char *path, const void *bytes, size_t length) { /* Native executable fixture for Git's optional diff/textconv command. Extra * arguments added by Git are deliberately ignored. Normal harness entry keeps * argv[0] for a private executable copy; neither mode changes the environment. */ +const char *tf_runner_image(int argc, char **argv); /* test_main.c */ int tf_maybe_run_git_facts_diff_probe(int argc, char **argv); int tf_maybe_run_git_facts_diff_probe(int argc, char **argv) { if (argc >= 2 && argv && strcmp(argv[1], "__cbm_git_facts_diff_probe") == 0) { @@ -74,7 +75,7 @@ int tf_maybe_run_git_facts_diff_probe(int argc, char **argv) { } argv[1] = "test_impact_git"; } - gf_runner_binary = argc > 0 && argv ? argv[0] : NULL; + gf_runner_binary = tf_runner_image(argc, argv); return -1; }