tools: fix v build-tools, make v test more robust (#19803)

This commit is contained in:
Delyan Angelov 2023-11-07 21:19:58 +02:00 committed by GitHub
parent d86b3689d9
commit 92a72df5f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 10 deletions

View file

@ -10,6 +10,7 @@ import sync.pool
import v.pref import v.pref
import v.util.vtest import v.util.vtest
import runtime import runtime
import rand
pub const github_job = os.getenv('GITHUB_JOB') pub const github_job = os.getenv('GITHUB_JOB')
@ -64,6 +65,7 @@ pub mut:
fail_fast bool fail_fast bool
benchmark benchmark.Benchmark benchmark benchmark.Benchmark
rm_binaries bool = true rm_binaries bool = true
build_tools bool // builds only executables in cmd/tools; used by `v build-tools'
silent_mode bool silent_mode bool
show_stats bool show_stats bool
progress_mode bool progress_mode bool
@ -72,7 +74,7 @@ pub mut:
nmessage_idx int // currently printed message index nmessage_idx int // currently printed message index
failed_cmds shared []string failed_cmds shared []string
reporter Reporter = Reporter(NormalReporter{}) 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) { pub fn (mut ts TestSession) add_failed_cmd(cmd string) {
@ -370,6 +372,9 @@ pub fn (mut ts TestSession) test() {
continue continue
} }
} }
if ts.build_tools && dot_relative_file.ends_with('_test.v') {
continue
}
remaining_files << dot_relative_file remaining_files << dot_relative_file
} }
remaining_files = vtest.filter_vtest_only(remaining_files, fix_slashes: false) 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.worker_threads_finish(mut ts)
ts.reporter.divider() ts.reporter.divider()
ts.show_list_of_failed_tests() 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.benchmark.nfail == 0 {
if ts.rm_binaries { if ts.rm_binaries {
os.rmdir_all(ts.vtmp_dir) or {} os.rmdir_all(ts.vtmp_dir) or {}
} }
} }
// remove empty session folders:
if os.ls(ts.vtmp_dir) or { [] }.len == 0 { if os.ls(ts.vtmp_dir) or { [] }.len == 0 {
os.rmdir_all(ts.vtmp_dir) or {} 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() flow_id: thread_id.str()
} }
normalised_relative_file := relative_file.replace('\\', '/') normalised_relative_file := relative_file.replace('\\', '/')
// Ensure that the generated binaries will be stored in the temporary folder. // Ensure that the generated binaries will be stored in an *unique*, fresh, and per test folder,
// Remove them after a test passes/fails. // 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) fname := os.file_name(file)
generated_binary_fname := if os.user_os() == 'windows' && !run_js { 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 { } 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 produces_file_output {
if ts.rm_binaries { if ts.rm_binaries {
os.rm(generated_binary_fpath) or {} os.rm(generated_binary_fpath) or {}
} }
cmd_options << ' -o ${os.quoted_path(generated_binary_fpath)}' cmd_options << ' -o ${os.quoted_path(generated_binary_fpath)}'
} }
cmd := '${os.quoted_path(ts.vexe)} ${cmd_options.join(' ')} ${os.quoted_path(file)}' 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 { if produces_file_output && ts.rm_binaries {
os.rm(generated_binary_fpath) or {} os.rmdir_all(test_folder_path) or {}
} }
return pool.no_result return pool.no_result
} }

View file

@ -36,6 +36,7 @@ fn main() {
buildopts := args_string.all_before('build-tools') buildopts := args_string.all_before('build-tools')
mut session := testing.prepare_test_session(buildopts, folder, skips, main_label) mut session := testing.prepare_test_session(buildopts, folder, skips, main_label)
session.rm_binaries = false session.rm_binaries = false
session.build_tools = true
for stool in tools_in_subfolders { for stool in tools_in_subfolders {
session.add(os.join_path(tfolder, stool)) session.add(os.join_path(tfolder, stool))
} }