1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#!/usr/bin/env python3
# SPDX-license-identifier: Apache-2.0
# Copyright © 2021 Intel Corporation
"""Script for running a single project test.
This script is meant for Meson developers who want to run a single project
test, with all of the rules from the test.json file loaded.
"""
import argparse
import pathlib
import typing as T
from mesonbuild import mlog
from run_project_tests import TestDef, load_test_json, run_test, BuildStep, test_emits_skip_msg
from run_project_tests import setup_commands, detect_system_compiler, print_tool_versions
if T.TYPE_CHECKING:
from run_project_tests import CompilerArgumentType
class ArgumentType(CompilerArgumentType):
"""Typing information for command line arguments."""
case: pathlib.Path
subtests: T.List[int]
backend: str
extra_args: T.List[str]
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('case', type=pathlib.Path, help='The test case to run')
parser.add_argument('extra_args', nargs='*',
help='arguments that are passed directly to Meson (remember to have -- before these).')
parser.add_argument('--subtest', type=int, action='append', dest='subtests', help='which subtests to run')
parser.add_argument('--backend', action='store', help="Which backend to use")
parser.add_argument('--cross-file', action='store', help='File describing cross compilation environment.')
parser.add_argument('--native-file', action='store', help='File describing native compilation environment.')
parser.add_argument('--use-tmpdir', action='store_true', help='Use tmp directory for temporary files.')
args = T.cast('ArgumentType', parser.parse_args())
setup_commands(args.backend)
detect_system_compiler(args)
print_tool_versions()
test = TestDef(args.case, args.case.stem, [])
tests = load_test_json(test, False)
if args.subtests:
tests = [t for i, t in enumerate(tests) if i in args.subtests]
def should_fail(path: pathlib.Path) -> str:
dir_ = path.parent.stem
# FIXME: warning tets might not be handled correctly still…
if dir_.startswith(('failing', 'warning')):
if ' ' in dir_:
return dir_.split(' ')[1]
return 'meson'
return ''
results = [run_test(t, t.args + args.extra_args, should_fail(t.path), args.use_tmpdir) for t in tests]
failed = False
for test, result in zip(tests, results):
if result is None:
is_skipped = True
skip_reason = 'not run because preconditions were not met'
else:
for l in result.stdo.splitlines():
if test_emits_skip_msg(l):
is_skipped = True
offset = l.index('MESON_SKIP_TEST') + 16
skip_reason = l[offset:].strip()
break
else:
is_skipped = False
skip_reason = ''
if is_skipped:
msg = mlog.yellow('SKIP:')
elif result.msg:
msg = mlog.red('FAIL:')
failed = True
else:
msg = mlog.green('PASS:')
mlog.log(msg, *test.display_name())
if skip_reason:
mlog.log(mlog.bold('Reason:'), skip_reason)
if result is not None and result.msg and 'MESON_SKIP_TEST' not in result.stdo:
mlog.log('reason:', result.msg)
if result.step is BuildStep.configure:
# For configure failures, instead of printing stdout,
# print the meson log if available since it's a superset
# of stdout and often has very useful information.
mlog.log(result.mlog)
else:
mlog.log(result.stdo)
for cmd_res in result.cicmds:
mlog.log(cmd_res)
mlog.log(result.stde)
exit(1 if failed else 0)
if __name__ == "__main__":
main()
|