From eec60a3018720753f70be3d2de7fdd2b4ad276b7 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Wed, 29 Jun 2022 18:49:53 +1000 Subject: [PATCH] gen.golang: add run support & testrunner --- vlib/v/builder/compile.v | 14 ++- vlib/v/checker/checker.v | 4 +- vlib/v/gen/golang/tests/golang_test.v | 94 +++++++++++++++++++ .../golang/tests/{simple.vv => simple.go.vv} | 0 .../tests/{simple.vv.out => simple.go.vv.out} | 0 5 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 vlib/v/gen/golang/tests/golang_test.v rename vlib/v/gen/golang/tests/{simple.vv => simple.go.vv} (100%) rename vlib/v/gen/golang/tests/{simple.vv.out => simple.go.vv.out} (100%) diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index a518987317..5e4f4601f9 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -83,18 +83,22 @@ fn (mut b Builder) run_compiled_executable_and_exit() { exit(0) } compiled_file := os.real_path(b.pref.out_name) + mut run_args := []string{cap: b.pref.run_args.len + 1} run_file := if b.pref.backend.is_js() { + run_args << compiled_file node_basename := $if windows { 'node.exe' } $else { 'node' } os.find_abs_path_of_executable(node_basename) or { - panic('Could not find `node` in system path. Do you have Node.js installed?') + panic('Could not find `$node_basename` in system path. Do you have Node.js installed?') + } + } else if b.pref.backend == .golang { + run_args << ['run', compiled_file] + go_basename := $if windows { 'go.exe' } $else { 'go' } + os.find_abs_path_of_executable(go_basename) or { + panic('Could not find `$go_basename` in system path. Do you have Node.js installed?') } } else { compiled_file } - mut run_args := []string{cap: b.pref.run_args.len + 1} - if b.pref.backend.is_js() { - run_args << compiled_file - } run_args << b.pref.run_args mut run_process := os.new_process(run_file) run_process.set_args(run_args) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c0ad65c37a..7f372a7e50 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1766,7 +1766,9 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) { node.ct_conds = c.ct_cond_stack.clone() } if c.pref.backend.is_js() || c.pref.backend == .golang { - if !c.file.path.ends_with('.js.v') && !c.file.path.ends_with('.go.v') { + // consider the the best way to handle the .go.vv files + if !c.file.path.ends_with('.js.v') && !c.file.path.ends_with('.go.v') + && !c.file.path.ends_with('.go.vv') { c.error('hash statements are only allowed in backend specific files such "x.js.v" and "x.go.v"', node.pos) } diff --git a/vlib/v/gen/golang/tests/golang_test.v b/vlib/v/gen/golang/tests/golang_test.v new file mode 100644 index 0000000000..7cec75a2ca --- /dev/null +++ b/vlib/v/gen/golang/tests/golang_test.v @@ -0,0 +1,94 @@ +import os +import benchmark +import term + +const is_verbose = os.getenv('VTEST_SHOW_CMD') != '' + +// TODO some logic copy pasted from valgrind_test.v and compiler_test.v, move to a module +fn test_golang() { + $if arm64 { + return + } + mut bench := benchmark.new_benchmark() + vexe := os.getenv('VEXE') + vroot := os.dir(vexe) + dir := os.join_path(vroot, 'vlib/v/gen/golang/tests') + files := os.ls(dir) or { panic(err) } + // + wrkdir := os.join_path(os.temp_dir(), 'vtests', 'golang') + os.mkdir_all(wrkdir) or { panic(err) } + os.chdir(wrkdir) or {} + tests := files.filter(it.ends_with('.vv')) + if tests.len == 0 { + println('no golang tests found') + assert false + } + bench.set_total_expected_steps(tests.len) + for test in tests { + bench.step() + full_test_path := os.real_path(os.join_path(dir, test)) + test_file_name := os.file_name(test) + relative_test_path := full_test_path.replace(vroot + '/', '') + work_test_path := '$wrkdir/$test_file_name' + go_out_test_path := '$wrkdir/${test_file_name}.go' + cmd := '${os.quoted_path(vexe)} -o ${os.quoted_path(go_out_test_path)} -b go ${os.quoted_path(full_test_path)}' + if is_verbose { + println(cmd) + } + res_golang := os.execute(cmd) + if res_golang.exit_code != 0 { + bench.fail() + eprintln(bench.step_message_fail(cmd)) + continue + } + tmperrfile := '$dir/${test}.tmperr' + go_basename := $if windows { 'go.exe' } $else { 'go' } + res := os.execute('$go_basename run ${os.quoted_path(go_out_test_path)} 2> ${os.quoted_path(tmperrfile)}') + if res.exit_code != 0 { + bench.fail() + eprintln(bench.step_message_fail('$full_test_path failed to run')) + eprintln(res.output) + continue + } + mut expected := os.read_file('$dir/${test}.out') or { panic(err) } + errfile := '$dir/${test}.err' + if os.exists(errfile) { + mut err_expected := os.read_file('$dir/${test}.err') or { panic(err) } + err_expected = err_expected.trim_right('\r\n').replace('\r\n', '\n') + errstr := os.read_file(tmperrfile) or { panic(err) } + mut err_found := errstr.trim_right('\r\n').replace('\r\n', '\n') + if err_expected != err_found { + println(term.red('FAIL')) + println('============') + println('stderr expected: "$err_expected" len=$err_expected.len') + println('============') + println('stderr found:"$err_found" len=$err_found.len') + println('============\n') + bench.fail() + continue + } + } + os.rm(tmperrfile) or {} + expected = expected.trim_right('\r\n').replace('\r\n', '\n') + mut found := res.output.trim_right('\r\n').replace('\r\n', '\n') + found = found.trim_space() + if expected != found { + println(term.red('FAIL')) + println('============') + println('expected: "$expected" len=$expected.len') + println('============') + println('found:"$found" len=$found.len') + println('============\n') + bench.fail() + continue + } + bench.ok() + eprintln(bench.step_message_ok(relative_test_path)) + } + bench.stop() + eprintln(term.h_divider('-')) + eprintln(bench.total_message('golang')) + if bench.nfail > 0 { + exit(1) + } +} diff --git a/vlib/v/gen/golang/tests/simple.vv b/vlib/v/gen/golang/tests/simple.go.vv similarity index 100% rename from vlib/v/gen/golang/tests/simple.vv rename to vlib/v/gen/golang/tests/simple.go.vv diff --git a/vlib/v/gen/golang/tests/simple.vv.out b/vlib/v/gen/golang/tests/simple.go.vv.out similarity index 100% rename from vlib/v/gen/golang/tests/simple.vv.out rename to vlib/v/gen/golang/tests/simple.go.vv.out