v2 / vlib / v / tests / builtin_overflow_test.v
133 lines · 123 sloc · 4.28 KB · e1b3e5b656a56e08dc0f32f13f4e4f992932d5ec
Raw
1// vtest build: tinyc && !self_sandboxed_packaging? && !sanitized_job?
2import os
3import time
4import term
5import v.util.diff
6import v.util.vtest
7
8const vexe = @VEXE
9
10const vroot = os.real_path(@VMODROOT)
11
12const testdata_folder = os.join_path(vroot, 'vlib/v/tests/testdata/builtin_overflow')
13
14fn mm(s string) string {
15 return term.colorize(term.magenta, s)
16}
17
18fn mj(input ...string) string {
19 return mm(input.filter(it.len > 0).join(' '))
20}
21
22fn test_out_files() {
23 println(term.colorize(term.green, '> testing whether .out files match:'))
24 os.chdir(vroot) or {}
25 output_path := os.join_path(os.vtmp_dir(), 'overflow_outs')
26 os.mkdir_all(output_path)!
27 defer {
28 os.rmdir_all(output_path) or {}
29 }
30 files := os.ls(testdata_folder) or { [] }
31 tests := files.filter(it.ends_with('.out'))
32 if tests.len == 0 {
33 eprintln('no `.out` tests found in ${testdata_folder}')
34 return
35 }
36 paths := vtest.filter_vtest_only(tests, basepath: testdata_folder).sorted()
37 mut total_errors := 0
38 for out_path in paths {
39 basename, path, relpath, out_relpath := target2paths(out_path, '.out')
40 pexe := os.join_path(output_path, '${basename}.exe')
41 //
42 file_options := '-g -check-overflow'
43 alloptions := '-o ${os.quoted_path(pexe)} ${file_options}'
44 label := mj('v', file_options, 'run', relpath) + ' == ${mm(out_relpath)} '
45 //
46 compile_cmd := '${os.quoted_path(vexe)} ${alloptions} ${os.quoted_path(path)}'
47 sw_compile := time.new_stopwatch()
48 compilation := os.execute(compile_cmd)
49 compile_ms := sw_compile.elapsed().milliseconds()
50 ensure_compilation_succeeded(compilation, compile_cmd)
51 //
52 sw_run := time.new_stopwatch()
53 res := os.execute(os.quoted_path(pexe))
54 run_ms := sw_run.elapsed().milliseconds()
55 //
56 if res.exit_code < 0 {
57 println('nope')
58 panic(res.output)
59 }
60 mut found := res.output.trim_right('\r\n').replace('\r\n', '\n')
61 mut expected := os.read_file(out_path)!
62 expected = expected.trim_right('\r\n').replace('\r\n', '\n')
63 if expected.contains('================ V panic ================') {
64 // panic include backtraces and absolute file paths, so can't do char by char comparison
65 n_found := normalize_panic_message(found, vroot)
66 n_expected := normalize_panic_message(expected, vroot)
67 if found.contains('================ V panic ================') {
68 if n_found.starts_with(n_expected) {
69 println('${term.green('OK (panic)')} C:${compile_ms:6}ms, R:${run_ms:2}ms ${label}')
70 continue
71 } else {
72 // Both have panics, but there was a difference...
73 // Pass the normalized strings for further reporting.
74 // There is no point in comparing the backtraces too.
75 found = n_found
76 expected = n_expected
77 }
78 }
79 }
80 if expected != found {
81 println('${term.red('FAIL')} C:${compile_ms:6}ms, R:${run_ms:2}ms ${label}')
82 if diff_ := diff.compare_text(expected, found) {
83 println(term.header('difference:', '-'))
84 println(diff_)
85 } else {
86 println(term.header('expected:', '-'))
87 println(expected)
88 println(term.header('found:', '-'))
89 println(found)
90 }
91 println(term.h_divider('-'))
92 total_errors++
93 } else {
94 println('${term.green('OK ')} C:${compile_ms:6}ms, R:${run_ms:2}ms ${label}')
95 }
96 }
97 assert total_errors == 0
98}
99
100fn normalize_panic_message(message string, vroot string) string {
101 mut msg := message.all_before('=========================================')
102 // change windows to nix path
103 s := vroot.replace(os.path_separator, '/')
104 msg = msg.replace(s + '/', '')
105 msg = msg.trim_space()
106 return msg
107}
108
109fn vroot_relative(opath string) string {
110 nvroot := vroot.replace(os.path_separator, '/') + '/'
111 npath := opath.replace(os.path_separator, '/')
112 return npath.replace(nvroot, '')
113}
114
115fn ensure_compilation_succeeded(compilation os.Result, cmd string) {
116 if compilation.exit_code < 0 {
117 eprintln('> cmd exit_code < 0, cmd: ${cmd}')
118 panic(compilation.output)
119 }
120 if compilation.exit_code != 0 {
121 eprintln('> cmd exit_code != 0, cmd: ${cmd}')
122 panic('compilation failed: ${compilation.output}')
123 }
124}
125
126fn target2paths(target_path string, postfix string) (string, string, string, string) {
127 basename := os.file_name(target_path).replace(postfix, '')
128 target_dir := os.dir(target_path)
129 path := os.join_path(target_dir, '${basename}.vv')
130 relpath := vroot_relative(path)
131 target_relpath := vroot_relative(target_path)
132 return basename, path, relpath, target_relpath
133}
134