| 1 | // vtest build: !msvc |
| 2 | module main |
| 3 | |
| 4 | import os |
| 5 | |
| 6 | const parallel_cc_test_path = os.join_path(os.vtmp_dir(), 'parallel_cc_failure_test') |
| 7 | const parallel_cc_vexe = @VEXE |
| 8 | |
| 9 | fn run_parallel_cc_case(case_name string, files map[string]string) os.Result { |
| 10 | return run_parallel_cc_case_with_env(case_name, files, {}) |
| 11 | } |
| 12 | |
| 13 | fn run_parallel_cc_case_with_env(case_name string, files map[string]string, env_overrides map[string]string) os.Result { |
| 14 | return run_parallel_cc_case_with_args(case_name, ['-parallel-cc', 'main.v'], files, |
| 15 | env_overrides) |
| 16 | } |
| 17 | |
| 18 | fn run_parallel_cc_case_with_args(case_name string, args []string, files map[string]string, env_overrides map[string]string) os.Result { |
| 19 | case_dir := os.join_path(parallel_cc_test_path, case_name) |
| 20 | os.rmdir_all(case_dir) or {} |
| 21 | os.mkdir_all(case_dir) or { panic(err) } |
| 22 | defer { |
| 23 | os.rmdir_all(case_dir) or {} |
| 24 | } |
| 25 | for rel_path, contents in files { |
| 26 | fpath := os.join_path(case_dir, rel_path) |
| 27 | os.mkdir_all(os.dir(fpath)) or { panic(err) } |
| 28 | os.write_file(fpath, contents) or { panic(err) } |
| 29 | } |
| 30 | mut env := os.environ() |
| 31 | for key, value in env_overrides { |
| 32 | env[key] = value |
| 33 | } |
| 34 | mut p := os.new_process(parallel_cc_vexe) |
| 35 | p.set_work_folder(case_dir) |
| 36 | p.set_args(args) |
| 37 | p.set_environment(env) |
| 38 | p.set_redirect_stdio() |
| 39 | p.wait() |
| 40 | stdout := p.stdout_slurp() |
| 41 | stderr := p.stderr_slurp() |
| 42 | exit_code := p.code |
| 43 | p.close() |
| 44 | return os.Result{ |
| 45 | exit_code: exit_code |
| 46 | output: '${stdout}${stderr}' |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | fn run_parallel_cc_failure_case(case_name string, files map[string]string) os.Result { |
| 51 | return run_parallel_cc_case(case_name, files) |
| 52 | } |
| 53 | |
| 54 | fn test_parallel_cc_fails_when_c_compilation_fails() { |
| 55 | res := run_parallel_cc_failure_case('compile_fail', { |
| 56 | 'main.v': 'module main |
| 57 | #include "definitely_missing_parallel_cc_header.h" |
| 58 | fn main() {} |
| 59 | ' |
| 60 | }) |
| 61 | assert res.exit_code == 1, res.output |
| 62 | assert res.output.contains('failed parallel C compilation'), res.output |
| 63 | } |
| 64 | |
| 65 | fn test_parallel_cc_fails_when_final_linking_fails() { |
| 66 | res := run_parallel_cc_failure_case('link_fail', { |
| 67 | 'parallel_cc_duplicate_symbol.h': 'int parallel_cc_duplicate_symbol(void) { return 42; } |
| 68 | ' |
| 69 | 'main.v': 'module main |
| 70 | #include "@DIR/parallel_cc_duplicate_symbol.h" |
| 71 | fn C.parallel_cc_duplicate_symbol() int |
| 72 | fn main() { |
| 73 | println(C.parallel_cc_duplicate_symbol()) |
| 74 | } |
| 75 | ' |
| 76 | }) |
| 77 | assert res.exit_code == 1, res.output |
| 78 | assert res.output.contains('failed to link after parallel C compilation'), res.output |
| 79 | } |
| 80 | |
| 81 | fn test_parallel_cc_succeeds_with_array_sort_compare_helper() { |
| 82 | res := run_parallel_cc_case('array_sort_compare_helper', { |
| 83 | 'main.v': 'module main |
| 84 | fn main() { |
| 85 | mut xs := [3, 1, 2] |
| 86 | xs.sort(a < b) |
| 87 | println(xs) |
| 88 | } |
| 89 | ' |
| 90 | }) |
| 91 | assert res.exit_code == 0, res.output |
| 92 | } |
| 93 | |
| 94 | fn test_parallel_cc_uses_resolved_compiler_even_when_cc_env_is_invalid() { |
| 95 | res := run_parallel_cc_case_with_env('ignore_invalid_cc_env', { |
| 96 | 'main.v': 'module main |
| 97 | fn main() { |
| 98 | println("hello") |
| 99 | } |
| 100 | ' |
| 101 | }, { |
| 102 | 'CC': 'definitely_missing_parallel_cc_compiler_23174' |
| 103 | }) |
| 104 | assert res.exit_code == 0, res.output |
| 105 | } |
| 106 | |