# Copyright 2016-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.

from mesonbuild.mesonlib.universal import windows_proof_rm
import subprocess
import re
import json
import tempfile
import textwrap
import os
import shutil
import platform
import pickle
import zipfile, tarfile
import sys
from unittest import mock, SkipTest, skipIf, skipUnless
from contextlib import contextmanager
from glob import glob
from pathlib import (PurePath, Path)
import typing as T

import mesonbuild.mlog
import mesonbuild.depfile
import mesonbuild.dependencies.base
import mesonbuild.dependencies.factory
import mesonbuild.envconfig
import mesonbuild.environment
import mesonbuild.coredata
import mesonbuild.modules.gnome
from mesonbuild.mesonlib import (
    BuildDirLock, MachineChoice, is_windows, is_osx, is_cygwin, is_dragonflybsd,
    is_sunos, windows_proof_rmtree, python_command, version_compare, split_args, quote_arg,
    relpath, is_linux, git, search_version, do_conf_file, do_conf_str, default_prefix,
    MesonException, EnvironmentException, OptionKey
)

from mesonbuild.compilers import (
    GnuCompiler, ClangCompiler, IntelGnuLikeCompiler, VisualStudioCCompiler,
    VisualStudioCPPCompiler, ClangClCCompiler, ClangClCPPCompiler,
    detect_static_linker, detect_c_compiler, compiler_from_language,
    detect_compiler_for
)

from mesonbuild.dependencies import PkgConfigDependency
from mesonbuild.build import Target, ConfigurationData, Executable, SharedLibrary, StaticLibrary
import mesonbuild.modules.pkgconfig
from mesonbuild.scripts import destdir_join

from mesonbuild.wrap.wrap import PackageDefinition, WrapException

from run_tests import (
    Backend, exe_suffix, get_fake_env, get_convincing_fake_env_and_cc
)

from .baseplatformtests import BasePlatformTests
from .helpers import *

@contextmanager
def temp_filename():
    '''A context manager which provides a filename to an empty temporary file.

    On exit the file will be deleted.
    '''

    fd, filename = tempfile.mkstemp()
    os.close(fd)
    try:
        yield filename
    finally:
        try:
            os.remove(filename)
        except OSError:
            pass

def _git_init(project_dir):
    # If a user has git configuration init.defaultBranch set we want to override that
    with tempfile.TemporaryDirectory() as d:
        out = git(['--version'], str(d))[1]
    if version_compare(search_version(out), '>= 2.28'):
        extra_cmd = ['--initial-branch', 'master']
    else:
        extra_cmd = []

    subprocess.check_call(['git', 'init'] + extra_cmd, cwd=project_dir, stdout=subprocess.DEVNULL)
    subprocess.check_call(['git', 'config',
                           'user.name', 'Author Person'], cwd=project_dir)
    subprocess.check_call(['git', 'config',
                           'user.email', 'teh_coderz@example.com'], cwd=project_dir)
    _git_add_all(project_dir)

def _git_add_all(project_dir):
    subprocess.check_call('git add *', cwd=project_dir, shell=True,
                          stdout=subprocess.DEVNULL)
    subprocess.check_call(['git', 'commit', '--no-gpg-sign', '-a', '-m', 'I am a project'], cwd=project_dir,
                          stdout=subprocess.DEVNULL)

class AllPlatformTests(BasePlatformTests):
    '''
    Tests that should run on all platforms
    '''

    def test_default_options_prefix(self):
        '''
        Tests that setting a prefix in default_options in project() works.
        Can't be an ordinary test because we pass --prefix to meson there.
        https://github.com/mesonbuild/meson/issues/1349
        '''
        testdir = os.path.join(self.common_test_dir, '87 default options')
        self.init(testdir, default_args=False, inprocess=True)
        opts = self.introspect('--buildoptions')
        for opt in opts:
            if opt['name'] == 'prefix':
                prefix = opt['value']
                break
        else:
            raise self.fail('Did not find option "prefix"')
        self.assertEqual(prefix, '/absoluteprefix')

    def test_do_conf_file_preserve_newlines(self):

        def conf_file(in_data, confdata):
            with temp_filename() as fin:
                with open(fin, 'wb') as fobj:
                    fobj.write(in_data.encode('utf-8'))
                with temp_filename() as fout:
                    do_conf_file(fin, fout, confdata, 'meson')
                    with open(fout, 'rb') as fobj:
                        return fobj.read().decode('utf-8')

        confdata = {'VAR': ('foo', 'bar')}
        self.assertEqual(conf_file('@VAR@\n@VAR@\n', confdata), 'foo\nfoo\n')
        self.assertEqual(conf_file('@VAR@\r\n@VAR@\r\n', confdata), 'foo\r\nfoo\r\n')

    def test_do_conf_file_by_format(self):
        def conf_str(in_data, confdata, vformat):
            (result, missing_variables, confdata_useless) = do_conf_str('configuration_file', in_data, confdata, variable_format = vformat)
            return '\n'.join(result)

        def check_formats(confdata, result):
            self.assertEqual(conf_str(['#mesondefine VAR'], confdata, 'meson'), result)
            self.assertEqual(conf_str(['#cmakedefine VAR ${VAR}'], confdata, 'cmake'), result)
            self.assertEqual(conf_str(['#cmakedefine VAR @VAR@'], confdata, 'cmake@'), result)

        confdata = ConfigurationData()
        # Key error as they do not exists
        check_formats(confdata, '/* #undef VAR */\n')

        # Check boolean
        confdata.values = {'VAR': (False, 'description')}
        check_formats(confdata, '#undef VAR\n')
        confdata.values = {'VAR': (True, 'description')}
        check_formats(confdata, '#define VAR\n')

        # Check string
        confdata.values = {'VAR': ('value', 'description')}
        check_formats(confdata, '#define VAR value\n')

        # Check integer
        confdata.values = {'VAR': (10, 'description')}
        check_formats(confdata, '#define VAR 10\n')

        # Check multiple string with cmake formats
        confdata.values = {'VAR': ('value', 'description')}
        self.assertEqual(conf_str(['#cmakedefine VAR xxx @VAR@ yyy @VAR@'], confdata, 'cmake@'), '#define VAR xxx value yyy value\n')
        self.assertEqual(conf_str(['#define VAR xxx @VAR@ yyy @VAR@'], confdata, 'cmake@'), '#define VAR xxx value yyy value')
        self.assertEqual(conf_str(['#cmakedefine VAR xxx ${VAR} yyy ${VAR}'], confdata, 'cmake'), '#define VAR xxx value yyy value\n')
        self.assertEqual(conf_str(['#define VAR xxx ${VAR} yyy ${VAR}'], confdata, 'cmake'), '#define VAR xxx value yyy value')

        # Handles meson format exceptions
        #   Unknown format
        self.assertRaises(MesonException, conf_str, ['#mesondefine VAR xxx'], confdata, 'unknown_format')
        #   More than 2 params in mesondefine
        self.assertRaises(MesonException, conf_str, ['#mesondefine VAR xxx'], confdata, 'meson')
        #   Mismatched line with format
        self.assertRaises(MesonException, conf_str, ['#cmakedefine VAR'], confdata, 'meson')
        self.assertRaises(MesonException, conf_str, ['#mesondefine VAR'], confdata, 'cmake')
        self.assertRaises(MesonException, conf_str, ['#mesondefine VAR'], confdata, 'cmake@')
        #   Dict value in confdata
        confdata.values = {'VAR': (['value'], 'description')}
        self.assertRaises(MesonException, conf_str, ['#mesondefine VAR'], confdata, 'meson')

    def test_absolute_prefix_libdir(self):
        '''
        Tests that setting absolute paths for --prefix and --libdir work. Can't
        be an ordinary test because these are set via the command-line.
        https://github.com/mesonbuild/meson/issues/1341
        https://github.com/mesonbuild/meson/issues/1345
        '''
        testdir = os.path.join(self.common_test_dir, '87 default options')
        # on Windows, /someabs is *not* an absolute path
        prefix = 'x:/someabs' if is_windows() else '/someabs'
        libdir = 'libdir'
        extra_args = ['--prefix=' + prefix,
                      # This can just be a relative path, but we want to test
                      # that passing this as an absolute path also works
                      '--libdir=' + prefix + '/' + libdir]
        self.init(testdir, extra_args=extra_args, default_args=False)
        opts = self.introspect('--buildoptions')
        for opt in opts:
            if opt['name'] == 'prefix':
                self.assertEqual(prefix, opt['value'])
            elif opt['name'] == 'libdir':
                self.assertEqual(libdir, opt['value'])

    def test_libdir_can_be_outside_prefix(self):
        '''
        Tests that libdir is allowed to be outside prefix.
        Must be a unit test for obvious reasons.
        '''
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        # libdir being inside prefix is ok
        if is_windows():
            args = ['--prefix', 'x:/opt', '--libdir', 'x:/opt/lib32']
        else:
            args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
        self.init(testdir, extra_args=args)
        self.wipe()
        # libdir not being inside prefix is ok too
        if is_windows():
            args = ['--prefix', 'x:/usr', '--libdir', 'x:/opt/lib32']
        else:
            args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
        self.init(testdir, extra_args=args)
        self.wipe()
        # libdir can be outside prefix even when set via mesonconf
        self.init(testdir)
        if is_windows():
            self.setconf('-Dlibdir=x:/opt', will_build=False)
        else:
            self.setconf('-Dlibdir=/opt', will_build=False)

    def test_prefix_dependent_defaults(self):
        '''
        Tests that configured directory paths are set to prefix dependent
        defaults.
        '''
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        expected = {
            '/opt': {'prefix': '/opt',
                     'bindir': 'bin', 'datadir': 'share', 'includedir': 'include',
                     'infodir': 'share/info',
                     'libexecdir': 'libexec', 'localedir': 'share/locale',
                     'localstatedir': 'var', 'mandir': 'share/man',
                     'sbindir': 'sbin', 'sharedstatedir': 'com',
                     'sysconfdir': 'etc'},
            '/usr': {'prefix': '/usr',
                     'bindir': 'bin', 'datadir': 'share', 'includedir': 'include',
                     'infodir': 'share/info',
                     'libexecdir': 'libexec', 'localedir': 'share/locale',
                     'localstatedir': '/var', 'mandir': 'share/man',
                     'sbindir': 'sbin', 'sharedstatedir': '/var/lib',
                     'sysconfdir': '/etc'},
            '/usr/local': {'prefix': '/usr/local',
                           'bindir': 'bin', 'datadir': 'share',
                           'includedir': 'include', 'infodir': 'share/info',
                           'libexecdir': 'libexec',
                           'localedir': 'share/locale',
                           'localstatedir': '/var/local', 'mandir': 'share/man',
                           'sbindir': 'sbin', 'sharedstatedir': '/var/local/lib',
                           'sysconfdir': 'etc'},
            # N.B. We don't check 'libdir' as it's platform dependent, see
            # default_libdir():
        }

        if default_prefix() == '/usr/local':
            expected[None] = expected['/usr/local']

        for prefix in expected:
            args = []
            if prefix:
                args += ['--prefix', prefix]
            self.init(testdir, extra_args=args, default_args=False)
            opts = self.introspect('--buildoptions')
            for opt in opts:
                name = opt['name']
                value = opt['value']
                if name in expected[prefix]:
                    self.assertEqual(value, expected[prefix][name])
            self.wipe()

    def test_default_options_prefix_dependent_defaults(self):
        '''
        Tests that setting a prefix in default_options in project() sets prefix
        dependent defaults for other options, and that those defaults can
        be overridden in default_options or by the command line.
        '''
        testdir = os.path.join(self.common_test_dir, '163 default options prefix dependent defaults')
        expected = {
            '':
            {'prefix':         '/usr',
             'sysconfdir':     '/etc',
             'localstatedir':  '/var',
             'sharedstatedir': '/sharedstate'},
            '--prefix=/usr':
            {'prefix':         '/usr',
             'sysconfdir':     '/etc',
             'localstatedir':  '/var',
             'sharedstatedir': '/sharedstate'},
            '--sharedstatedir=/var/state':
            {'prefix':         '/usr',
             'sysconfdir':     '/etc',
             'localstatedir':  '/var',
             'sharedstatedir': '/var/state'},
            '--sharedstatedir=/var/state --prefix=/usr --sysconfdir=sysconf':
            {'prefix':         '/usr',
             'sysconfdir':     'sysconf',
             'localstatedir':  '/var',
             'sharedstatedir': '/var/state'},
        }
        for args in expected:
            self.init(testdir, extra_args=args.split(), default_args=False)
            opts = self.introspect('--buildoptions')
            for opt in opts:
                name = opt['name']
                value = opt['value']
                if name in expected[args]:
                    self.assertEqual(value, expected[args][name])
            self.wipe()

    def test_clike_get_library_dirs(self):
        env = get_fake_env()
        cc = detect_c_compiler(env, MachineChoice.HOST)
        for d in cc.get_library_dirs(env):
            self.assertTrue(os.path.exists(d))
            self.assertTrue(os.path.isdir(d))
            self.assertTrue(os.path.isabs(d))

    def test_static_library_overwrite(self):
        '''
        Tests that static libraries are never appended to, always overwritten.
        Has to be a unit test because this involves building a project,
        reconfiguring, and building it again so that `ar` is run twice on the
        same static library.
        https://github.com/mesonbuild/meson/issues/1355
        '''
        testdir = os.path.join(self.common_test_dir, '3 static')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        static_linker = detect_static_linker(env, cc)
        if is_windows():
            raise SkipTest('https://github.com/mesonbuild/meson/issues/1526')
        if not isinstance(static_linker, mesonbuild.linkers.ArLinker):
            raise SkipTest('static linker is not `ar`')
        # Configure
        self.init(testdir)
        # Get name of static library
        targets = self.introspect('--targets')
        self.assertEqual(len(targets), 1)
        libname = targets[0]['filename'][0]
        # Build and get contents of static library
        self.build()
        before = self._run(['ar', 't', os.path.join(self.builddir, libname)]).split()
        # Filter out non-object-file contents
        before = [f for f in before if f.endswith(('.o', '.obj'))]
        # Static library should contain only one object
        self.assertEqual(len(before), 1, msg=before)
        # Change the source to be built into the static library
        self.setconf('-Dsource=libfile2.c')
        self.build()
        after = self._run(['ar', 't', os.path.join(self.builddir, libname)]).split()
        # Filter out non-object-file contents
        after = [f for f in after if f.endswith(('.o', '.obj'))]
        # Static library should contain only one object
        self.assertEqual(len(after), 1, msg=after)
        # and the object must have changed
        self.assertNotEqual(before, after)

    def test_static_compile_order(self):
        '''
        Test that the order of files in a compiler command-line while compiling
        and linking statically is deterministic. This can't be an ordinary test
        case because we need to inspect the compiler database.
        https://github.com/mesonbuild/meson/pull/951
        '''
        testdir = os.path.join(self.common_test_dir, '5 linkstatic')
        self.init(testdir)
        compdb = self.get_compdb()
        # Rules will get written out in this order
        self.assertTrue(compdb[0]['file'].endswith("libfile.c"))
        self.assertTrue(compdb[1]['file'].endswith("libfile2.c"))
        self.assertTrue(compdb[2]['file'].endswith("libfile3.c"))
        self.assertTrue(compdb[3]['file'].endswith("libfile4.c"))
        # FIXME: We don't have access to the linker command

    def test_run_target_files_path(self):
        '''
        Test that run_targets are run from the correct directory
        https://github.com/mesonbuild/meson/issues/957
        '''
        testdir = os.path.join(self.common_test_dir, '51 run target')
        self.init(testdir)
        self.run_target('check_exists')
        self.run_target('check-env')
        self.run_target('check-env-ct')

    def test_run_target_subdir(self):
        '''
        Test that run_targets are run from the correct directory
        https://github.com/mesonbuild/meson/issues/957
        '''
        testdir = os.path.join(self.common_test_dir, '51 run target')
        self.init(testdir)
        self.run_target('textprinter')

    def test_install_introspection(self):
        '''
        Tests that the Meson introspection API exposes install filenames correctly
        https://github.com/mesonbuild/meson/issues/829
        '''
        if self.backend is not Backend.ninja:
            raise SkipTest(f'{self.backend.name!r} backend can\'t install files')
        testdir = os.path.join(self.common_test_dir, '8 install')
        self.init(testdir)
        intro = self.introspect('--targets')
        if intro[0]['type'] == 'executable':
            intro = intro[::-1]
        self.assertPathListEqual(intro[0]['install_filename'], ['/usr/lib/libstat.a'])
        self.assertPathListEqual(intro[1]['install_filename'], ['/usr/bin/prog' + exe_suffix])

    def test_install_subdir_introspection(self):
        '''
        Test that the Meson introspection API also contains subdir install information
        https://github.com/mesonbuild/meson/issues/5556
        '''
        testdir = os.path.join(self.common_test_dir, '59 install subdir')
        self.init(testdir)
        intro = self.introspect('--installed')
        expected = {
            'sub2': 'share/sub2',
            'subdir/sub1': 'share/sub1',
            'subdir/sub_elided': 'share',
            'sub1': 'share/sub1',
            'sub/sub1': 'share/sub1',
            'sub_elided': 'share',
            'nested_elided/sub': 'share',
            'new_directory': 'share/new_directory',
        }

        self.assertEqual(len(intro), len(expected))

        # Convert expected to PurePath
        expected_converted = {PurePath(os.path.join(testdir, key)): PurePath(os.path.join(self.prefix, val)) for key, val in expected.items()}
        intro_converted = {PurePath(key): PurePath(val) for key, val in intro.items()}

        for src, dst in expected_converted.items():
            self.assertIn(src, intro_converted)
            self.assertEqual(dst, intro_converted[src])

    def test_install_introspection_multiple_outputs(self):
        '''
        Tests that the Meson introspection API exposes multiple install filenames correctly without crashing
        https://github.com/mesonbuild/meson/pull/4555

        Reverted to the first file only because of https://github.com/mesonbuild/meson/pull/4547#discussion_r244173438
        TODO Change the format to a list officially in a followup PR
        '''
        if self.backend is not Backend.ninja:
            raise SkipTest(f'{self.backend.name!r} backend can\'t install files')
        testdir = os.path.join(self.common_test_dir, '140 custom target multiple outputs')
        self.init(testdir)
        intro = self.introspect('--targets')
        if intro[0]['type'] == 'executable':
            intro = intro[::-1]
        self.assertPathListEqual(intro[0]['install_filename'], ['/usr/include/diff.h', '/usr/bin/diff.sh'])
        self.assertPathListEqual(intro[1]['install_filename'], ['/opt/same.h', '/opt/same.sh'])
        self.assertPathListEqual(intro[2]['install_filename'], ['/usr/include/first.h', None])
        self.assertPathListEqual(intro[3]['install_filename'], [None, '/usr/bin/second.sh'])

    def read_install_logs(self):
        # Find logged files and directories
        with Path(self.builddir, 'meson-logs', 'install-log.txt').open(encoding='utf-8') as f:
            return list(map(lambda l: Path(l.strip()),
                              filter(lambda l: not l.startswith('#'),
                                     f.readlines())))

    def test_install_log_content(self):
        '''
        Tests that the install-log.txt is consistent with the installed files and directories.
        Specifically checks that the log file only contains one entry per file/directory.
        https://github.com/mesonbuild/meson/issues/4499
        '''
        testdir = os.path.join(self.common_test_dir, '59 install subdir')
        self.init(testdir)
        self.install()
        installpath = Path(self.installdir)
        # Find installed files and directories
        expected = {installpath: 0}
        for name in installpath.rglob('*'):
            expected[name] = 0
        logged = self.read_install_logs()
        for name in logged:
            self.assertTrue(name in expected, f'Log contains extra entry {name}')
            expected[name] += 1

        for name, count in expected.items():
            self.assertGreater(count, 0, f'Log is missing entry for {name}')
            self.assertLess(count, 2, f'Log has multiple entries for {name}')

        # Verify that with --dry-run we obtain the same logs but with nothing
        # actually installed
        windows_proof_rmtree(self.installdir)
        self._run(self.meson_command + ['install', '--dry-run', '--destdir', self.installdir], workdir=self.builddir)
        self.assertEqual(logged, self.read_install_logs())
        self.assertFalse(os.path.exists(self.installdir))

        # If destdir is relative to build directory it should install
        # exactly the same files.
        rel_installpath = os.path.relpath(self.installdir, self.builddir)
        self._run(self.meson_command + ['install', '--dry-run', '--destdir', rel_installpath, '-C', self.builddir])
        self.assertEqual(logged, self.read_install_logs())

    def test_uninstall(self):
        exename = os.path.join(self.installdir, 'usr/bin/prog' + exe_suffix)
        dirname = os.path.join(self.installdir, 'usr/share/dir')
        testdir = os.path.join(self.common_test_dir, '8 install')
        self.init(testdir)
        self.assertPathDoesNotExist(exename)
        self.install()
        self.assertPathExists(exename)
        self.uninstall()
        self.assertPathDoesNotExist(exename)
        self.assertPathDoesNotExist(dirname)

    def test_forcefallback(self):
        testdir = os.path.join(self.unit_test_dir, '31 forcefallback')
        self.init(testdir, extra_args=['--wrap-mode=forcefallback'])
        self.build()
        self.run_tests()

    def test_implicit_forcefallback(self):
        testdir = os.path.join(self.unit_test_dir, '95 implicit force fallback')
        with self.assertRaises(subprocess.CalledProcessError):
            self.init(testdir)
        self.init(testdir, extra_args=['--wrap-mode=forcefallback'])
        self.new_builddir()
        self.init(testdir, extra_args=['--force-fallback-for=something'])

    def test_nopromote(self):
        testdir = os.path.join(self.common_test_dir, '98 subproject subdir')
        with self.assertRaises(subprocess.CalledProcessError) as cm:
            self.init(testdir, extra_args=['--wrap-mode=nopromote'])
        self.assertIn('dependency subsub found: NO', cm.exception.stdout)

    def test_force_fallback_for(self):
        testdir = os.path.join(self.unit_test_dir, '31 forcefallback')
        self.init(testdir, extra_args=['--force-fallback-for=zlib,foo'])
        self.build()
        self.run_tests()

    def test_force_fallback_for_nofallback(self):
        testdir = os.path.join(self.unit_test_dir, '31 forcefallback')
        self.init(testdir, extra_args=['--force-fallback-for=zlib,foo', '--wrap-mode=nofallback'])
        self.build()
        self.run_tests()

    def test_testrepeat(self):
        testdir = os.path.join(self.common_test_dir, '206 tap tests')
        self.init(testdir)
        self.build()
        self._run(self.mtest_command + ['--repeat=2'])

    def test_verbose(self):
        testdir = os.path.join(self.common_test_dir, '206 tap tests')
        self.init(testdir)
        self.build()
        out = self._run(self.mtest_command + ['--suite', 'verbose'])
        self.assertIn('1/1 subtest 1', out)

    def test_testsetups(self):
        if not shutil.which('valgrind'):
            raise SkipTest('Valgrind not installed.')
        testdir = os.path.join(self.unit_test_dir, '2 testsetups')
        self.init(testdir)
        self.build()
        # Run tests without setup
        self.run_tests()
        with open(os.path.join(self.logdir, 'testlog.txt'), encoding='utf-8') as f:
            basic_log = f.read()
        # Run buggy test with setup that has env that will make it fail
        self.assertRaises(subprocess.CalledProcessError,
                          self._run, self.mtest_command + ['--setup=valgrind'])
        with open(os.path.join(self.logdir, 'testlog-valgrind.txt'), encoding='utf-8') as f:
            vg_log = f.read()
        self.assertNotIn('TEST_ENV is set', basic_log)
        self.assertNotIn('Memcheck', basic_log)
        self.assertIn('TEST_ENV is set', vg_log)
        self.assertIn('Memcheck', vg_log)
        # Run buggy test with setup without env that will pass
        self._run(self.mtest_command + ['--setup=wrapper'])
        # Setup with no properties works
        self._run(self.mtest_command + ['--setup=empty'])
        # Setup with only env works
        self._run(self.mtest_command + ['--setup=onlyenv'])
        self._run(self.mtest_command + ['--setup=onlyenv2'])
        self._run(self.mtest_command + ['--setup=onlyenv3'])
        # Setup with only a timeout works
        self._run(self.mtest_command + ['--setup=timeout'])
        # Setup that does not define a wrapper works with --wrapper
        self._run(self.mtest_command + ['--setup=timeout', '--wrapper', shutil.which('valgrind')])
        # Setup that skips test works
        self._run(self.mtest_command + ['--setup=good'])
        with open(os.path.join(self.logdir, 'testlog-good.txt'), encoding='utf-8') as f:
            exclude_suites_log = f.read()
        self.assertNotIn('buggy', exclude_suites_log)
        # --suite overrides add_test_setup(xclude_suites)
        self._run(self.mtest_command + ['--setup=good', '--suite', 'buggy'])
        with open(os.path.join(self.logdir, 'testlog-good.txt'), encoding='utf-8') as f:
            include_suites_log = f.read()
        self.assertIn('buggy', include_suites_log)

    def test_testsetup_selection(self):
        testdir = os.path.join(self.unit_test_dir, '14 testsetup selection')
        self.init(testdir)
        self.build()

        # Run tests without setup
        self.run_tests()

        self.assertRaises(subprocess.CalledProcessError, self._run, self.mtest_command + ['--setup=missingfromfoo'])
        self._run(self.mtest_command + ['--setup=missingfromfoo', '--no-suite=foo:'])

        self._run(self.mtest_command + ['--setup=worksforall'])
        self._run(self.mtest_command + ['--setup=main:worksforall'])

        self.assertRaises(subprocess.CalledProcessError, self._run,
                          self.mtest_command + ['--setup=onlyinbar'])
        self.assertRaises(subprocess.CalledProcessError, self._run,
                          self.mtest_command + ['--setup=onlyinbar', '--no-suite=main:'])
        self._run(self.mtest_command + ['--setup=onlyinbar', '--no-suite=main:', '--no-suite=foo:'])
        self._run(self.mtest_command + ['--setup=bar:onlyinbar'])
        self.assertRaises(subprocess.CalledProcessError, self._run,
                          self.mtest_command + ['--setup=foo:onlyinbar'])
        self.assertRaises(subprocess.CalledProcessError, self._run,
                          self.mtest_command + ['--setup=main:onlyinbar'])

    def test_testsetup_default(self):
        testdir = os.path.join(self.unit_test_dir, '48 testsetup default')
        self.init(testdir)
        self.build()

        # Run tests without --setup will cause the default setup to be used
        self.run_tests()
        with open(os.path.join(self.logdir, 'testlog.txt'), encoding='utf-8') as f:
            default_log = f.read()

        # Run tests with explicitly using the same setup that is set as default
        self._run(self.mtest_command + ['--setup=mydefault'])
        with open(os.path.join(self.logdir, 'testlog-mydefault.txt'), encoding='utf-8') as f:
            mydefault_log = f.read()

        # Run tests with another setup
        self._run(self.mtest_command + ['--setup=other'])
        with open(os.path.join(self.logdir, 'testlog-other.txt'), encoding='utf-8') as f:
            other_log = f.read()

        self.assertIn('ENV_A is 1', default_log)
        self.assertIn('ENV_B is 2', default_log)
        self.assertIn('ENV_C is 2', default_log)

        self.assertIn('ENV_A is 1', mydefault_log)
        self.assertIn('ENV_B is 2', mydefault_log)
        self.assertIn('ENV_C is 2', mydefault_log)

        self.assertIn('ENV_A is 1', other_log)
        self.assertIn('ENV_B is 3', other_log)
        self.assertIn('ENV_C is 2', other_log)

    def assertFailedTestCount(self, failure_count, command):
        try:
            self._run(command)
            self.assertEqual(0, failure_count, 'Expected %d tests to fail.' % failure_count)
        except subprocess.CalledProcessError as e:
            self.assertEqual(e.returncode, failure_count)

    def test_suite_selection(self):
        testdir = os.path.join(self.unit_test_dir, '4 suite selection')
        self.init(testdir)
        self.build()

        self.assertFailedTestCount(4, self.mtest_command)

        self.assertFailedTestCount(0, self.mtest_command + ['--suite', ':success'])
        self.assertFailedTestCount(3, self.mtest_command + ['--suite', ':fail'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', ':success'])
        self.assertFailedTestCount(1, self.mtest_command + ['--no-suite', ':fail'])

        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'mainprj'])
        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc'])
        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail'])
        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjmix'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'mainprj'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjfail'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjmix'])

        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'mainprj:fail'])
        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'mainprj:success'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'mainprj:fail'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'mainprj:success'])

        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail:fail'])
        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjfail:success'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjfail:fail'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjfail:success'])

        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc:fail'])
        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc:success'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc:fail'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc:success'])

        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjmix:fail'])
        self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjmix:success'])
        self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjmix:fail'])
        self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjmix:success'])

        self.assertFailedTestCount(2, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix:fail'])
        self.assertFailedTestCount(3, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj'])
        self.assertFailedTestCount(2, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj', '--no-suite', 'subprjmix:fail'])
        self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj', '--no-suite', 'subprjmix:fail', 'mainprj-failing_test'])

        self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjfail:fail', '--no-suite', 'subprjmix:fail'])

    def test_build_by_default(self):
        testdir = os.path.join(self.common_test_dir, '129 build by default')
        self.init(testdir)
        self.build()
        genfile1 = os.path.join(self.builddir, 'generated1.dat')
        genfile2 = os.path.join(self.builddir, 'generated2.dat')
        exe1 = os.path.join(self.builddir, 'fooprog' + exe_suffix)
        exe2 = os.path.join(self.builddir, 'barprog' + exe_suffix)
        self.assertPathExists(genfile1)
        self.assertPathExists(genfile2)
        self.assertPathDoesNotExist(exe1)
        self.assertPathDoesNotExist(exe2)
        self.build(target=('fooprog' + exe_suffix))
        self.assertPathExists(exe1)
        self.build(target=('barprog' + exe_suffix))
        self.assertPathExists(exe2)

    def test_internal_include_order(self):
        if mesonbuild.environment.detect_msys2_arch() and ('MESON_RSP_THRESHOLD' in os.environ):
            raise SkipTest('Test does not yet support gcc rsp files on msys2')

        testdir = os.path.join(self.common_test_dir, '130 include order')
        self.init(testdir)
        execmd = fxecmd = None
        for cmd in self.get_compdb():
            if 'someexe' in cmd['command']:
                execmd = cmd['command']
                continue
            if 'somefxe' in cmd['command']:
                fxecmd = cmd['command']
                continue
        if not execmd or not fxecmd:
            raise Exception('Could not find someexe and somfxe commands')
        # Check include order for 'someexe'
        incs = [a for a in split_args(execmd) if a.startswith("-I")]
        self.assertEqual(len(incs), 9)
        # Need to run the build so the private dir is created.
        self.build()
        pdirs = glob(os.path.join(self.builddir, 'sub4/someexe*.p'))
        self.assertEqual(len(pdirs), 1)
        privdir = pdirs[0][len(self.builddir)+1:]
        self.assertPathEqual(incs[0], "-I" + privdir)
        # target build subdir
        self.assertPathEqual(incs[1], "-Isub4")
        # target source subdir
        self.assertPathBasenameEqual(incs[2], 'sub4')
        # include paths added via per-target c_args: ['-I'...]
        self.assertPathBasenameEqual(incs[3], 'sub3')
        # target include_directories: build dir
        self.assertPathEqual(incs[4], "-Isub2")
        # target include_directories: source dir
        self.assertPathBasenameEqual(incs[5], 'sub2')
        # target internal dependency include_directories: build dir
        self.assertPathEqual(incs[6], "-Isub1")
        # target internal dependency include_directories: source dir
        self.assertPathBasenameEqual(incs[7], 'sub1')
        # custom target include dir
        self.assertPathEqual(incs[8], '-Ictsub')
        # Check include order for 'somefxe'
        incs = [a for a in split_args(fxecmd) if a.startswith('-I')]
        self.assertEqual(len(incs), 9)
        # target private dir
        pdirs = glob(os.path.join(self.builddir, 'somefxe*.p'))
        self.assertEqual(len(pdirs), 1)
        privdir = pdirs[0][len(self.builddir)+1:]
        self.assertPathEqual(incs[0], '-I' + privdir)
        # target build dir
        self.assertPathEqual(incs[1], '-I.')
        # target source dir
        self.assertPathBasenameEqual(incs[2], os.path.basename(testdir))
        # target internal dependency correct include_directories: build dir
        self.assertPathEqual(incs[3], "-Isub4")
        # target internal dependency correct include_directories: source dir
        self.assertPathBasenameEqual(incs[4], 'sub4')
        # target internal dependency dep include_directories: build dir
        self.assertPathEqual(incs[5], "-Isub1")
        # target internal dependency dep include_directories: source dir
        self.assertPathBasenameEqual(incs[6], 'sub1')
        # target internal dependency wrong include_directories: build dir
        self.assertPathEqual(incs[7], "-Isub2")
        # target internal dependency wrong include_directories: source dir
        self.assertPathBasenameEqual(incs[8], 'sub2')

    def test_compiler_detection(self):
        '''
        Test that automatic compiler detection and setting from the environment
        both work just fine. This is needed because while running project tests
        and other unit tests, we always read CC/CXX/etc from the environment.
        '''
        gnu = GnuCompiler
        clang = ClangCompiler
        intel = IntelGnuLikeCompiler
        msvc = (VisualStudioCCompiler, VisualStudioCPPCompiler)
        clangcl = (ClangClCCompiler, ClangClCPPCompiler)
        ar = mesonbuild.linkers.ArLinker
        lib = mesonbuild.linkers.VisualStudioLinker
        langs = [('c', 'CC'), ('cpp', 'CXX')]
        if not is_windows() and platform.machine().lower() != 'e2k':
            langs += [('objc', 'OBJC'), ('objcpp', 'OBJCXX')]
        testdir = os.path.join(self.unit_test_dir, '5 compiler detection')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        for lang, evar in langs:
            # Detect with evar and do sanity checks on that
            if evar in os.environ:
                ecc = compiler_from_language(env, lang, MachineChoice.HOST)
                self.assertTrue(ecc.version)
                elinker = detect_static_linker(env, ecc)
                # Pop it so we don't use it for the next detection
                evalue = os.environ.pop(evar)
                # Very rough/strict heuristics. Would never work for actual
                # compiler detection, but should be ok for the tests.
                ebase = os.path.basename(evalue)
                if ebase.startswith('g') or ebase.endswith(('-gcc', '-g++')):
                    self.assertIsInstance(ecc, gnu)
                    self.assertIsInstance(elinker, ar)
                elif 'clang-cl' in ebase:
                    self.assertIsInstance(ecc, clangcl)
                    self.assertIsInstance(elinker, lib)
                elif 'clang' in ebase:
                    self.assertIsInstance(ecc, clang)
                    self.assertIsInstance(elinker, ar)
                elif ebase.startswith('ic'):
                    self.assertIsInstance(ecc, intel)
                    self.assertIsInstance(elinker, ar)
                elif ebase.startswith('cl'):
                    self.assertIsInstance(ecc, msvc)
                    self.assertIsInstance(elinker, lib)
                else:
                    raise AssertionError(f'Unknown compiler {evalue!r}')
                # Check that we actually used the evalue correctly as the compiler
                self.assertEqual(ecc.get_exelist(), split_args(evalue))
            # Do auto-detection of compiler based on platform, PATH, etc.
            cc = compiler_from_language(env, lang, MachineChoice.HOST)
            self.assertTrue(cc.version)
            linker = detect_static_linker(env, cc)
            # Check compiler type
            if isinstance(cc, gnu):
                self.assertIsInstance(linker, ar)
                if is_osx():
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.AppleDynamicLinker)
                elif is_sunos():
                    self.assertIsInstance(cc.linker, (mesonbuild.linkers.SolarisDynamicLinker, mesonbuild.linkers.GnuLikeDynamicLinkerMixin))
                else:
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.GnuLikeDynamicLinkerMixin)
            if isinstance(cc, clangcl):
                self.assertIsInstance(linker, lib)
                self.assertIsInstance(cc.linker, mesonbuild.linkers.ClangClDynamicLinker)
            if isinstance(cc, clang):
                self.assertIsInstance(linker, ar)
                if is_osx():
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.AppleDynamicLinker)
                elif is_windows():
                    # This is clang, not clang-cl. This can be either an
                    # ld-like linker of link.exe-like linker (usually the
                    # former for msys2, the latter otherwise)
                    self.assertIsInstance(cc.linker, (mesonbuild.linkers.MSVCDynamicLinker, mesonbuild.linkers.GnuLikeDynamicLinkerMixin))
                else:
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.GnuLikeDynamicLinkerMixin)
            if isinstance(cc, intel):
                self.assertIsInstance(linker, ar)
                if is_osx():
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.AppleDynamicLinker)
                elif is_windows():
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.XilinkDynamicLinker)
                else:
                    self.assertIsInstance(cc.linker, mesonbuild.linkers.GnuDynamicLinker)
            if isinstance(cc, msvc):
                self.assertTrue(is_windows())
                self.assertIsInstance(linker, lib)
                self.assertEqual(cc.id, 'msvc')
                self.assertTrue(hasattr(cc, 'is_64'))
                self.assertIsInstance(cc.linker, mesonbuild.linkers.MSVCDynamicLinker)
                # If we're on Windows CI, we know what the compiler will be
                if 'arch' in os.environ:
                    if os.environ['arch'] == 'x64':
                        self.assertTrue(cc.is_64)
                    else:
                        self.assertFalse(cc.is_64)
            # Set evar ourselves to a wrapper script that just calls the same
            # exelist + some argument. This is meant to test that setting
            # something like `ccache gcc -pipe` or `distcc ccache gcc` works.
            wrapper = os.path.join(testdir, 'compiler wrapper.py')
            wrappercc = python_command + [wrapper] + cc.get_exelist() + ['-DSOME_ARG']
            os.environ[evar] = ' '.join(quote_arg(w) for w in wrappercc)

            # Check static linker too
            wrapperlinker = python_command + [wrapper] + linker.get_exelist() + linker.get_always_args()
            os.environ['AR'] = ' '.join(quote_arg(w) for w in wrapperlinker)

            # Need a new env to re-run environment loading
            env = get_fake_env(testdir, self.builddir, self.prefix)

            wcc = compiler_from_language(env, lang, MachineChoice.HOST)
            wlinker = detect_static_linker(env, wcc)
            # Pop it so we don't use it for the next detection
            os.environ.pop('AR')
            # Must be the same type since it's a wrapper around the same exelist
            self.assertIs(type(cc), type(wcc))
            self.assertIs(type(linker), type(wlinker))
            # Ensure that the exelist is correct
            self.assertEqual(wcc.get_exelist(), wrappercc)
            self.assertEqual(wlinker.get_exelist(), wrapperlinker)
            # Ensure that the version detection worked correctly
            self.assertEqual(cc.version, wcc.version)
            if hasattr(cc, 'is_64'):
                self.assertEqual(cc.is_64, wcc.is_64)

    def test_always_prefer_c_compiler_for_asm(self):
        testdir = os.path.join(self.common_test_dir, '133 c cpp and asm')
        # Skip if building with MSVC
        env = get_fake_env(testdir, self.builddir, self.prefix)
        if detect_c_compiler(env, MachineChoice.HOST).get_id() == 'msvc':
            raise SkipTest('MSVC can\'t compile assembly')
        self.init(testdir)
        commands = {'c-asm': {}, 'cpp-asm': {}, 'cpp-c-asm': {}, 'c-cpp-asm': {}}
        for cmd in self.get_compdb():
            # Get compiler
            split = split_args(cmd['command'])
            if split[0] == 'ccache':
                compiler = split[1]
            else:
                compiler = split[0]
            # Classify commands
            if 'Ic-asm' in cmd['command']:
                if cmd['file'].endswith('.S'):
                    commands['c-asm']['asm'] = compiler
                elif cmd['file'].endswith('.c'):
                    commands['c-asm']['c'] = compiler
                else:
                    raise AssertionError('{!r} found in cpp-asm?'.format(cmd['command']))
            elif 'Icpp-asm' in cmd['command']:
                if cmd['file'].endswith('.S'):
                    commands['cpp-asm']['asm'] = compiler
                elif cmd['file'].endswith('.cpp'):
                    commands['cpp-asm']['cpp'] = compiler
                else:
                    raise AssertionError('{!r} found in cpp-asm?'.format(cmd['command']))
            elif 'Ic-cpp-asm' in cmd['command']:
                if cmd['file'].endswith('.S'):
                    commands['c-cpp-asm']['asm'] = compiler
                elif cmd['file'].endswith('.c'):
                    commands['c-cpp-asm']['c'] = compiler
                elif cmd['file'].endswith('.cpp'):
                    commands['c-cpp-asm']['cpp'] = compiler
                else:
                    raise AssertionError('{!r} found in c-cpp-asm?'.format(cmd['command']))
            elif 'Icpp-c-asm' in cmd['command']:
                if cmd['file'].endswith('.S'):
                    commands['cpp-c-asm']['asm'] = compiler
                elif cmd['file'].endswith('.c'):
                    commands['cpp-c-asm']['c'] = compiler
                elif cmd['file'].endswith('.cpp'):
                    commands['cpp-c-asm']['cpp'] = compiler
                else:
                    raise AssertionError('{!r} found in cpp-c-asm?'.format(cmd['command']))
            else:
                raise AssertionError('Unknown command {!r} found'.format(cmd['command']))
        # Check that .S files are always built with the C compiler
        self.assertEqual(commands['c-asm']['asm'], commands['c-asm']['c'])
        self.assertEqual(commands['c-asm']['asm'], commands['cpp-asm']['asm'])
        self.assertEqual(commands['cpp-asm']['asm'], commands['c-cpp-asm']['c'])
        self.assertEqual(commands['c-cpp-asm']['asm'], commands['c-cpp-asm']['c'])
        self.assertEqual(commands['cpp-c-asm']['asm'], commands['cpp-c-asm']['c'])
        self.assertNotEqual(commands['cpp-asm']['asm'], commands['cpp-asm']['cpp'])
        self.assertNotEqual(commands['c-cpp-asm']['c'], commands['c-cpp-asm']['cpp'])
        self.assertNotEqual(commands['cpp-c-asm']['c'], commands['cpp-c-asm']['cpp'])
        # Check that the c-asm target is always linked with the C linker
        build_ninja = os.path.join(self.builddir, 'build.ninja')
        with open(build_ninja, encoding='utf-8') as f:
            contents = f.read()
            m = re.search('build c-asm.*: c_LINKER', contents)
        self.assertIsNotNone(m, msg=contents)

    def test_preprocessor_checks_CPPFLAGS(self):
        '''
        Test that preprocessor compiler checks read CPPFLAGS and also CFLAGS but
        not LDFLAGS.
        '''
        testdir = os.path.join(self.common_test_dir, '132 get define')
        define = 'MESON_TEST_DEFINE_VALUE'
        # NOTE: this list can't have \n, ' or "
        # \n is never substituted by the GNU pre-processor via a -D define
        # ' and " confuse split_args() even when they are escaped
        # % and # confuse the MSVC preprocessor
        # !, ^, *, and < confuse lcc preprocessor
        value = 'spaces and fun@$&()-=_+{}[]:;>?,./~`'
        for env_var in ['CPPFLAGS', 'CFLAGS']:
            env = {}
            env[env_var] = f'-D{define}="{value}"'
            env['LDFLAGS'] = '-DMESON_FAIL_VALUE=cflags-read'
            self.init(testdir, extra_args=[f'-D{define}={value}'], override_envvars=env)

    def test_custom_target_exe_data_deterministic(self):
        testdir = os.path.join(self.common_test_dir, '109 custom target capture')
        self.init(testdir)
        meson_exe_dat1 = glob(os.path.join(self.privatedir, 'meson_exe*.dat'))
        self.wipe()
        self.init(testdir)
        meson_exe_dat2 = glob(os.path.join(self.privatedir, 'meson_exe*.dat'))
        self.assertListEqual(meson_exe_dat1, meson_exe_dat2)

    def test_noop_changes_cause_no_rebuilds(self):
        '''
        Test that no-op changes to the build files such as mtime do not cause
        a rebuild of anything.
        '''
        testdir = os.path.join(self.common_test_dir, '6 linkshared')
        self.init(testdir)
        self.build()
        # Immediately rebuilding should not do anything
        self.assertBuildIsNoop()
        # Changing mtime of meson.build should not rebuild anything
        self.utime(os.path.join(testdir, 'meson.build'))
        self.assertReconfiguredBuildIsNoop()
        # Changing mtime of libefile.c should rebuild the library, but not relink the executable
        self.utime(os.path.join(testdir, 'libfile.c'))
        self.assertBuildRelinkedOnlyTarget('mylib')

    def test_source_changes_cause_rebuild(self):
        '''
        Test that changes to sources and headers cause rebuilds, but not
        changes to unused files (as determined by the dependency file) in the
        input files list.
        '''
        testdir = os.path.join(self.common_test_dir, '19 header in file list')
        self.init(testdir)
        self.build()
        # Immediately rebuilding should not do anything
        self.assertBuildIsNoop()
        # Changing mtime of header.h should rebuild everything
        self.utime(os.path.join(testdir, 'header.h'))
        self.assertBuildRelinkedOnlyTarget('prog')

    def test_custom_target_changes_cause_rebuild(self):
        '''
        Test that in a custom target, changes to the input files, the
        ExternalProgram, and any File objects on the command-line cause
        a rebuild.
        '''
        testdir = os.path.join(self.common_test_dir, '57 custom header generator')
        self.init(testdir)
        self.build()
        # Immediately rebuilding should not do anything
        self.assertBuildIsNoop()
        # Changing mtime of these should rebuild everything
        for f in ('input.def', 'makeheader.py', 'somefile.txt'):
            self.utime(os.path.join(testdir, f))
            self.assertBuildRelinkedOnlyTarget('prog')

    def test_source_generator_program_cause_rebuild(self):
        '''
        Test that changes to generator programs in the source tree cause
        a rebuild.
        '''
        testdir = os.path.join(self.common_test_dir, '90 gen extra')
        self.init(testdir)
        self.build()
        # Immediately rebuilding should not do anything
        self.assertBuildIsNoop()
        # Changing mtime of generator should rebuild the executable
        self.utime(os.path.join(testdir, 'srcgen.py'))
        self.assertRebuiltTarget('basic')

    def test_static_library_lto(self):
        '''
        Test that static libraries can be built with LTO and linked to
        executables. On Linux, this requires the use of gcc-ar.
        https://github.com/mesonbuild/meson/issues/1646
        '''
        testdir = os.path.join(self.common_test_dir, '5 linkstatic')

        env = get_fake_env(testdir, self.builddir, self.prefix)
        if detect_c_compiler(env, MachineChoice.HOST).get_id() == 'clang' and is_windows():
            raise SkipTest('LTO not (yet) supported by windows clang')

        self.init(testdir, extra_args='-Db_lto=true')
        self.build()
        self.run_tests()

    @skip_if_not_base_option('b_lto_threads')
    def test_lto_threads(self):
        testdir = os.path.join(self.common_test_dir, '6 linkshared')

        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        extra_args: T.List[str] = []
        if cc.get_id() == 'clang':
            if is_windows():
                raise SkipTest('LTO not (yet) supported by windows clang')

        self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_threads=8'] + extra_args)
        self.build()
        self.run_tests()

        expected = set(cc.get_lto_compile_args(threads=8))
        targets = self.introspect('--targets')
        # This assumes all of the targets support lto
        for t in targets:
            for s in t['target_sources']:
                for e in expected:
                    self.assertIn(e, s['parameters'])

    @skip_if_not_base_option('b_lto_mode')
    @skip_if_not_base_option('b_lto_threads')
    def test_lto_mode(self):
        testdir = os.path.join(self.common_test_dir, '6 linkshared')

        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() != 'clang':
            raise SkipTest('Only clang currently supports thinLTO')
        if cc.linker.id not in {'ld.lld', 'ld.gold', 'ld64', 'lld-link'}:
            raise SkipTest('thinLTO requires ld.lld, ld.gold, ld64, or lld-link')
        elif is_windows():
            raise SkipTest('LTO not (yet) supported by windows clang')

        self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_mode=thin', '-Db_lto_threads=8', '-Dc_args=-Werror=unused-command-line-argument'])
        self.build()
        self.run_tests()

        expected = set(cc.get_lto_compile_args(threads=8, mode='thin'))
        targets = self.introspect('--targets')
        # This assumes all of the targets support lto
        for t in targets:
            for s in t['target_sources']:
                self.assertTrue(expected.issubset(set(s['parameters'])), f'Incorrect values for {t["name"]}')

    def test_dist_git(self):
        if not shutil.which('git'):
            raise SkipTest('Git not found')
        if self.backend is not Backend.ninja:
            raise SkipTest('Dist is only supported with Ninja')

        try:
            self.dist_impl(_git_init, _git_add_all)
        except PermissionError:
            # When run under Windows CI, something (virus scanner?)
            # holds on to the git files so cleaning up the dir
            # fails sometimes.
            pass

    def has_working_hg(self):
        if not shutil.which('hg'):
            return False
        try:
            # This check should not be necessary, but
            # CI under macOS passes the above test even
            # though Mercurial is not installed.
            if subprocess.call(['hg', '--version'],
                               stdout=subprocess.DEVNULL,
                               stderr=subprocess.DEVNULL) != 0:
                return False
            return True
        except FileNotFoundError:
            return False

    def test_dist_hg(self):
        if not self.has_working_hg():
            raise SkipTest('Mercurial not found or broken.')
        if self.backend is not Backend.ninja:
            raise SkipTest('Dist is only supported with Ninja')

        def hg_init(project_dir):
            subprocess.check_call(['hg', 'init'], cwd=project_dir)
            with open(os.path.join(project_dir, '.hg', 'hgrc'), 'w', encoding='utf-8') as f:
                print('[ui]', file=f)
                print('username=Author Person <teh_coderz@example.com>', file=f)
            subprocess.check_call(['hg', 'add', 'meson.build', 'distexe.c'], cwd=project_dir)
            subprocess.check_call(['hg', 'commit', '-m', 'I am a project'], cwd=project_dir)

        try:
            self.dist_impl(hg_init, include_subprojects=False)
        except PermissionError:
            # When run under Windows CI, something (virus scanner?)
            # holds on to the hg files so cleaning up the dir
            # fails sometimes.
            pass

    def test_dist_git_script(self):
        if not shutil.which('git'):
            raise SkipTest('Git not found')
        if self.backend is not Backend.ninja:
            raise SkipTest('Dist is only supported with Ninja')

        try:
            with tempfile.TemporaryDirectory() as tmpdir:
                project_dir = os.path.join(tmpdir, 'a')
                shutil.copytree(os.path.join(self.unit_test_dir, '35 dist script'),
                                project_dir)
                _git_init(project_dir)
                self.init(project_dir)
                self.build('dist')

                self.new_builddir()
                self.init(project_dir, extra_args=['-Dsub:broken_dist_script=false'])
                self._run(self.meson_command + ['dist', '--include-subprojects'], workdir=self.builddir)
        except PermissionError:
            # When run under Windows CI, something (virus scanner?)
            # holds on to the git files so cleaning up the dir
            # fails sometimes.
            pass

    def create_dummy_subproject(self, project_dir, name):
        path = os.path.join(project_dir, 'subprojects', name)
        os.makedirs(path)
        with open(os.path.join(path, 'meson.build'), 'w', encoding='utf-8') as ofile:
            ofile.write(f"project('{name}', version: '1.0')")
        return path

    def dist_impl(self, vcs_init, vcs_add_all=None, include_subprojects=True):
        # Create this on the fly because having rogue .git directories inside
        # the source tree leads to all kinds of trouble.
        with tempfile.TemporaryDirectory() as project_dir:
            with open(os.path.join(project_dir, 'meson.build'), 'w', encoding='utf-8') as ofile:
                ofile.write(textwrap.dedent('''\
                    project('disttest', 'c', version : '1.4.3')
                    e = executable('distexe', 'distexe.c')
                    test('dist test', e)
                    subproject('vcssub', required : false)
                    subproject('tarballsub', required : false)
                    subproject('samerepo', required : false)
                    '''))
            with open(os.path.join(project_dir, 'distexe.c'), 'w', encoding='utf-8') as ofile:
                ofile.write(textwrap.dedent('''\
                    #include<stdio.h>

                    int main(int argc, char **argv) {
                        printf("I am a distribution test.\\n");
                        return 0;
                    }
                    '''))
            xz_distfile = os.path.join(self.distdir, 'disttest-1.4.3.tar.xz')
            xz_checksumfile = xz_distfile + '.sha256sum'
            gz_distfile = os.path.join(self.distdir, 'disttest-1.4.3.tar.gz')
            gz_checksumfile = gz_distfile + '.sha256sum'
            zip_distfile = os.path.join(self.distdir, 'disttest-1.4.3.zip')
            zip_checksumfile = zip_distfile + '.sha256sum'
            vcs_init(project_dir)
            if include_subprojects:
                vcs_init(self.create_dummy_subproject(project_dir, 'vcssub'))
                self.create_dummy_subproject(project_dir, 'tarballsub')
                self.create_dummy_subproject(project_dir, 'unusedsub')
            if vcs_add_all:
                vcs_add_all(self.create_dummy_subproject(project_dir, 'samerepo'))
            self.init(project_dir)
            self.build('dist')
            self.assertPathExists(xz_distfile)
            self.assertPathExists(xz_checksumfile)
            self.assertPathDoesNotExist(gz_distfile)
            self.assertPathDoesNotExist(gz_checksumfile)
            self.assertPathDoesNotExist(zip_distfile)
            self.assertPathDoesNotExist(zip_checksumfile)
            self._run(self.meson_command + ['dist', '--formats', 'gztar'],
                      workdir=self.builddir)
            self.assertPathExists(gz_distfile)
            self.assertPathExists(gz_checksumfile)
            self._run(self.meson_command + ['dist', '--formats', 'zip'],
                      workdir=self.builddir)
            self.assertPathExists(zip_distfile)
            self.assertPathExists(zip_checksumfile)
            os.remove(xz_distfile)
            os.remove(xz_checksumfile)
            os.remove(gz_distfile)
            os.remove(gz_checksumfile)
            os.remove(zip_distfile)
            os.remove(zip_checksumfile)
            self._run(self.meson_command + ['dist', '--formats', 'xztar,gztar,zip'],
                      workdir=self.builddir)
            self.assertPathExists(xz_distfile)
            self.assertPathExists(xz_checksumfile)
            self.assertPathExists(gz_distfile)
            self.assertPathExists(gz_checksumfile)
            self.assertPathExists(zip_distfile)
            self.assertPathExists(zip_checksumfile)

            if include_subprojects:
                # Verify that without --include-subprojects we have files from
                # the main project and also files from subprojects part of the
                # main vcs repository.
                z = zipfile.ZipFile(zip_distfile)
                expected = ['disttest-1.4.3/',
                            'disttest-1.4.3/meson.build',
                            'disttest-1.4.3/distexe.c']
                if vcs_add_all:
                    expected += ['disttest-1.4.3/subprojects/',
                                 'disttest-1.4.3/subprojects/samerepo/',
                                 'disttest-1.4.3/subprojects/samerepo/meson.build']
                self.assertEqual(sorted(expected),
                                 sorted(z.namelist()))
                # Verify that with --include-subprojects we now also have files
                # from tarball and separate vcs subprojects. But not files from
                # unused subprojects.
                self._run(self.meson_command + ['dist', '--formats', 'zip', '--include-subprojects'],
                          workdir=self.builddir)
                z = zipfile.ZipFile(zip_distfile)
                expected += ['disttest-1.4.3/subprojects/tarballsub/',
                             'disttest-1.4.3/subprojects/tarballsub/meson.build',
                             'disttest-1.4.3/subprojects/vcssub/',
                             'disttest-1.4.3/subprojects/vcssub/meson.build']
                self.assertEqual(sorted(expected),
                                 sorted(z.namelist()))
            if vcs_add_all:
                # Verify we can distribute separately subprojects in the same vcs
                # repository as the main project.
                subproject_dir = os.path.join(project_dir, 'subprojects', 'samerepo')
                self.new_builddir()
                self.init(subproject_dir)
                self.build('dist')
                xz_distfile = os.path.join(self.distdir, 'samerepo-1.0.tar.xz')
                xz_checksumfile = xz_distfile + '.sha256sum'
                self.assertPathExists(xz_distfile)
                self.assertPathExists(xz_checksumfile)
                tar = tarfile.open(xz_distfile, "r:xz")  # [ignore encoding]
                self.assertEqual(sorted(['samerepo-1.0',
                                         'samerepo-1.0/meson.build']),
                                 sorted(i.name for i in tar))

    def test_rpath_uses_ORIGIN(self):
        '''
        Test that built targets use $ORIGIN in rpath, which ensures that they
        are relocatable and ensures that builds are reproducible since the
        build directory won't get embedded into the built binaries.
        '''
        if is_windows() or is_cygwin():
            raise SkipTest('Windows PE/COFF binaries do not use RPATH')
        testdir = os.path.join(self.common_test_dir, '39 library chain')
        self.init(testdir)
        self.build()
        for each in ('prog', 'subdir/liblib1.so', ):
            rpath = get_rpath(os.path.join(self.builddir, each))
            self.assertTrue(rpath, f'Rpath could not be determined for {each}.')
            if is_dragonflybsd():
                # DragonflyBSD will prepend /usr/lib/gccVERSION to the rpath,
                # so ignore that.
                self.assertTrue(rpath.startswith('/usr/lib/gcc'))
                rpaths = rpath.split(':')[1:]
            else:
                rpaths = rpath.split(':')
            for path in rpaths:
                self.assertTrue(path.startswith('$ORIGIN'), msg=(each, path))
        # These two don't link to anything else, so they do not need an rpath entry.
        for each in ('subdir/subdir2/liblib2.so', 'subdir/subdir3/liblib3.so'):
            rpath = get_rpath(os.path.join(self.builddir, each))
            if is_dragonflybsd():
                # The rpath should be equal to /usr/lib/gccVERSION
                self.assertTrue(rpath.startswith('/usr/lib/gcc'))
                self.assertEqual(len(rpath.split(':')), 1)
            else:
                self.assertIsNone(rpath)

    def test_dash_d_dedup(self):
        testdir = os.path.join(self.unit_test_dir, '9 d dedup')
        self.init(testdir)
        cmd = self.get_compdb()[0]['command']
        self.assertTrue('-D FOO -D BAR' in cmd or
                        '"-D" "FOO" "-D" "BAR"' in cmd or
                        '/D FOO /D BAR' in cmd or
                        '"/D" "FOO" "/D" "BAR"' in cmd)

    def test_all_forbidden_targets_tested(self):
        '''
        Test that all forbidden targets are tested in the '150 reserved targets'
        test. Needs to be a unit test because it accesses Meson internals.
        '''
        testdir = os.path.join(self.common_test_dir, '150 reserved targets')
        targets = mesonbuild.coredata.FORBIDDEN_TARGET_NAMES
        # We don't actually define a target with this name
        targets.pop('build.ninja')
        # Remove this to avoid multiple entries with the same name
        # but different case.
        targets.pop('PHONY')
        for i in targets:
            self.assertPathExists(os.path.join(testdir, i))

    def detect_prebuild_env(self):
        env = get_fake_env()
        cc = detect_c_compiler(env, MachineChoice.HOST)
        stlinker = detect_static_linker(env, cc)
        if is_windows():
            object_suffix = 'obj'
            shared_suffix = 'dll'
        elif is_cygwin():
            object_suffix = 'o'
            shared_suffix = 'dll'
        elif is_osx():
            object_suffix = 'o'
            shared_suffix = 'dylib'
        else:
            object_suffix = 'o'
            shared_suffix = 'so'
        return (cc, stlinker, object_suffix, shared_suffix)

    def pbcompile(self, compiler, source, objectfile, extra_args=None):
        cmd = compiler.get_exelist()
        extra_args = extra_args or []
        if compiler.get_argument_syntax() == 'msvc':
            cmd += ['/nologo', '/Fo' + objectfile, '/c', source] + extra_args
        else:
            cmd += ['-c', source, '-o', objectfile] + extra_args
        subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    def test_prebuilt_object(self):
        (compiler, _, object_suffix, _) = self.detect_prebuild_env()
        tdir = os.path.join(self.unit_test_dir, '15 prebuilt object')
        source = os.path.join(tdir, 'source.c')
        objectfile = os.path.join(tdir, 'prebuilt.' + object_suffix)
        self.pbcompile(compiler, source, objectfile)
        try:
            self.init(tdir)
            self.build()
            self.run_tests()
        finally:
            os.unlink(objectfile)

    def build_static_lib(self, compiler, linker, source, objectfile, outfile, extra_args=None):
        if extra_args is None:
            extra_args = []
        link_cmd = linker.get_exelist()
        link_cmd += linker.get_always_args()
        link_cmd += linker.get_std_link_args(False)
        link_cmd += linker.get_output_args(outfile)
        link_cmd += [objectfile]
        self.pbcompile(compiler, source, objectfile, extra_args=extra_args)
        try:
            subprocess.check_call(link_cmd)
        finally:
            os.unlink(objectfile)

    def test_prebuilt_static_lib(self):
        (cc, stlinker, object_suffix, _) = self.detect_prebuild_env()
        tdir = os.path.join(self.unit_test_dir, '16 prebuilt static')
        source = os.path.join(tdir, 'libdir/best.c')
        objectfile = os.path.join(tdir, 'libdir/best.' + object_suffix)
        stlibfile = os.path.join(tdir, 'libdir/libbest.a')
        self.build_static_lib(cc, stlinker, source, objectfile, stlibfile)
        # Run the test
        try:
            self.init(tdir)
            self.build()
            self.run_tests()
        finally:
            os.unlink(stlibfile)

    def build_shared_lib(self, compiler, source, objectfile, outfile, impfile, extra_args=None):
        if extra_args is None:
            extra_args = []
        if compiler.get_argument_syntax() == 'msvc':
            link_cmd = compiler.get_linker_exelist() + [
                '/NOLOGO', '/DLL', '/DEBUG', '/IMPLIB:' + impfile,
                '/OUT:' + outfile, objectfile]
        else:
            if not (compiler.info.is_windows() or compiler.info.is_cygwin() or compiler.info.is_darwin()):
                extra_args += ['-fPIC']
            link_cmd = compiler.get_exelist() + ['-shared', '-o', outfile, objectfile]
            if not is_osx():
                link_cmd += ['-Wl,-soname=' + os.path.basename(outfile)]
        self.pbcompile(compiler, source, objectfile, extra_args=extra_args)
        try:
            subprocess.check_call(link_cmd)
        finally:
            os.unlink(objectfile)

    def test_prebuilt_shared_lib(self):
        (cc, _, object_suffix, shared_suffix) = self.detect_prebuild_env()
        tdir = os.path.join(self.unit_test_dir, '17 prebuilt shared')
        source = os.path.join(tdir, 'alexandria.c')
        objectfile = os.path.join(tdir, 'alexandria.' + object_suffix)
        impfile = os.path.join(tdir, 'alexandria.lib')
        if cc.get_argument_syntax() == 'msvc':
            shlibfile = os.path.join(tdir, 'alexandria.' + shared_suffix)
        elif is_cygwin():
            shlibfile = os.path.join(tdir, 'cygalexandria.' + shared_suffix)
        else:
            shlibfile = os.path.join(tdir, 'libalexandria.' + shared_suffix)
        self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)

        if is_windows():
            def cleanup() -> None:
                """Clean up all the garbage MSVC writes in the source tree."""

                for fname in glob(os.path.join(tdir, 'alexandria.*')):
                    if os.path.splitext(fname)[1] not in {'.c', '.h'}:
                        os.unlink(fname)
            self.addCleanup(cleanup)
        else:
            self.addCleanup(os.unlink, shlibfile)

        # Run the test
        self.init(tdir)
        self.build()
        self.run_tests()

    def test_prebuilt_shared_lib_rpath(self) -> None:
        (cc, _, object_suffix, shared_suffix) = self.detect_prebuild_env()
        tdir = os.path.join(self.unit_test_dir, '17 prebuilt shared')
        with tempfile.TemporaryDirectory() as d:
            source = os.path.join(tdir, 'alexandria.c')
            objectfile = os.path.join(d, 'alexandria.' + object_suffix)
            impfile = os.path.join(d, 'alexandria.lib')
            if cc.get_argument_syntax() == 'msvc':
                shlibfile = os.path.join(d, 'alexandria.' + shared_suffix)
            elif is_cygwin():
                shlibfile = os.path.join(d, 'cygalexandria.' + shared_suffix)
            else:
                shlibfile = os.path.join(d, 'libalexandria.' + shared_suffix)
            # Ensure MSVC extra files end up in the directory that gets deleted
            # at the end
            with chdir(d):
                self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)

            # Run the test
            self.init(tdir, extra_args=[f'-Dsearch_dir={d}'])
            self.build()
            self.run_tests()

    def test_underscore_prefix_detection_list(self) -> None:
        '''
        Test the underscore detection hardcoded lookup list
        against what was detected in the binary.
        '''
        env, cc = get_convincing_fake_env_and_cc(self.builddir, self.prefix)
        expected_uscore = cc._symbols_have_underscore_prefix_searchbin(env)
        list_uscore = cc._symbols_have_underscore_prefix_list(env)
        if list_uscore is not None:
            self.assertEqual(list_uscore, expected_uscore)
        else:
            raise SkipTest('No match in underscore prefix list for this platform.')

    def test_underscore_prefix_detection_define(self) -> None:
        '''
        Test the underscore detection based on compiler-defined preprocessor macro
        against what was detected in the binary.
        '''
        env, cc = get_convincing_fake_env_and_cc(self.builddir, self.prefix)
        expected_uscore = cc._symbols_have_underscore_prefix_searchbin(env)
        define_uscore = cc._symbols_have_underscore_prefix_define(env)
        if define_uscore is not None:
            self.assertEqual(define_uscore, expected_uscore)
        else:
            raise SkipTest('Did not find the underscore prefix define __USER_LABEL_PREFIX__')

    @skipIfNoPkgconfig
    def test_pkgconfig_static(self):
        '''
        Test that the we prefer static libraries when `static: true` is
        passed to dependency() with pkg-config. Can't be an ordinary test
        because we need to build libs and try to find them from meson.build

        Also test that it's not a hard error to have unsatisfiable library deps
        since system libraries -lm will never be found statically.
        https://github.com/mesonbuild/meson/issues/2785
        '''
        (cc, stlinker, objext, shext) = self.detect_prebuild_env()
        testdir = os.path.join(self.unit_test_dir, '18 pkgconfig static')
        source = os.path.join(testdir, 'foo.c')
        objectfile = os.path.join(testdir, 'foo.' + objext)
        stlibfile = os.path.join(testdir, 'libfoo.a')
        impfile = os.path.join(testdir, 'foo.lib')
        if cc.get_argument_syntax() == 'msvc':
            shlibfile = os.path.join(testdir, 'foo.' + shext)
        elif is_cygwin():
            shlibfile = os.path.join(testdir, 'cygfoo.' + shext)
        else:
            shlibfile = os.path.join(testdir, 'libfoo.' + shext)
        # Build libs
        self.build_static_lib(cc, stlinker, source, objectfile, stlibfile, extra_args=['-DFOO_STATIC'])
        self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)
        # Run test
        try:
            self.init(testdir, override_envvars={'PKG_CONFIG_LIBDIR': self.builddir})
            self.build()
            self.run_tests()
        finally:
            os.unlink(stlibfile)
            os.unlink(shlibfile)
            if is_windows():
                # Clean up all the garbage MSVC writes in the
                # source tree.
                for fname in glob(os.path.join(testdir, 'foo.*')):
                    if os.path.splitext(fname)[1] not in ['.c', '.h', '.in']:
                        os.unlink(fname)

    @skipIfNoPkgconfig
    @mock.patch.dict(os.environ)
    def test_pkgconfig_gen_escaping(self):
        testdir = os.path.join(self.common_test_dir, '44 pkgconfig-gen')
        prefix = '/usr/with spaces'
        libdir = 'lib'
        self.init(testdir, extra_args=['--prefix=' + prefix,
                                       '--libdir=' + libdir])
        # Find foo dependency
        os.environ['PKG_CONFIG_LIBDIR'] = self.privatedir
        env = get_fake_env(testdir, self.builddir, self.prefix)
        kwargs = {'required': True, 'silent': True}
        foo_dep = PkgConfigDependency('libanswer', env, kwargs)
        # Ensure link_args are properly quoted
        libdir = PurePath(prefix) / PurePath(libdir)
        link_args = ['-L' + libdir.as_posix(), '-lanswer']
        self.assertEqual(foo_dep.get_link_args(), link_args)
        # Ensure include args are properly quoted
        incdir = PurePath(prefix) / PurePath('include')
        cargs = ['-I' + incdir.as_posix(), '-DLIBFOO']
        # pkg-config and pkgconf does not respect the same order
        self.assertEqual(sorted(foo_dep.get_compile_args()), sorted(cargs))

    def test_array_option_change(self):
        def get_opt():
            opts = self.introspect('--buildoptions')
            for x in opts:
                if x.get('name') == 'list':
                    return x
            raise Exception(opts)

        expected = {
            'name': 'list',
            'description': 'list',
            'section': 'user',
            'type': 'array',
            'value': ['foo', 'bar'],
            'choices': ['foo', 'bar', 'oink', 'boink'],
            'machine': 'any',
        }
        tdir = os.path.join(self.unit_test_dir, '19 array option')
        self.init(tdir)
        original = get_opt()
        self.assertDictEqual(original, expected)

        expected['value'] = ['oink', 'boink']
        self.setconf('-Dlist=oink,boink')
        changed = get_opt()
        self.assertEqual(changed, expected)

    def test_array_option_bad_change(self):
        def get_opt():
            opts = self.introspect('--buildoptions')
            for x in opts:
                if x.get('name') == 'list':
                    return x
            raise Exception(opts)

        expected = {
            'name': 'list',
            'description': 'list',
            'section': 'user',
            'type': 'array',
            'value': ['foo', 'bar'],
            'choices': ['foo', 'bar', 'oink', 'boink'],
            'machine': 'any',
        }
        tdir = os.path.join(self.unit_test_dir, '19 array option')
        self.init(tdir)
        original = get_opt()
        self.assertDictEqual(original, expected)
        with self.assertRaises(subprocess.CalledProcessError):
            self.setconf('-Dlist=bad')
        changed = get_opt()
        self.assertDictEqual(changed, expected)

    def test_array_option_empty_equivalents(self):
        """Array options treat -Dopt=[] and -Dopt= as equivalent."""
        def get_opt():
            opts = self.introspect('--buildoptions')
            for x in opts:
                if x.get('name') == 'list':
                    return x
            raise Exception(opts)

        expected = {
            'name': 'list',
            'description': 'list',
            'section': 'user',
            'type': 'array',
            'value': [],
            'choices': ['foo', 'bar', 'oink', 'boink'],
            'machine': 'any',
        }
        tdir = os.path.join(self.unit_test_dir, '19 array option')
        self.init(tdir, extra_args='-Dlist=')
        original = get_opt()
        self.assertDictEqual(original, expected)

    def opt_has(self, name, value):
        res = self.introspect('--buildoptions')
        found = False
        for i in res:
            if i['name'] == name:
                self.assertEqual(i['value'], value)
                found = True
                break
        self.assertTrue(found, "Array option not found in introspect data.")

    def test_free_stringarray_setting(self):
        testdir = os.path.join(self.common_test_dir, '40 options')
        self.init(testdir)
        self.opt_has('free_array_opt', [])
        self.setconf('-Dfree_array_opt=foo,bar', will_build=False)
        self.opt_has('free_array_opt', ['foo', 'bar'])
        self.setconf("-Dfree_array_opt=['a,b', 'c,d']", will_build=False)
        self.opt_has('free_array_opt', ['a,b', 'c,d'])

    # When running under Travis Mac CI, the file updates seem to happen
    # too fast so the timestamps do not get properly updated.
    # Call this method before file operations in appropriate places
    # to make things work.
    def mac_ci_delay(self):
        if is_osx() and is_ci():
            import time
            time.sleep(1)

    def test_options_with_choices_changing(self) -> None:
        """Detect when options like arrays or combos have their choices change."""
        testdir = Path(os.path.join(self.unit_test_dir, '83 change option choices'))
        options1 = str(testdir / 'meson_options.1.txt')
        options2 = str(testdir / 'meson_options.2.txt')

        # Test that old options are changed to the new defaults if they are not valid
        real_options = str(testdir / 'meson_options.txt')
        self.addCleanup(os.unlink, real_options)

        shutil.copy(options1, real_options)
        self.init(str(testdir))
        self.mac_ci_delay()
        shutil.copy(options2, real_options)

        self.build()
        opts = self.introspect('--buildoptions')
        for item in opts:
            if item['name'] == 'combo':
                self.assertEqual(item['value'], 'b')
                self.assertEqual(item['choices'], ['b', 'c', 'd'])
            elif item['name'] == 'array':
                self.assertEqual(item['value'], ['b'])
                self.assertEqual(item['choices'], ['b', 'c', 'd'])

        self.wipe()
        self.mac_ci_delay()

        # When the old options are valid they should remain
        shutil.copy(options1, real_options)
        self.init(str(testdir), extra_args=['-Dcombo=c', '-Darray=b,c'])
        self.mac_ci_delay()
        shutil.copy(options2, real_options)
        self.build()
        opts = self.introspect('--buildoptions')
        for item in opts:
            if item['name'] == 'combo':
                self.assertEqual(item['value'], 'c')
                self.assertEqual(item['choices'], ['b', 'c', 'd'])
            elif item['name'] == 'array':
                self.assertEqual(item['value'], ['b', 'c'])
                self.assertEqual(item['choices'], ['b', 'c', 'd'])

    def test_subproject_promotion(self):
        testdir = os.path.join(self.unit_test_dir, '12 promote')
        workdir = os.path.join(self.builddir, 'work')
        shutil.copytree(testdir, workdir)
        spdir = os.path.join(workdir, 'subprojects')
        s3dir = os.path.join(spdir, 's3')
        scommondir = os.path.join(spdir, 'scommon')
        self.assertFalse(os.path.isdir(s3dir))
        subprocess.check_call(self.wrap_command + ['promote', 's3'],
                              cwd=workdir,
                              stdout=subprocess.DEVNULL)
        self.assertTrue(os.path.isdir(s3dir))
        self.assertFalse(os.path.isdir(scommondir))
        self.assertNotEqual(subprocess.call(self.wrap_command + ['promote', 'scommon'],
                                            cwd=workdir,
                                            stderr=subprocess.DEVNULL), 0)
        self.assertNotEqual(subprocess.call(self.wrap_command + ['promote', 'invalid/path/to/scommon'],
                                            cwd=workdir,
                                            stderr=subprocess.DEVNULL), 0)
        self.assertFalse(os.path.isdir(scommondir))
        subprocess.check_call(self.wrap_command + ['promote', 'subprojects/s2/subprojects/scommon'], cwd=workdir)
        self.assertTrue(os.path.isdir(scommondir))
        promoted_wrap = os.path.join(spdir, 'athing.wrap')
        self.assertFalse(os.path.isfile(promoted_wrap))
        subprocess.check_call(self.wrap_command + ['promote', 'athing'], cwd=workdir)
        self.assertTrue(os.path.isfile(promoted_wrap))
        self.init(workdir)
        self.build()

    def test_subproject_promotion_wrap(self):
        testdir = os.path.join(self.unit_test_dir, '43 promote wrap')
        workdir = os.path.join(self.builddir, 'work')
        shutil.copytree(testdir, workdir)
        spdir = os.path.join(workdir, 'subprojects')

        ambiguous_wrap = os.path.join(spdir, 'ambiguous.wrap')
        self.assertNotEqual(subprocess.call(self.wrap_command + ['promote', 'ambiguous'],
                                            cwd=workdir,
                                            stderr=subprocess.DEVNULL), 0)
        self.assertFalse(os.path.isfile(ambiguous_wrap))
        subprocess.check_call(self.wrap_command + ['promote', 'subprojects/s2/subprojects/ambiguous.wrap'], cwd=workdir)
        self.assertTrue(os.path.isfile(ambiguous_wrap))

    def test_warning_location(self):
        tdir = os.path.join(self.unit_test_dir, '22 warning location')
        out = self.init(tdir)
        for expected in [
            r'meson.build:4: WARNING: Keyword argument "link_with" defined multiple times.',
            r'sub' + os.path.sep + r'meson.build:3: WARNING: Keyword argument "link_with" defined multiple times.',
            r'meson.build:6: WARNING: a warning of some sort',
            r'sub' + os.path.sep + r'meson.build:4: WARNING: subdir warning',
            r'meson.build:7: WARNING: Module unstable-simd has no backwards or forwards compatibility and might not exist in future releases.',
            r"meson.build:11: WARNING: The variable(s) 'MISSING' in the input file 'conf.in' are not present in the given configuration data.",
        ]:
            self.assertRegex(out, re.escape(expected))

        for wd in [
            self.src_root,
            self.builddir,
            os.getcwd(),
        ]:
            self.new_builddir()
            out = self.init(tdir, workdir=wd)
            expected = os.path.join(relpath(tdir, self.src_root), 'meson.build')
            relwd = relpath(self.src_root, wd)
            if relwd != '.':
                expected = os.path.join(relwd, expected)
                expected = '\n' + expected + ':'
            self.assertIn(expected, out)

    def test_error_location_path(self):
        '''Test locations in meson errors contain correct paths'''
        # this list contains errors from all the different steps in the
        # lexer/parser/interpreter we have tests for.
        for (t, f) in [
            ('10 out of bounds', 'meson.build'),
            ('18 wrong plusassign', 'meson.build'),
            ('59 bad option argument', 'meson_options.txt'),
            ('97 subdir parse error', os.path.join('subdir', 'meson.build')),
            ('98 invalid option file', 'meson_options.txt'),
        ]:
            tdir = os.path.join(self.src_root, 'test cases', 'failing', t)

            for wd in [
                self.src_root,
                self.builddir,
                os.getcwd(),
            ]:
                try:
                    self.init(tdir, workdir=wd)
                except subprocess.CalledProcessError as e:
                    expected = os.path.join('test cases', 'failing', t, f)
                    relwd = relpath(self.src_root, wd)
                    if relwd != '.':
                        expected = os.path.join(relwd, expected)
                    expected = '\n' + expected + ':'
                    self.assertIn(expected, e.output)
                else:
                    self.fail('configure unexpectedly succeeded')

    def test_permitted_method_kwargs(self):
        tdir = os.path.join(self.unit_test_dir, '25 non-permitted kwargs')
        with self.assertRaises(subprocess.CalledProcessError) as cm:
            self.init(tdir)
        self.assertIn('ERROR: compiler.has_header_symbol got unknown keyword arguments "prefixxx"', cm.exception.output)

    def test_templates(self):
        ninja = mesonbuild.environment.detect_ninja()
        if ninja is None:
            raise SkipTest('This test currently requires ninja. Fix this once "meson build" works.')

        langs = ['c']
        env = get_fake_env()
        for l in ['cpp', 'cs', 'd', 'java', 'cuda', 'fortran', 'objc', 'objcpp', 'rust']:
            try:
                comp = detect_compiler_for(env, l, MachineChoice.HOST)
                with tempfile.TemporaryDirectory() as d:
                    comp.sanity_check(d, env)
                langs.append(l)
            except EnvironmentException:
                pass

        # The D template fails under mac CI and we don't know why.
        # Patches welcome
        if is_osx():
            langs = [l for l in langs if l != 'd']

        for lang in langs:
            for target_type in ('executable', 'library'):
                # test empty directory
                with tempfile.TemporaryDirectory() as tmpdir:
                    self._run(self.meson_command + ['init', '--language', lang, '--type', target_type],
                              workdir=tmpdir)
                    self._run(self.setup_command + ['--backend=ninja', 'builddir'],
                              workdir=tmpdir)
                    self._run(ninja,
                              workdir=os.path.join(tmpdir, 'builddir'))
            # test directory with existing code file
            if lang in {'c', 'cpp', 'd'}:
                with tempfile.TemporaryDirectory() as tmpdir:
                    with open(os.path.join(tmpdir, 'foo.' + lang), 'w', encoding='utf-8') as f:
                        f.write('int main(void) {}')
                    self._run(self.meson_command + ['init', '-b'], workdir=tmpdir)
            elif lang in {'java'}:
                with tempfile.TemporaryDirectory() as tmpdir:
                    with open(os.path.join(tmpdir, 'Foo.' + lang), 'w', encoding='utf-8') as f:
                        f.write('public class Foo { public static void main() {} }')
                    self._run(self.meson_command + ['init', '-b'], workdir=tmpdir)

    def test_compiler_run_command(self):
        '''
        The test checks that the compiler object can be passed to
        run_command().
        '''
        testdir = os.path.join(self.unit_test_dir, '24 compiler run_command')
        self.init(testdir)

    def test_identical_target_name_in_subproject_flat_layout(self):
        '''
        Test that identical targets in different subprojects do not collide
        if layout is flat.
        '''
        testdir = os.path.join(self.common_test_dir, '172 identical target name in subproject flat layout')
        self.init(testdir, extra_args=['--layout=flat'])
        self.build()

    def test_identical_target_name_in_subdir_flat_layout(self):
        '''
        Test that identical targets in different subdirs do not collide
        if layout is flat.
        '''
        testdir = os.path.join(self.common_test_dir, '181 same target name flat layout')
        self.init(testdir, extra_args=['--layout=flat'])
        self.build()

    def test_flock(self):
        exception_raised = False
        with tempfile.TemporaryDirectory() as tdir:
            os.mkdir(os.path.join(tdir, 'meson-private'))
            with BuildDirLock(tdir):
                try:
                    with BuildDirLock(tdir):
                        pass
                except MesonException:
                    exception_raised = True
        self.assertTrue(exception_raised, 'Double locking did not raise exception.')

    @skipIf(is_osx(), 'Test not applicable to OSX')
    def test_check_module_linking(self):
        """
        Test that link_with: a shared module issues a warning
        https://github.com/mesonbuild/meson/issues/2865
        (That an error is raised on OSX is exercised by test failing/78)
        """
        tdir = os.path.join(self.unit_test_dir, '30 shared_mod linking')
        out = self.init(tdir)
        msg = ('''DEPRECATION: target prog links against shared module mymod, which is incorrect.
             This will be an error in the future, so please use shared_library() for mymod instead.
             If shared_module() was used for mymod because it has references to undefined symbols,
             use shared_libary() with `override_options: ['b_lundef=false']` instead.''')
        self.assertIn(msg, out)

    def test_mixed_language_linker_check(self):
        testdir = os.path.join(self.unit_test_dir, '96 compiler.links file arg')
        self.init(testdir)
        cmds = self.get_meson_log_compiler_checks()
        self.assertEqual(len(cmds), 5)
        # Path to the compilers, gleaned from cc.compiles tests
        cc = cmds[0][0]
        cxx = cmds[1][0]
        # cc.links
        self.assertEqual(cmds[2][0], cc)
        # cxx.links with C source
        self.assertEqual(cmds[3][0], cc)
        self.assertEqual(cmds[4][0], cxx)
        if self.backend is Backend.ninja:
            # updating the file to check causes a reconfigure
            #
            # only the ninja backend is competent enough to detect reconfigured
            # no-op builds without build targets
            self.utime(os.path.join(testdir, 'test.c'))
            self.assertReconfiguredBuildIsNoop()

    def test_ndebug_if_release_disabled(self):
        testdir = os.path.join(self.unit_test_dir, '28 ndebug if-release')
        self.init(testdir, extra_args=['--buildtype=release', '-Db_ndebug=if-release'])
        self.build()
        exe = os.path.join(self.builddir, 'main')
        self.assertEqual(b'NDEBUG=1', subprocess.check_output(exe).strip())

    def test_ndebug_if_release_enabled(self):
        testdir = os.path.join(self.unit_test_dir, '28 ndebug if-release')
        self.init(testdir, extra_args=['--buildtype=debugoptimized', '-Db_ndebug=if-release'])
        self.build()
        exe = os.path.join(self.builddir, 'main')
        self.assertEqual(b'NDEBUG=0', subprocess.check_output(exe).strip())

    def test_guessed_linker_dependencies(self):
        '''
        Test that meson adds dependencies for libraries based on the final
        linker command line.
        '''
        testdirbase = os.path.join(self.unit_test_dir, '29 guessed linker dependencies')
        testdirlib = os.path.join(testdirbase, 'lib')

        extra_args = None
        libdir_flags = ['-L']
        env = get_fake_env(testdirlib, self.builddir, self.prefix)
        if detect_c_compiler(env, MachineChoice.HOST).get_id() in {'msvc', 'clang-cl', 'intel-cl'}:
            # msvc-like compiler, also test it with msvc-specific flags
            libdir_flags += ['/LIBPATH:', '-LIBPATH:']
        else:
            # static libraries are not linkable with -l with msvc because meson installs them
            # as .a files which unix_args_to_native will not know as it expects libraries to use
            # .lib as extension. For a DLL the import library is installed as .lib. Thus for msvc
            # this tests needs to use shared libraries to test the path resolving logic in the
            # dependency generation code path.
            extra_args = ['--default-library', 'static']

        initial_builddir = self.builddir
        initial_installdir = self.installdir

        for libdir_flag in libdir_flags:
            # build library
            self.new_builddir()
            self.init(testdirlib, extra_args=extra_args)
            self.build()
            self.install()
            libbuilddir = self.builddir
            installdir = self.installdir
            libdir = os.path.join(self.installdir, self.prefix.lstrip('/').lstrip('\\'), 'lib')

            # build user of library
            self.new_builddir()
            # replace is needed because meson mangles platform paths passed via LDFLAGS
            self.init(os.path.join(testdirbase, 'exe'),
                      override_envvars={"LDFLAGS": '{}{}'.format(libdir_flag, libdir.replace('\\', '/'))})
            self.build()
            self.assertBuildIsNoop()

            # rebuild library
            exebuilddir = self.builddir
            self.installdir = installdir
            self.builddir = libbuilddir
            # Microsoft's compiler is quite smart about touching import libs on changes,
            # so ensure that there is actually a change in symbols.
            self.setconf('-Dmore_exports=true')
            self.build()
            self.install()
            # no ensure_backend_detects_changes needed because self.setconf did that already

            # assert user of library will be rebuild
            self.builddir = exebuilddir
            self.assertRebuiltTarget('app')

            # restore dirs for the next test case
            self.installdir = initial_builddir
            self.builddir = initial_installdir

    def test_conflicting_d_dash_option(self):
        testdir = os.path.join(self.unit_test_dir, '37 mixed command line args')
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as e:
            self.init(testdir, extra_args=['-Dbindir=foo', '--bindir=bar'])
            # Just to ensure that we caught the correct error
            self.assertIn('as both', e.stderr)

    def _test_same_option_twice(self, arg, args):
        testdir = os.path.join(self.unit_test_dir, '37 mixed command line args')
        self.init(testdir, extra_args=args)
        opts = self.introspect('--buildoptions')
        for item in opts:
            if item['name'] == arg:
                self.assertEqual(item['value'], 'bar')
                return
        raise Exception(f'Missing {arg} value?')

    def test_same_dash_option_twice(self):
        self._test_same_option_twice('bindir', ['--bindir=foo', '--bindir=bar'])

    def test_same_d_option_twice(self):
        self._test_same_option_twice('bindir', ['-Dbindir=foo', '-Dbindir=bar'])

    def test_same_project_d_option_twice(self):
        self._test_same_option_twice('one', ['-Done=foo', '-Done=bar'])

    def _test_same_option_twice_configure(self, arg, args):
        testdir = os.path.join(self.unit_test_dir, '37 mixed command line args')
        self.init(testdir)
        self.setconf(args)
        opts = self.introspect('--buildoptions')
        for item in opts:
            if item['name'] == arg:
                self.assertEqual(item['value'], 'bar')
                return
        raise Exception(f'Missing {arg} value?')

    def test_same_dash_option_twice_configure(self):
        self._test_same_option_twice_configure(
            'bindir', ['--bindir=foo', '--bindir=bar'])

    def test_same_d_option_twice_configure(self):
        self._test_same_option_twice_configure(
            'bindir', ['-Dbindir=foo', '-Dbindir=bar'])

    def test_same_project_d_option_twice_configure(self):
        self._test_same_option_twice_configure(
            'one', ['-Done=foo', '-Done=bar'])

    def test_command_line(self):
        testdir = os.path.join(self.unit_test_dir, '34 command line')

        # Verify default values when passing no args that affect the
        # configuration, and as a bonus, test that --profile-self works.
        out = self.init(testdir, extra_args=['--profile-self', '--fatal-meson-warnings'])
        self.assertNotIn('[default: true]', out)
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('default_library')].value, 'static')
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
        self.assertEqual(obj.options[OptionKey('set_sub_opt')].value, True)
        self.assertEqual(obj.options[OptionKey('subp_opt', 'subp')].value, 'default3')
        self.wipe()

        # warning_level is special, it's --warnlevel instead of --warning-level
        # for historical reasons
        self.init(testdir, extra_args=['--warnlevel=2', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '2')
        self.setconf('--warnlevel=3')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '3')
        self.wipe()

        # But when using -D syntax, it should be 'warning_level'
        self.init(testdir, extra_args=['-Dwarning_level=2', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '2')
        self.setconf('-Dwarning_level=3')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '3')
        self.wipe()

        # Mixing --option and -Doption is forbidden
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm:
            self.init(testdir, extra_args=['--warnlevel=1', '-Dwarning_level=3'])
            if isinstance(cm.exception, subprocess.CalledProcessError):
                self.assertNotEqual(0, cm.exception.returncode)
                self.assertIn('as both', cm.exception.output)
            else:
                self.assertIn('as both', str(cm.exception))
        self.init(testdir)
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm:
            self.setconf(['--warnlevel=1', '-Dwarning_level=3'])
            if isinstance(cm.exception, subprocess.CalledProcessError):
                self.assertNotEqual(0, cm.exception.returncode)
                self.assertIn('as both', cm.exception.output)
            else:
                self.assertIn('as both', str(cm.exception))
        self.wipe()

        # --default-library should override default value from project()
        self.init(testdir, extra_args=['--default-library=both', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('default_library')].value, 'both')
        self.setconf('--default-library=shared')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('default_library')].value, 'shared')
        if self.backend is Backend.ninja:
            # reconfigure target works only with ninja backend
            self.build('reconfigure')
            obj = mesonbuild.coredata.load(self.builddir)
            self.assertEqual(obj.options[OptionKey('default_library')].value, 'shared')
        self.wipe()

        # Should fail on unknown options
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm:
            self.init(testdir, extra_args=['-Dbad=1', '-Dfoo=2', '-Dwrong_link_args=foo'])
            self.assertNotEqual(0, cm.exception.returncode)
            self.assertIn(msg, cm.exception.output)
        self.wipe()

        # Should fail on malformed option
        msg = "Option 'foo' must have a value separated by equals sign."
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm:
            self.init(testdir, extra_args=['-Dfoo'])
            if isinstance(cm.exception, subprocess.CalledProcessError):
                self.assertNotEqual(0, cm.exception.returncode)
                self.assertIn(msg, cm.exception.output)
            else:
                self.assertIn(msg, str(cm.exception))
        self.init(testdir)
        with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm:
            self.setconf('-Dfoo')
            if isinstance(cm.exception, subprocess.CalledProcessError):
                self.assertNotEqual(0, cm.exception.returncode)
                self.assertIn(msg, cm.exception.output)
            else:
                self.assertIn(msg, str(cm.exception))
        self.wipe()

        # It is not an error to set wrong option for unknown subprojects or
        # language because we don't have control on which one will be selected.
        self.init(testdir, extra_args=['-Dc_wrong=1', '-Dwrong:bad=1', '-Db_wrong=1'])
        self.wipe()

        # Test we can set subproject option
        self.init(testdir, extra_args=['-Dsubp:subp_opt=foo', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('subp_opt', 'subp')].value, 'foo')
        self.wipe()

        # c_args value should be parsed with split_args
        self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dfoo', '-Dbar', '-Dthird=one two'])

        self.setconf('-Dc_args="foo bar" one two')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['foo bar', 'one', 'two'])
        self.wipe()

        self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('set_percent_opt')].value, 'myoption%')
        self.wipe()

        # Setting a 2nd time the same option should override the first value
        try:
            self.init(testdir, extra_args=['--bindir=foo', '--bindir=bar',
                                           '-Dbuildtype=plain', '-Dbuildtype=release',
                                           '-Db_sanitize=address', '-Db_sanitize=thread',
                                           '-Dc_args=-Dfoo', '-Dc_args=-Dbar',
                                           '-Db_lundef=false', '--fatal-meson-warnings'])
            obj = mesonbuild.coredata.load(self.builddir)
            self.assertEqual(obj.options[OptionKey('bindir')].value, 'bar')
            self.assertEqual(obj.options[OptionKey('buildtype')].value, 'release')
            self.assertEqual(obj.options[OptionKey('b_sanitize')].value, 'thread')
            self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dbar'])
            self.setconf(['--bindir=bar', '--bindir=foo',
                          '-Dbuildtype=release', '-Dbuildtype=plain',
                          '-Db_sanitize=thread', '-Db_sanitize=address',
                          '-Dc_args=-Dbar', '-Dc_args=-Dfoo'])
            obj = mesonbuild.coredata.load(self.builddir)
            self.assertEqual(obj.options[OptionKey('bindir')].value, 'foo')
            self.assertEqual(obj.options[OptionKey('buildtype')].value, 'plain')
            self.assertEqual(obj.options[OptionKey('b_sanitize')].value, 'address')
            self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dfoo'])
            self.wipe()
        except KeyError:
            # Ignore KeyError, it happens on CI for compilers that does not
            # support b_sanitize. We have to test with a base option because
            # they used to fail this test with Meson 0.46 an earlier versions.
            pass

    def test_warning_level_0(self):
        testdir = os.path.join(self.common_test_dir, '207 warning level 0')

        # Verify default values when passing no args
        self.init(testdir)
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
        self.wipe()

        # verify we can override w/ --warnlevel
        self.init(testdir, extra_args=['--warnlevel=1'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
        self.setconf('--warnlevel=0')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
        self.wipe()

        # verify we can override w/ -Dwarning_level
        self.init(testdir, extra_args=['-Dwarning_level=1'])
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
        self.setconf('-Dwarning_level=0')
        obj = mesonbuild.coredata.load(self.builddir)
        self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
        self.wipe()

    def test_feature_check_usage_subprojects(self):
        testdir = os.path.join(self.unit_test_dir, '40 featurenew subprojects')
        out = self.init(testdir)
        # Parent project warns correctly
        self.assertRegex(out, "WARNING: Project targeting '>=0.45'.*'0.47.0': dict")
        # Subprojects warn correctly
        self.assertRegex(out, r"foo\| .*WARNING: Project targeting '>=0.40'.*'0.44.0': disabler")
        self.assertRegex(out, r"baz\| .*WARNING: Project targeting '!=0.40'.*'0.44.0': disabler")
        # Subproject has a new-enough meson_version, no warning
        self.assertNotRegex(out, "WARNING: Project targeting.*Python")
        # Ensure a summary is printed in the subproject and the outer project
        self.assertRegex(out, r"\| WARNING: Project specifies a minimum meson_version '>=0.40'")
        self.assertRegex(out, r"\| \* 0.44.0: {'disabler'}")
        self.assertRegex(out, "WARNING: Project specifies a minimum meson_version '>=0.45'")
        self.assertRegex(out, " * 0.47.0: {'dict'}")

    def test_configure_file_warnings(self):
        testdir = os.path.join(self.common_test_dir, "14 configure file")
        out = self.init(testdir)
        self.assertRegex(out, "WARNING:.*'empty'.*config.h.in.*not present.*")
        self.assertRegex(out, "WARNING:.*'FOO_BAR'.*nosubst-nocopy2.txt.in.*not present.*")
        self.assertRegex(out, "WARNING:.*'empty'.*config.h.in.*not present.*")
        self.assertRegex(out, "WARNING:.*empty configuration_data.*test.py.in")
        # Warnings for configuration files that are overwritten.
        self.assertRegex(out, "WARNING:.*\"double_output.txt\".*overwrites")
        self.assertRegex(out, "WARNING:.*\"subdir.double_output2.txt\".*overwrites")
        self.assertNotRegex(out, "WARNING:.*no_write_conflict.txt.*overwrites")
        self.assertNotRegex(out, "WARNING:.*@BASENAME@.*overwrites")
        self.assertRegex(out, "WARNING:.*\"sameafterbasename\".*overwrites")
        # No warnings about empty configuration data objects passed to files with substitutions
        self.assertNotRegex(out, "WARNING:.*empty configuration_data.*nosubst-nocopy1.txt.in")
        self.assertNotRegex(out, "WARNING:.*empty configuration_data.*nosubst-nocopy2.txt.in")
        with open(os.path.join(self.builddir, 'nosubst-nocopy1.txt'), 'rb') as f:
            self.assertEqual(f.read().strip(), b'/* #undef FOO_BAR */')
        with open(os.path.join(self.builddir, 'nosubst-nocopy2.txt'), 'rb') as f:
            self.assertEqual(f.read().strip(), b'')

    def test_dirs(self):
        with tempfile.TemporaryDirectory() as containing:
            with tempfile.TemporaryDirectory(dir=containing) as srcdir:
                mfile = os.path.join(srcdir, 'meson.build')
                of = open(mfile, 'w', encoding='utf-8')
                of.write("project('foobar', 'c')\n")
                of.close()
                pc = subprocess.run(self.setup_command,
                                    cwd=srcdir,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.DEVNULL)
                self.assertIn(b'Must specify at least one directory name', pc.stdout)
                with tempfile.TemporaryDirectory(dir=srcdir) as builddir:
                    subprocess.run(self.setup_command,
                                   check=True,
                                   cwd=builddir,
                                   stdout=subprocess.DEVNULL,
                                   stderr=subprocess.DEVNULL)

    def get_opts_as_dict(self):
        result = {}
        for i in self.introspect('--buildoptions'):
            result[i['name']] = i['value']
        return result

    def test_buildtype_setting(self):
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        self.init(testdir)
        opts = self.get_opts_as_dict()
        self.assertEqual(opts['buildtype'], 'debug')
        self.assertEqual(opts['debug'], True)
        self.setconf('-Ddebug=false')
        opts = self.get_opts_as_dict()
        self.assertEqual(opts['debug'], False)
        self.assertEqual(opts['buildtype'], 'debug')
        self.assertEqual(opts['optimization'], '0')
        self.setconf('-Doptimization=g')
        opts = self.get_opts_as_dict()
        self.assertEqual(opts['debug'], False)
        self.assertEqual(opts['buildtype'], 'debug')
        self.assertEqual(opts['optimization'], 'g')

    @skipIfNoPkgconfig
    @skipIf(is_windows(), 'Help needed with fixing this test on windows')
    def test_native_dep_pkgconfig(self):
        testdir = os.path.join(self.unit_test_dir,
                               '45 native dep pkgconfig var')
        with tempfile.NamedTemporaryFile(mode='w', delete=False) as crossfile:
            crossfile.write(textwrap.dedent(
                '''[binaries]
                pkgconfig = '{}'

                [properties]

                [host_machine]
                system = 'linux'
                cpu_family = 'arm'
                cpu = 'armv7'
                endian = 'little'
                '''.format(os.path.join(testdir, 'cross_pkgconfig.py'))))
            crossfile.flush()
            self.meson_cross_files = [crossfile.name]

        env = {'PKG_CONFIG_LIBDIR':  os.path.join(testdir,
                                                  'native_pkgconfig')}
        self.init(testdir, extra_args=['-Dstart_native=false'], override_envvars=env)
        self.wipe()
        self.init(testdir, extra_args=['-Dstart_native=true'], override_envvars=env)

    @skipIfNoPkgconfig
    @skipIf(is_windows(), 'Help needed with fixing this test on windows')
    def test_pkg_config_libdir(self):
        testdir = os.path.join(self.unit_test_dir,
                               '45 native dep pkgconfig var')
        with tempfile.NamedTemporaryFile(mode='w', delete=False) as crossfile:
            crossfile.write(textwrap.dedent(
                '''[binaries]
                pkgconfig = 'pkg-config'

                [properties]
                pkg_config_libdir = ['{}']

                [host_machine]
                system = 'linux'
                cpu_family = 'arm'
                cpu = 'armv7'
                endian = 'little'
                '''.format(os.path.join(testdir, 'cross_pkgconfig'))))
            crossfile.flush()
            self.meson_cross_files = [crossfile.name]

        env = {'PKG_CONFIG_LIBDIR':  os.path.join(testdir,
                                                  'native_pkgconfig')}
        self.init(testdir, extra_args=['-Dstart_native=false'], override_envvars=env)
        self.wipe()
        self.init(testdir, extra_args=['-Dstart_native=true'], override_envvars=env)

    def __reconfigure(self):
        # Set an older version to force a reconfigure from scratch
        filename = os.path.join(self.privatedir, 'coredata.dat')
        with open(filename, 'rb') as f:
            obj = pickle.load(f)
        obj.version = '0.47.0'
        with open(filename, 'wb') as f:
            pickle.dump(obj, f)

    def test_reconfigure(self):
        testdir = os.path.join(self.unit_test_dir, '47 reconfigure')
        self.init(testdir, extra_args=['-Dopt1=val1', '-Dsub1:werror=true'])
        self.setconf('-Dopt2=val2')

        self.__reconfigure()

        out = self.init(testdir, extra_args=['--reconfigure', '-Dopt3=val3'])
        self.assertRegex(out, 'Regenerating configuration from scratch')
        self.assertRegex(out, 'opt1 val1')
        self.assertRegex(out, 'opt2 val2')
        self.assertRegex(out, 'opt3 val3')
        self.assertRegex(out, 'opt4 default4')
        self.assertRegex(out, 'sub1:werror true')
        self.build()
        self.run_tests()

        # Create a file in builddir and verify wipe command removes it
        filename = os.path.join(self.builddir, 'something')
        open(filename, 'w', encoding='utf-8').close()
        self.assertTrue(os.path.exists(filename))
        out = self.init(testdir, extra_args=['--wipe', '-Dopt4=val4'])
        self.assertFalse(os.path.exists(filename))
        self.assertRegex(out, 'opt1 val1')
        self.assertRegex(out, 'opt2 val2')
        self.assertRegex(out, 'opt3 val3')
        self.assertRegex(out, 'opt4 val4')
        self.assertRegex(out, 'sub1:werror true')
        self.assertTrue(Path(self.builddir, '.gitignore').exists())
        self.build()
        self.run_tests()

    def test_wipe_from_builddir(self):
        testdir = os.path.join(self.common_test_dir, '157 custom target subdir depend files')
        self.init(testdir)
        self.__reconfigure()
        self.init(testdir, extra_args=['--wipe'], workdir=self.builddir)

    def test_target_construct_id_from_path(self):
        # This id is stable but not guessable.
        # The test is supposed to prevent unintentional
        # changes of target ID generation.
        target_id = Target.construct_id_from_path('some/obscure/subdir',
                                                  'target-id', '@suffix')
        self.assertEqual('5e002d3@@target-id@suffix', target_id)
        target_id = Target.construct_id_from_path('subproject/foo/subdir/bar',
                                                  'target2-id', '@other')
        self.assertEqual('81d46d1@@target2-id@other', target_id)

    def test_introspect_projectinfo_without_configured_build(self):
        testfile = os.path.join(self.common_test_dir, '33 run program', 'meson.build')
        res = self.introspect_directory(testfile, '--projectinfo')
        self.assertEqual(set(res['buildsystem_files']), {'meson.build'})
        self.assertEqual(res['version'], 'undefined')
        self.assertEqual(res['descriptive_name'], 'run command')
        self.assertEqual(res['subprojects'], [])

        testfile = os.path.join(self.common_test_dir, '40 options', 'meson.build')
        res = self.introspect_directory(testfile, '--projectinfo')
        self.assertEqual(set(res['buildsystem_files']), {'meson_options.txt', 'meson.build'})
        self.assertEqual(res['version'], 'undefined')
        self.assertEqual(res['descriptive_name'], 'options')
        self.assertEqual(res['subprojects'], [])

        testfile = os.path.join(self.common_test_dir, '43 subproject options', 'meson.build')
        res = self.introspect_directory(testfile, '--projectinfo')
        self.assertEqual(set(res['buildsystem_files']), {'meson_options.txt', 'meson.build'})
        self.assertEqual(res['version'], 'undefined')
        self.assertEqual(res['descriptive_name'], 'suboptions')
        self.assertEqual(len(res['subprojects']), 1)
        subproject_files = {f.replace('\\', '/') for f in res['subprojects'][0]['buildsystem_files']}
        self.assertEqual(subproject_files, {'subprojects/subproject/meson_options.txt', 'subprojects/subproject/meson.build'})
        self.assertEqual(res['subprojects'][0]['name'], 'subproject')
        self.assertEqual(res['subprojects'][0]['version'], 'undefined')
        self.assertEqual(res['subprojects'][0]['descriptive_name'], 'subproject')

    def test_introspect_projectinfo_subprojects(self):
        testdir = os.path.join(self.common_test_dir, '98 subproject subdir')
        self.init(testdir)
        res = self.introspect('--projectinfo')
        expected = {
            'descriptive_name': 'proj',
            'version': 'undefined',
            'subproject_dir': 'subprojects',
            'subprojects': [
                {
                    'descriptive_name': 'sub',
                    'name': 'sub',
                    'version': '1.0'
                },
                {
                    'descriptive_name': 'sub_implicit',
                    'name': 'sub_implicit',
                    'version': '1.0',
                },
                {
                    'descriptive_name': 'sub-novar',
                    'name': 'sub_novar',
                    'version': '1.0',
                },
                {
                    'descriptive_name': 'sub_static',
                    'name': 'sub_static',
                    'version': 'undefined'
                },
                {
                    'descriptive_name': 'subsub',
                    'name': 'subsub',
                    'version': 'undefined'
                },
                {
                    'descriptive_name': 'subsubsub',
                    'name': 'subsubsub',
                    'version': 'undefined'
                },
            ]
        }
        res['subprojects'] = sorted(res['subprojects'], key=lambda i: i['name'])
        self.assertDictEqual(expected, res)

    def test_introspection_target_subproject(self):
        testdir = os.path.join(self.common_test_dir, '42 subproject')
        self.init(testdir)
        res = self.introspect('--targets')

        expected = {
            'sublib': 'sublib',
            'simpletest': 'sublib',
            'user': None
        }

        for entry in res:
            name = entry['name']
            self.assertEqual(entry['subproject'], expected[name])

    def test_introspect_projectinfo_subproject_dir(self):
        testdir = os.path.join(self.common_test_dir, '75 custom subproject dir')
        self.init(testdir)
        res = self.introspect('--projectinfo')

        self.assertEqual(res['subproject_dir'], 'custom_subproject_dir')

    def test_introspect_projectinfo_subproject_dir_from_source(self):
        testfile = os.path.join(self.common_test_dir, '75 custom subproject dir', 'meson.build')
        res = self.introspect_directory(testfile, '--projectinfo')

        self.assertEqual(res['subproject_dir'], 'custom_subproject_dir')

    @skipIfNoExecutable('clang-format')
    def test_clang_format(self):
        if self.backend is not Backend.ninja:
            raise SkipTest(f'Clang-format is for now only supported on Ninja, not {self.backend.name}')
        testdir = os.path.join(self.unit_test_dir, '53 clang-format')

        # Ensure that test project is in git even when running meson from tarball.
        srcdir = os.path.join(self.builddir, 'src')
        shutil.copytree(testdir, srcdir)
        _git_init(srcdir)
        testdir = srcdir
        self.new_builddir()

        testfile = os.path.join(testdir, 'prog.c')
        badfile = os.path.join(testdir, 'prog_orig_c')
        goodfile = os.path.join(testdir, 'prog_expected_c')
        testheader = os.path.join(testdir, 'header.h')
        badheader = os.path.join(testdir, 'header_orig_h')
        goodheader = os.path.join(testdir, 'header_expected_h')
        includefile = os.path.join(testdir, '.clang-format-include')
        try:
            shutil.copyfile(badfile, testfile)
            shutil.copyfile(badheader, testheader)
            self.init(testdir)
            self.assertNotEqual(Path(testfile).read_text(encoding='utf-8'),
                                Path(goodfile).read_text(encoding='utf-8'))
            self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'),
                                Path(goodheader).read_text(encoding='utf-8'))

            # test files are not in git so this should do nothing
            self.run_target('clang-format')
            self.assertNotEqual(Path(testfile).read_text(encoding='utf-8'),
                                Path(goodfile).read_text(encoding='utf-8'))
            self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'),
                                Path(goodheader).read_text(encoding='utf-8'))

            # Add an include file to reformat everything
            with open(includefile, 'w', encoding='utf-8') as f:
                f.write('*')
            self.run_target('clang-format')
            self.assertEqual(Path(testheader).read_text(encoding='utf-8'),
                             Path(goodheader).read_text(encoding='utf-8'))
        finally:
            if os.path.exists(testfile):
                os.unlink(testfile)
            if os.path.exists(testheader):
                os.unlink(testheader)
            if os.path.exists(includefile):
                os.unlink(includefile)

    @skipIfNoExecutable('clang-tidy')
    def test_clang_tidy(self):
        if self.backend is not Backend.ninja:
            raise SkipTest(f'Clang-tidy is for now only supported on Ninja, not {self.backend.name}')
        if shutil.which('c++') is None:
            raise SkipTest('Clang-tidy breaks when ccache is used and "c++" not in path.')
        if is_osx():
            raise SkipTest('Apple ships a broken clang-tidy that chokes on -pipe.')
        testdir = os.path.join(self.unit_test_dir, '68 clang-tidy')
        dummydir = os.path.join(testdir, 'dummydir.h')
        self.init(testdir, override_envvars={'CXX': 'c++'})
        out = self.run_target('clang-tidy')
        self.assertIn('cttest.cpp:4:20', out)
        self.assertNotIn(dummydir, out)

    def test_identity_cross(self):
        testdir = os.path.join(self.unit_test_dir, '69 cross')
        # Do a build to generate a cross file where the host is this target
        self.init(testdir, extra_args=['-Dgenerate=true'])
        self.meson_cross_files = [os.path.join(self.builddir, "crossfile")]
        self.assertTrue(os.path.exists(self.meson_cross_files[0]))
        # Now verify that this is detected as cross
        self.new_builddir()
        self.init(testdir)

    def test_introspect_buildoptions_without_configured_build(self):
        testdir = os.path.join(self.unit_test_dir, '58 introspect buildoptions')
        testfile = os.path.join(testdir, 'meson.build')
        res_nb = self.introspect_directory(testfile, ['--buildoptions'] + self.meson_args)
        self.init(testdir, default_args=False)
        res_wb = self.introspect('--buildoptions')
        self.maxDiff = None
        # XXX: These now generate in a different order, is that okay?
        self.assertListEqual(sorted(res_nb, key=lambda x: x['name']), sorted(res_wb, key=lambda x: x['name']))

    def test_meson_configure_from_source_does_not_crash(self):
        testdir = os.path.join(self.unit_test_dir, '58 introspect buildoptions')
        self._run(self.mconf_command + [testdir])

    def test_introspect_buildoptions_cross_only(self):
        testdir = os.path.join(self.unit_test_dir, '82 cross only introspect')
        testfile = os.path.join(testdir, 'meson.build')
        res = self.introspect_directory(testfile, ['--buildoptions'] + self.meson_args)
        optnames = [o['name'] for o in res]
        self.assertIn('c_args', optnames)
        self.assertNotIn('build.c_args', optnames)

    def test_introspect_json_flat(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        self.init(testdir, extra_args=['-Dlayout=flat'])
        infodir = os.path.join(self.builddir, 'meson-info')
        self.assertPathExists(infodir)

        with open(os.path.join(infodir, 'intro-targets.json'), encoding='utf-8') as fp:
            targets = json.load(fp)

        for i in targets:
            for out in i['filename']:
                assert os.path.relpath(out, self.builddir).startswith('meson-out')

    def test_introspect_json_dump(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        self.init(testdir)
        infodir = os.path.join(self.builddir, 'meson-info')
        self.assertPathExists(infodir)

        def assertKeyTypes(key_type_list, obj, strict: bool = True):
            for i in key_type_list:
                if isinstance(i[1], (list, tuple)) and None in i[1]:
                    i = (i[0], tuple(x for x in i[1] if x is not None))
                    if i[0] not in obj or obj[i[0]] is None:
                        continue
                self.assertIn(i[0], obj)
                self.assertIsInstance(obj[i[0]], i[1])
            if strict:
                for k in obj.keys():
                    found = False
                    for i in key_type_list:
                        if k == i[0]:
                            found = True
                            break
                    self.assertTrue(found, f'Key "{k}" not in expected list')

        root_keylist = [
            ('benchmarks', list),
            ('buildoptions', list),
            ('buildsystem_files', list),
            ('dependencies', list),
            ('installed', dict),
            ('projectinfo', dict),
            ('targets', list),
            ('tests', list),
        ]

        test_keylist = [
            ('cmd', list),
            ('env', dict),
            ('name', str),
            ('timeout', int),
            ('suite', list),
            ('is_parallel', bool),
            ('protocol', str),
            ('depends', list),
            ('workdir', (str, None)),
            ('priority', int),
        ]

        buildoptions_keylist = [
            ('name', str),
            ('section', str),
            ('type', str),
            ('description', str),
            ('machine', str),
            ('choices', (list, None)),
            ('value', (str, int, bool, list)),
        ]

        buildoptions_typelist = [
            ('combo', str, [('choices', list)]),
            ('string', str, []),
            ('boolean', bool, []),
            ('integer', int, []),
            ('array', list, []),
        ]

        buildoptions_sections = ['core', 'backend', 'base', 'compiler', 'directory', 'user', 'test']
        buildoptions_machines = ['any', 'build', 'host']

        dependencies_typelist = [
            ('name', str),
            ('version', str),
            ('compile_args', list),
            ('link_args', list),
        ]

        targets_typelist = [
            ('name', str),
            ('id', str),
            ('type', str),
            ('defined_in', str),
            ('filename', list),
            ('build_by_default', bool),
            ('target_sources', list),
            ('extra_files', list),
            ('subproject', (str, None)),
            ('install_filename', (list, None)),
            ('installed', bool),
        ]

        targets_sources_typelist = [
            ('language', str),
            ('compiler', list),
            ('parameters', list),
            ('sources', list),
            ('generated_sources', list),
        ]

        # First load all files
        res = {}
        for i in root_keylist:
            curr = os.path.join(infodir, 'intro-{}.json'.format(i[0]))
            self.assertPathExists(curr)
            with open(curr, encoding='utf-8') as fp:
                res[i[0]] = json.load(fp)

        assertKeyTypes(root_keylist, res)

        # Match target ids to input and output files for ease of reference
        src_to_id = {}
        out_to_id = {}
        name_to_out = {}
        for i in res['targets']:
            print(json.dump(i, sys.stdout))
            out_to_id.update({os.path.relpath(out, self.builddir): i['id']
                              for out in i['filename']})
            name_to_out.update({i['name']: i['filename']})
            for group in i['target_sources']:
                src_to_id.update({os.path.relpath(src, testdir): i['id']
                                  for src in group['sources']})

        # Check Tests and benchmarks
        tests_to_find = ['test case 1', 'test case 2', 'benchmark 1']
        deps_to_find = {'test case 1': [src_to_id['t1.cpp']],
                        'test case 2': [src_to_id['t2.cpp'], src_to_id['t3.cpp']],
                        'benchmark 1': [out_to_id['file2'], out_to_id['file3'], out_to_id['file4'], src_to_id['t3.cpp']]}
        for i in res['benchmarks'] + res['tests']:
            assertKeyTypes(test_keylist, i)
            if i['name'] in tests_to_find:
                tests_to_find.remove(i['name'])
            self.assertEqual(sorted(i['depends']),
                             sorted(deps_to_find[i['name']]))
        self.assertListEqual(tests_to_find, [])

        # Check buildoptions
        buildopts_to_find = {'cpp_std': 'c++11'}
        for i in res['buildoptions']:
            assertKeyTypes(buildoptions_keylist, i)
            valid_type = False
            for j in buildoptions_typelist:
                if i['type'] == j[0]:
                    self.assertIsInstance(i['value'], j[1])
                    assertKeyTypes(j[2], i, strict=False)
                    valid_type = True
                    break

            self.assertIn(i['section'], buildoptions_sections)
            self.assertIn(i['machine'], buildoptions_machines)
            self.assertTrue(valid_type)
            if i['name'] in buildopts_to_find:
                self.assertEqual(i['value'], buildopts_to_find[i['name']])
                buildopts_to_find.pop(i['name'], None)
        self.assertDictEqual(buildopts_to_find, {})

        # Check buildsystem_files
        bs_files = ['meson.build', 'meson_options.txt', 'sharedlib/meson.build', 'staticlib/meson.build']
        bs_files = [os.path.join(testdir, x) for x in bs_files]
        self.assertPathListEqual(list(sorted(res['buildsystem_files'])), list(sorted(bs_files)))

        # Check dependencies
        dependencies_to_find = ['threads']
        for i in res['dependencies']:
            assertKeyTypes(dependencies_typelist, i)
            if i['name'] in dependencies_to_find:
                dependencies_to_find.remove(i['name'])
        self.assertListEqual(dependencies_to_find, [])

        # Check projectinfo
        self.assertDictEqual(res['projectinfo'], {'version': '1.2.3', 'descriptive_name': 'introspection', 'subproject_dir': 'subprojects', 'subprojects': []})

        # Check targets
        targets_to_find = {
            'sharedTestLib': ('shared library', True, False, 'sharedlib/meson.build',
                              [os.path.join(testdir, 'sharedlib', 'shared.cpp')]),
            'staticTestLib': ('static library', True, False, 'staticlib/meson.build',
                              [os.path.join(testdir, 'staticlib', 'static.c')]),
            'custom target test 1': ('custom', False, False, 'meson.build',
                                     [os.path.join(testdir, 'cp.py')]),
            'custom target test 2': ('custom', False, False, 'meson.build',
                                     name_to_out['custom target test 1']),
            'test1': ('executable', True, True, 'meson.build',
                      [os.path.join(testdir, 't1.cpp')]),
            'test2': ('executable', True, False, 'meson.build',
                      [os.path.join(testdir, 't2.cpp')]),
            'test3': ('executable', True, False, 'meson.build',
                      [os.path.join(testdir, 't3.cpp')]),
            'custom target test 3': ('custom', False, False, 'meson.build',
                                     name_to_out['test3']),
        }
        for i in res['targets']:
            assertKeyTypes(targets_typelist, i)
            if i['name'] in targets_to_find:
                tgt = targets_to_find[i['name']]
                self.assertEqual(i['type'], tgt[0])
                self.assertEqual(i['build_by_default'], tgt[1])
                self.assertEqual(i['installed'], tgt[2])
                self.assertPathEqual(i['defined_in'], os.path.join(testdir, tgt[3]))
                targets_to_find.pop(i['name'], None)
            for j in i['target_sources']:
                assertKeyTypes(targets_sources_typelist, j)
                self.assertEqual(j['sources'], [os.path.normpath(f) for f in tgt[4]])
        self.assertDictEqual(targets_to_find, {})

    def test_introspect_file_dump_equals_all(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        self.init(testdir)
        res_all = self.introspect('--all')
        res_file = {}

        root_keylist = [
            'benchmarks',
            'buildoptions',
            'buildsystem_files',
            'dependencies',
            'installed',
            'install_plan',
            'projectinfo',
            'targets',
            'tests',
        ]

        infodir = os.path.join(self.builddir, 'meson-info')
        self.assertPathExists(infodir)
        for i in root_keylist:
            curr = os.path.join(infodir, f'intro-{i}.json')
            self.assertPathExists(curr)
            with open(curr, encoding='utf-8') as fp:
                res_file[i] = json.load(fp)

        self.assertEqual(res_all, res_file)

    def test_introspect_meson_info(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        introfile = os.path.join(self.builddir, 'meson-info', 'meson-info.json')
        self.init(testdir)
        self.assertPathExists(introfile)
        with open(introfile, encoding='utf-8') as fp:
            res1 = json.load(fp)

        for i in ['meson_version', 'directories', 'introspection', 'build_files_updated', 'error']:
            self.assertIn(i, res1)

        self.assertEqual(res1['error'], False)
        self.assertEqual(res1['build_files_updated'], True)

    def test_introspect_config_update(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        introfile = os.path.join(self.builddir, 'meson-info', 'intro-buildoptions.json')
        self.init(testdir)
        self.assertPathExists(introfile)
        with open(introfile, encoding='utf-8') as fp:
            res1 = json.load(fp)

        for i in res1:
            if i['name'] == 'cpp_std':
                i['value'] = 'c++14'
            if i['name'] == 'build.cpp_std':
                i['value'] = 'c++14'
            if i['name'] == 'buildtype':
                i['value'] = 'release'
            if i['name'] == 'optimization':
                i['value'] = '3'
            if i['name'] == 'debug':
                i['value'] = False

        self.setconf('-Dcpp_std=c++14')
        self.setconf('-Dbuildtype=release')

        with open(introfile, encoding='utf-8') as fp:
            res2 = json.load(fp)

        self.assertListEqual(res1, res2)

    def test_introspect_targets_from_source(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        testfile = os.path.join(testdir, 'meson.build')
        introfile = os.path.join(self.builddir, 'meson-info', 'intro-targets.json')
        self.init(testdir)
        self.assertPathExists(introfile)
        with open(introfile, encoding='utf-8') as fp:
            res_wb = json.load(fp)

        res_nb = self.introspect_directory(testfile, ['--targets'] + self.meson_args)

        # Account for differences in output
        res_wb = [i for i in res_wb if i['type'] != 'custom']
        for i in res_wb:
            i['filename'] = [os.path.relpath(x, self.builddir) for x in i['filename']]
            if 'install_filename' in i:
                del i['install_filename']

            sources = []
            for j in i['target_sources']:
                sources += j['sources']
            i['target_sources'] = [{
                'language': 'unknown',
                'compiler': [],
                'parameters': [],
                'sources': sources,
                'generated_sources': []
            }]

        self.maxDiff = None
        self.assertListEqual(res_nb, res_wb)

    def test_introspect_ast_source(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        testfile = os.path.join(testdir, 'meson.build')
        res_nb = self.introspect_directory(testfile, ['--ast'] + self.meson_args)

        node_counter = {}

        def accept_node(json_node):
            self.assertIsInstance(json_node, dict)
            for i in ['lineno', 'colno', 'end_lineno', 'end_colno']:
                self.assertIn(i, json_node)
                self.assertIsInstance(json_node[i], int)
            self.assertIn('node', json_node)
            n = json_node['node']
            self.assertIsInstance(n, str)
            self.assertIn(n, nodes)
            if n not in node_counter:
                node_counter[n] = 0
            node_counter[n] = node_counter[n] + 1
            for nodeDesc in nodes[n]:
                key = nodeDesc[0]
                func = nodeDesc[1]
                self.assertIn(key, json_node)
                if func is None:
                    tp = nodeDesc[2]
                    self.assertIsInstance(json_node[key], tp)
                    continue
                func(json_node[key])

        def accept_node_list(node_list):
            self.assertIsInstance(node_list, list)
            for i in node_list:
                accept_node(i)

        def accept_kwargs(kwargs):
            self.assertIsInstance(kwargs, list)
            for i in kwargs:
                self.assertIn('key', i)
                self.assertIn('val', i)
                accept_node(i['key'])
                accept_node(i['val'])

        nodes = {
            'BooleanNode': [('value', None, bool)],
            'IdNode': [('value', None, str)],
            'NumberNode': [('value', None, int)],
            'StringNode': [('value', None, str)],
            'FormatStringNode': [('value', None, str)],
            'ContinueNode': [],
            'BreakNode': [],
            'ArgumentNode': [('positional', accept_node_list), ('kwargs', accept_kwargs)],
            'ArrayNode': [('args', accept_node)],
            'DictNode': [('args', accept_node)],
            'EmptyNode': [],
            'OrNode': [('left', accept_node), ('right', accept_node)],
            'AndNode': [('left', accept_node), ('right', accept_node)],
            'ComparisonNode': [('left', accept_node), ('right', accept_node), ('ctype', None, str)],
            'ArithmeticNode': [('left', accept_node), ('right', accept_node), ('op', None, str)],
            'NotNode': [('right', accept_node)],
            'CodeBlockNode': [('lines', accept_node_list)],
            'IndexNode': [('object', accept_node), ('index', accept_node)],
            'MethodNode': [('object', accept_node), ('args', accept_node), ('name', None, str)],
            'FunctionNode': [('args', accept_node), ('name', None, str)],
            'AssignmentNode': [('value', accept_node), ('var_name', None, str)],
            'PlusAssignmentNode': [('value', accept_node), ('var_name', None, str)],
            'ForeachClauseNode': [('items', accept_node), ('block', accept_node), ('varnames', None, list)],
            'IfClauseNode': [('ifs', accept_node_list), ('else', accept_node)],
            'IfNode': [('condition', accept_node), ('block', accept_node)],
            'UMinusNode': [('right', accept_node)],
            'TernaryNode': [('condition', accept_node), ('true', accept_node), ('false', accept_node)],
        }

        accept_node(res_nb)

        for n, c in [('ContinueNode', 2), ('BreakNode', 1), ('NotNode', 3)]:
            self.assertIn(n, node_counter)
            self.assertEqual(node_counter[n], c)

    def test_introspect_dependencies_from_source(self):
        testdir = os.path.join(self.unit_test_dir, '56 introspection')
        testfile = os.path.join(testdir, 'meson.build')
        res_nb = self.introspect_directory(testfile, ['--scan-dependencies'] + self.meson_args)
        expected = [
            {
                'name': 'threads',
                'required': True,
                'version': [],
                'has_fallback': False,
                'conditional': False
            },
            {
                'name': 'zlib',
                'required': False,
                'version': [],
                'has_fallback': False,
                'conditional': False
            },
            {
                'name': 'bugDep1',
                'required': True,
                'version': [],
                'has_fallback': False,
                'conditional': False
            },
            {
                'name': 'somethingthatdoesnotexist',
                'required': True,
                'version': ['>=1.2.3'],
                'has_fallback': False,
                'conditional': True
            },
            {
                'name': 'look_i_have_a_fallback',
                'required': True,
                'version': ['>=1.0.0', '<=99.9.9'],
                'has_fallback': True,
                'conditional': True
            }
        ]
        self.maxDiff = None
        self.assertListEqual(res_nb, expected)

    def test_unstable_coredata(self):
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        self.init(testdir)
        # just test that the command does not fail (e.g. because it throws an exception)
        self._run([*self.meson_command, 'unstable-coredata', self.builddir])

    @skip_if_no_cmake
    def test_cmake_prefix_path(self):
        testdir = os.path.join(self.unit_test_dir, '62 cmake_prefix_path')
        self.init(testdir, extra_args=['-Dcmake_prefix_path=' + os.path.join(testdir, 'prefix')])

    @skip_if_no_cmake
    def test_cmake_parser(self):
        testdir = os.path.join(self.unit_test_dir, '63 cmake parser')
        self.init(testdir, extra_args=['-Dcmake_prefix_path=' + os.path.join(testdir, 'prefix')])

    def test_alias_target(self):
        testdir = os.path.join(self.unit_test_dir, '64 alias target')
        self.init(testdir)
        self.build()
        self.assertPathDoesNotExist(os.path.join(self.builddir, 'prog' + exe_suffix))
        self.assertPathDoesNotExist(os.path.join(self.builddir, 'hello.txt'))
        self.run_target('build-all')
        self.assertPathExists(os.path.join(self.builddir, 'prog' + exe_suffix))
        self.assertPathExists(os.path.join(self.builddir, 'hello.txt'))
        out = self.run_target('aliased-run')
        self.assertIn('a run target was here', out)

    def test_configure(self):
        testdir = os.path.join(self.common_test_dir, '2 cpp')
        self.init(testdir)
        self._run(self.mconf_command + [self.builddir])

    def test_summary(self):
        testdir = os.path.join(self.unit_test_dir, '71 summary')
        out = self.init(testdir, extra_args=['-Denabled_opt=enabled'])
        expected = textwrap.dedent(r'''
            Some Subproject 2.0

                string : bar
                integer: 1
                boolean: True

            subsub undefined

                Something: Some value

            My Project 1.0

              Configuration
                Some boolean   : False
                Another boolean: True
                Some string    : Hello World
                A list         : string
                                 1
                                 True
                empty list     :
                enabled_opt    : enabled
                A number       : 1
                yes            : YES
                no             : NO
                coma list      : a, b, c

              Stuff
                missing prog   : NO
                existing prog  : ''' + sys.executable + '''
                missing dep    : NO
                external dep   : YES 1.2.3
                internal dep   : YES

              Plugins
                long coma list : alpha, alphacolor, apetag, audiofx, audioparsers, auparse,
                                 autodetect, avi

              Subprojects
                sub            : YES
                sub2           : NO Problem encountered: This subproject failed
                subsub         : YES

              User defined options
                backend        : ''' + self.backend.name + '''
                libdir         : lib
                prefix         : /usr
                enabled_opt    : enabled
            ''')
        expected_lines = expected.split('\n')[1:]
        out_start = out.find(expected_lines[0])
        out_lines = out[out_start:].split('\n')[:len(expected_lines)]
        for e, o in zip(expected_lines, out_lines):
            if e.startswith('    external dep'):
                self.assertRegex(o, r'^    external dep   : (YES [0-9.]*|NO)$')
            else:
                self.assertEqual(o, e)

    def test_meson_compile(self):
        """Test the meson compile command."""

        def get_exe_name(basename: str) -> str:
            if is_windows():
                return f'{basename}.exe'
            else:
                return basename

        def get_shared_lib_name(basename: str) -> str:
            if mesonbuild.environment.detect_msys2_arch():
                return f'lib{basename}.dll'
            elif is_windows():
                return f'{basename}.dll'
            elif is_cygwin():
                return f'cyg{basename}.dll'
            elif is_osx():
                return f'lib{basename}.dylib'
            else:
                return f'lib{basename}.so'

        def get_static_lib_name(basename: str) -> str:
            return f'lib{basename}.a'

        # Base case (no targets or additional arguments)

        testdir = os.path.join(self.common_test_dir, '1 trivial')
        self.init(testdir)

        self._run([*self.meson_command, 'compile', '-C', self.builddir])
        self.assertPathExists(os.path.join(self.builddir, get_exe_name('trivialprog')))

        # `--clean`

        self._run([*self.meson_command, 'compile', '-C', self.builddir, '--clean'])
        self.assertPathDoesNotExist(os.path.join(self.builddir, get_exe_name('trivialprog')))

        # Target specified in a project with unique names

        testdir = os.path.join(self.common_test_dir, '6 linkshared')
        self.init(testdir, extra_args=['--wipe'])
        # Multiple targets and target type specified
        self._run([*self.meson_command, 'compile', '-C', self.builddir, 'mylib', 'mycpplib:shared_library'])
        # Check that we have a shared lib, but not an executable, i.e. check that target actually worked
        self.assertPathExists(os.path.join(self.builddir, get_shared_lib_name('mylib')))
        self.assertPathDoesNotExist(os.path.join(self.builddir, get_exe_name('prog')))
        self.assertPathExists(os.path.join(self.builddir, get_shared_lib_name('mycpplib')))
        self.assertPathDoesNotExist(os.path.join(self.builddir, get_exe_name('cppprog')))

        # Target specified in a project with non unique names

        testdir = os.path.join(self.common_test_dir, '185 same target name')
        self.init(testdir, extra_args=['--wipe'])
        self._run([*self.meson_command, 'compile', '-C', self.builddir, './foo'])
        self.assertPathExists(os.path.join(self.builddir, get_static_lib_name('foo')))
        self._run([*self.meson_command, 'compile', '-C', self.builddir, 'sub/foo'])
        self.assertPathExists(os.path.join(self.builddir, 'sub', get_static_lib_name('foo')))

        # run_target

        testdir = os.path.join(self.common_test_dir, '51 run target')
        self.init(testdir, extra_args=['--wipe'])
        out = self._run([*self.meson_command, 'compile', '-C', self.builddir, 'py3hi'])
        self.assertIn('I am Python3.', out)

        # `--$BACKEND-args`

        testdir = os.path.join(self.common_test_dir, '1 trivial')
        if self.backend is Backend.ninja:
            self.init(testdir, extra_args=['--wipe'])
            # Dry run - should not create a program
            self._run([*self.meson_command, 'compile', '-C', self.builddir, '--ninja-args=-n'])
            self.assertPathDoesNotExist(os.path.join(self.builddir, get_exe_name('trivialprog')))
        elif self.backend is Backend.vs:
            self.init(testdir, extra_args=['--wipe'])
            self._run([*self.meson_command, 'compile', '-C', self.builddir])
            # Explicitly clean the target through msbuild interface
            self._run([*self.meson_command, 'compile', '-C', self.builddir, '--vs-args=-t:{}:Clean'.format(re.sub(r'[\%\$\@\;\.\(\)\']', '_', get_exe_name('trivialprog')))])
            self.assertPathDoesNotExist(os.path.join(self.builddir, get_exe_name('trivialprog')))

    def test_spurious_reconfigure_built_dep_file(self):
        testdir = os.path.join(self.unit_test_dir, '73 dep files')

        # Regression test: Spurious reconfigure was happening when build
        # directory is inside source directory.
        # See https://gitlab.freedesktop.org/gstreamer/gst-build/-/issues/85.
        srcdir = os.path.join(self.builddir, 'srctree')
        shutil.copytree(testdir, srcdir)
        builddir = os.path.join(srcdir, '_build')
        self.change_builddir(builddir)

        self.init(srcdir)
        self.build()

        # During first configure the file did not exist so no dependency should
        # have been set. A rebuild should not trigger a reconfigure.
        self.clean()
        out = self.build()
        self.assertNotIn('Project configured', out)

        self.init(srcdir, extra_args=['--reconfigure'])

        # During the reconfigure the file did exist, but is inside build
        # directory, so no dependency should have been set. A rebuild should not
        # trigger a reconfigure.
        self.clean()
        out = self.build()
        self.assertNotIn('Project configured', out)

    def _test_junit(self, case: str) -> None:
        try:
            import lxml.etree as et
        except ImportError:
            raise SkipTest('lxml required, but not found.')

        schema = et.XMLSchema(et.parse(str(Path(self.src_root) / 'data' / 'schema.xsd')))

        self.init(case)
        self.run_tests()

        junit = et.parse(str(Path(self.builddir) / 'meson-logs' / 'testlog.junit.xml'))
        try:
            schema.assertValid(junit)
        except et.DocumentInvalid as e:
            self.fail(e.error_log)

    def test_junit_valid_tap(self):
        self._test_junit(os.path.join(self.common_test_dir, '206 tap tests'))

    def test_junit_valid_exitcode(self):
        self._test_junit(os.path.join(self.common_test_dir, '41 test args'))

    def test_junit_valid_gtest(self):
        self._test_junit(os.path.join(self.framework_test_dir, '2 gtest'))

    def test_link_language_linker(self):
        # TODO: there should be some way to query how we're linking things
        # without resorting to reading the ninja.build file
        if self.backend is not Backend.ninja:
            raise SkipTest('This test reads the ninja file')

        testdir = os.path.join(self.common_test_dir, '225 link language')
        self.init(testdir)

        build_ninja = os.path.join(self.builddir, 'build.ninja')
        with open(build_ninja, encoding='utf-8') as f:
            contents = f.read()

        self.assertRegex(contents, r'build main(\.exe)?.*: c_LINKER')
        self.assertRegex(contents, r'build (lib|cyg)?mylib.*: c_LINKER')

    def test_commands_documented(self):
        '''
        Test that all listed meson commands are documented in Commands.md.
        '''

        # The docs directory is not in release tarballs.
        if not os.path.isdir('docs'):
            raise SkipTest('Doc directory does not exist.')
        doc_path = 'docs/markdown/Commands.md'

        md = None
        with open(doc_path, encoding='utf-8') as f:
            md = f.read()
        self.assertIsNotNone(md)

        ## Get command sections

        section_pattern = re.compile(r'^### (.+)$', re.MULTILINE)
        md_command_section_matches = [i for i in section_pattern.finditer(md)]
        md_command_sections = dict()
        for i, s in enumerate(md_command_section_matches):
            section_end = len(md) if i == len(md_command_section_matches) - 1 else md_command_section_matches[i + 1].start()
            md_command_sections[s.group(1)] = (s.start(), section_end)

        ## Validate commands

        md_commands = {k for k,v in md_command_sections.items()}
        help_output = self._run(self.meson_command + ['--help'])
        # Python's argument parser might put the command list to its own line. Or it might not.
        self.assertTrue(help_output.startswith('usage: '))
        lines = help_output.split('\n')
        line1 = lines[0]
        line2 = lines[1]
        if '{' in line1:
            cmndline = line1
        else:
            self.assertIn('{', line2)
            cmndline = line2
        cmndstr = cmndline.split('{')[1]
        self.assertIn('}', cmndstr)
        help_commands = set(cmndstr.split('}')[0].split(','))
        self.assertTrue(len(help_commands) > 0, 'Must detect some command names.')

        self.assertEqual(md_commands | {'help'}, help_commands, f'Doc file: `{doc_path}`')

        ## Validate that each section has proper placeholders

        def get_data_pattern(command):
            return re.compile(
                r'{{ ' + command + r'_usage.inc }}[\r\n]'
                r'.*?'
                r'{{ ' + command + r'_arguments.inc }}[\r\n]',
                flags = re.MULTILINE|re.DOTALL)

        for command in md_commands:
            m = get_data_pattern(command).search(md, pos=md_command_sections[command][0], endpos=md_command_sections[command][1])
            self.assertIsNotNone(m, f'Command `{command}` is missing placeholders for dynamic data. Doc file: `{doc_path}`')

    def _check_coverage_files(self, types=('text', 'xml', 'html')):
        covdir = Path(self.builddir) / 'meson-logs'
        files = []
        if 'text' in types:
            files.append('coverage.txt')
        if 'xml' in types:
            files.append('coverage.xml')
        if 'html' in types:
            files.append('coveragereport/index.html')
        for f in files:
            self.assertTrue((covdir / f).is_file(), msg=f'{f} is not a file')

    def test_coverage(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage')
        self._check_coverage_files()

    def test_coverage_complex(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '105 generatorcustom')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage')
        self._check_coverage_files()

    def test_coverage_html(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage-html')
        self._check_coverage_files(['html'])

    def test_coverage_text(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage-text')
        self._check_coverage_files(['text'])

    def test_coverage_xml(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '1 trivial')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage-xml')
        self._check_coverage_files(['xml'])

    def test_coverage_escaping(self):
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with coverage on MSYS2')
        gcovr_exe, gcovr_new_rootdir = mesonbuild.environment.detect_gcovr()
        if not gcovr_exe:
            raise SkipTest('gcovr not found, or too old')
        testdir = os.path.join(self.common_test_dir, '243 escape++')
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_id() == 'clang':
            if not mesonbuild.environment.detect_llvm_cov():
                raise SkipTest('llvm-cov not found')
        if cc.get_id() == 'msvc':
            raise SkipTest('Test only applies to non-MSVC compilers')
        self.init(testdir, extra_args=['-Db_coverage=true'])
        self.build()
        self.run_tests()
        self.run_target('coverage')
        self._check_coverage_files()

    def test_cross_file_constants(self):
        with temp_filename() as crossfile1, temp_filename() as crossfile2:
            with open(crossfile1, 'w', encoding='utf-8') as f:
                f.write(textwrap.dedent(
                    '''
                    [constants]
                    compiler = 'gcc'
                    '''))
            with open(crossfile2, 'w', encoding='utf-8') as f:
                f.write(textwrap.dedent(
                    '''
                    [constants]
                    toolchain = '/toolchain/'
                    common_flags = ['--sysroot=' + toolchain / 'sysroot']

                    [properties]
                    c_args = common_flags + ['-DSOMETHING']
                    cpp_args = c_args + ['-DSOMETHING_ELSE']

                    [binaries]
                    c = toolchain / compiler
                    '''))

            values = mesonbuild.coredata.parse_machine_files([crossfile1, crossfile2])
            self.assertEqual(values['binaries']['c'], '/toolchain/gcc')
            self.assertEqual(values['properties']['c_args'],
                             ['--sysroot=/toolchain/sysroot', '-DSOMETHING'])
            self.assertEqual(values['properties']['cpp_args'],
                             ['--sysroot=/toolchain/sysroot', '-DSOMETHING', '-DSOMETHING_ELSE'])

    @skipIf(is_windows(), 'Directory cleanup fails for some reason')
    def test_wrap_git(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            srcdir = os.path.join(tmpdir, 'src')
            shutil.copytree(os.path.join(self.unit_test_dir, '80 wrap-git'), srcdir)
            upstream = os.path.join(srcdir, 'subprojects', 'wrap_git_upstream')
            upstream_uri = Path(upstream).as_uri()
            _git_init(upstream)
            with open(os.path.join(srcdir, 'subprojects', 'wrap_git.wrap'), 'w', encoding='utf-8') as f:
                f.write(textwrap.dedent('''
                  [wrap-git]
                  url = {}
                  patch_directory = wrap_git_builddef
                  revision = master
                '''.format(upstream_uri)))
            self.init(srcdir)
            self.build()
            self.run_tests()

    def test_extract_objects_custom_target_no_warning(self):
        testdir = os.path.join(self.common_test_dir, '22 object extraction')

        out = self.init(testdir)
        self.assertNotRegex(out, "WARNING:.*can't be converted to File object")

    def test_multi_output_custom_target_no_warning(self):
        testdir = os.path.join(self.common_test_dir, '228 custom_target source')

        out = self.init(testdir)
        self.assertNotRegex(out, 'WARNING:.*Using the first one.')
        self.build()
        self.run_tests()

    @skipUnless(is_linux() and (re.search('^i.86$|^x86$|^x64$|^x86_64$|^amd64$', platform.processor()) is not None),
        'Requires ASM compiler for x86 or x86_64 platform currently only available on Linux CI runners')
    def test_nostdlib(self):
        testdir = os.path.join(self.unit_test_dir, '77 nostdlib')
        machinefile = os.path.join(self.builddir, 'machine.txt')
        with open(machinefile, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [properties]
                c_stdlib = 'mylibc'
                '''))

        # Test native C stdlib
        self.meson_native_files = [machinefile]
        self.init(testdir)
        self.build()

        # Test cross C stdlib
        self.new_builddir()
        self.meson_native_files = []
        self.meson_cross_files = [machinefile]
        self.init(testdir)
        self.build()

    def test_meson_version_compare(self):
        testdir = os.path.join(self.unit_test_dir, '81 meson version compare')
        out = self.init(testdir)
        self.assertNotRegex(out, r'WARNING')

    def test_wrap_redirect(self):
        redirect_wrap = os.path.join(self.builddir, 'redirect.wrap')
        real_wrap = os.path.join(self.builddir, 'foo/subprojects/real.wrap')
        os.makedirs(os.path.dirname(real_wrap))

        # Invalid redirect, filename must have .wrap extension
        with open(redirect_wrap, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [wrap-redirect]
                filename = foo/subprojects/real.wrapper
                '''))
        with self.assertRaisesRegex(WrapException, 'wrap-redirect filename must be a .wrap file'):
            PackageDefinition(redirect_wrap)

        # Invalid redirect, filename cannot be in parent directory
        with open(redirect_wrap, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [wrap-redirect]
                filename = ../real.wrap
                '''))
        with self.assertRaisesRegex(WrapException, 'wrap-redirect filename cannot contain ".."'):
            PackageDefinition(redirect_wrap)

        # Invalid redirect, filename must be in foo/subprojects/real.wrap
        with open(redirect_wrap, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [wrap-redirect]
                filename = foo/real.wrap
                '''))
        with self.assertRaisesRegex(WrapException, 'wrap-redirect filename must be in the form foo/subprojects/bar.wrap'):
            PackageDefinition(redirect_wrap)

        # Correct redirect
        with open(redirect_wrap, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [wrap-redirect]
                filename = foo/subprojects/real.wrap
                '''))
        with open(real_wrap, 'w', encoding='utf-8') as f:
            f.write(textwrap.dedent('''
                [wrap-git]
                url = http://invalid
                '''))
        wrap = PackageDefinition(redirect_wrap)
        self.assertEqual(wrap.get('url'), 'http://invalid')

    @skip_if_no_cmake
    def test_nested_cmake_rebuild(self) -> None:
        # This checks a bug where if a non-meson project is used as a third
        # level (or deeper) subproject it doesn't cause a rebuild if the build
        # files for that project are changed
        if os.environ.get('MESON_CI_JOBNAME') == 'linux-bionic-gcc':
            raise SkipTest('Unsupported CMake version')
        testdir = os.path.join(self.unit_test_dir, '84 nested subproject regenerate depends')
        cmakefile = Path(testdir) / 'subprojects' / 'sub2' / 'CMakeLists.txt'
        self.init(testdir)
        self.build()
        with cmakefile.open('a', encoding='utf-8'):
            os.utime(str(cmakefile))
        self.assertReconfiguredBuildIsNoop()

    def test_version_file(self):
        srcdir = os.path.join(self.common_test_dir, '2 cpp')
        self.init(srcdir)
        projinfo = self.introspect('--projectinfo')
        self.assertEqual(projinfo['version'], '1.0.0')

    def test_cflags_cppflags(self):
        envs = {'CPPFLAGS': '-DCPPFLAG',
                'CFLAGS': '-DCFLAG',
                'CXXFLAGS': '-DCXXFLAG'}
        srcdir = os.path.join(self.unit_test_dir, '88 multiple envvars')
        self.init(srcdir, override_envvars=envs)
        self.build()

    def test_build_b_options(self) -> None:
        # Currently (0.57) these do nothing, but they've always been allowed
        srcdir = os.path.join(self.common_test_dir, '2 cpp')
        self.init(srcdir, extra_args=['-Dbuild.b_lto=true'])

    def test_install_skip_subprojects(self):
        testdir = os.path.join(self.unit_test_dir, '91 install skip subprojects')
        self.init(testdir)
        self.build()

        main_expected = [
            '',
            'share',
            'include',
            'foo',
            'bin',
            'share/foo',
            'share/foo/foo.dat',
            'include/foo.h',
            'foo/foofile',
            'bin/foo' + exe_suffix,
        ]
        bar_expected = [
            'bar',
            'share/foo/bar.dat',
            'include/bar.h',
            'bin/bar' + exe_suffix,
            'bar/barfile'
        ]
        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)
        if cc.get_argument_syntax() == 'msvc':
            main_expected.append('bin/foo.pdb')
            bar_expected.append('bin/bar.pdb')
        prefix = destdir_join(self.installdir, self.prefix)
        main_expected = [Path(prefix, p) for p in main_expected]
        bar_expected = [Path(prefix, p) for p in bar_expected]
        all_expected = main_expected + bar_expected

        def check_installed_files(extra_args, expected):
            args = ['install', '--destdir', self.installdir] + extra_args
            self._run(self.meson_command + args, workdir=self.builddir)
            all_files = [p for p in Path(self.installdir).rglob('*')]
            self.assertEqual(sorted(expected), sorted(all_files))
            windows_proof_rmtree(self.installdir)

        check_installed_files([], all_expected)
        check_installed_files(['--skip-subprojects'], main_expected)
        check_installed_files(['--skip-subprojects', 'bar'], main_expected)
        check_installed_files(['--skip-subprojects', 'another'], all_expected)

    def test_adding_subproject_to_configure_project(self) -> None:
        srcdir = os.path.join(self.unit_test_dir, '92 new subproject in configured project')
        self.init(srcdir)
        self.build()
        self.setconf('-Duse-sub=true')
        self.build()

    def test_devenv(self):
        testdir = os.path.join(self.unit_test_dir, '90 devenv')
        self.init(testdir)
        self.build()

        cmd = self.meson_command + ['devenv', '-C', self.builddir]
        script = os.path.join(testdir, 'test-devenv.py')
        app = os.path.join(self.builddir, 'app')
        self._run(cmd + python_command + [script])
        self.assertEqual('This is text.', self._run(cmd + [app]).strip())

    def test_clang_format_check(self):
        if self.backend is not Backend.ninja:
            raise SkipTest(f'Skipping clang-format tests with {self.backend.name} backend')
        if not shutil.which('clang-format'):
            raise SkipTest('clang-format not found')

        testdir = os.path.join(self.unit_test_dir, '93 clangformat')
        newdir = os.path.join(self.builddir, 'testdir')
        shutil.copytree(testdir, newdir)
        self.new_builddir()
        self.init(newdir)

        # Should reformat 1 file but not return error
        output = self.build('clang-format')
        self.assertEqual(1, output.count('File reformatted:'))

        # Reset source tree then try again with clang-format-check, it should
        # return an error code this time.
        windows_proof_rmtree(newdir)
        shutil.copytree(testdir, newdir)
        with self.assertRaises(subprocess.CalledProcessError):
            output = self.build('clang-format-check')
            self.assertEqual(1, output.count('File reformatted:'))

        # The check format should not touch any files. Thus
        # running format again has some work to do.
        output = self.build('clang-format')
        self.assertEqual(1, output.count('File reformatted:'))
        self.build('clang-format-check')

    def test_custom_target_implicit_include(self):
        testdir = os.path.join(self.unit_test_dir, '94 custominc')
        self.init(testdir)
        self.build()
        compdb = self.get_compdb()
        matches = 0
        for c in compdb:
            if 'prog.c' in c['file']:
                self.assertNotIn('easytogrepfor', c['command'])
                matches += 1
        self.assertEqual(matches, 1)
        matches = 0
        for c in compdb:
            if 'prog2.c' in c['file']:
                self.assertIn('easytogrepfor', c['command'])
                matches += 1
        self.assertEqual(matches, 1)

    def test_env_flags_to_linker(self) -> None:
        # Compilers that act as drivers should add their compiler flags to the
        # linker, those that do not shouldn't
        with mock.patch.dict(os.environ, {'CFLAGS': '-DCFLAG', 'LDFLAGS': '-flto'}):
            env = get_fake_env()

            # Get the compiler so we know which compiler class to mock.
            cc =  detect_compiler_for(env, 'c', MachineChoice.HOST)
            cc_type = type(cc)

            # Test a compiler that acts as a linker
            with mock.patch.object(cc_type, 'INVOKES_LINKER', True):
                cc =  detect_compiler_for(env, 'c', MachineChoice.HOST)
                link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language)
                self.assertEqual(sorted(link_args), sorted(['-DCFLAG', '-flto']))

            # And one that doesn't
            with mock.patch.object(cc_type, 'INVOKES_LINKER', False):
                cc =  detect_compiler_for(env, 'c', MachineChoice.HOST)
                link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language)
                self.assertEqual(sorted(link_args), sorted(['-flto']))

    def test_install_tag(self) -> None:
        testdir = os.path.join(self.unit_test_dir, '98 install all targets')
        self.init(testdir)
        self.build()

        env = get_fake_env(testdir, self.builddir, self.prefix)
        cc = detect_c_compiler(env, MachineChoice.HOST)

        def shared_lib_name(name):
            if cc.get_id() in {'msvc', 'clang-cl'}:
                return f'bin/{name}.dll'
            elif is_windows():
                return f'bin/lib{name}.dll'
            elif is_cygwin():
                return f'bin/cyg{name}.dll'
            elif is_osx():
                return f'lib/lib{name}.dylib'
            return f'lib/lib{name}.so'

        def exe_name(name):
            if is_windows() or is_cygwin():
                return f'{name}.exe'
            return name

        installpath = Path(self.installdir)

        expected_common = {
            installpath,
            Path(installpath, 'usr'),
        }

        expected_devel = expected_common | {
            Path(installpath, 'usr/include'),
            Path(installpath, 'usr/include/bar-devel.h'),
            Path(installpath, 'usr/include/bar2-devel.h'),
            Path(installpath, 'usr/include/foo1-devel.h'),
            Path(installpath, 'usr/include/foo2-devel.h'),
            Path(installpath, 'usr/include/foo3-devel.h'),
            Path(installpath, 'usr/include/out-devel.h'),
            Path(installpath, 'usr/lib'),
            Path(installpath, 'usr/lib/libstatic.a'),
            Path(installpath, 'usr/lib/libboth.a'),
            Path(installpath, 'usr/lib/libboth2.a'),
        }

        if cc.get_id() in {'msvc', 'clang-cl'}:
            expected_devel |= {
                Path(installpath, 'usr/bin'),
                Path(installpath, 'usr/bin/app.pdb'),
                Path(installpath, 'usr/bin/app2.pdb'),
                Path(installpath, 'usr/bin/both.pdb'),
                Path(installpath, 'usr/bin/both2.pdb'),
                Path(installpath, 'usr/bin/bothcustom.pdb'),
                Path(installpath, 'usr/bin/shared.pdb'),
                Path(installpath, 'usr/bin/versioned_shared-1.pdb'),
                Path(installpath, 'usr/lib/both.lib'),
                Path(installpath, 'usr/lib/both2.lib'),
                Path(installpath, 'usr/lib/bothcustom.lib'),
                Path(installpath, 'usr/lib/shared.lib'),
                Path(installpath, 'usr/lib/versioned_shared.lib'),
            }
        elif is_windows() or is_cygwin():
            expected_devel |= {
                Path(installpath, 'usr/lib/libboth.dll.a'),
                Path(installpath, 'usr/lib/libboth2.dll.a'),
                Path(installpath, 'usr/lib/libshared.dll.a'),
                Path(installpath, 'usr/lib/libbothcustom.dll.a'),
                Path(installpath, 'usr/lib/libversioned_shared.dll.a'),
            }
        else:
            expected_devel |= {
                Path(installpath, 'usr/' + shared_lib_name('versioned_shared')),
            }

        expected_runtime = expected_common | {
            Path(installpath, 'usr/bin'),
            Path(installpath, 'usr/bin/' + exe_name('app')),
            Path(installpath, 'usr/bin/' + exe_name('app2')),
            Path(installpath, 'usr/' + shared_lib_name('shared')),
            Path(installpath, 'usr/' + shared_lib_name('both')),
            Path(installpath, 'usr/' + shared_lib_name('both2')),
        }

        if is_windows() or is_cygwin():
            expected_runtime |= {
                Path(installpath, 'usr/' + shared_lib_name('versioned_shared-1')),
            }
        elif is_osx():
            expected_runtime |= {
                Path(installpath, 'usr/' + shared_lib_name('versioned_shared.1')),
            }
        else:
            expected_runtime |= {
                Path(installpath, 'usr/' + shared_lib_name('versioned_shared') + '.1'),
                Path(installpath, 'usr/' + shared_lib_name('versioned_shared') + '.1.2.3'),
            }

        expected_custom = expected_common | {
            Path(installpath, 'usr/share'),
            Path(installpath, 'usr/share/bar-custom.txt'),
            Path(installpath, 'usr/share/foo-custom.h'),
            Path(installpath, 'usr/share/out1-custom.txt'),
            Path(installpath, 'usr/share/out2-custom.txt'),
            Path(installpath, 'usr/share/out3-custom.txt'),
            Path(installpath, 'usr/share/custom_files'),
            Path(installpath, 'usr/share/custom_files/data.txt'),
            Path(installpath, 'usr/lib'),
            Path(installpath, 'usr/lib/libbothcustom.a'),
            Path(installpath, 'usr/' + shared_lib_name('bothcustom')),
        }

        if is_windows() or is_cygwin():
            expected_custom |= {Path(installpath, 'usr/bin')}
        else:
            expected_runtime |= {Path(installpath, 'usr/lib')}

        expected_runtime_custom = expected_runtime | expected_custom

        expected_all = expected_devel | expected_runtime | expected_custom | {
            Path(installpath, 'usr/share/foo-notag.h'),
            Path(installpath, 'usr/share/bar-notag.txt'),
            Path(installpath, 'usr/share/out1-notag.txt'),
            Path(installpath, 'usr/share/out2-notag.txt'),
            Path(installpath, 'usr/share/out3-notag.txt'),
            Path(installpath, 'usr/share/foo2.h'),
            Path(installpath, 'usr/share/out1.txt'),
            Path(installpath, 'usr/share/out2.txt'),
        }

        def do_install(tags, expected_files, expected_scripts):
            cmd = self.meson_command + ['install', '--dry-run', '--destdir', self.installdir]
            cmd += ['--tags', tags] if tags else []
            stdout = self._run(cmd, workdir=self.builddir)
            installed = self.read_install_logs()
            self.assertEqual(sorted(expected_files), sorted(installed))
            self.assertEqual(expected_scripts, stdout.count('Running custom install script'))

        do_install('devel', expected_devel, 0)
        do_install('runtime', expected_runtime, 0)
        do_install('custom', expected_custom, 1)
        do_install('runtime,custom', expected_runtime_custom, 1)
        do_install(None, expected_all, 2)

    def test_introspect_install_plan(self):
        testdir = os.path.join(self.unit_test_dir, '98 install all targets')
        introfile = os.path.join(self.builddir, 'meson-info', 'intro-install_plan.json')
        self.init(testdir)
        self.assertPathExists(introfile)
        with open(introfile, encoding='utf-8') as fp:
            res = json.load(fp)

        env = get_fake_env(testdir, self.builddir, self.prefix)

        def output_name(name, type_):
            target = type_(name=name, subdir=None, subproject=None,
                           for_machine=MachineChoice.HOST, sources=[],
                           structured_sources=None,
                           objects=[], environment=env, compilers=env.coredata.compilers[MachineChoice.HOST],
                           kwargs={})
            target.process_compilers()
            target.process_compilers_late([])
            return target.filename

        shared_lib_name = lambda name: output_name(name, SharedLibrary)
        static_lib_name = lambda name: output_name(name, StaticLibrary)
        exe_name = lambda name: output_name(name, Executable)

        expected = {
            'targets': {
                f'{self.builddir}/out1-notag.txt': {
                    'destination': '{prefix}/share/out1-notag.txt',
                    'tag': None,
                },
                f'{self.builddir}/out2-notag.txt': {
                    'destination': '{prefix}/share/out2-notag.txt',
                    'tag': None,
                },
                f'{self.builddir}/libstatic.a': {
                    'destination': '{libdir_static}/libstatic.a',
                    'tag': 'devel',
                },
                f'{self.builddir}/' + exe_name('app'): {
                    'destination': '{bindir}/' + exe_name('app'),
                    'tag': 'runtime',
                },
                f'{self.builddir}/subdir/' + exe_name('app2'): {
                    'destination': '{bindir}/' + exe_name('app2'),
                    'tag': 'runtime',
                },
                f'{self.builddir}/' + shared_lib_name('shared'): {
                    'destination': '{libdir_shared}/' + shared_lib_name('shared'),
                    'tag': 'runtime',
                },
                f'{self.builddir}/' + shared_lib_name('both'): {
                    'destination': '{libdir_shared}/' + shared_lib_name('both'),
                    'tag': 'runtime',
                },
                f'{self.builddir}/' + static_lib_name('both'): {
                    'destination': '{libdir_static}/' + static_lib_name('both'),
                    'tag': 'devel',
                },
                f'{self.builddir}/' + shared_lib_name('bothcustom'): {
                    'destination': '{libdir_shared}/' + shared_lib_name('bothcustom'),
                    'tag': 'custom',
                },
                f'{self.builddir}/' + static_lib_name('bothcustom'): {
                    'destination': '{libdir_static}/' + static_lib_name('bothcustom'),
                    'tag': 'custom',
                },
                f'{self.builddir}/subdir/' + shared_lib_name('both2'): {
                    'destination': '{libdir_shared}/' + shared_lib_name('both2'),
                    'tag': 'runtime',
                },
                f'{self.builddir}/subdir/' + static_lib_name('both2'): {
                    'destination': '{libdir_static}/' + static_lib_name('both2'),
                    'tag': 'devel',
                },
                f'{self.builddir}/out1-custom.txt': {
                    'destination': '{prefix}/share/out1-custom.txt',
                    'tag': 'custom',
                },
                f'{self.builddir}/out2-custom.txt': {
                    'destination': '{prefix}/share/out2-custom.txt',
                    'tag': 'custom',
                },
                f'{self.builddir}/out3-custom.txt': {
                    'destination': '{prefix}/share/out3-custom.txt',
                    'tag': 'custom',
                },
                f'{self.builddir}/subdir/out1.txt': {
                    'destination': '{prefix}/share/out1.txt',
                    'tag': None,
                },
                f'{self.builddir}/subdir/out2.txt': {
                    'destination': '{prefix}/share/out2.txt',
                    'tag': None,
                },
                f'{self.builddir}/out-devel.h': {
                    'destination': '{prefix}/include/out-devel.h',
                    'tag': 'devel',
                },
                f'{self.builddir}/out3-notag.txt': {
                    'destination': '{prefix}/share/out3-notag.txt',
                    'tag': None,
                },
            },
            'configure': {
                f'{self.builddir}/foo-notag.h': {
                    'destination': '{prefix}/share/foo-notag.h',
                    'tag': None,
                },
                f'{self.builddir}/foo2-devel.h': {
                    'destination': '{prefix}/include/foo2-devel.h',
                    'tag': 'devel',
                },
                f'{self.builddir}/foo-custom.h': {
                    'destination': '{prefix}/share/foo-custom.h',
                    'tag': 'custom',
                },
                f'{self.builddir}/subdir/foo2.h': {
                    'destination': '{prefix}/share/foo2.h',
                    'tag': None,
                },
            },
            'data': {
                f'{testdir}/bar-notag.txt': {
                    'destination': '{datadir}/share/bar-notag.txt',
                    'tag': None,
                },
                f'{testdir}/bar-devel.h': {
                    'destination': '{datadir}/include/bar-devel.h',
                    'tag': 'devel',
                },
                f'{testdir}/bar-custom.txt': {
                    'destination': '{datadir}/share/bar-custom.txt',
                    'tag': 'custom',
                },
                f'{testdir}/subdir/bar2-devel.h': {
                    'destination': '{datadir}/include/bar2-devel.h',
                    'tag': 'devel',
                },
            },
            'headers': {
                f'{testdir}/foo1-devel.h': {
                    'destination': '{includedir}/foo1-devel.h',
                    'tag': 'devel',
                },
                f'{testdir}/subdir/foo3-devel.h': {
                    'destination': '{includedir}/foo3-devel.h',
                    'tag': 'devel',
                },
            }
        }

        fix_path = lambda path: os.path.sep.join(path.split('/'))
        expected_fixed = {
            data_type: {
                fix_path(source): {
                    key: fix_path(value) if key == 'destination' else value
                    for key, value in attributes.items()
                }
                for source, attributes in files.items()
            }
            for data_type, files in expected.items()
        }

        for data_type, files in expected_fixed.items():
            for file, details in files.items():
                with self.subTest(key='{}.{}'.format(data_type, file)):
                    self.assertEqual(res[data_type][file], details)

    @skip_if_not_language('rust')
    @unittest.skipIf(not shutil.which('clippy-driver'), 'Test requires clippy-driver')
    def test_rust_clippy(self) -> None:
        if self.backend is not Backend.ninja:
            raise unittest.SkipTest('Rust is only supported with ninja currently')
        # When clippy is used, we should get an exception since a variable named
        # "foo" is used, but is on our denylist
        testdir = os.path.join(self.rust_test_dir, '1 basic')
        self.init(testdir, extra_args=['--werror'], override_envvars={'RUSTC': 'clippy-driver'})
        with self.assertRaises(subprocess.CalledProcessError) as cm:
            self.build()
        self.assertIn('error: use of a blacklisted/placeholder name `foo`', cm.exception.stdout)

    @skip_if_not_language('rust')
    def test_rust_rlib_linkage(self) -> None:
        if self.backend is not Backend.ninja:
            raise unittest.SkipTest('Rust is only supported with ninja currently')
        template = textwrap.dedent('''\
                use std::process::exit;

                pub fn fun() {{
                    exit({});
                }}
            ''')

        testdir = os.path.join(self.unit_test_dir, '101 rlib linkage')
        gen_file = os.path.join(testdir, 'lib.rs')
        with open(gen_file, 'w') as f:
            f.write(template.format(0))
        self.addCleanup(windows_proof_rm, gen_file)

        self.init(testdir)
        self.build()
        self.run_tests()

        with open(gen_file, 'w') as f:
            f.write(template.format(39))

        self.build()
        with self.assertRaises(subprocess.CalledProcessError) as cm:
            self.run_tests()
        self.assertEqual(cm.exception.returncode, 1)
        self.assertIn('exit status 39', cm.exception.stdout)

    def test_custom_target_name(self):
        testdir = os.path.join(self.unit_test_dir, '99 custom target name')
        self.init(testdir)
        out = self.build()
        if self.backend is Backend.ninja:
            self.assertIn('Generating file.txt with a custom command', out)
            self.assertIn('Generating subdir/file.txt with a custom command', out)
