v / cmd / v2 / test_all.vsh
299 lines · 259 sloc · 7.96 KB · a50faaff318c966c987d90768b6e79941a093002
Raw
1#!/usr/bin/env -S v
2
3import os
4
5const total_steps = 15
6const v2_bak = '/tmp/v2_src_bak_test_all'
7const cleanc_cache = '/tmp/v2_cleanc_obj_cache'
8const gitly_clone_dir = '/tmp/v2_test_gitly_clone'
9const gitly_repo_url = 'https://github.com/vlang/gitly'
10
11struct Config {
12 v1_compiler string
13 script_dir string
14 repo_root string
15 v2_src string
16 backend_arch string
17 backend_flag string
18}
19
20struct Args {
21 backend_arch string
22 opt_flag string
23}
24
25fn main() {
26 cfg := parse_config()
27 os.chdir(cfg.script_dir) or { fail('failed to enter ${cfg.script_dir}: ${err}') }
28
29 rm_rf(cleanc_cache)
30
31 section(1, '${cfg.backend_arch} self-host hello world')
32 backup_v2_src(cfg)
33 run('${q(cfg.v1_compiler)} -gc none -cc cc -o v2 v2.v')
34 restore_v2_src(cfg)
35 run('./v2 --no-parallel -backend ${cfg.backend_arch} -gc none -nocache ${cfg.backend_flag} -o v3 v2.v')
36 run('./v3 --no-parallel -backend ${cfg.backend_arch} ${cfg.backend_flag} -o hello_backend hello.v')
37 run('./hello_backend')
38 cleanup_files(['v3', 'hello_backend'])
39
40 section(2, '${cfg.backend_arch} self-host chain (v2->v3->v4->v5->v6)')
41 println(' Building v3 from v2...')
42 run('./v2 --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v3_chain v2.v')
43 println(' Building v4 from v3...')
44 run('./v3_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v4_chain v2.v')
45 println(' Building v5 from v4...')
46 run('./v4_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v5_chain v2.v')
47 println(' Building v6 from v5...')
48 run('./v5_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v6_chain v2.v')
49 v5_size := os.file_size('v5_chain')
50 v6_size := os.file_size('v6_chain')
51 if v5_size == v6_size {
52 println(' v5=v6 (${v5_size} bytes) - chain converged')
53 } else {
54 fail(' FAIL: v5 (${v5_size}) != v6 (${v6_size})')
55 }
56 cleanup_files(['v3_chain', 'v4_chain', 'v5_chain', 'v6_chain'])
57
58 section(3, 'Self-host test')
59 run('bash test_v2_self.sh')
60
61 section(4, 'Builtin test files (cleanc)')
62 rm_rf(cleanc_cache)
63 run('./v2 ../../vlib/builtin/array_test.v')
64 run('./v2 ../../vlib/builtin/string_test.v')
65 run('./v2 ../../vlib/builtin/map_test.v')
66
67 section(5, 'Builtin test files (${cfg.backend_arch})')
68 for backend_test in ['array_test.v', 'string_test.v', 'map_test.v'] {
69 run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} "../../vlib/builtin/${backend_test}"')
70 }
71
72 section(6, 'Math test')
73 run('./v2 ../../vlib/math/math_test.v')
74
75 section(7, 'Math test (${cfg.backend_arch})')
76 run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} ../../vlib/math/math_test.v')
77
78 section(8, 'Sumtype tests')
79 for st in sumtype_tests() {
80 run('./v2 ${st}')
81 }
82
83 section(9, 'Sumtype tests (${cfg.backend_arch})')
84 for st in sumtype_tests() {
85 run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} ${st}')
86 }
87
88 section(10, 'SSA backends test (${cfg.backend_arch})')
89 run('${q(cfg.v1_compiler)} -gc none run test_ssa_backends.v ${cfg.backend_arch} ${cfg.backend_flag}')
90
91 section(11, 'SSA backends test (cleanc)')
92 run('${q(cfg.v1_compiler)} -gc none run test_ssa_backends.v cleanc')
93
94 section(12, 'Transformer unit tests')
95 run('${q(cfg.v1_compiler)} -gc none ../../vlib/v2/transformer/transformer_test.v')
96
97 section(13, 'Transformer integration test')
98 run('${q(cfg.v1_compiler)} -gc none ../../vlib/v2/transformer/transformer_v2_darwin_test.v')
99
100 section(14, 'Cleanc runtime tests')
101 run('${q(cfg.v1_compiler)} -gc none run ../../vlib/v2/gen/cleanc/tests/run_tests.v')
102
103 section(15, 'Gitly build (cleanc, -d use_openssl -d sqlite)')
104 v2_bin := os.join_path(cfg.script_dir, 'v2')
105 gitly_dir := resolve_gitly_dir()
106 os.chdir(gitly_dir) or { fail('failed to enter ${gitly_dir}: ${err}') }
107 run('${q(v2_bin)} -v -showcc -o x -stats -d use_openssl -d sqlite .')
108 cleanup_files(['x'])
109 os.chdir(cfg.script_dir) or { fail('failed to return to ${cfg.script_dir}: ${err}') }
110
111 println('')
112 println('=== ALL TESTS PASSED ===')
113}
114
115fn resolve_gitly_dir() string {
116 local := os.join_path(os.home_dir(), 'code', 'gitly')
117 if os.is_dir(local) {
118 println(' Using local gitly at ${local}')
119 return local
120 }
121 if os.is_dir(gitly_clone_dir) {
122 println(' Reusing cloned gitly at ${gitly_clone_dir}')
123 return gitly_clone_dir
124 }
125 println(' Cloning ${gitly_repo_url} into ${gitly_clone_dir}...')
126 run('git clone --depth 1 ${gitly_repo_url} ${q(gitly_clone_dir)}')
127 return gitly_clone_dir
128}
129
130fn parse_config() Config {
131 args := parse_args()
132 script_dir := os.real_path(@DIR)
133 repo_root := os.real_path(os.join_path(script_dir, '..', '..'))
134 v1_compiler := absolute_path(os.getenv_opt('V') or { os.join_path(repo_root, 'v') })
135 if !os.is_executable(v1_compiler) {
136 fail('FAIL: v1 compiler not found: ${v1_compiler}')
137 }
138 backend_flag := args.opt_flag
139 return Config{
140 v1_compiler: v1_compiler
141 script_dir: script_dir
142 repo_root: repo_root
143 v2_src: os.join_path(repo_root, 'vlib', 'v2')
144 backend_arch: args.backend_arch
145 backend_flag: backend_flag
146 }
147}
148
149fn parse_args() Args {
150 mut backend_arch := ''
151 mut opt_flag := '-O0'
152 mut i := 1
153 for i < os.args.len {
154 arg := os.args[i]
155 match arg {
156 '-arch', '--arch' {
157 i++
158 if i >= os.args.len {
159 fail('missing value after -arch/--arch')
160 }
161 backend_arch = parse_backend_arch(os.args[i])
162 }
163 '-prod' {
164 opt_flag = '-prod'
165 }
166 '-O0' {
167 opt_flag = '-O0'
168 }
169 '-h', '--help' {
170 println('Usage: v run cmd/v2/test_all.vsh [-arch|--arch auto|x64|arm64] [-prod|-O0]')
171 println('')
172 println('By default, backend tests use the native host architecture.')
173 println('With -arch/--arch auto, backend tests use the native host architecture.')
174 println('With -arch/--arch x64, backend tests use the x64 backend.')
175 println('With -arch/--arch arm64, backend tests use the ARM64 backend.')
176 println('With -prod, x64 and ARM64 backend builds use -prod.')
177 println('With -O0, x64 and ARM64 backend builds use -O0.')
178 println('With x64 backend builds, -O0 is passed through, but SSA optimize is still forced by the backend.')
179 exit(0)
180 }
181 else {
182 fail('unknown argument: ${arg}')
183 }
184 }
185
186 i++
187 }
188 if backend_arch == '' {
189 backend_arch = native_backend_arch()
190 }
191 return Args{
192 backend_arch: backend_arch
193 opt_flag: opt_flag
194 }
195}
196
197fn parse_backend_arch(arch string) string {
198 match arch {
199 'auto' {
200 return native_backend_arch()
201 }
202 'x64', 'arm64' {
203 return arch
204 }
205 else {
206 fail('unsupported architecture: ${arch}; expected auto, x64 or arm64')
207 }
208 }
209
210 return ''
211}
212
213fn native_backend_arch() string {
214 machine := os.uname().machine.to_lower()
215 match machine {
216 'x86_64', 'amd64' {
217 return 'x64'
218 }
219 'aarch64', 'arm64' {
220 return 'arm64'
221 }
222 else {
223 fail('unsupported native architecture: ${machine}; pass -arch/--arch x64 or -arch/--arch arm64')
224 }
225 }
226
227 return ''
228}
229
230fn absolute_path(path string) string {
231 if os.is_abs_path(path) {
232 return path
233 }
234 return os.join_path(os.getwd(), path)
235}
236
237fn section(step int, title string) {
238 if step > 1 {
239 println('')
240 }
241 println('=== ${step}/${total_steps}: ${title} ===')
242}
243
244fn backup_v2_src(cfg Config) {
245 rm_rf(v2_bak)
246 run('cp -R ${q(cfg.v2_src)} ${q(v2_bak)}')
247}
248
249fn restore_v2_src(cfg Config) {
250 run('rsync -a --delete ${q(v2_bak + '/')} ${q(cfg.v2_src + '/')}')
251}
252
253fn rm_rf(path string) {
254 if !os.exists(path) {
255 return
256 }
257 if os.is_dir(path) {
258 os.rmdir_all(path) or { fail('failed to remove ${path}: ${err}') }
259 return
260 }
261 os.rm(path) or { fail('failed to remove ${path}: ${err}') }
262}
263
264fn cleanup_files(paths []string) {
265 for path in paths {
266 os.rm(path) or {}
267 }
268}
269
270fn run(cmd string) {
271 code := os.system(cmd)
272 if code != 0 {
273 exit(code)
274 }
275}
276
277fn q(path string) string {
278 return os.quoted_path(path)
279}
280
281fn fail(message string) {
282 eprintln(message)
283 exit(1)
284}
285
286fn sumtype_tests() []string {
287 return [
288 'test_sumtype.v',
289 'test_sumtype2.v',
290 'test_sumtype3.v',
291 'test_sumtype4.v',
292 'test_sumtype_pos.v',
293 'test_sumtype_data.v',
294 'test_sumtype_ifexpr.v',
295 'test_sumtype_nested.v',
296 'test_sumtype_many.v',
297 'test_sumtype_global.v',
298 ]
299}
300