test: general refactoring of run_project_tests.py

pull/6666/head
Daniel Mensinger 5 years ago
parent fb2b637bbb
commit 1da11be132
No known key found for this signature in database
GPG Key ID: 54DD94C131E277D4
  1. 85
      run_project_tests.py

@ -106,10 +106,12 @@ class TestDef:
return '{} ({})'.format(self.path.as_posix(), self.name)
return self.path.as_posix()
def __lt__(self, other: T.Any) -> T.Union[bool, type(NotImplemented)]:
def __lt__(self, other: T.Any) -> bool:
if isinstance(other, TestDef):
# None is not sortable, so replace it with an empty string
return (self.path, self.name or '') < (other.path, other.name or '')
s_id = int(self.path.name.split(' ')[0])
o_id = int(other.path.name.split(' ')[0])
return (s_id, self.path, self.name or '') < (o_id, other.path, other.name or '')
return NotImplemented
class AutoDeletedDir:
@ -240,10 +242,9 @@ def platform_fix_name(fname: str, compiler, env) -> str:
return fname
def validate_install(srcdir: str, installdir: Path, compiler, env) -> str:
def validate_install(srcdir: Path, installdir: Path, compiler, env) -> str:
# List of installed files
info_file = Path(srcdir) / 'installed_files.txt'
installdir = Path(installdir)
info_file = srcdir / 'installed_files.txt'
expected = {} # type: T.Dict[Path, bool]
ret_msg = ''
# Generate list of expected files
@ -377,58 +378,59 @@ def parse_test_args(testdir):
# Build directory name must be the same so Ccache works over
# consecutive invocations.
def create_deterministic_builddir(src_dir, name):
def create_deterministic_builddir(test: TestDef) -> str:
import hashlib
if name:
src_dir += name
src_dir = test.path.as_posix()
if test.name:
src_dir += test.name
rel_dirname = 'b ' + hashlib.sha256(src_dir.encode(errors='ignore')).hexdigest()[0:10]
os.mkdir(rel_dirname)
abs_pathname = os.path.join(os.getcwd(), rel_dirname)
return abs_pathname
def run_test(skipped, testdir, name, extra_args, compiler, backend, flags, commands, should_fail):
if skipped:
def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail):
if test.skip:
return None
with AutoDeletedDir(create_deterministic_builddir(testdir, name)) as build_dir:
with AutoDeletedDir(create_deterministic_builddir(test)) as build_dir:
with AutoDeletedDir(tempfile.mkdtemp(prefix='i ', dir=os.getcwd())) as install_dir:
try:
return _run_test(testdir, build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail)
return _run_test(test, build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail)
finally:
mlog.shutdown() # Close the log file because otherwise Windows wets itself.
def pass_prefix_to_test(dirname):
if '39 prefix absolute' in dirname:
def pass_prefix_to_test(dirname: Path):
if '39 prefix absolute' in dirname.name:
return False
return True
def pass_libdir_to_test(dirname):
if '8 install' in dirname:
def pass_libdir_to_test(dirname: Path):
if '8 install' in dirname.name:
return False
if '38 libdir must be inside prefix' in dirname:
if '38 libdir must be inside prefix' in dirname.name:
return False
if '195 install_mode' in dirname:
if '195 install_mode' in dirname.name:
return False
return True
def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail):
def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, compiler, backend, flags, commands, should_fail):
compile_commands, clean_commands, install_commands, uninstall_commands = commands
test_args = parse_test_args(testdir)
gen_start = time.time()
setup_env = None
# Configure in-process
if pass_prefix_to_test(testdir):
if pass_prefix_to_test(test.path):
gen_args = ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
else:
gen_args = []
if pass_libdir_to_test(testdir):
if pass_libdir_to_test(test.path):
gen_args += ['--libdir', 'lib']
gen_args += [testdir, test_build_dir] + flags + test_args + extra_args
nativefile = os.path.join(testdir, 'nativefile.ini')
if os.path.exists(nativefile):
gen_args.extend(['--native-file', nativefile])
crossfile = os.path.join(testdir, 'crossfile.ini')
if os.path.exists(crossfile):
gen_args.extend(['--cross-file', crossfile])
gen_args += [test.path.as_posix(), test_build_dir] + flags + extra_args
nativefile = test.path / 'nativefile.ini'
crossfile = test.path / 'crossfile.ini'
if nativefile.exists():
gen_args.extend(['--native-file', nativefile.as_posix()])
if crossfile.exists():
gen_args.extend(['--cross-file', crossfile.as_posix()])
setup_env_file = os.path.join(testdir, 'setup_env.json')
if os.path.exists(setup_env_file):
setup_env = os.environ.copy()
@ -462,7 +464,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
# Touch the meson.build file to force a regenerate so we can test that
# regeneration works before a build is run.
ensure_backend_detects_changes(backend)
os.utime(os.path.join(testdir, 'meson.build'))
os.utime(str(test.path / 'meson.build'))
# Build with subprocess
dir_args = get_backend_args_for_dir(backend, test_build_dir)
build_start = time.time()
@ -479,7 +481,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
# Touch the meson.build file to force a regenerate so we can test that
# regeneration works after a build is complete.
ensure_backend_detects_changes(backend)
os.utime(os.path.join(testdir, 'meson.build'))
os.utime(str(test.path / 'meson.build'))
test_start = time.time()
# Test in-process
(returncode, tstdo, tstde, test_log) = run_test_inprocess(test_build_dir)
@ -515,19 +517,19 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
testresult.add_step(BuildStep.install, '', '')
if not install_commands:
return testresult
install_msg = validate_install(testdir, install_dir, compiler, builddata.environment)
install_msg = validate_install(test.path, Path(install_dir), compiler, builddata.environment)
if install_msg:
testresult.fail(install_msg)
return testresult
return testresult
def gather_tests(testdir: Path) -> T.Iterator[TestDef]:
tests = [t.name for t in testdir.glob('*') if t.is_dir()]
def gather_tests(testdir: Path) -> T.List[TestDef]:
tests = [t.name for t in testdir.iterdir() if t.is_dir()]
tests = [t for t in tests if not t.startswith('.')] # Filter non-tests files (dot files, etc)
tests = [TestDef(testdir / t, None, []) for t in tests]
all_tests = []
for t in tests:
test_defs = [TestDef(testdir / t, None, []) for t in tests]
all_tests = [] # type: T.List[TestDef]
for t in test_defs:
matrix_file = t.path / 'test_matrix.json'
if not matrix_file.is_file():
all_tests += [t]
@ -552,8 +554,8 @@ def gather_tests(testdir: Path) -> T.Iterator[TestDef]:
# Skip the matrix entry if environment variable is present
if 'skip_on_env' in i:
for env in i['skip_on_env']:
if env in os.environ:
for skip_env_var in i['skip_on_env']:
if skip_env_var in os.environ:
skip = True
# Only run the test if all compiler ID's match
@ -880,7 +882,8 @@ def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
suite_args = ['--fatal-meson-warnings']
should_fail = name.split('warning-')[1]
result = executor.submit(run_test, skipped or t.skip, t.path.as_posix(), t.name, extra_args + suite_args + t.args,
t.skip = skipped or t.skip
result = executor.submit(run_test, t, extra_args + suite_args + t.args,
system_compiler, backend, backend_flags, commands, should_fail)
futures.append((testname, t, result))
for (testname, t, result) in futures:
@ -1033,11 +1036,11 @@ def detect_system_compiler(options):
for lang in sorted(compilers.all_languages):
try:
comp = env.compiler_from_language(lang, MachineChoice.HOST)
details = '{} {} [{}]'.format(' '.join(comp.get_exelist()), comp.get_version_string(), comp.get_id())
details = '{:<10} {} {}'.format('[' + comp.get_id() + ']', ' '.join(comp.get_exelist()), comp.get_version_string())
compiler_id_map[lang] = comp.get_id()
except mesonlib.MesonException:
comp = None
details = 'not found'
details = '[not found]'
print('%-7s: %s' % (lang, details))
# note C compiler for later use by platform_fix_name()

Loading…
Cancel
Save