diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2020-05-13 11:32:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-13 11:32:28 -0700 |
commit | 85708facaea88f0909e3e58eb42738eb11729b88 (patch) | |
tree | 8b5a2942f8b84bdd402486aec2883e7832010c1b /run_project_tests.py | |
parent | d526af89ca0e52fa076a805e4f585d16dbd1562a (diff) | |
parent | 1dee6c618d879c20bf0a70eebc54bc8caf47716f (diff) | |
download | meson-85708facaea88f0909e3e58eb42738eb11729b88.zip meson-85708facaea88f0909e3e58eb42738eb11729b88.tar.gz meson-85708facaea88f0909e3e58eb42738eb11729b88.tar.bz2 |
Merge pull request #6620 from jon-turney/test-output-check
Add a mechanism for validating meson output in tests
Diffstat (limited to 'run_project_tests.py')
-rwxr-xr-x | run_project_tests.py | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/run_project_tests.py b/run_project_tests.py index 9da67b2..18731d6 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -191,6 +191,7 @@ class TestDef: self.env = os.environ.copy() self.installed_files = [] # type: T.List[InstalledFile] self.do_not_set_opts = [] # type: T.List[str] + self.stdout = [] # type: T.List[T.Dict[str, str]] def __repr__(self) -> str: return '<{}: {:<48} [{}: {}] -- {}>'.format(type(self).__name__, str(self.path), self.name, self.args, self.skip) @@ -341,19 +342,19 @@ def log_text_file(logfile, testdir, stdo, stde): def bold(text): - return mlog.bold(text).get_text(mlog.colorize_console) + return mlog.bold(text).get_text(mlog.colorize_console()) def green(text): - return mlog.green(text).get_text(mlog.colorize_console) + return mlog.green(text).get_text(mlog.colorize_console()) def red(text): - return mlog.red(text).get_text(mlog.colorize_console) + return mlog.red(text).get_text(mlog.colorize_console()) def yellow(text): - return mlog.yellow(text).get_text(mlog.colorize_console) + return mlog.yellow(text).get_text(mlog.colorize_console()) def _run_ci_include(args: T.List[str]) -> str: @@ -381,6 +382,54 @@ def run_ci_commands(raw_log: str) -> T.List[str]: res += ['CI COMMAND {}:\n{}\n'.format(cmd[0], ci_commands[cmd[0]](cmd[1:]))] return res +def _compare_output(expected: T.List[T.Dict[str, str]], output: str, desc: str) -> str: + if expected: + i = iter(expected) + + def next_expected(i): + # Get the next expected line + item = next(i) + how = item.get('match', 'literal') + expected = item.get('line') + + # Simple heuristic to automatically convert path separators for + # Windows: + # + # Any '/' appearing before 'WARNING' or 'ERROR' (i.e. a path in a + # filename part of a location) is replaced with '\' (in a re: '\\' + # which matches a literal '\') + # + # (There should probably be a way to turn this off for more complex + # cases which don't fit this) + if mesonlib.is_windows(): + if how != "re": + sub = r'\\' + else: + sub = r'\\\\' + expected = re.sub(r'/(?=.*(WARNING|ERROR))', sub, expected) + + return how, expected + + try: + how, expected = next_expected(i) + for actual in output.splitlines(): + if how == "re": + match = bool(re.match(expected, actual)) + else: + match = (expected == actual) + if match: + how, expected = next_expected(i) + + # reached the end of output without finding expected + return 'expected "{}" not found in {}'.format(expected, desc) + except StopIteration: + # matched all expected lines + pass + + return '' + +def validate_output(test: TestDef, stdo: str, stde: str) -> str: + return _compare_output(test.stdout, stdo, 'stdout') def run_test_inprocess(testdir): old_stdout = sys.stdout @@ -452,6 +501,11 @@ def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, cicmds = run_ci_commands(mesonlog) testresult = TestResult(cicmds) testresult.add_step(BuildStep.configure, stdo, stde, mesonlog, time.time() - gen_start) + output_msg = validate_output(test, stdo, stde) + testresult.mlog += output_msg + if output_msg: + testresult.fail('Unexpected output while configuring.') + return testresult if should_fail == 'meson': if returncode == 1: return testresult @@ -566,6 +620,9 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: if 'installed' in test_def: installed = [InstalledFile(x) for x in test_def['installed']] + # Handle expected output + stdout = test_def.get('stdout', []) + # Handle the do_not_set_opts list do_not_set_opts = test_def.get('do_not_set_opts', []) # type: T.List[str] @@ -583,6 +640,7 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: t.env.update(env) t.installed_files = installed t.do_not_set_opts = do_not_set_opts + t.stdout = stdout all_tests += [t] continue @@ -653,6 +711,7 @@ def gather_tests(testdir: Path) -> T.List[TestDef]: test.env.update(env) test.installed_files = installed test.do_not_set_opts = do_not_set_opts + test.stdout = stdout all_tests += [test] return sorted(all_tests) |