#!/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
from mesonbuild.mlog import blue, bold, cyan, green, red, yellow, normal_green
from mesonbuild.coredata import backendlist, version as meson_version
from mesonbuild.mesonmain import setup_vsenv
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

    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

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'

        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 ['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 == 'implib' or self.typ == 'implibempty':
            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():
                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]]

        # 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
skip_scientific = under_ci and ('SKIP_SCIENTIFIC' in os.environ)
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: signal.Signals, 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 cahce
# 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 thest 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


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]

    # 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]]]

    # 'matrix; entry is present, so build multiple tests from matrix definition
    opt_list = []  # type: T.List[T.List[T.Tuple[str, 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]]
        for i in val:
            assert isinstance(i, dict)
            assert "val" in i
            skip = False

            # Skip the matrix entry if environment variable is present
            if 'skip_on_env' in i:
                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
            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)]
                continue

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

        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])
        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
        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'],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
        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 skippable(suite: str, test: str) -> bool:
    # Everything is optional when not running on CI
    if not under_ci:
        return True

    if not suite.endswith('frameworks'):
        return True

    # this test assumptions aren't valid for Windows paths
    if test.endswith('38 libdir must be inside prefix'):
        return True

    # gtk-doc test may be skipped, pending upstream fixes for spaces in
    # filenames landing in the distro used for CI
    if test.endswith('10 gtk-doc'):
        return True

    # NetCDF is not in the CI Docker image
    if test.endswith('netcdf'):
        return True

    # MSVC doesn't link with GFortran
    if test.endswith('14 fortran links c'):
        return True

    # Blocks are not supported on all compilers
    if test.endswith('29 blocks'):
        return True

    # Scientific libraries are skippable on certain systems
    # See the discussion here: https://github.com/mesonbuild/meson/pull/6562
    if any([x in test for x in ['17 mpi', '25 hdf5', '30 scalapack']]) and skip_scientific:
        return True

    # These create OS specific tests, and need to be skippable
    if any([x in test for x in ['16 sdl', '17 mpi']]):
        return True

    # We test cmake, and llvm-config. Some linux spins don't provide cmake or
    # don't provide either the static or shared llvm libraries (fedora and
    # opensuse only have the dynamic ones, for example).
    if test.endswith('15 llvm'):
        return True

    # This test breaks with gobject-introspection <= 1.58.1
    if test.endswith('34 gir static lib'):
        return True

    # Boost test should only be skipped for windows CI build matrix entries
    # which don't define BOOST_ROOT
    if test.endswith('1 boost'):
        if mesonlib.is_windows():
            return 'BOOST_ROOT' not in os.environ
        return False

    # Not all OSes have all of the methods for qt (qmake and pkg-config), don't
    # fail if that happens.
    #
    # On macOS we should have all of the requirements at all times.
    if test.endswith('4 qt'):
        return not mesonlib.is_osx()

    # Bindgen isn't available in all distros
    if test.endswith('12 bindgen'):
        return False

    # No frameworks test should be skipped on linux CI, as we expect all
    # prerequisites to be installed
    if mesonlib.is_linux():
        return False

    # Other framework tests are allowed to be skipped on other platforms
    return True

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() and 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('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)),
        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, 'key `{}` is not a recognized category'.format(key)
        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]  ')
    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

        # Acutal 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) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(t.category, t.path.as_posix()))):
            f.update_log(TestStatus.SKIP)
            current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, 'classname': t.category})
            ET.SubElement(current_test, 'skipped', {})
            skipped_tests += 1
            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 seperator 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

    with TemporaryDirectoryWinProof(prefix='b ', dir=None if options.use_tmpdir else '.') as build_dir:
        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, build_dir, 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 '{} (invalid {} executable)'.format(exe, t.tool)
        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__':
    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
    # Due to Ninja deficiency, almost 50% of build time
    # is spent waiting. Do something useful instead.
    #
    # Remove this once the following issue has been resolved:
    # https://github.com/mesonbuild/meson/pull/2082
    if not mesonlib.is_windows():  # twice as fast on Windows by *not* multiplying by 2.
        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)
