mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
Add a test for the --vsenv meson setup option
The tests and the unittests both unconditionally call setup_vsenv() because all tests are run using the backend commands directly: ninja, msbuild, etc. There's no way to undo this vs env setup, so the only way to test that --vsenv works is by: 1. Removing all paths in PATH that provide ninja 2. Changing setup_vsenv(force=True) to forcibly set-up a new vsenv when MESON_FORCE_VSENV_FOR_UNITTEST is set 3. Mock-patching build_command, test_command, install_command to use `meson` instead of `ninja` 4. Asserting that 'Activating VS' is in the output for all commands 5. Ensure that compilation works because ninja is picked up from the vs env. I manually checked that this test actually does fail when the previous commit is reverted.
This commit is contained in:
1 parent
1cda222a1a
commit
faf79f4539
5 files changed
+57
-17
No files matched your search
@@ -26,15 +26,16 @@ def _setup_vsenv(force: bool) -> bool:
|
||||
return False
|
||||
if os.environ.get('OSTYPE') == 'cygwin':
|
||||
return False
|
||||
if 'Visual Studio' in os.environ['PATH']:
|
||||
return False
|
||||
# VSINSTALL is set when running setvars from a Visual Studio installation
|
||||
# Tested with Visual Studio 2012 and 2017
|
||||
if 'VSINSTALLDIR' in os.environ:
|
||||
return False
|
||||
# Check explicitly for cl when on Windows
|
||||
if shutil.which('cl.exe'):
|
||||
return False
|
||||
if 'MESON_FORCE_VSENV_FOR_UNITTEST' not in os.environ:
|
||||
if 'Visual Studio' in os.environ['PATH']:
|
||||
return False
|
||||
# VSINSTALL is set when running setvars from a Visual Studio installation
|
||||
# Tested with Visual Studio 2012 and 2017
|
||||
if 'VSINSTALLDIR' in os.environ:
|
||||
return False
|
||||
# Check explicitly for cl when on Windows
|
||||
if shutil.which('cl.exe'):
|
||||
return False
|
||||
if not force:
|
||||
if shutil.which('cc'):
|
||||
return False
|
||||
|
||||
+3
-4
@@ -261,11 +261,10 @@ def ensure_backend_detects_changes(backend: Backend) -> None:
|
||||
time.sleep(1)
|
||||
|
||||
def run_mtest_inprocess(commandlist: T.List[str]) -> T.Tuple[int, str, str]:
|
||||
stderr = StringIO()
|
||||
stdout = StringIO()
|
||||
with mock.patch.object(sys, 'stdout', stdout), mock.patch.object(sys, 'stderr', stderr):
|
||||
out = StringIO()
|
||||
with mock.patch.object(sys, 'stdout', out), mock.patch.object(sys, 'stderr', out):
|
||||
returncode = mtest.run_with_args(commandlist)
|
||||
return returncode, stdout.getvalue(), stderr.getvalue()
|
||||
return returncode, stdout.getvalue()
|
||||
|
||||
def clear_meson_configure_class_caches() -> None:
|
||||
compilers.CCompiler.find_library_cache = {}
|
||||
|
||||
@@ -249,10 +249,10 @@ class BasePlatformTests(TestCase):
|
||||
|
||||
def run_tests(self, *, inprocess=False, override_envvars=None):
|
||||
if not inprocess:
|
||||
self._run(self.test_command, workdir=self.builddir, override_envvars=override_envvars)
|
||||
return self._run(self.test_command, workdir=self.builddir, override_envvars=override_envvars)
|
||||
else:
|
||||
with mock.patch.dict(os.environ, override_envvars):
|
||||
run_mtest_inprocess(['-C', self.builddir])
|
||||
return run_mtest_inprocess(['-C', self.builddir])[1]
|
||||
|
||||
def install(self, *, use_destdir=True, override_envvars=None):
|
||||
if self.backend is not Backend.ninja:
|
||||
@@ -263,7 +263,7 @@ class BasePlatformTests(TestCase):
|
||||
override_envvars = destdir
|
||||
else:
|
||||
override_envvars.update(destdir)
|
||||
self._run(self.install_command, workdir=self.builddir, override_envvars=override_envvars)
|
||||
return self._run(self.install_command, workdir=self.builddir, override_envvars=override_envvars)
|
||||
|
||||
def uninstall(self, *, override_envvars=None):
|
||||
self._run(self.uninstall_command, workdir=self.builddir, override_envvars=override_envvars)
|
||||
|
||||
+15
-1
@@ -5,11 +5,13 @@ import unittest
|
||||
import functools
|
||||
import re
|
||||
import typing as T
|
||||
from pathlib import Path
|
||||
from contextlib import contextmanager
|
||||
|
||||
from mesonbuild.compilers import detect_c_compiler, compiler_from_language
|
||||
from mesonbuild.mesonlib import (
|
||||
MachineChoice, is_osx, is_cygwin, EnvironmentException, OptionKey, MachineChoice
|
||||
MachineChoice, is_osx, is_cygwin, EnvironmentException, OptionKey, MachineChoice,
|
||||
OrderedSet
|
||||
)
|
||||
from run_tests import get_fake_env
|
||||
|
||||
@@ -170,3 +172,15 @@ def get_rpath(fname: str) -> T.Optional[str]:
|
||||
# don't check for, so clear those
|
||||
final = ':'.join([e for e in raw.split(':') if not e.startswith('/nix')])
|
||||
return final
|
||||
|
||||
def get_path_without_cmd(cmd: str, path: str) -> str:
|
||||
pathsep = os.pathsep
|
||||
paths = OrderedSet([Path(p).resolve() for p in path.split(pathsep)])
|
||||
while True:
|
||||
full_path = shutil.which(cmd, path=path)
|
||||
if full_path is None:
|
||||
break
|
||||
dirname = Path(full_path).resolve().parent
|
||||
paths.discard(dirname)
|
||||
path = pathsep.join([str(p) for p in paths])
|
||||
return path
|
||||
@@ -373,3 +373,29 @@ class WindowsTests(BasePlatformTests):
|
||||
raise SkipTest('Not using MSVC')
|
||||
self.init(testdir, extra_args=['-Dtest-failure=true'])
|
||||
self.assertRaises(subprocess.CalledProcessError, self.build)
|
||||
|
||||
@unittest.skipIf(is_cygwin(), "Needs visual studio")
|
||||
def test_vsenv_option(self):
|
||||
if self.backend is not Backend.ninja:
|
||||
raise SkipTest('Only ninja backend is valid for test')
|
||||
env = os.environ.copy()
|
||||
env['MESON_FORCE_VSENV_FOR_UNITTEST'] = '1'
|
||||
# Remove ninja from PATH to ensure that the one provided by Visual
|
||||
# Studio is picked, as a regression test for
|
||||
# https://github.com/mesonbuild/meson/issues/9774
|
||||
env['PATH'] = get_path_without_cmd('ninja', env['PATH'])
|
||||
testdir = os.path.join(self.common_test_dir, '1 trivial')
|
||||
out = self.init(testdir, extra_args=['--vsenv'], override_envvars=env)
|
||||
self.assertIn('Activating VS', out)
|
||||
self.assertRegex(out, 'Visual Studio environment is needed to run Ninja')
|
||||
# All these directly call ninja with the full path, so we need to patch
|
||||
# it out to use meson subcommands
|
||||
with mock.patch.object(self, 'build_command', self.meson_command + ['compile']):
|
||||
out = self.build(override_envvars=env)
|
||||
self.assertIn('Activating VS', out)
|
||||
with mock.patch.object(self, 'test_command', self.meson_command + ['test']):
|
||||
out = self.run_tests(override_envvars=env)
|
||||
self.assertIn('Activating VS', out)
|
||||
with mock.patch.object(self, 'install_command', self.meson_command + ['install']):
|
||||
out = self.install(override_envvars=env)
|
||||
self.assertIn('Activating VS', out)
|
||||
Reference in new issue
Block a user