v2 / vlib / v / tests / trace_calls_test.v
88 lines · 80 sloc · 2.99 KB · bf29124d3b7d766aca92767dd63a4eb7b4a3ba81
Raw
1// vtest build: !(os_id_ubuntu? && musl?) && !sanitized_job?
2import os
3
4const vexe = @VEXE
5const gcc_path = os.find_abs_path_of_executable('gcc') or { '' }
6const cdefs_h_32bit_exists = os.exists('/usr/include/i386-linux-gnu/sys/cdefs.h')
7
8fn separator() {
9 eprintln('-'.repeat(30))
10}
11
12fn 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
25fn 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
46struct CmdOutput {
47 cmd string
48 output string
49}
50
51fn 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
61fn 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
66fn 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