| 1 | // vtest build: !self_sandboxed_packaging? && !sanitized_job? |
| 2 | // .out file: |
| 3 | // To test a panic, remove everything after the long `===` line |
| 4 | // You can also remove the line with 'line:' e.g. for a builtin fn |
| 5 | import os |
| 6 | import rand |
| 7 | import term |
| 8 | import v.util.diff |
| 9 | import v.util.vtest |
| 10 | |
| 11 | @[markused] |
| 12 | const turn_off_vcolors = os.setenv('VCOLORS', 'never', true) |
| 13 | |
| 14 | const v_ci_ubuntu_musl = os.getenv('V_CI_UBUNTU_MUSL').len > 0 |
| 15 | |
| 16 | const skip_files = [ |
| 17 | 'do_not_remove_this', |
| 18 | 'tmpl_parse_html.vv', // skipped, due to a V template compilation problem after b42c824 |
| 19 | ] |
| 20 | |
| 21 | fn test_all() { |
| 22 | mut total_oks := 0 |
| 23 | mut total_oks_panic := 0 |
| 24 | mut total_skips := 0 |
| 25 | mut total_errors := 0 |
| 26 | vexe := os.getenv('VEXE') |
| 27 | vroot := os.dir(vexe) |
| 28 | os.chdir(vroot) or {} |
| 29 | dir := 'vlib/v/slow_tests/inout' |
| 30 | mut files := os.ls(dir) or { panic(err) } |
| 31 | files.sort() |
| 32 | tests := files.filter(it.ends_with('.vv') || it.ends_with('.vsh')) |
| 33 | if tests.len == 0 { |
| 34 | println('no compiler tests found') |
| 35 | assert false |
| 36 | } |
| 37 | paths := vtest.filter_vtest_only(tests, basepath: dir) |
| 38 | println('Found ${paths.len} .vv/.vsh files in ${dir} ...') |
| 39 | for idx, path in paths { |
| 40 | vprint('${idx + 1:3}/${paths.len:-3} ${path} ') |
| 41 | fname := os.file_name(path) |
| 42 | if fname in skip_files { |
| 43 | vprintln(term.bright_yellow('SKIP')) |
| 44 | total_skips++ |
| 45 | continue |
| 46 | } |
| 47 | if v_ci_ubuntu_musl { |
| 48 | if fname.contains('orm_') { |
| 49 | // the ORM programs use db.sqlite, which is not easy to install in a way usable by ubuntu-musl, so just skip them: |
| 50 | vprintln(term.bright_yellow('SKIP on ubuntu musl')) |
| 51 | continue |
| 52 | } |
| 53 | } |
| 54 | program := path |
| 55 | tname := rand.ulid() |
| 56 | tbase := os.join_path(os.vtmp_dir(), tname) |
| 57 | texe := if os.user_os() == 'windows' { '${tbase}.exe' } else { tbase } |
| 58 | compilation := |
| 59 | os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(tbase)} -cflags "-w" -cg ${os.quoted_path(program)}') |
| 60 | if compilation.exit_code < 0 { |
| 61 | panic(compilation.output) |
| 62 | } |
| 63 | if compilation.exit_code != 0 { |
| 64 | panic('compilation failed: ${compilation.output}') |
| 65 | } |
| 66 | res := os.execute(os.quoted_path(texe)) |
| 67 | if res.exit_code < 0 { |
| 68 | vprintln('nope') |
| 69 | panic(res.output) |
| 70 | } |
| 71 | $if windows { |
| 72 | os.rm(texe) or {} |
| 73 | $if msvc { |
| 74 | os.rm('${tbase}.ilk') or {} |
| 75 | os.rm('${tbase}.pdb') or {} |
| 76 | } |
| 77 | } $else { |
| 78 | os.rm(texe) or {} |
| 79 | } |
| 80 | // println('============') |
| 81 | // println(res.output) |
| 82 | // println('============') |
| 83 | mut found := res.output.trim_right('\r\n').replace('\r\n', '\n') |
| 84 | mut expected := os.read_file(program.replace('.vv', '').replace('.vsh', '') + '.out') or { |
| 85 | panic(err) |
| 86 | } |
| 87 | expected = expected.trim_right('\r\n').replace('\r\n', '\n') |
| 88 | if expected.contains('================ V panic ================') { |
| 89 | // panic include backtraces and absolute file paths, so can't do char by char comparison |
| 90 | n_found := normalize_panic_message(found, vroot) |
| 91 | n_expected := normalize_panic_message(expected, vroot) |
| 92 | if found.contains('================ V panic ================') { |
| 93 | if n_found.starts_with(n_expected) { |
| 94 | vprintln(term.green('OK (panic)')) |
| 95 | total_oks_panic++ |
| 96 | continue |
| 97 | } else { |
| 98 | // Both have panics, but there was a difference... |
| 99 | // Pass the normalized strings for further reporting. |
| 100 | // There is no point in comparing the backtraces too. |
| 101 | found = n_found |
| 102 | expected = n_expected |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | if expected != found { |
| 107 | println(term.red('FAIL')) |
| 108 | if diff_ := diff.compare_text(expected, found) { |
| 109 | println(term.header('difference:', '-')) |
| 110 | println(diff_) |
| 111 | } else { |
| 112 | println(err) |
| 113 | println(term.header('expected:', '-')) |
| 114 | println(expected) |
| 115 | println(term.header('found:', '-')) |
| 116 | println(found) |
| 117 | } |
| 118 | println(term.h_divider('-')) |
| 119 | total_errors++ |
| 120 | } else { |
| 121 | vprintln(term.green('OK')) |
| 122 | total_oks++ |
| 123 | } |
| 124 | } |
| 125 | println('>>> Summary: files: ${paths.len}, ok: ${total_oks}, ok panics: ${total_oks_panic}, skipped: ${total_skips}, errors: ${total_errors} .') |
| 126 | assert total_errors == 0 |
| 127 | } |
| 128 | |
| 129 | fn normalize_panic_message(message string, vroot string) string { |
| 130 | mut msg := message.all_before('=========================================') |
| 131 | // change windows to nix path |
| 132 | s := vroot.replace(os.path_separator, '/') |
| 133 | // remove vroot |
| 134 | msg = msg.replace(s + '/', '') |
| 135 | msg = msg.trim_space() |
| 136 | return msg |
| 137 | } |
| 138 | |
| 139 | @[if !silent ?] |
| 140 | fn vprint(msg string) { |
| 141 | print(msg) |
| 142 | } |
| 143 | |
| 144 | @[if !silent ?] |
| 145 | fn vprintln(msg string) { |
| 146 | println(msg) |
| 147 | } |
| 148 | |