| 1 | #!/usr/bin/env -S v |
| 2 | |
| 3 | import os |
| 4 | |
| 5 | const total_steps = 15 |
| 6 | const v2_bak = '/tmp/v2_src_bak_test_all' |
| 7 | const cleanc_cache = '/tmp/v2_cleanc_obj_cache' |
| 8 | const gitly_clone_dir = '/tmp/v2_test_gitly_clone' |
| 9 | const gitly_repo_url = 'https://github.com/vlang/gitly' |
| 10 | |
| 11 | struct 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 | |
| 20 | struct Args { |
| 21 | backend_arch string |
| 22 | opt_flag string |
| 23 | } |
| 24 | |
| 25 | fn 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 | |
| 115 | fn 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 | |
| 130 | fn 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 | |
| 149 | fn 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 | |
| 197 | fn 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 | |
| 213 | fn 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 | |
| 230 | fn 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 | |
| 237 | fn section(step int, title string) { |
| 238 | if step > 1 { |
| 239 | println('') |
| 240 | } |
| 241 | println('=== ${step}/${total_steps}: ${title} ===') |
| 242 | } |
| 243 | |
| 244 | fn backup_v2_src(cfg Config) { |
| 245 | rm_rf(v2_bak) |
| 246 | run('cp -R ${q(cfg.v2_src)} ${q(v2_bak)}') |
| 247 | } |
| 248 | |
| 249 | fn restore_v2_src(cfg Config) { |
| 250 | run('rsync -a --delete ${q(v2_bak + '/')} ${q(cfg.v2_src + '/')}') |
| 251 | } |
| 252 | |
| 253 | fn 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 | |
| 264 | fn cleanup_files(paths []string) { |
| 265 | for path in paths { |
| 266 | os.rm(path) or {} |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | fn run(cmd string) { |
| 271 | code := os.system(cmd) |
| 272 | if code != 0 { |
| 273 | exit(code) |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | fn q(path string) string { |
| 278 | return os.quoted_path(path) |
| 279 | } |
| 280 | |
| 281 | fn fail(message string) { |
| 282 | eprintln(message) |
| 283 | exit(1) |
| 284 | } |
| 285 | |
| 286 | fn 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 | |