| 1 | // vtest retry: 3 |
| 2 | import os |
| 3 | import time |
| 4 | |
| 5 | const vexe = os.getenv('VEXE') |
| 6 | const crun_folder = os.join_path(os.vtmp_dir(), 'crun_folder') |
| 7 | const vprogram_file = os.join_path(crun_folder, 'vprogram.vv') |
| 8 | |
| 9 | fn testsuite_begin() { |
| 10 | os.setenv('VCACHE', crun_folder, true) |
| 11 | os.rmdir_all(crun_folder) or {} |
| 12 | os.mkdir_all(crun_folder) or {} |
| 13 | assert os.is_dir(crun_folder) |
| 14 | } |
| 15 | |
| 16 | fn testsuite_end() { |
| 17 | os.chdir(os.wd_at_startup) or {} |
| 18 | os.rmdir_all(crun_folder) or {} |
| 19 | assert !os.is_dir(crun_folder) |
| 20 | } |
| 21 | |
| 22 | fn test_saving_simple_v_program() { |
| 23 | os.write_file(vprogram_file, 'print("hello")')! |
| 24 | assert true |
| 25 | } |
| 26 | |
| 27 | fn test_crun_simple_v_program_several_times() { |
| 28 | mut sw := time.new_stopwatch() |
| 29 | mut times := []i64{} |
| 30 | for i in 0 .. 10 { |
| 31 | vcrun(vprogram_file) |
| 32 | times << sw.elapsed().microseconds() |
| 33 | time.sleep(50 * time.millisecond) |
| 34 | sw.restart() |
| 35 | } |
| 36 | dump(times) |
| 37 | assert times.first() > times.last() * 2 // cruns compile just once, if the source file is not changed |
| 38 | $if !windows { |
| 39 | os.system('ls -la ${crun_folder}') |
| 40 | os.system('find ${crun_folder}') |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | fn test_crun_rebuilds_when_local_c_source_changes() { |
| 45 | module_dir := os.join_path(crun_folder, 'c_source_module') |
| 46 | main_file := os.join_path(module_dir, 'code_tests.v') |
| 47 | os.mkdir_all(module_dir)! |
| 48 | os.write_file(os.join_path(module_dir, 'v.mod'), "Module {\n\tname: 'c_source_module'\n}\n")! |
| 49 | os.write_file(main_file, [ |
| 50 | 'module main', |
| 51 | '', |
| 52 | '#include "@VMODROOT/code.c"', |
| 53 | '', |
| 54 | '@[keep_args_alive]', |
| 55 | 'fn C.foo(arg [4]int)', |
| 56 | '', |
| 57 | 'fn main() {', |
| 58 | '\tC.foo([1, 2, 3, 4]!)', |
| 59 | '}', |
| 60 | ].join('\n'))! |
| 61 | write_c_source_module(module_dir, 'OLD', 2)! |
| 62 | // `crun` cache invalidation uses second-resolution mtimes. |
| 63 | time.sleep(1100 * time.millisecond) |
| 64 | first := vcrun(module_dir) |
| 65 | assert first.output == 'OLD:0:1\nOLD:1:2\n' |
| 66 | time.sleep(1100 * time.millisecond) |
| 67 | write_c_source_module(module_dir, 'NEW', 4)! |
| 68 | second := vcrun(module_dir) |
| 69 | assert second.output == 'NEW:0:1\nNEW:1:2\nNEW:2:3\nNEW:3:4\n' |
| 70 | } |
| 71 | |
| 72 | fn write_c_source_module(module_dir string, prefix string, count int) ! { |
| 73 | os.write_file(os.join_path(module_dir, 'code.c'), [ |
| 74 | '#include <stdio.h>', |
| 75 | '', |
| 76 | 'void foo(int arg[4]) {', |
| 77 | '\tfor (int i = 0; i < ${count}; ++i) {', |
| 78 | '\t\tprintf("${prefix}:%d:%d\\n", i, arg[i]);', |
| 79 | '\t}', |
| 80 | '}', |
| 81 | ].join('\n'))! |
| 82 | } |
| 83 | |
| 84 | fn vcrun(target string) os.Result { |
| 85 | cmd := '${os.quoted_path(vexe)} crun ${os.quoted_path(target)}' |
| 86 | eprintln('now: ${time.now().format_ss_milli()} | cmd: ${cmd}') |
| 87 | res := os.execute(cmd) |
| 88 | assert res.exit_code == 0 |
| 89 | return res |
| 90 | } |
| 91 | |
| 92 | fn test_crun_simple_v_program_output() { |
| 93 | res := vcrun(vprogram_file) |
| 94 | assert res.output == 'hello' |
| 95 | } |
| 96 | |