From 92a72df5f8f1c20c77ffdbfdfe92c84952d3386b Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 7 Nov 2023 21:19:58 +0200 Subject: [PATCH] tools: fix `v build-tools`, make `v test` more robust (#19803) --- cmd/tools/modules/testing/common.v | 37 ++++++++++++++++++++++-------- cmd/tools/vbuild-tools.v | 1 + 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 8b6ab37f0f..ede787d707 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -10,6 +10,7 @@ import sync.pool import v.pref import v.util.vtest import runtime +import rand pub const github_job = os.getenv('GITHUB_JOB') @@ -64,6 +65,7 @@ pub mut: fail_fast bool benchmark benchmark.Benchmark rm_binaries bool = true + build_tools bool // builds only executables in cmd/tools; used by `v build-tools' silent_mode bool show_stats bool progress_mode bool @@ -72,7 +74,7 @@ pub mut: nmessage_idx int // currently printed message index failed_cmds shared []string reporter Reporter = Reporter(NormalReporter{}) - hash string // used during testing in temporary directory and file names to prevent collisions when files and directories are created in a test file. + hash string // used as part of the name of the temporary directory created for tests, to ease cleanup } pub fn (mut ts TestSession) add_failed_cmd(cmd string) { @@ -370,6 +372,9 @@ pub fn (mut ts TestSession) test() { continue } } + if ts.build_tools && dot_relative_file.ends_with('_test.v') { + continue + } remaining_files << dot_relative_file } remaining_files = vtest.filter_vtest_only(remaining_files, fix_slashes: false) @@ -396,13 +401,13 @@ pub fn (mut ts TestSession) test() { ts.reporter.worker_threads_finish(mut ts) ts.reporter.divider() ts.show_list_of_failed_tests() - // cleanup generated .tmp.c files after successful tests: + + // cleanup the session folder, if everything was ok: if ts.benchmark.nfail == 0 { if ts.rm_binaries { os.rmdir_all(ts.vtmp_dir) or {} } } - // remove empty session folders: if os.ls(ts.vtmp_dir) or { [] }.len == 0 { os.rmdir_all(ts.vtmp_dir) or {} } @@ -451,20 +456,32 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { flow_id: thread_id.str() } normalised_relative_file := relative_file.replace('\\', '/') - // Ensure that the generated binaries will be stored in the temporary folder. - // Remove them after a test passes/fails. + // Ensure that the generated binaries will be stored in an *unique*, fresh, and per test folder, + // inside the common session temporary folder, used for all the tests. + // This is done to provide a clean working environment, for each test, that will not contain + // files from other tests, and will make sure that tests with the same name, can be compiled + // inside their own folders, without name conflicts (and without locking issues on windows, + // where an executable is not writable, if it is running). + // Note, that the common session temporary folder ts.vtmp_dir, + // will be removed after all tests are done. + mut test_folder_path := os.join_path(ts.vtmp_dir, rand.ulid()) + if ts.build_tools { + // `v build-tools`, produce all executables in the same session folder, so that they can be copied later: + test_folder_path = ts.vtmp_dir + } else { + os.mkdir_all(test_folder_path) or {} + } fname := os.file_name(file) generated_binary_fname := if os.user_os() == 'windows' && !run_js { - '${fname.all_before_last('.v')}_${ts.hash}.exe' + fname.all_before_last('.v') + '.exe' } else { - '${fname.all_before_last('.v')}_${ts.hash}' + fname.all_before_last('.v') } - generated_binary_fpath := os.join_path_single(ts.vtmp_dir, generated_binary_fname) + generated_binary_fpath := os.join_path_single(test_folder_path, generated_binary_fname) if produces_file_output { if ts.rm_binaries { os.rm(generated_binary_fpath) or {} } - cmd_options << ' -o ${os.quoted_path(generated_binary_fpath)}' } cmd := '${os.quoted_path(ts.vexe)} ${cmd_options.join(' ')} ${os.quoted_path(file)}' @@ -603,7 +620,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { } } if produces_file_output && ts.rm_binaries { - os.rm(generated_binary_fpath) or {} + os.rmdir_all(test_folder_path) or {} } return pool.no_result } diff --git a/cmd/tools/vbuild-tools.v b/cmd/tools/vbuild-tools.v index 21dd815f2f..4bf39de98f 100644 --- a/cmd/tools/vbuild-tools.v +++ b/cmd/tools/vbuild-tools.v @@ -36,6 +36,7 @@ fn main() { buildopts := args_string.all_before('build-tools') mut session := testing.prepare_test_session(buildopts, folder, skips, main_label) session.rm_binaries = false + session.build_tools = true for stool in tools_in_subfolders { session.add(os.join_path(tfolder, stool)) }