v2 / vlib / v / gen / wasm / tests_decompile / must_have_test.v
120 lines · 107 sloc · 3.38 KB · 1e1c9b9e8a40cf4d14c63690365dbc769e0e2104
Raw
1import os
2import term
3import benchmark
4
5fn test_wasm_when_decompiled_must_have() {
6 vexe := @VEXE
7 vroot := os.dir(vexe).replace(os.path_separator, '/')
8 decompiler := os.find_abs_path_of_executable('wasm-decompile') or {
9 eprintln('> skipping test, since it needs `wasm-decompile`, which is not present')
10 return
11 }
12
13 dir := vroot + '/vlib/v/gen/wasm/tests_decompile'
14 vv_files := os.walk_ext(dir, '.vv')
15 assert vv_files.len > 0
16
17 mut bench := benchmark.new_benchmark()
18 bench.set_total_expected_steps(vv_files.len)
19
20 wrkdir := os.join_path(os.vtmp_dir(), 'wasm_tests_decompile')
21 os.mkdir_all(wrkdir)!
22 os.chdir(wrkdir)!
23
24 vv_files_loop: for vv_file in vv_files {
25 bench.step()
26 must_have_path := vv_file.replace('.vv', '.wasm.must_have')
27 vv_file_name := os.file_name(vv_file).replace('.vv', '')
28 full_vv_path := os.real_path(vv_file).replace(os.path_separator, '/')
29 relative_vv_path := full_vv_path.replace(vroot + '/', '')
30 full_wasm_path := '${wrkdir}/${vv_file_name}.wasm'
31 full_dcmp_path := '${wrkdir}/${vv_file_name}.dcmp'
32
33 file_options := get_file_options(vv_file)
34 cmd := '${os.quoted_path(vexe)} -b wasm ${file_options.vflags} -o ${os.quoted_path(full_wasm_path)} ${os.quoted_path(full_vv_path)}'
35 // println(cmd)
36 res_wasm := os.execute(cmd)
37 if res_wasm.exit_code != 0 {
38 bench.fail()
39 eprintln(bench.step_message_fail(cmd))
40 eprintln(' res_wasm.exit_code: ${res_wasm.exit_code}')
41 eprintln(' res_wasm.output : ${res_wasm.output}')
42 continue
43 }
44
45 cmd_decompile := '${os.quoted_path(decompiler)} ${os.quoted_path(full_wasm_path)} --output=${os.quoted_path(full_dcmp_path)}'
46 // println(cmd_decompile)
47 res_dcmp := os.execute(cmd_decompile)
48 if res_dcmp.exit_code != 0 {
49 bench.fail()
50 eprintln(bench.step_message_fail(cmd_decompile))
51 eprintln(' res_dcmp.exit_code: ${res_dcmp.exit_code}')
52 eprintln(' res_dcmp.output : ${res_dcmp.output}')
53 continue
54 }
55
56 expected_lines := os.read_lines(must_have_path) or { [] }
57 generated_wasm_lines := os.read_lines(full_dcmp_path) or {
58 bench.fail()
59 eprintln('missing ${full_dcmp_path}')
60 continue
61 }
62
63 mut failed_patterns := []string{}
64 for idx_expected_line, eline in expected_lines {
65 if eline == '' {
66 continue
67 }
68 if !does_line_match_one_of_generated_lines(eline, generated_wasm_lines) {
69 failed_patterns << eline
70 eprintln('${must_have_path}:${idx_expected_line + 1}: expected match error:')
71 eprintln('`${cmd_decompile}` did NOT produce expected line:')
72 eprintln(term.colorize(term.red, eline))
73 continue
74 }
75 }
76 if failed_patterns.len > 0 {
77 eprintln('> failed match patterns: ${failed_patterns.len}')
78 bench.fail()
79 continue
80 }
81
82 bench.ok()
83 eprintln(bench.step_message_ok(relative_vv_path))
84 }
85 bench.stop()
86 eprintln(term.h_divider('-'))
87 eprintln(bench.total_message('decompiled wasm must have'))
88 if bench.nfail > 0 {
89 exit(1)
90 }
91 os.rmdir_all(wrkdir) or {}
92}
93
94struct FileOptions {
95mut:
96 vflags string
97}
98
99pub fn get_file_options(file string) FileOptions {
100 mut res := FileOptions{}
101 lines := os.read_lines(file) or { [] }
102 for line in lines {
103 if line.starts_with('// vtest vflags:') {
104 res.vflags = line.all_after(':').trim_space()
105 }
106 }
107 return res
108}
109
110fn does_line_match_one_of_generated_lines(line string, generated_c_lines []string) bool {
111 for cline in generated_c_lines {
112 if line == cline {
113 return true
114 }
115 if cline.contains(line) {
116 return true
117 }
118 }
119 return false
120}
121