#!/usr/bin/env python3

# Copyright 2012-2021 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Work around some pathlib bugs...
from mesonbuild import _pathlib
import sys
sys.modules['pathlib'] = _pathlib

from concurrent.futures import ProcessPoolExecutor, CancelledError
from enum import Enum
from io import StringIO
from pathlib import Path, PurePath
import argparse
import functools
import itertools
import json
import multiprocessing
import os
import re
import shlex
import shutil
import signal
import subprocess
import tempfile
import time
import typing as T
import xml.etree.ElementTree as ET
import collections

from mesonbuild import build
from mesonbuild import environment
from mesonbuild import compilers
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mtest
from mesonbuild.compilers import compiler_from_language, detect_objc_compiler, detect_objcpp_compiler
from mesonbuild.build import ConfigurationData
from mesonbuild.mesonlib import MachineChoice, Popen_safe, TemporaryDirectoryWinProof, setup_vsenv
from mesonbuild.mlog import blue, bold, cyan, green, red, yellow, normal_green
from mesonbuild.coredata import backendlist, version as meson_version
from mesonbuild.modules.python import PythonExternalProgram
from run_tests import get_fake_options, run_configure, get_meson_script
from run_tests import get_backend_commands, get_backend_args_for_dir, Backend
from run_tests import ensure_backend_detects_changes
from run_tests import guess_backend

if T.TYPE_CHECKING:
    from types import FrameType
    from mesonbuild.environment import Environment
    from mesonbuild._typing import Protocol
    from concurrent.futures import Future
    from mesonbuild.modules.python import PythonIntrospectionDict

    class CompilerArgumentType(Protocol):
        cross_file: str
        native_file: str
        use_tmpdir: bool


    class ArgumentType(CompilerArgumentType):

        """Typing information for command line arguments."""

        extra_args: T.List[str]
        backend: str
        num_workers: int
        failfast: bool
        no_unittests: bool
        only: T.List[str]

ALL_TESTS = ['cmake', 'common', 'native', 'warning-meson', 'failing-meson', 'failing-build', 'failing-test',
             'keyval', 'platform-osx', 'platform-windows', 'platform-linux',
             'java', 'C#', 'vala', 'cython', 'rust', 'd', 'objective c', 'objective c++',
             'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm',
             ]


class BuildStep(Enum):
    configure = 1
    build = 2
    test = 3
    install = 4
    clean = 5
    validate = 6


class TestResult(BaseException):
    def __init__(self, cicmds: T.List[str]) -> None:
        self.msg    = ''  # empty msg indicates test success
        self.stdo   = ''
        self.stde   = ''
        self.mlog   = ''
        self.cicmds = cicmds
        self.conftime:  float = 0
        self.buildtime: float = 0
        self.testtime:  float = 0

    def add_step(self, step: BuildStep, stdo: str, stde: str, mlog: str = '', time: float = 0) -> None:
        self.step = step
        self.stdo += stdo
        self.stde += stde
        self.mlog += mlog
        if step == BuildStep.configure:
            self.conftime = time
        elif step == BuildStep.build:
            self.buildtime = time
        elif step == BuildStep.test:
            self.testtime = time

    def fail(self, msg: str) -> None:
        self.msg = msg

python = PythonExternalProgram(sys.executable)
python.sanity()

class InstalledFile:
    def __init__(self, raw: T.Dict[str, str]):
        self.path = raw['file']
        self.typ = raw['type']
        self.platform = raw.get('platform', None)
        self.language = raw.get('language', 'c')  # type: str

        version = raw.get('version', '')  # type: str
        if version:
            self.version = version.split('.')  # type: T.List[str]
        else:
            # split on '' will return [''], we want an empty list though
            self.version = []

    def get_path(self, compiler: str, env: environment.Environment) -> T.Optional[Path]:
        p = Path(self.path)
        canonical_compiler = compiler
        if ((compiler in ['clang-cl', 'intel-cl']) or
                (env.machines.host.is_windows() and compiler in {'pgi', 'dmd', 'ldc'})):
            canonical_compiler = 'msvc'

        python_suffix = python.info['suffix']

        has_pdb = False
        if self.language in {'c', 'cpp'}:
            has_pdb = canonical_compiler == 'msvc'
        elif self.language == 'd':
            # dmd's optlink does not genearte pdb iles
            has_pdb = env.coredata.compilers.host['d'].linker.id in {'link', 'lld-link'}

        # Abort if the platform does not match
        matches = {
            'msvc': canonical_compiler == 'msvc',
            'gcc': canonical_compiler != 'msvc',
            'cygwin': env.machines.host.is_cygwin(),
            '!cygwin': not env.machines.host.is_cygwin(),
        }.get(self.platform or '', True)
        if not matches:
            return None

        # Handle the different types
        if self.typ in {'py_implib', 'python_lib', 'python_file'}:
            val = p.as_posix()
            val = val.replace('@PYTHON_PLATLIB@', python.platlib)
            val = val.replace('@PYTHON_PURELIB@', python.purelib)
            p = Path(val)
            if self.typ == 'python_file':
                return p
            if self.typ == 'python_lib':
                return p.with_suffix(python_suffix)
        if self.typ in ['file', 'dir']:
            return p
        elif self.typ == 'shared_lib':
            if env.machines.host.is_windows() or env.machines.host.is_cygwin():
                # Windows only has foo.dll and foo-X.dll
                if len(self.version) > 1:
                    return None
                if self.version:
                    p = p.with_name('{}-{}'.format(p.name, self.version[0]))
                return p.with_suffix('.dll')

            p = p.with_name(f'lib{p.name}')
            if env.machines.host.is_darwin():
                # MacOS only has libfoo.dylib and libfoo.X.dylib
                if len(self.version) > 1:
                    return None

                # pathlib.Path.with_suffix replaces, not appends
                suffix = '.dylib'
                if self.version:
                    suffix = '.{}{}'.format(self.version[0], suffix)
            else:
                # pathlib.Path.with_suffix replaces, not appends
                suffix = '.so'
                if self.version:
                    suffix = '{}.{}'.format(suffix, '.'.join(self.version))
            return p.with_suffix(suffix)
        elif self.typ == 'exe':
            if env.machines.host.is_windows() or env.machines.host.is_cygwin():
                return p.with_suffix('.exe')
        elif self.typ == 'pdb':
            if self.version:
                p = p.with_name('{}-{}'.format(p.name, self.version[0]))
            return p.with_suffix('.pdb') if has_pdb else None
        elif self.typ in {'implib', 'implibempty', 'py_implib'}:
            if env.machines.host.is_windows() and canonical_compiler == 'msvc':
                # only MSVC doesn't generate empty implibs
                if self.typ == 'implibempty' and compiler == 'msvc':
                    return None
                return p.parent / (re.sub(r'^lib', '', p.name) + '.lib')
            elif env.machines.host.is_windows() or env.machines.host.is_cygwin():
                if self.typ == 'py_implib':
                    p = p.with_suffix(python_suffix)
                return p.with_suffix('.dll.a')
            else:
                return None
        elif self.typ == 'expr':
            return Path(platform_fix_name(p.as_posix(), canonical_compiler, env))
        else:
            raise RuntimeError(f'Invalid installed file type {self.typ}')

        return p

    def get_paths(self, compiler: str, env: environment.Environment, installdir: Path) -> T.List[Path]:
        p = self.get_path(compiler, env)
        if not p:
            return []
        if self.typ == 'dir':
            abs_p = installdir / p
            if not abs_p.exists():
                raise RuntimeError(f'{p} does not exist')
            if not abs_p.is_dir():
                raise RuntimeError(f'{p} is not a directory')
            return [x.relative_to(installdir) for x in abs_p.rglob('*') if x.is_file() or x.is_symlink()]
        else:
            return [p]

@functools.total_ordering
class TestDef:
    def __init__(self, path: Path, name: T.Optional[str], args: T.List[str], skip: bool = False):
        self.category = path.parts[1]
        self.path = path
        self.name = name
        self.args = args
        self.skip = skip
        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]]
        self.skip_expected = False

        # Always print a stack trace for Meson exceptions
        self.env['MESON_FORCE_BACKTRACE'] = '1'

    def __repr__(self) -> str:
        return '<{}: {:<48} [{}: {}] -- {}>'.format(type(self).__name__, str(self.path), self.name, self.args, self.skip)

    def display_name(self) -> mlog.TV_LoggableList:
        # Remove the redundant 'test cases' part
        section, id = self.path.parts[1:3]
        res: mlog.TV_LoggableList = [f'{section}:', bold(id)]
        if self.name:
            res += [f'   ({self.name})']
        return res

    def __lt__(self, other: object) -> bool:
        if isinstance(other, TestDef):
            # None is not sortable, so replace it with an empty string
            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

failing_logs: T.List[str] = []
print_debug = 'MESON_PRINT_TEST_OUTPUT' in os.environ
under_ci = 'CI' in os.environ
ci_jobname = os.environ.get('MESON_CI_JOBNAME', None)
do_debug = under_ci or print_debug
no_meson_log_msg = 'No meson-log.txt found.'

host_c_compiler: T.Optional[str]   = None
compiler_id_map: T.Dict[str, str]  = {}
tool_vers_map:   T.Dict[str, str]  = {}

compile_commands:   T.List[str]
clean_commands:     T.List[str]
test_commands:      T.List[str]
install_commands:   T.List[str]
uninstall_commands: T.List[str]

backend:      'Backend'
backend_flags: T.List[str]

stop: bool = False
is_worker_process: bool = False

# Let's have colors in our CI output
if under_ci:
    def _ci_colorize_console() -> bool:
        return not is_worker_process

    mlog.colorize_console = _ci_colorize_console

class StopException(Exception):
    def __init__(self) -> None:
        super().__init__('Stopped by user')

def stop_handler(signal: int, frame: T.Optional['FrameType']) -> None:
    global stop
    stop = True
signal.signal(signal.SIGINT, stop_handler)
signal.signal(signal.SIGTERM, stop_handler)

def setup_commands(optbackend: str) -> None:
    global do_debug, backend, backend_flags
    global compile_commands, clean_commands, test_commands, install_commands, uninstall_commands
    backend, backend_flags = guess_backend(optbackend, shutil.which('msbuild'))
    compile_commands, clean_commands, test_commands, install_commands, \
        uninstall_commands = get_backend_commands(backend, do_debug)

# TODO try to eliminate or at least reduce this function
def platform_fix_name(fname: str, canonical_compiler: str, env: environment.Environment) -> str:
    if '?lib' in fname:
        if env.machines.host.is_windows() and canonical_compiler == 'msvc':
            fname = re.sub(r'lib/\?lib(.*)\.', r'bin/\1.', fname)
            fname = re.sub(r'/\?lib/', r'/bin/', fname)
        elif env.machines.host.is_windows():
            fname = re.sub(r'lib/\?lib(.*)\.', r'bin/lib\1.', fname)
            fname = re.sub(r'\?lib(.*)\.dll$', r'lib\1.dll', fname)
            fname = re.sub(r'/\?lib/', r'/bin/', fname)
        elif env.machines.host.is_cygwin():
            fname = re.sub(r'lib/\?lib(.*)\.so$', r'bin/cyg\1.dll', fname)
            fname = re.sub(r'lib/\?lib(.*)\.', r'bin/cyg\1.', fname)
            fname = re.sub(r'\?lib(.*)\.dll$', r'cyg\1.dll', fname)
            fname = re.sub(r'/\?lib/', r'/bin/', fname)
        else:
            fname = re.sub(r'\?lib', 'lib', fname)

    if fname.endswith('?so'):
        if env.machines.host.is_windows() and canonical_compiler == 'msvc':
            fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
            fname = re.sub(r'/(?:lib|)([^/]*?)\?so$', r'/\1.dll', fname)
            return fname
        elif env.machines.host.is_windows():
            fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
            fname = re.sub(r'/([^/]*?)\?so$', r'/\1.dll', fname)
            return fname
        elif env.machines.host.is_cygwin():
            fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
            fname = re.sub(r'/lib([^/]*?)\?so$', r'/cyg\1.dll', fname)
            fname = re.sub(r'/([^/]*?)\?so$', r'/\1.dll', fname)
            return fname
        elif env.machines.host.is_darwin():
            return fname[:-3] + '.dylib'
        else:
            return fname[:-3] + '.so'

    return fname

def validate_install(test: TestDef, installdir: Path, env: environment.Environment) -> str:
    ret_msg = ''
    expected_raw = []  # type: T.List[Path]
    for i in test.installed_files:
        try:
            expected_raw += i.get_paths(host_c_compiler, env, installdir)
        except RuntimeError as err:
            ret_msg += f'Expected path error: {err}\n'
    expected = {x: False for x in expected_raw}
    found = [x.relative_to(installdir) for x in installdir.rglob('*') if x.is_file() or x.is_symlink()]
    # Mark all found files as found and detect unexpected files
    for fname in found:
        if fname not in expected:
            ret_msg += f'Extra file {fname} found.\n'
            continue
        expected[fname] = True
    # Check if expected files were found
    for p, f in expected.items():
        if not f:
            ret_msg += f'Expected file {p} missing.\n'
    # List dir content on error
    if ret_msg != '':
        ret_msg += '\nInstall dir contents:\n'
        for p in found:
            ret_msg += f'  - {p}\n'
    return ret_msg

def log_text_file(logfile: T.TextIO, testdir: Path, result: TestResult) -> None:
    logfile.write('%s\nstdout\n\n---\n' % testdir.as_posix())
    logfile.write(result.stdo)
    logfile.write('\n\n---\n\nstderr\n\n---\n')
    logfile.write(result.stde)
    logfile.write('\n\n---\n\n')
    if print_debug:
        try:
            print(result.stdo)
        except UnicodeError:
            sanitized_out = result.stdo.encode('ascii', errors='replace').decode()
            print(sanitized_out)
        try:
            print(result.stde, file=sys.stderr)
        except UnicodeError:
            sanitized_err = result.stde.encode('ascii', errors='replace').decode()
            print(sanitized_err, file=sys.stderr)


def _run_ci_include(args: T.List[str]) -> str:
    if not args:
        return 'At least one parameter required'
    try:
        data = Path(args[0]).read_text(errors='ignore', encoding='utf-8')
        return 'Included file {}:\n{}\n'.format(args[0], data)
    except Exception:
        return 'Failed to open {}'.format(args[0])

ci_commands = {
    'ci_include': _run_ci_include
}

def run_ci_commands(raw_log: str) -> T.List[str]:
    res = []
    for l in raw_log.splitlines():
        if not l.startswith('!meson_ci!/'):
            continue
        cmd = shlex.split(l[11:])
        if not cmd or cmd[0] not in ci_commands:
            continue
        res += ['CI COMMAND {}:\n{}\n'.format(cmd[0], ci_commands[cmd[0]](cmd[1:]))]
    return res

class OutputMatch:
    def __init__(self, how: str, expected: str, count: int) -> None:
        self.how = how
        self.expected = expected
        self.count = count

    def match(self, actual: str) -> bool:
        if self.how == "re":
            return bool(re.match(self.expected, actual))
        return self.expected == actual

def _compare_output(expected: T.List[T.Dict[str, str]], output: str, desc: str) -> str:
    if expected:
        matches:   T.List[OutputMatch] = []
        nomatches: T.List[OutputMatch] = []
        for item in expected:
            how = item.get('match', 'literal')
            expected_line = item.get('line')
            count = int(item.get('count', -1))

            # 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_line = re.sub(r'/(?=.*(WARNING|ERROR))', sub, expected_line)

            m = OutputMatch(how, expected_line, count)
            if count == 0:
                nomatches.append(m)
            else:
                matches.append(m)


        i = 0
        for actual in output.splitlines():
            # Verify this line does not match any unexpected lines (item.count == 0)
            for match in nomatches:
                if match.match(actual):
                    return f'unexpected "{match.expected}" found in {desc}'
            # If we matched all expected lines, continue to verify there are
            # no unexpected line. If nomatches is empty then we are done already.
            if i >= len(matches):
                if not nomatches:
                    break
                continue
            # Check if this line match current expected line
            match = matches[i]
            if match.match(actual):
                if match.count < 0:
                    # count was not specified, continue with next expected line,
                    # it does not matter if this line will be matched again or
                    # not.
                    i += 1
                else:
                    # count was specified (must be >0), continue expecting this
                    # same line. If count reached 0 we continue with next
                    # expected line but remember that this one must not match
                    # anymore.
                    match.count -= 1
                    if match.count == 0:
                        nomatches.append(match)
                        i += 1

        if i < len(matches):
            # reached the end of output without finding expected
            return f'expected "{matches[i].expected}" not found in {desc}'

    return ''

def validate_output(test: TestDef, stdo: str, stde: str) -> str:
    return _compare_output(test.stdout, stdo, 'stdout')

# There are some class variables and such that cache
# information. Clear all of these. The better solution
# would be to change the code so that no state is persisted
# but that would be a lot of work given that Meson was originally
# coded to run as a batch process.
def clear_internal_caches() -> None:
    import mesonbuild.interpreterbase
    from mesonbuild.dependencies import CMakeDependency
    from mesonbuild.mesonlib import PerMachine
    mesonbuild.interpreterbase.FeatureNew.feature_registry = {}
    CMakeDependency.class_cmakeinfo = PerMachine(None, None)

def run_test_inprocess(testdir: str) -> T.Tuple[int, str, str, str]:
    old_stdout = sys.stdout
    sys.stdout = mystdout = StringIO()
    old_stderr = sys.stderr
    sys.stderr = mystderr = StringIO()
    old_cwd = os.getcwd()
    os.chdir(testdir)
    test_log_fname = Path('meson-logs', 'testlog.txt')
    try:
        returncode_test = mtest.run_with_args(['--no-rebuild'])
        if test_log_fname.exists():
            test_log = test_log_fname.open(encoding='utf-8', errors='ignore').read()
        else:
            test_log = ''
        returncode_benchmark = mtest.run_with_args(['--no-rebuild', '--benchmark', '--logbase', 'benchmarklog'])
    finally:
        sys.stdout = old_stdout
        sys.stderr = old_stderr
        os.chdir(old_cwd)
    return max(returncode_test, returncode_benchmark), mystdout.getvalue(), mystderr.getvalue(), test_log

# Build directory name must be the same so Ccache works over
# consecutive invocations.
def create_deterministic_builddir(test: TestDef, use_tmpdir: bool) -> str:
    import hashlib
    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]
    abs_pathname = os.path.join(tempfile.gettempdir() if use_tmpdir else os.getcwd(), rel_dirname)
    if os.path.exists(abs_pathname):
        mesonlib.windows_proof_rmtree(abs_pathname)
    os.mkdir(abs_pathname)
    return abs_pathname

def format_parameter_file(file_basename: str, test: TestDef, test_build_dir: str) -> Path:
    confdata = ConfigurationData()
    confdata.values = {'MESON_TEST_ROOT': (str(test.path.absolute()), 'base directory of current test')}

    template = test.path / (file_basename + '.in')
    destination = Path(test_build_dir) / file_basename
    mesonlib.do_conf_file(str(template), str(destination), confdata, 'meson')

    return destination

def detect_parameter_files(test: TestDef, test_build_dir: str) -> T.Tuple[Path, Path]:
    nativefile = test.path / 'nativefile.ini'
    crossfile = test.path / 'crossfile.ini'

    if os.path.exists(str(test.path / 'nativefile.ini.in')):
        nativefile = format_parameter_file('nativefile.ini', test, test_build_dir)

    if os.path.exists(str(test.path / 'crossfile.ini.in')):
        crossfile = format_parameter_file('crossfile.ini', test, test_build_dir)

    return nativefile, crossfile

# In previous python versions the global variables are lost in ProcessPoolExecutor.
# So, we use this tuple to restore some of them
class GlobalState(T.NamedTuple):
    compile_commands:   T.List[str]
    clean_commands:     T.List[str]
    test_commands:      T.List[str]
    install_commands:   T.List[str]
    uninstall_commands: T.List[str]

    backend:      'Backend'
    backend_flags: T.List[str]

    host_c_compiler: T.Optional[str]

def run_test(test: TestDef,
             extra_args: T.List[str],
             should_fail: str,
             use_tmp: bool,
             state: T.Optional[GlobalState] = None) -> T.Optional[TestResult]:
    # Unpack the global state
    global compile_commands, clean_commands, test_commands, install_commands, uninstall_commands, backend, backend_flags, host_c_compiler
    if state is not None:
        compile_commands, clean_commands, test_commands, install_commands, uninstall_commands, backend, backend_flags, host_c_compiler = state
    # Store that this is a worker process
    global is_worker_process
    is_worker_process = True
    # Setup the test environment
    assert not test.skip, 'Skipped test should not be run'
    build_dir = create_deterministic_builddir(test, use_tmp)
    try:
        with TemporaryDirectoryWinProof(prefix='i ', dir=None if use_tmp else os.getcwd()) as install_dir:
            try:
                return _run_test(test, build_dir, install_dir, extra_args, should_fail)
            except TestResult as r:
                return r
            finally:
                mlog.shutdown() # Close the log file because otherwise Windows wets itself.
    finally:
        mesonlib.windows_proof_rmtree(build_dir)

def _run_test(test: TestDef,
              test_build_dir: str,
              install_dir: str,
              extra_args: T.List[str],
              should_fail: str) -> TestResult:
    gen_start = time.time()
    # Configure in-process
    gen_args = []  # type: T.List[str]
    if 'prefix' not in test.do_not_set_opts:
        gen_args += ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
    if 'libdir' not in test.do_not_set_opts:
        gen_args += ['--libdir', 'lib']
    gen_args += [test.path.as_posix(), test_build_dir] + backend_flags + extra_args

    nativefile, crossfile = detect_parameter_files(test, test_build_dir)

    if nativefile.exists():
        gen_args.extend(['--native-file', nativefile.as_posix()])
    if crossfile.exists():
        gen_args.extend(['--cross-file', crossfile.as_posix()])
    (returncode, stdo, stde) = run_configure(gen_args, env=test.env, catch_exception=True)
    try:
        logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt')
        mesonlog = logfile.open(errors='ignore', encoding='utf-8').read()
    except Exception:
        mesonlog = no_meson_log_msg
    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
        elif returncode != 0:
            testresult.fail(f'Test exited with unexpected status {returncode}.')
            return testresult
        else:
            testresult.fail('Test that should have failed succeeded.')
            return testresult
    if returncode != 0:
        testresult.fail('Generating the build system failed.')
        return testresult
    builddata = build.load(test_build_dir)
    dir_args = get_backend_args_for_dir(backend, test_build_dir)

    # Build with subprocess
    def build_step() -> None:
        build_start = time.time()
        pc, o, e = Popen_safe(compile_commands + dir_args, cwd=test_build_dir)
        testresult.add_step(BuildStep.build, o, e, '', time.time() - build_start)
        if should_fail == 'build':
            if pc.returncode != 0:
                raise testresult
            testresult.fail('Test that should have failed to build succeeded.')
            raise testresult
        if pc.returncode != 0:
            testresult.fail('Compiling source code failed.')
            raise testresult

    # Touch the meson.build file to force a regenerate
    def force_regenerate() -> None:
        ensure_backend_detects_changes(backend)
        os.utime(str(test.path / 'meson.build'))

    # just test building
    build_step()

    # test that regeneration works for build step
    force_regenerate()
    build_step()  # TBD: assert nothing gets built after the regenerate?

    # test that regeneration works for test step
    force_regenerate()

    # Test in-process
    clear_internal_caches()
    test_start = time.time()
    (returncode, tstdo, tstde, test_log) = run_test_inprocess(test_build_dir)
    testresult.add_step(BuildStep.test, tstdo, tstde, test_log, time.time() - test_start)
    if should_fail == 'test':
        if returncode != 0:
            return testresult
        testresult.fail('Test that should have failed to run unit tests succeeded.')
        return testresult
    if returncode != 0:
        testresult.fail('Running unit tests failed.')
        return testresult

    # Do installation, if the backend supports it
    if install_commands:
        env = test.env.copy()
        env['DESTDIR'] = install_dir
        # Install with subprocess
        pi, o, e = Popen_safe(install_commands, cwd=test_build_dir, env=env)
        testresult.add_step(BuildStep.install, o, e)
        if pi.returncode != 0:
            testresult.fail('Running install failed.')
            return testresult

    # Clean with subprocess
    env = test.env.copy()
    pi, o, e = Popen_safe(clean_commands + dir_args, cwd=test_build_dir, env=env)
    testresult.add_step(BuildStep.clean, o, e)
    if pi.returncode != 0:
        testresult.fail('Running clean failed.')
        return testresult

    # Validate installed files
    testresult.add_step(BuildStep.install, '', '')
    if not install_commands:
        return testresult
    install_msg = validate_install(test, Path(install_dir), builddata.environment)
    if install_msg:
        testresult.fail('\n' + install_msg)
        return testresult

    return testresult


# processing of test.json 'skip_*' keys, which can appear at top level, or in
# matrix:
def _skip_keys(test_def: T.Dict) -> T.Tuple[bool, bool]:
    skip_expected = False

    # Test is expected to skip if MESON_CI_JOBNAME contains any of the list of
    # substrings
    if ('skip_on_jobname' in test_def) and (ci_jobname is not None):
        skip_expected = any(s in ci_jobname for s in test_def['skip_on_jobname'])

    # Test is expected to skip if os matches
    if 'skip_on_os' in test_def:
        mesonenv = environment.Environment(None, None, get_fake_options('/'))
        for skip_os in test_def['skip_on_os']:
            if skip_os.startswith('!'):
                if mesonenv.machines.host.system != skip_os[1:]:
                    skip_expected = True
            else:
                if mesonenv.machines.host.system == skip_os:
                    skip_expected = True

    # Skip if environment variable is present
    skip = False
    if 'skip_on_env' in test_def:
        for skip_env_var in test_def['skip_on_env']:
            if skip_env_var in os.environ:
                skip = True

    return (skip, skip_expected)


def load_test_json(t: TestDef, stdout_mandatory: bool) -> T.List[TestDef]:
    all_tests: T.List[TestDef] = []
    test_def = {}
    test_def_file = t.path / 'test.json'
    if test_def_file.is_file():
        test_def = json.loads(test_def_file.read_text(encoding='utf-8'))

    # Handle additional environment variables
    env = {}  # type: T.Dict[str, str]
    if 'env' in test_def:
        assert isinstance(test_def['env'], dict)
        env = test_def['env']
        for key, val in env.items():
            val = val.replace('@ROOT@', t.path.resolve().as_posix())
            val = val.replace('@PATH@', t.env.get('PATH', ''))
            env[key] = val

    # Handle installed files
    installed = []  # type: T.List[InstalledFile]
    if 'installed' in test_def:
        installed = [InstalledFile(x) for x in test_def['installed']]

    # Handle expected output
    stdout = test_def.get('stdout', [])
    if stdout_mandatory and not stdout:
        raise RuntimeError(f"{test_def_file} must contain a non-empty stdout key")

    # Handle the do_not_set_opts list
    do_not_set_opts = test_def.get('do_not_set_opts', [])  # type: T.List[str]

    (t.skip, t.skip_expected) = _skip_keys(test_def)

    # Skip tests if the tool requirements are not met
    if 'tools' in test_def:
        assert isinstance(test_def['tools'], dict)
        for tool, vers_req in test_def['tools'].items():
            if tool not in tool_vers_map:
                t.skip = True
            elif not mesonlib.version_compare(tool_vers_map[tool], vers_req):
                t.skip = True

    # Skip the matrix code and just update the existing test
    if 'matrix' not in test_def:
        t.env.update(env)
        t.installed_files = installed
        t.do_not_set_opts = do_not_set_opts
        t.stdout = stdout
        return [t]

    new_opt_list: T.List[T.List[T.Tuple[str, bool, bool]]]

    # 'matrix; entry is present, so build multiple tests from matrix definition
    opt_list = []  # type: T.List[T.List[T.Tuple[str, bool, bool]]]
    matrix = test_def['matrix']
    assert "options" in matrix
    for key, val in matrix["options"].items():
        assert isinstance(val, list)
        tmp_opts = []  # type: T.List[T.Tuple[str, bool, bool]]
        for i in val:
            assert isinstance(i, dict)
            assert "val" in i

            (skip, skip_expected) = _skip_keys(i)

            # Only run the test if all compiler ID's match
            if 'compilers' in i:
                for lang, id_list in i['compilers'].items():
                    if lang not in compiler_id_map or compiler_id_map[lang] not in id_list:
                        skip = True
                        break

            # Add an empty matrix entry
            if i['val'] is None:
                tmp_opts += [(None, skip, skip_expected)]
                continue

            tmp_opts += [('{}={}'.format(key, i['val']), skip, skip_expected)]

        if opt_list:
            new_opt_list = []
            for i in opt_list:
                for j in tmp_opts:
                    new_opt_list += [[*i, j]]
            opt_list = new_opt_list
        else:
            opt_list = [[x] for x in tmp_opts]

    # Exclude specific configurations
    if 'exclude' in matrix:
        assert isinstance(matrix['exclude'], list)
        new_opt_list = []
        for i in opt_list:
            exclude = False
            opt_names = [x[0] for x in i]
            for j in matrix['exclude']:
                ex_list = [f'{k}={v}' for k, v in j.items()]
                if all([x in opt_names for x in ex_list]):
                    exclude = True
                    break

            if not exclude:
                new_opt_list += [i]

        opt_list = new_opt_list

    for i in opt_list:
        name = ' '.join([x[0] for x in i if x[0] is not None])
        opts = ['-D' + x[0] for x in i if x[0] is not None]
        skip = any([x[1] for x in i])
        skip_expected = any([x[2] for x in i])
        test = TestDef(t.path, name, opts, skip or t.skip)
        test.env.update(env)
        test.installed_files = installed
        test.do_not_set_opts = do_not_set_opts
        test.stdout = stdout
        test.skip_expected = skip_expected or t.skip_expected
        all_tests.append(test)

    return all_tests


def gather_tests(testdir: Path, stdout_mandatory: bool, only: T.List[str]) -> T.List[TestDef]:
    all_tests: T.List[TestDef] = []
    for t in testdir.iterdir():
        # Filter non-tests files (dot files, etc)
        if not t.is_dir() or t.name.startswith('.'):
            continue
        if only and not any(t.name.startswith(prefix) for prefix in only):
            continue
        test_def = TestDef(t, None, [])
        all_tests.extend(load_test_json(test_def, stdout_mandatory))
    return sorted(all_tests)


def have_d_compiler() -> bool:
    if shutil.which("ldc2"):
        return True
    elif shutil.which("ldc"):
        return True
    elif shutil.which("gdc"):
        return True
    elif shutil.which("dmd"):
        # The Windows installer sometimes produces a DMD install
        # that exists but segfaults every time the compiler is run.
        # Don't know why. Don't know how to fix. Skip in this case.
        cp = subprocess.run(['dmd', '--version'],
                            capture_output=True)
        if cp.stdout == b'':
            return False
        return True
    return False

def have_objc_compiler(use_tmp: bool) -> bool:
    with TemporaryDirectoryWinProof(prefix='b ', dir=None if use_tmp else '.') as build_dir:
        env = environment.Environment(None, build_dir, get_fake_options('/'))
        try:
            objc_comp = detect_objc_compiler(env, MachineChoice.HOST)
        except mesonlib.MesonException:
            return False
        if not objc_comp:
            return False
        env.coredata.process_new_compiler('objc', objc_comp, env)
        try:
            objc_comp.sanity_check(env.get_scratch_dir(), env)
        except mesonlib.MesonException:
            return False
    return True

def have_objcpp_compiler(use_tmp: bool) -> bool:
    with TemporaryDirectoryWinProof(prefix='b ', dir=None if use_tmp else '.') as build_dir:
        env = environment.Environment(None, build_dir, get_fake_options('/'))
        try:
            objcpp_comp = detect_objcpp_compiler(env, MachineChoice.HOST)
        except mesonlib.MesonException:
            return False
        if not objcpp_comp:
            return False
        env.coredata.process_new_compiler('objcpp', objcpp_comp, env)
        try:
            objcpp_comp.sanity_check(env.get_scratch_dir(), env)
        except mesonlib.MesonException:
            return False
    return True

def have_java() -> bool:
    if shutil.which('javac') and shutil.which('java'):
        return True
    return False

def skip_dont_care(t: TestDef) -> bool:
    # Everything is optional when not running on CI
    if not under_ci:
        return True

    # Non-frameworks test are allowed to determine their own skipping under CI (currently)
    if not t.category.endswith('frameworks'):
        return True

    if mesonlib.is_osx() and '6 gettext' in str(t.path):
        return True

    return False

def skip_csharp(backend: Backend) -> bool:
    if backend is not Backend.ninja:
        return True
    if not shutil.which('resgen'):
        return True
    if shutil.which('mcs'):
        return False
    if shutil.which('csc'):
        # Only support VS2017 for now. Earlier versions fail
        # under CI in mysterious ways.
        try:
            stdo = subprocess.check_output(['csc', '/version'])
        except subprocess.CalledProcessError:
            return True
        # Having incrementing version numbers would be too easy.
        # Microsoft reset the versioning back to 1.0 (from 4.x)
        # when they got the Roslyn based compiler. Thus there
        # is NO WAY to reliably do version number comparisons.
        # Only support the version that ships with VS2017.
        return not stdo.startswith(b'2.')
    return True

# In Azure some setups have a broken rustc that will error out
# on all compilation attempts.

def has_broken_rustc() -> bool:
    dirname = Path('brokenrusttest')
    if dirname.exists():
        mesonlib.windows_proof_rmtree(dirname.as_posix())
    dirname.mkdir()
    sanity_file = dirname / 'sanity.rs'
    sanity_file.write_text('fn main() {\n}\n', encoding='utf-8')
    pc = subprocess.run(['rustc', '-o', 'sanity.exe', 'sanity.rs'],
                        cwd=dirname.as_posix(),
                        stdout = subprocess.DEVNULL,
                        stderr = subprocess.DEVNULL)
    mesonlib.windows_proof_rmtree(dirname.as_posix())
    return pc.returncode != 0

def should_skip_rust(backend: Backend) -> bool:
    if not shutil.which('rustc'):
        return True
    if backend is not Backend.ninja:
        return True
    if mesonlib.is_windows():
        if has_broken_rustc():
            return True
    return False

def detect_tests_to_run(only: T.Dict[str, T.List[str]], use_tmp: bool) -> T.List[T.Tuple[str, T.List[TestDef], bool]]:
    """
    Parameters
    ----------
    only: dict of categories and list of test cases, optional
        specify names of tests to run

    Returns
    -------
    gathered_tests: list of tuple of str, list of TestDef, bool
        tests to run
    """

    skip_fortran = not(shutil.which('gfortran') or
                       shutil.which('flang') or
                       shutil.which('pgfortran') or
                       shutil.which('nagfor') or
                       shutil.which('ifort'))

    class TestCategory:
        def __init__(self, category: str, subdir: str, skip: bool = False, stdout_mandatory: bool = False):
            self.category = category                  # category name
            self.subdir = subdir                      # subdirectory
            self.skip = skip                          # skip condition
            self.stdout_mandatory = stdout_mandatory  # expected stdout is mandatory for tests in this category

    all_tests = [
        TestCategory('cmake', 'cmake', not shutil.which('cmake') or (os.environ.get('compiler') == 'msvc2015' and under_ci) or (os.environ.get('MESON_CI_JOBNAME') == 'linux-bionic-gcc')),
        TestCategory('common', 'common'),
        TestCategory('native', 'native'),
        TestCategory('warning-meson', 'warning', stdout_mandatory=True),
        TestCategory('failing-meson', 'failing', stdout_mandatory=True),
        TestCategory('failing-build', 'failing build'),
        TestCategory('failing-test',  'failing test'),
        TestCategory('keyval', 'keyval'),
        TestCategory('platform-osx', 'osx', not mesonlib.is_osx()),
        TestCategory('platform-windows', 'windows', not mesonlib.is_windows() and not mesonlib.is_cygwin()),
        TestCategory('platform-linux', 'linuxlike', mesonlib.is_osx() or mesonlib.is_windows()),
        TestCategory('java', 'java', backend is not Backend.ninja or mesonlib.is_osx() or not have_java()),
        TestCategory('C#', 'csharp', skip_csharp(backend)),
        TestCategory('vala', 'vala', backend is not Backend.ninja or not shutil.which(os.environ.get('VALAC', 'valac'))),
        TestCategory('cython', 'cython', backend is not Backend.ninja or not shutil.which(os.environ.get('CYTHON', 'cython'))),
        TestCategory('rust', 'rust', should_skip_rust(backend)),
        TestCategory('d', 'd', backend is not Backend.ninja or not have_d_compiler()),
        TestCategory('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler(options.use_tmpdir)),
        TestCategory('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler(options.use_tmpdir)),
        TestCategory('fortran', 'fortran', skip_fortran or backend != Backend.ninja),
        TestCategory('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')),
        # CUDA tests on Windows: use Ninja backend:  python run_project_tests.py --only cuda --backend ninja
        TestCategory('cuda', 'cuda', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('nvcc')),
        TestCategory('python3', 'python3', backend is not Backend.ninja),
        TestCategory('python', 'python'),
        TestCategory('fpga', 'fpga', shutil.which('yosys') is None),
        TestCategory('frameworks', 'frameworks'),
        TestCategory('nasm', 'nasm'),
        TestCategory('wasm', 'wasm', shutil.which('emcc') is None or backend is not Backend.ninja),
    ]

    categories = [t.category for t in all_tests]
    assert categories == ALL_TESTS, 'argparse("--only", choices=ALL_TESTS) need to be updated to match all_tests categories'

    if only:
        for key in only.keys():
            assert key in categories, f'key `{key}` is not a recognized category'
        all_tests = [t for t in all_tests if t.category in only.keys()]

    gathered_tests = [(t.category, gather_tests(Path('test cases', t.subdir), t.stdout_mandatory, only[t.category]), t.skip) for t in all_tests]
    return gathered_tests

def run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
              log_name_base: str,
              failfast: bool,
              extra_args: T.List[str],
              use_tmp: bool,
              num_workers: int) -> T.Tuple[int, int, int]:
    txtname = log_name_base + '.txt'
    with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf:
        return _run_tests(all_tests, log_name_base, failfast, extra_args, use_tmp, num_workers, lf)

class TestStatus(Enum):
    OK = normal_green(' [SUCCESS] ')
    SKIP = yellow(' [SKIPPED] ')
    ERROR = red('  [ERROR]  ')
    UNEXSKIP = red('[UNEXSKIP] ')
    UNEXRUN = red(' [UNEXRUN] ')
    CANCELED = cyan('[CANCELED] ')
    RUNNING = blue(' [RUNNING] ')  # Should never be actually printed
    LOG = bold('   [LOG]   ')      # Should never be actually printed

def default_print(*args: mlog.TV_Loggable, sep: str = ' ') -> None:
    print(*args, sep=sep)

safe_print = default_print

class TestRunFuture:
    def __init__(self, name: str, testdef: TestDef, future: T.Optional['Future[T.Optional[TestResult]]']) -> None:
        super().__init__()
        self.name = name
        self.testdef = testdef
        self.future = future
        self.status = TestStatus.RUNNING if self.future is not None else TestStatus.SKIP

    @property
    def result(self) -> T.Optional[TestResult]:
        return self.future.result() if self.future else None

    def log(self) -> None:
        without_install = '' if install_commands else '(without install)'
        safe_print(self.status.value, without_install, *self.testdef.display_name())

    def update_log(self, new_status: TestStatus) -> None:
        self.status = new_status
        self.log()

    def cancel(self) -> None:
        if self.future is not None and self.future.cancel():
            self.status = TestStatus.CANCELED

class LogRunFuture:
    def __init__(self, msgs: mlog.TV_LoggableList) -> None:
        self.msgs = msgs
        self.status = TestStatus.LOG

    def log(self) -> None:
        safe_print(*self.msgs, sep='')

    def cancel(self) -> None:
        pass

RunFutureUnion = T.Union[TestRunFuture, LogRunFuture]

def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
               log_name_base: str,
               failfast: bool,
               extra_args: T.List[str],
               use_tmp: bool,
               num_workers: int,
               logfile: T.TextIO) -> T.Tuple[int, int, int]:
    global stop, host_c_compiler
    xmlname = log_name_base + '.xml'
    junit_root = ET.Element('testsuites')
    conf_time:  float = 0
    build_time: float = 0
    test_time:  float = 0
    passing_tests = 0
    failing_tests = 0
    skipped_tests = 0

    print(f'\nRunning tests with {num_workers} workers')

    # Pack the global state
    state = (compile_commands, clean_commands, test_commands, install_commands, uninstall_commands, backend, backend_flags, host_c_compiler)
    executor = ProcessPoolExecutor(max_workers=num_workers)

    futures: T.List[RunFutureUnion] = []

    # First, collect and start all tests and also queue log messages
    for name, test_cases, skipped in all_tests:
        current_suite = ET.SubElement(junit_root, 'testsuite', {'name': name, 'tests': str(len(test_cases))})
        if skipped:
            futures += [LogRunFuture(['\n', bold(f'Not running {name} tests.'), '\n'])]
        else:
            futures += [LogRunFuture(['\n', bold(f'Running {name} tests.'), '\n'])]

        for t in test_cases:
            # Jenkins screws us over by automatically sorting test cases by name
            # and getting it wrong by not doing logical number sorting.
            (testnum, testbase) = t.path.name.split(' ', 1)
            testname = '%.3d %s' % (int(testnum), testbase)
            if t.name:
                testname += f' ({t.name})'
            should_fail = ''
            suite_args = []
            if name.startswith('failing'):
                should_fail = name.split('failing-')[1]
            if name.startswith('warning'):
                suite_args = ['--fatal-meson-warnings']
                should_fail = name.split('warning-')[1]

            if skipped or t.skip:
                futures += [TestRunFuture(testname, t, None)]
                continue
            result_future = executor.submit(run_test, t, extra_args + suite_args + t.args, should_fail, use_tmp, state=state)
            futures += [TestRunFuture(testname, t, result_future)]

    # Ensure we only cancel once
    tests_canceled = False

    # Optionally enable the tqdm progress bar
    global safe_print
    futures_iter: T.Iterable[RunFutureUnion] = futures
    try:
        from tqdm import tqdm
        futures_iter = tqdm(futures, desc='Running tests', unit='test')

        def tqdm_print(*args: mlog.TV_Loggable, sep: str = ' ') -> None:
            tqdm.write(sep.join([str(x) for x in args]))

        safe_print = tqdm_print
    except ImportError:
        pass

    # Wait and handle the test results and print the stored log output
    for f in futures_iter:
        # Just a log entry to print something to stdout
        sys.stdout.flush()
        if isinstance(f, LogRunFuture):
            f.log()
            continue

        # Actual Test run
        testname = f.name
        t        = f.testdef
        try:
            result = f.result
        except (CancelledError, KeyboardInterrupt):
            f.status = TestStatus.CANCELED

        if stop and not tests_canceled:
            num_running = sum(1 if f2.status is TestStatus.RUNNING  else 0 for f2 in futures)
            for f2 in futures:
                f2.cancel()
            executor.shutdown()
            num_canceled = sum(1 if f2.status is TestStatus.CANCELED else 0 for f2 in futures)
            safe_print(f'\nCanceled {num_canceled} out of {num_running} running tests.')
            safe_print(f'Finishing the remaining {num_running - num_canceled} tests.\n')
            tests_canceled = True

        # Handle canceled tests
        if f.status is TestStatus.CANCELED:
            f.log()
            continue

        # Handle skipped tests
        if result is None:
            # skipped due to skipped category skip or 'tools:' or 'skip_on_env:'
            is_skipped = True
            skip_as_expected = True
        else:
            # skipped due to test outputting 'MESON_SKIP_TEST'
            is_skipped = 'MESON_SKIP_TEST' in result.stdo
            if not skip_dont_care(t):
                skip_as_expected = (is_skipped == t.skip_expected)
            else:
                skip_as_expected = True

        if is_skipped:
            skipped_tests += 1

        if is_skipped and skip_as_expected:
            f.update_log(TestStatus.SKIP)
            current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, 'classname': t.category})
            ET.SubElement(current_test, 'skipped', {})
            continue

        if not skip_as_expected:
            failing_tests += 1
            if is_skipped:
                skip_msg = 'Test asked to be skipped, but was not expected to'
                status = TestStatus.UNEXSKIP
            else:
                skip_msg = 'Test ran, but was expected to be skipped'
                status = TestStatus.UNEXRUN
            result.msg = f"{skip_msg} for MESON_CI_JOBNAME '{ci_jobname}'"

            f.update_log(status)
            current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, 'classname': t.category})
            ET.SubElement(current_test, 'failure', {'message': result.msg})
            continue

        # Handle Failed tests
        if result.msg != '':
            f.update_log(TestStatus.ERROR)
            safe_print(bold('During:'), result.step.name)
            safe_print(bold('Reason:'), result.msg)
            failing_tests += 1
            # Append a visual separator for the different test cases
            cols = shutil.get_terminal_size((100, 20)).columns
            name_str = ' '.join([str(x) for x in f.testdef.display_name()])
            name_len = len(re.sub(r'\x1B[^m]+m', '', name_str))  # Do not count escape sequences
            left_w = (cols // 2) - (name_len // 2) - 1
            left_w = max(3, left_w)
            right_w = cols - left_w - name_len - 2
            right_w = max(3, right_w)
            failing_logs.append(f'\n\x1b[31m{"="*left_w}\x1b[0m {name_str} \x1b[31m{"="*right_w}\x1b[0m\n')
            if result.step == BuildStep.configure and result.mlog != no_meson_log_msg:
                # 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.
                failing_logs.append(result.mlog)
            elif under_ci:
                # Always print the complete meson log when running in
                # a CI. This helps debugging issues that only occur in
                # a hard to reproduce environment
                failing_logs.append(result.mlog)
                failing_logs.append(result.stdo)
            else:
                failing_logs.append(result.stdo)
            for cmd_res in result.cicmds:
                failing_logs.append(cmd_res)
            failing_logs.append(result.stde)
            if failfast:
                safe_print("Cancelling the rest of the tests")
                for f2 in futures:
                    f2.cancel()
        else:
            f.update_log(TestStatus.OK)
            passing_tests += 1
        conf_time += result.conftime
        build_time += result.buildtime
        test_time += result.testtime
        total_time = conf_time + build_time + test_time
        log_text_file(logfile, t.path, result)
        current_test = ET.SubElement(
            current_suite,
            'testcase',
            {'name': testname, 'classname': t.category, 'time': '%.3f' % total_time}
        )
        if result.msg != '':
            ET.SubElement(current_test, 'failure', {'message': result.msg})
        stdoel = ET.SubElement(current_test, 'system-out')
        stdoel.text = result.stdo
        stdeel = ET.SubElement(current_test, 'system-err')
        stdeel.text = result.stde

    # Reset, just in case
    safe_print = default_print

    print()
    print("Total configuration time: %.2fs" % conf_time)
    print("Total build time:         %.2fs" % build_time)
    print("Total test time:          %.2fs" % test_time)
    ET.ElementTree(element=junit_root).write(xmlname, xml_declaration=True, encoding='UTF-8')
    return passing_tests, failing_tests, skipped_tests

def check_meson_commands_work(use_tmpdir: bool, extra_args: T.List[str]) -> None:
    global backend, compile_commands, test_commands, install_commands
    testdir = PurePath('test cases', 'common', '1 trivial').as_posix()
    meson_commands = mesonlib.python_command + [get_meson_script()]
    with TemporaryDirectoryWinProof(prefix='b ', dir=None if use_tmpdir else '.') as build_dir:
        print('Checking that configuring works...')
        gen_cmd = meson_commands + [testdir, build_dir] + backend_flags + extra_args
        pc, o, e = Popen_safe(gen_cmd)
        if pc.returncode != 0:
            raise RuntimeError(f'Failed to configure {testdir!r}:\n{e}\n{o}')
        print('Checking that introspect works...')
        pc, o, e = Popen_safe(meson_commands + ['introspect', '--targets'], cwd=build_dir)
        json.loads(o)
        if pc.returncode != 0:
            raise RuntimeError(f'Failed to introspect --targets {testdir!r}:\n{e}\n{o}')
        print('Checking that building works...')
        dir_args = get_backend_args_for_dir(backend, build_dir)
        pc, o, e = Popen_safe(compile_commands + dir_args, cwd=build_dir)
        if pc.returncode != 0:
            raise RuntimeError(f'Failed to build {testdir!r}:\n{e}\n{o}')
        print('Checking that testing works...')
        pc, o, e = Popen_safe(test_commands, cwd=build_dir)
        if pc.returncode != 0:
            raise RuntimeError(f'Failed to test {testdir!r}:\n{e}\n{o}')
        if install_commands:
            print('Checking that installing works...')
            pc, o, e = Popen_safe(install_commands, cwd=build_dir)
            if pc.returncode != 0:
                raise RuntimeError(f'Failed to install {testdir!r}:\n{e}\n{o}')


def detect_system_compiler(options: 'CompilerArgumentType') -> None:
    global host_c_compiler, compiler_id_map

    fake_opts = get_fake_options('/')
    if options.cross_file:
        fake_opts.cross_file = [options.cross_file]
    if options.native_file:
        fake_opts.native_file = [options.native_file]

    env = environment.Environment(None, None, fake_opts)

    print_compilers(env, MachineChoice.HOST)
    if options.cross_file:
        print_compilers(env, MachineChoice.BUILD)

    for lang in sorted(compilers.all_languages):
        try:
            comp = compiler_from_language(env, lang, MachineChoice.HOST)
            # note compiler id for later use with test.json matrix
            compiler_id_map[lang] = comp.get_id()
        except mesonlib.MesonException:
            comp = None

        # note C compiler for later use by platform_fix_name()
        if lang == 'c':
            if comp:
                host_c_compiler = comp.get_id()
            else:
                raise RuntimeError("Could not find C compiler.")


def print_compilers(env: 'Environment', machine: MachineChoice) -> None:
    print()
    print(f'{machine.get_lower_case_name()} machine compilers')
    print()
    for lang in sorted(compilers.all_languages):
        try:
            comp = compiler_from_language(env, lang, machine)
            details = '{:<10} {} {}'.format('[' + comp.get_id() + ']', ' '.join(comp.get_exelist()), comp.get_version_string())
        except mesonlib.MesonException:
            details = '[not found]'
        print(f'{lang:<7}: {details}')

class ToolInfo(T.NamedTuple):
    tool: str
    args: T.List[str]
    regex: T.Pattern
    match_group: int

def print_tool_versions() -> None:
    tools: T.List[ToolInfo] = [
        ToolInfo(
            'ninja',
            ['--version'],
            re.compile(r'^([0-9]+(\.[0-9]+)*(-[a-z0-9]+)?)$'),
            1,
        ),
        ToolInfo(
            'cmake',
            ['--version'],
            re.compile(r'^cmake version ([0-9]+(\.[0-9]+)*(-[a-z0-9]+)?)$'),
            1,
        ),
        ToolInfo(
            'hotdoc',
            ['--version'],
            re.compile(r'^([0-9]+(\.[0-9]+)*(-[a-z0-9]+)?)$'),
            1,
        ),
    ]

    def get_version(t: ToolInfo) -> str:
        exe = shutil.which(t.tool)
        if not exe:
            return 'not found'

        args = [t.tool] + t.args
        pc, o, e = Popen_safe(args)
        if pc.returncode != 0:
            return f'{exe} (invalid {t.tool} executable)'
        for i in o.split('\n'):
            i = i.strip('\n\r\t ')
            m = t.regex.match(i)
            if m is not None:
                tool_vers_map[t.tool] = m.group(t.match_group)
                return '{} ({})'.format(exe, m.group(t.match_group))

        return f'{exe} (unknown)'

    print()
    print('tools')
    print()

    max_width = max([len(x.tool) for x in tools] + [7])
    for tool in tools:
        print('{0:<{2}}: {1}'.format(tool.tool, get_version(tool), max_width))
    print()

def clear_transitive_files() -> None:
    a = Path('test cases/common')
    for d in a.glob('*subproject subdir/subprojects/subsubsub*'):
        if d.is_dir():
            mesonlib.windows_proof_rmtree(str(d))
        else:
            mesonlib.windows_proof_rm(str(d))

if __name__ == '__main__':
    if under_ci and not ci_jobname:
        raise SystemExit('Running under CI but MESON_CI_JOBNAME is not set')

    setup_vsenv()

    try:
        # This fails in some CI environments for unknown reasons.
        num_workers = multiprocessing.cpu_count()
    except Exception as e:
        print('Could not determine number of CPUs due to the following reason:' + str(e))
        print('Defaulting to using only two processes')
        num_workers = 2

    parser = argparse.ArgumentParser(description="Run the test suite of Meson.")
    parser.add_argument('extra_args', nargs='*',
                        help='arguments that are passed directly to Meson (remember to have -- before these).')
    parser.add_argument('--backend', dest='backend', choices=backendlist)
    parser.add_argument('-j', dest='num_workers', type=int, default=num_workers,
                        help=f'Maximum number of parallel tests (default {num_workers})')
    parser.add_argument('--failfast', action='store_true',
                        help='Stop running if test case fails')
    parser.add_argument('--no-unittests', action='store_true',
                        help='Not used, only here to simplify run_tests.py')
    parser.add_argument('--only', default=[],
                        help='name of test(s) to run, in format "category[/name]" where category is one of: ' + ', '.join(ALL_TESTS), nargs='+')
    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.')
    options = T.cast('ArgumentType', parser.parse_args())

    if options.cross_file:
        options.extra_args += ['--cross-file', options.cross_file]
    if options.native_file:
        options.extra_args += ['--native-file', options.native_file]

    clear_transitive_files()

    print('Meson build system', meson_version, 'Project Tests')
    print('Using python', sys.version.split('\n')[0])
    if 'VSCMD_VER' in os.environ:
        print('VSCMD version', os.environ['VSCMD_VER'])
    setup_commands(options.backend)
    detect_system_compiler(options)
    print_tool_versions()
    script_dir = os.path.split(__file__)[0]
    if script_dir != '':
        os.chdir(script_dir)
    check_meson_commands_work(options.use_tmpdir, options.extra_args)
    only = collections.defaultdict(list)
    for i in options.only:
        try:
            cat, case = i.split('/')
            only[cat].append(case)
        except ValueError:
            only[i].append('')
    try:
        all_tests = detect_tests_to_run(only, options.use_tmpdir)
        res = run_tests(all_tests, 'meson-test-run', options.failfast, options.extra_args, options.use_tmpdir, options.num_workers)
        (passing_tests, failing_tests, skipped_tests) = res
    except StopException:
        pass
    print()
    print('Total passed tests: ', green(str(passing_tests)))
    print('Total failed tests: ', red(str(failing_tests)))
    print('Total skipped tests:', yellow(str(skipped_tests)))
    if failing_tests > 0:
        print('\nMesonlogs of failing tests\n')
        for l in failing_logs:
            try:
                print(l, '\n')
            except UnicodeError:
                print(l.encode('ascii', errors='replace').decode(), '\n')
    for name, dirs, _ in all_tests:
        dir_names = list({x.path.name for x in dirs})
        for k, g in itertools.groupby(dir_names, key=lambda x: x.split()[0]):
            tests = list(g)
            if len(tests) != 1:
                print('WARNING: The {} suite contains duplicate "{}" tests: "{}"'.format(name, k, '", "'.join(tests)))
    clear_transitive_files()
    raise SystemExit(failing_tests)
