|
|
@ -14,7 +14,7 @@ |
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
# limitations under the License. |
|
|
|
# limitations under the License. |
|
|
|
|
|
|
|
|
|
|
|
from typing import List, Tuple |
|
|
|
import typing |
|
|
|
import itertools |
|
|
|
import itertools |
|
|
|
import os |
|
|
|
import os |
|
|
|
import subprocess |
|
|
|
import subprocess |
|
|
@ -109,18 +109,10 @@ def setup_commands(optbackend): |
|
|
|
compile_commands, clean_commands, test_commands, install_commands, \ |
|
|
|
compile_commands, clean_commands, test_commands, install_commands, \ |
|
|
|
uninstall_commands = get_backend_commands(backend, do_debug) |
|
|
|
uninstall_commands = get_backend_commands(backend, do_debug) |
|
|
|
|
|
|
|
|
|
|
|
def get_relative_files_list_from_dir(fromdir): |
|
|
|
def get_relative_files_list_from_dir(fromdir: Path) -> typing.List[Path]: |
|
|
|
paths = [] |
|
|
|
return [file.relative_to(fromdir) for file in fromdir.rglob('*') if file.is_file()] |
|
|
|
for (root, _, files) in os.walk(fromdir): |
|
|
|
|
|
|
|
reldir = os.path.relpath(root, start=fromdir) |
|
|
|
def platform_fix_name(fname: str, compiler, env) -> str: |
|
|
|
for f in files: |
|
|
|
|
|
|
|
path = os.path.join(reldir, f).replace('\\', '/') |
|
|
|
|
|
|
|
if path.startswith('./'): |
|
|
|
|
|
|
|
path = path[2:] |
|
|
|
|
|
|
|
paths.append(path) |
|
|
|
|
|
|
|
return paths |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def platform_fix_name(fname, compiler, env): |
|
|
|
|
|
|
|
# canonicalize compiler |
|
|
|
# canonicalize compiler |
|
|
|
if compiler in {'clang-cl', 'intel-cl'}: |
|
|
|
if compiler in {'clang-cl', 'intel-cl'}: |
|
|
|
canonical_compiler = 'msvc' |
|
|
|
canonical_compiler = 'msvc' |
|
|
@ -200,35 +192,36 @@ def platform_fix_name(fname, compiler, env): |
|
|
|
|
|
|
|
|
|
|
|
return fname |
|
|
|
return fname |
|
|
|
|
|
|
|
|
|
|
|
def validate_install(srcdir, installdir, compiler, env): |
|
|
|
def validate_install(srcdir: str, installdir: Path, compiler, env) -> str: |
|
|
|
# List of installed files |
|
|
|
# List of installed files |
|
|
|
info_file = os.path.join(srcdir, 'installed_files.txt') |
|
|
|
info_file = Path(srcdir) / 'installed_files.txt' |
|
|
|
|
|
|
|
installdir = Path(installdir) |
|
|
|
# If this exists, the test does not install any other files |
|
|
|
# If this exists, the test does not install any other files |
|
|
|
noinst_file = 'usr/no-installed-files' |
|
|
|
noinst_file = Path('usr/no-installed-files') |
|
|
|
expected = {} |
|
|
|
expected = {} # type: typing.Dict[Path, bool] |
|
|
|
ret_msg = '' |
|
|
|
ret_msg = '' |
|
|
|
# Generate list of expected files |
|
|
|
# Generate list of expected files |
|
|
|
if os.path.exists(os.path.join(installdir, noinst_file)): |
|
|
|
if (installdir / noinst_file).is_file(): |
|
|
|
expected[noinst_file] = False |
|
|
|
expected[noinst_file] = False |
|
|
|
elif os.path.exists(info_file): |
|
|
|
elif info_file.is_file(): |
|
|
|
with open(info_file) as f: |
|
|
|
with info_file.open() as f: |
|
|
|
for line in f: |
|
|
|
for line in f: |
|
|
|
line = platform_fix_name(line.strip(), compiler, env) |
|
|
|
line = platform_fix_name(line.strip(), compiler, env) |
|
|
|
if line: |
|
|
|
if line: |
|
|
|
expected[line] = False |
|
|
|
expected[Path(line)] = False |
|
|
|
# Check if expected files were found |
|
|
|
# Check if expected files were found |
|
|
|
for fname in expected: |
|
|
|
for fname in expected: |
|
|
|
file_path = os.path.join(installdir, fname) |
|
|
|
file_path = installdir / fname |
|
|
|
if os.path.exists(file_path) or os.path.islink(file_path): |
|
|
|
if file_path.is_file() or file_path.is_symlink(): |
|
|
|
expected[fname] = True |
|
|
|
expected[fname] = True |
|
|
|
for (fname, found) in expected.items(): |
|
|
|
for (fname, found) in expected.items(): |
|
|
|
if not found: |
|
|
|
if not found: |
|
|
|
ret_msg += 'Expected file {0} missing.\n'.format(fname) |
|
|
|
ret_msg += 'Expected file {} missing.\n'.format(fname) |
|
|
|
# Check if there are any unexpected files |
|
|
|
# Check if there are any unexpected files |
|
|
|
found = get_relative_files_list_from_dir(installdir) |
|
|
|
found = get_relative_files_list_from_dir(installdir) |
|
|
|
for fname in found: |
|
|
|
for fname in found: |
|
|
|
if fname not in expected: |
|
|
|
if fname not in expected: |
|
|
|
ret_msg += 'Extra file {0} found.\n'.format(fname) |
|
|
|
ret_msg += 'Extra file {} found.\n'.format(fname) |
|
|
|
if ret_msg != '': |
|
|
|
if ret_msg != '': |
|
|
|
ret_msg += '\nInstall dir contents:\n' |
|
|
|
ret_msg += '\nInstall dir contents:\n' |
|
|
|
for i in found: |
|
|
|
for i in found: |
|
|
@ -445,7 +438,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen |
|
|
|
return TestResult(validate_install(testdir, install_dir, compiler, builddata.environment), |
|
|
|
return TestResult(validate_install(testdir, install_dir, compiler, builddata.environment), |
|
|
|
BuildStep.validate, stdo, stde, mesonlog, gen_time, build_time, test_time) |
|
|
|
BuildStep.validate, stdo, stde, mesonlog, gen_time, build_time, test_time) |
|
|
|
|
|
|
|
|
|
|
|
def gather_tests(testdir: Path) -> List[Path]: |
|
|
|
def gather_tests(testdir: Path) -> typing.List[Path]: |
|
|
|
test_names = [t.name for t in testdir.glob('*') if t.is_dir()] |
|
|
|
test_names = [t.name for t in testdir.glob('*') if t.is_dir()] |
|
|
|
test_names = [t for t in test_names if not t.startswith('.')] # Filter non-tests files (dot files, etc) |
|
|
|
test_names = [t for t in test_names if not t.startswith('.')] # Filter non-tests files (dot files, etc) |
|
|
|
test_nums = [(int(t.split()[0]), t) for t in test_names] |
|
|
|
test_nums = [(int(t.split()[0]), t) for t in test_names] |
|
|
@ -598,7 +591,7 @@ def should_skip_rust() -> bool: |
|
|
|
return True |
|
|
|
return True |
|
|
|
return False |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]: |
|
|
|
def detect_tests_to_run(only: typing.List[str]) -> typing.List[typing.Tuple[str, typing.List[Path], bool]]: |
|
|
|
""" |
|
|
|
""" |
|
|
|
Parameters |
|
|
|
Parameters |
|
|
|
---------- |
|
|
|
---------- |
|
|
@ -611,10 +604,8 @@ def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]: |
|
|
|
tests to run |
|
|
|
tests to run |
|
|
|
""" |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
ninja_fortran_compiler = shutil.which('gfortran') or shutil.which('flang') or shutil.which('pgfortran') or (not mesonlib.is_windows() and shutil.which('ifort')) |
|
|
|
skip_fortran = not(shutil.which('gfortran') or shutil.which('flang') or |
|
|
|
ninja_fortran = backend is Backend.ninja and ninja_fortran_compiler |
|
|
|
shutil.which('pgfortran') or shutil.which('ifort')) |
|
|
|
vs_fortran = mesonlib.is_windows() and backend is Backend.vs and shutil.which('ifort') |
|
|
|
|
|
|
|
skip_fortran = not(ninja_fortran or vs_fortran) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Name, subdirectory, skip condition. |
|
|
|
# Name, subdirectory, skip condition. |
|
|
|
all_tests = [ |
|
|
|
all_tests = [ |
|
|
@ -637,7 +628,7 @@ def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]: |
|
|
|
('d', 'd', backend is not Backend.ninja or not have_d_compiler()), |
|
|
|
('d', 'd', backend is not Backend.ninja or not have_d_compiler()), |
|
|
|
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler()), |
|
|
|
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler()), |
|
|
|
('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler()), |
|
|
|
('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler()), |
|
|
|
('fortran', 'fortran', skip_fortran), |
|
|
|
('fortran', 'fortran', skip_fortran or backend != Backend.ninja), |
|
|
|
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')), |
|
|
|
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')), |
|
|
|
('cuda', 'cuda', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('nvcc')), |
|
|
|
('cuda', 'cuda', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('nvcc')), |
|
|
|
('python3', 'python3', backend is not Backend.ninja), |
|
|
|
('python3', 'python3', backend is not Backend.ninja), |
|
|
@ -654,14 +645,14 @@ def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]: |
|
|
|
gathered_tests = [(name, gather_tests(Path('test cases', subdir)), skip) for name, subdir, skip in all_tests] |
|
|
|
gathered_tests = [(name, gather_tests(Path('test cases', subdir)), skip) for name, subdir, skip in all_tests] |
|
|
|
return gathered_tests |
|
|
|
return gathered_tests |
|
|
|
|
|
|
|
|
|
|
|
def run_tests(all_tests, log_name_base, failfast, extra_args): |
|
|
|
def run_tests(all_tests, log_name_base, failfast: bool, extra_args): |
|
|
|
global logfile |
|
|
|
global logfile |
|
|
|
txtname = log_name_base + '.txt' |
|
|
|
txtname = log_name_base + '.txt' |
|
|
|
with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf: |
|
|
|
with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf: |
|
|
|
logfile = lf |
|
|
|
logfile = lf |
|
|
|
return _run_tests(all_tests, log_name_base, failfast, extra_args) |
|
|
|
return _run_tests(all_tests, log_name_base, failfast, extra_args) |
|
|
|
|
|
|
|
|
|
|
|
def _run_tests(all_tests, log_name_base, failfast, extra_args): |
|
|
|
def _run_tests(all_tests, log_name_base, failfast: bool, extra_args): |
|
|
|
global stop, executor, futures, system_compiler |
|
|
|
global stop, executor, futures, system_compiler |
|
|
|
xmlname = log_name_base + '.xml' |
|
|
|
xmlname = log_name_base + '.xml' |
|
|
|
junit_root = ET.Element('testsuites') |
|
|
|
junit_root = ET.Element('testsuites') |
|
|
@ -767,8 +758,8 @@ def _run_tests(all_tests, log_name_base, failfast, extra_args): |
|
|
|
stdeel = ET.SubElement(current_test, 'system-err') |
|
|
|
stdeel = ET.SubElement(current_test, 'system-err') |
|
|
|
stdeel.text = result.stde |
|
|
|
stdeel.text = result.stde |
|
|
|
|
|
|
|
|
|
|
|
if failfast and failing_tests > 0: |
|
|
|
if failfast and failing_tests > 0: |
|
|
|
break |
|
|
|
break |
|
|
|
|
|
|
|
|
|
|
|
print("\nTotal configuration time: %.2fs" % conf_time) |
|
|
|
print("\nTotal configuration time: %.2fs" % conf_time) |
|
|
|
print("Total build time: %.2fs" % build_time) |
|
|
|
print("Total build time: %.2fs" % build_time) |
|
|
|