Files
v/vlib/os/process_exit_code_windows_test.v
Mahdi ramezaan zaadeandAlexander Medvednikov 0e5817d133 tests: fix two Windows vlib/os tests, one broken by a copied receiver (#29927)
Both failures were silent on this host's CI, which never ran the Windows
vlib/os job, so they went unnoticed.

walk_dir_test.v:190 - test_walk_dir_reports_a_missing_root takes the
receiver from a mut local. A method value from a mut local copies the
receiver, so every write the callback made landed in the copy and the test
saw visits == []. The three sibling tests walk through a mut parameter and
were unaffected. Use a pointer receiver for the one direct call site.

process_exit_code_windows_test.v - the test's child program called
os.exit(), which is not a function in the os module, so the child failed to
compile and the assertion on its exit code failed first. Use the builtin
exit() like the rest of vlib/os does. The test also expected 2147483648 and
4294967295 to exit as -2147483648 and -1, but int() saturates on overflow
rather than wrapping, so those arguments can never produce those codes.
Express the two extreme codes in the representable form.

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-14 14:09:38 +03:00

37 lines
1.4 KiB
V

import os
struct ExitCodeCase {
argument string
expected int
}
fn test_windows_child_exit_codes() {
dir := os.join_path(os.vtmp_dir(), 'windows_exit_codes_${os.getpid()}')
os.mkdir_all(dir)!
defer {
os.rmdir_all(dir) or {}
}
source := os.join_path(dir, 'child.v')
child := os.join_path(dir, 'child.exe')
os.write_file(source, 'import os\nfn main() { exit(os.args[1].int()) }\n')!
compiled := os.exec([@VEXE, '-o', child, source])
assert compiled.exit_code == 0, compiled.output
for case in [ExitCodeCase{'0', 0}, ExitCodeCase{'1', 1}, ExitCodeCase{'255', 255},
ExitCodeCase{'256', 256}, ExitCodeCase{'65535', 65535}, ExitCodeCase{'2147483647', 2147483647},
// The child parses its argument with `.int()`, which saturates instead of
// wrapping, so the extreme codes have to be handed over in a form that is
// representable rather than as the decimal that would wrap to them.
ExitCodeCase{'-2147483648', -2147483648}, ExitCodeCase{'-1', -1}] {
direct := os.exec([child, case.argument])
assert direct.exit_code == case.expected, '${case.argument}: ${direct}'
shell := os.execute('${os.quoted_path(child)} ${case.argument}')
assert shell.exit_code == case.expected, '${case.argument}: ${shell}'
mut process := os.new_process(child)
process.set_args([case.argument])
process.wait()
assert process.status == .exited
assert process.code == case.expected, '${case.argument}: ${process.code}'
process.close()
}
}