| 1 | // vtest build: !(os_id_ubuntu? && musl?) && !sanitized_job? |
| 2 | import os |
| 3 | |
| 4 | const vexe = @VEXE |
| 5 | const gcc_path = os.find_abs_path_of_executable('gcc') or { '' } |
| 6 | const cdefs_h_32bit_exists = os.exists('/usr/include/i386-linux-gnu/sys/cdefs.h') |
| 7 | |
| 8 | fn separator() { |
| 9 | eprintln('-'.repeat(30)) |
| 10 | } |
| 11 | |
| 12 | fn test_trace_fns() { |
| 13 | os.chdir(@VEXEROOT)! |
| 14 | folder := os.join_path('vlib', 'v', 'tests', 'testdata', 'trace_calls') |
| 15 | fpath := os.join_path(folder, 'single_println.vv') |
| 16 | should_match_fpath := os.join_path(folder, 'single_println.vv.must_match.simple') |
| 17 | assert run_trace_fns(fpath, 'println') == 1 |
| 18 | assert run_trace_fns(fpath, '_vinit') == 1 |
| 19 | assert run_trace_fns(fpath, 'println,main.main') == 2 |
| 20 | assert run_trace_fns(fpath, 'builtin') > 3 |
| 21 | eprintln('> `-trace-calls -trace-fns PATTERNS` works') |
| 22 | separator() |
| 23 | } |
| 24 | |
| 25 | fn test_tracing() { |
| 26 | os.chdir(@VEXEROOT)! |
| 27 | folder := os.join_path('vlib', 'v', 'tests', 'testdata', 'trace_calls') |
| 28 | files := os.walk_ext(folder, '.vv') |
| 29 | for fpath in files { |
| 30 | should_match_fpath := '${fpath}.must_match' |
| 31 | if !os.exists(should_match_fpath) { |
| 32 | eprintln('> skipping ${fpath}, because ${should_match_fpath} does not exist.') |
| 33 | continue |
| 34 | } |
| 35 | run_single_program(fpath, should_match_fpath, '', '64bit') |
| 36 | if cdefs_h_32bit_exists && gcc_path != '' { |
| 37 | // try running the same programs, compiled in 32bit mode too, if gcc is available: |
| 38 | run_single_program(fpath, should_match_fpath, '-cc gcc -m32 -gc none', '32bit') |
| 39 | } else { |
| 40 | eprintln('> skipping -m32 compilation since either 32bit headers are not installed, or you do not have gcc installed') |
| 41 | } |
| 42 | separator() |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | struct CmdOutput { |
| 47 | cmd string |
| 48 | output string |
| 49 | } |
| 50 | |
| 51 | fn run(fpath string, compiler_opts string, label string) CmdOutput { |
| 52 | cmd := '${os.quoted_path(vexe)} ${compiler_opts} -no-skip-unused -trace-calls run ${os.quoted_path(fpath)}' |
| 53 | res := os.execute(cmd) |
| 54 | if res.exit_code != 0 { |
| 55 | eprintln('> ${label} compilation output:\n${res.output}') |
| 56 | assert res.exit_code == 0, 'compilation of ${fpath} failed' |
| 57 | } |
| 58 | return CmdOutput{cmd, res.output} |
| 59 | } |
| 60 | |
| 61 | fn run_trace_fns(fpath string, patterns string) int { |
| 62 | // ignore the header line and the final output `hi` line: |
| 63 | return run(fpath, '-trace-fns ${patterns}', 'trace_fns_only_println').output.split_into_lines().len - 2 |
| 64 | } |
| 65 | |
| 66 | fn run_single_program(fpath string, should_match_fpath string, compiler_opts string, label string) { |
| 67 | c := run(fpath, compiler_opts, label) |
| 68 | lines := os.read_lines(should_match_fpath) or { |
| 69 | assert false, '${should_match_fpath} should be readable' |
| 70 | return |
| 71 | } |
| 72 | if lines.len == 0 { |
| 73 | assert false, '${should_match_fpath} should contain at least one line/glob match pattern' |
| 74 | } |
| 75 | mut matched := false |
| 76 | for line in lines { |
| 77 | if c.output.match_glob(line) { |
| 78 | matched = true |
| 79 | println('> ${label} trace output of ${fpath} matches line pattern: ${line}') |
| 80 | continue |
| 81 | } else { |
| 82 | eprintln('-----------------------------------') |
| 83 | eprintln(c.output) |
| 84 | eprintln('-----------------------------------') |
| 85 | assert false, '> trace output of ${fpath} DID NOT match the line pattern: `${line}`, run cmd:\n${c.cmd}' |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | |