Files

300 lines
8.0 KiB
V

#!/usr/bin/env -S v
import os
const total_steps = 15
const v2_bak = '/tmp/v2_src_bak_test_all'
const cleanc_cache = '/tmp/v2_cleanc_obj_cache'
const gitly_clone_dir = '/tmp/v2_test_gitly_clone'
const gitly_repo_url = 'https://github.com/vlang/gitly'
struct Config {
v1_compiler string
script_dir string
repo_root string
v2_src string
backend_arch string
backend_flag string
}
struct Args {
backend_arch string
opt_flag string
}
fn main() {
cfg := parse_config()
os.chdir(cfg.script_dir) or { fail('failed to enter ${cfg.script_dir}: ${err}') }
rm_rf(cleanc_cache)
section(1, '${cfg.backend_arch} self-host hello world')
backup_v2_src(cfg)
run('${q(cfg.v1_compiler)} -gc none -cc cc -o v2 v2.v')
restore_v2_src(cfg)
run('./v2 --no-parallel -backend ${cfg.backend_arch} -gc none -nocache ${cfg.backend_flag} -o v3 v2.v')
run('./v3 --no-parallel -backend ${cfg.backend_arch} ${cfg.backend_flag} -o hello_backend hello.v')
run('./hello_backend')
cleanup_files(['v3', 'hello_backend'])
section(2, '${cfg.backend_arch} self-host chain (v2->v3->v4->v5->v6)')
println(' Building v3 from v2...')
run('./v2 --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v3_chain v2.v')
println(' Building v4 from v3...')
run('./v3_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v4_chain v2.v')
println(' Building v5 from v4...')
run('./v4_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v5_chain v2.v')
println(' Building v6 from v5...')
run('./v5_chain --no-parallel -nocache -gc none -backend ${cfg.backend_arch} ${cfg.backend_flag} -o v6_chain v2.v')
v5_size := os.file_size('v5_chain')
v6_size := os.file_size('v6_chain')
if v5_size == v6_size {
println(' v5=v6 (${v5_size} bytes) - chain converged')
} else {
fail(' FAIL: v5 (${v5_size}) != v6 (${v6_size})')
}
cleanup_files(['v3_chain', 'v4_chain', 'v5_chain', 'v6_chain'])
section(3, 'Self-host test')
run('bash test_v2_self.sh')
section(4, 'Builtin test files (cleanc)')
rm_rf(cleanc_cache)
run('./v2 ../../vlib/builtin/array_test.v')
run('./v2 ../../vlib/builtin/string_test.v')
run('./v2 ../../vlib/builtin/map_test.v')
section(5, 'Builtin test files (${cfg.backend_arch})')
for backend_test in ['array_test.v', 'string_test.v', 'map_test.v'] {
run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} "../../vlib/builtin/${backend_test}"')
}
section(6, 'Math test')
run('./v2 ../../vlib/math/math_test.v')
section(7, 'Math test (${cfg.backend_arch})')
run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} ../../vlib/math/math_test.v')
section(8, 'Sumtype tests')
for st in sumtype_tests() {
run('./v2 ${st}')
}
section(9, 'Sumtype tests (${cfg.backend_arch})')
for st in sumtype_tests() {
run('./v2 -backend ${cfg.backend_arch} ${cfg.backend_flag} ${st}')
}
section(10, 'SSA backends test (${cfg.backend_arch})')
run('${q(cfg.v1_compiler)} -gc none run test_ssa_backends.v ${cfg.backend_arch} ${cfg.backend_flag}')
section(11, 'SSA backends test (cleanc)')
run('${q(cfg.v1_compiler)} -gc none run test_ssa_backends.v cleanc')
section(12, 'Transformer unit tests')
run('${q(cfg.v1_compiler)} -gc none ../../vlib/v2_toberemoved/transformer/transformer_test.v')
section(13, 'Transformer integration test')
run('${q(cfg.v1_compiler)} -gc none ../../vlib/v2_toberemoved/transformer/transformer_v2_darwin_test.v')
section(14, 'Cleanc runtime tests')
run('${q(cfg.v1_compiler)} -gc none run ../../vlib/v2_toberemoved/gen/cleanc/tests/run_tests.v')
section(15, 'Gitly build (cleanc, -d use_openssl -d sqlite)')
v2_bin := os.join_path(cfg.script_dir, 'v2')
gitly_dir := resolve_gitly_dir()
os.chdir(gitly_dir) or { fail('failed to enter ${gitly_dir}: ${err}') }
run('${q(v2_bin)} -v -showcc -o x -stats -d use_openssl -d sqlite .')
cleanup_files(['x'])
os.chdir(cfg.script_dir) or { fail('failed to return to ${cfg.script_dir}: ${err}') }
println('')
println('=== ALL TESTS PASSED ===')
}
fn resolve_gitly_dir() string {
local := os.join_path(os.home_dir(), 'code', 'gitly')
if os.is_dir(local) {
println(' Using local gitly at ${local}')
return local
}
if os.is_dir(gitly_clone_dir) {
println(' Reusing cloned gitly at ${gitly_clone_dir}')
return gitly_clone_dir
}
println(' Cloning ${gitly_repo_url} into ${gitly_clone_dir}...')
run('git clone --depth 1 ${gitly_repo_url} ${q(gitly_clone_dir)}')
return gitly_clone_dir
}
fn parse_config() Config {
args := parse_args()
script_dir := os.real_path(@DIR)
repo_root := os.real_path(os.join_path(script_dir, '..', '..'))
v1_compiler := absolute_path(os.getenv_opt('V') or { os.join_path(repo_root, 'v') })
if !os.is_executable(v1_compiler) {
fail('FAIL: v1 compiler not found: ${v1_compiler}')
}
backend_flag := args.opt_flag
return Config{
v1_compiler: v1_compiler
script_dir: script_dir
repo_root: repo_root
v2_src: os.join_path(repo_root, 'vlib', 'v2')
backend_arch: args.backend_arch
backend_flag: backend_flag
}
}
fn parse_args() Args {
mut backend_arch := ''
mut opt_flag := '-O0'
mut i := 1
for i < os.args.len {
arg := os.args[i]
match arg {
'-arch', '--arch' {
i++
if i >= os.args.len {
fail('missing value after -arch/--arch')
}
backend_arch = parse_backend_arch(os.args[i])
}
'-prod' {
opt_flag = '-prod'
}
'-O0' {
opt_flag = '-O0'
}
'-h', '--help' {
println('Usage: v run cmd/v2/test_all.vsh [-arch|--arch auto|x64|arm64] [-prod|-O0]')
println('')
println('By default, backend tests use the native host architecture.')
println('With -arch/--arch auto, backend tests use the native host architecture.')
println('With -arch/--arch x64, backend tests use the x64 backend.')
println('With -arch/--arch arm64, backend tests use the ARM64 backend.')
println('With -prod, x64 and ARM64 backend builds use -prod.')
println('With -O0, x64 and ARM64 backend builds use -O0.')
println('With x64 backend builds, -O0 is passed through, but SSA optimize is still forced by the backend.')
exit(0)
}
else {
fail('unknown argument: ${arg}')
}
}
i++
}
if backend_arch == '' {
backend_arch = native_backend_arch()
}
return Args{
backend_arch: backend_arch
opt_flag: opt_flag
}
}
fn parse_backend_arch(arch string) string {
match arch {
'auto' {
return native_backend_arch()
}
'x64', 'arm64' {
return arch
}
else {
fail('unsupported architecture: ${arch}; expected auto, x64 or arm64')
}
}
return ''
}
fn native_backend_arch() string {
machine := os.uname().machine.to_lower()
match machine {
'x86_64', 'amd64' {
return 'x64'
}
'aarch64', 'arm64' {
return 'arm64'
}
else {
fail('unsupported native architecture: ${machine}; pass -arch/--arch x64 or -arch/--arch arm64')
}
}
return ''
}
fn absolute_path(path string) string {
if os.is_abs_path(path) {
return path
}
return os.join_path(os.getwd(), path)
}
fn section(step int, title string) {
if step > 1 {
println('')
}
println('=== ${step}/${total_steps}: ${title} ===')
}
fn backup_v2_src(cfg Config) {
rm_rf(v2_bak)
run('cp -R ${q(cfg.v2_src)} ${q(v2_bak)}')
}
fn restore_v2_src(cfg Config) {
run('rsync -a --delete ${q(v2_bak + '/')} ${q(cfg.v2_src + '/')}')
}
fn rm_rf(path string) {
if !os.exists(path) {
return
}
if os.is_dir(path) {
os.rmdir_all(path) or { fail('failed to remove ${path}: ${err}') }
return
}
os.rm(path) or { fail('failed to remove ${path}: ${err}') }
}
fn cleanup_files(paths []string) {
for path in paths {
os.rm(path) or {}
}
}
fn run(cmd string) {
code := os.system(cmd)
if code != 0 {
exit(code)
}
}
fn q(path string) string {
return os.quoted_path(path)
}
fn fail(message string) {
eprintln(message)
exit(1)
}
fn sumtype_tests() []string {
return [
'test_sumtype.v',
'test_sumtype2.v',
'test_sumtype3.v',
'test_sumtype4.v',
'test_sumtype_pos.v',
'test_sumtype_data.v',
'test_sumtype_ifexpr.v',
'test_sumtype_nested.v',
'test_sumtype_many.v',
'test_sumtype_global.v',
]
}