aboutsummaryrefslogtreecommitdiff
path: root/run_project_tests.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2020-05-13 11:32:28 -0700
committerGitHub <noreply@github.com>2020-05-13 11:32:28 -0700
commit85708facaea88f0909e3e58eb42738eb11729b88 (patch)
tree8b5a2942f8b84bdd402486aec2883e7832010c1b /run_project_tests.py
parentd526af89ca0e52fa076a805e4f585d16dbd1562a (diff)
parent1dee6c618d879c20bf0a70eebc54bc8caf47716f (diff)
downloadmeson-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-xrun_project_tests.py67
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)