Skip to content

Commit 80ec7ec

Browse files
dcbakernirbheek
authored andcommitted
tests: Make monkey patching smarter
There are two problems here. The first is that we're doing manual monkey patching which is fragile and verbose, when unittest.mock is designed specifically to solve this exact problem. The second is that we're monkey patching os.environ at two different levels with the same information. So let's only do it once.
1 parent 807f887 commit 80ec7ec

File tree

2 files changed

+15
-40
lines changed

2 files changed

+15
-40
lines changed

run_tests.py

+13-25
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from enum import Enum
2727
from glob import glob
2828
from pathlib import Path
29+
from unittest import mock
2930
from mesonbuild import compilers
3031
from mesonbuild import dependencies
3132
from mesonbuild import mesonlib
@@ -255,16 +256,11 @@ def ensure_backend_detects_changes(backend):
255256
time.sleep(1)
256257

257258
def run_mtest_inprocess(commandlist):
258-
old_stdout = sys.stdout
259-
sys.stdout = mystdout = StringIO()
260-
old_stderr = sys.stderr
261-
sys.stderr = mystderr = StringIO()
262-
try:
259+
stderr = StringIO()
260+
stdout = StringIO()
261+
with mock.patch.object(sys, 'stdout', stdout), mock.patch.object(sys, 'stderr', stderr):
263262
returncode = mtest.run_with_args(commandlist)
264-
finally:
265-
sys.stdout = old_stdout
266-
sys.stderr = old_stderr
267-
return returncode, mystdout.getvalue(), mystderr.getvalue()
263+
return returncode, stdout.getvalue(), stderr.getvalue()
268264

269265
def clear_meson_configure_class_caches():
270266
compilers.CCompiler.library_dirs_cache = {}
@@ -275,22 +271,14 @@ def clear_meson_configure_class_caches():
275271
dependencies.PkgConfigDependency.class_pkgbin = mesonlib.PerMachine(None, None)
276272

277273
def run_configure_inprocess(commandlist, env=None):
278-
old_stdout = sys.stdout
279-
sys.stdout = mystdout = StringIO()
280-
old_stderr = sys.stderr
281-
sys.stderr = mystderr = StringIO()
282-
old_environ = os.environ.copy()
283-
if env is not None:
284-
os.environ.update(env)
285-
try:
286-
returncode = mesonmain.run(commandlist, get_meson_script())
287-
finally:
288-
sys.stdout = old_stdout
289-
sys.stderr = old_stderr
290-
clear_meson_configure_class_caches()
291-
os.environ.clear()
292-
os.environ.update(old_environ)
293-
return returncode, mystdout.getvalue(), mystderr.getvalue()
274+
stderr = StringIO()
275+
stdout = StringIO()
276+
with mock.patch.dict(os.environ, env or {}), mock.patch.object(sys, 'stdout', stdout), mock.patch.object(sys, 'stderr', stderr):
277+
try:
278+
returncode = mesonmain.run(commandlist, get_meson_script())
279+
finally:
280+
clear_meson_configure_class_caches()
281+
return returncode, stdout.getvalue(), stderr.getvalue()
294282

295283
def run_configure_external(full_command, env=None):
296284
pc, o, e = mesonlib.Popen_safe(full_command, env=env)

run_unittests.py

+2-15
Original file line numberDiff line numberDiff line change
@@ -1657,13 +1657,7 @@ def init(self, srcdir, *,
16571657
self.privatedir = os.path.join(self.builddir, 'meson-private')
16581658
if inprocess:
16591659
try:
1660-
if override_envvars is not None:
1661-
old_envvars = os.environ.copy()
1662-
os.environ.update(override_envvars)
1663-
(returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args)
1664-
if override_envvars is not None:
1665-
os.environ.clear()
1666-
os.environ.update(old_envvars)
1660+
(returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args, override_envvars)
16671661
if 'MESON_SKIP_TEST' in out:
16681662
raise unittest.SkipTest('Project requested skipping.')
16691663
if returncode != 0:
@@ -1707,15 +1701,8 @@ def run_tests(self, *, inprocess=False, override_envvars=None):
17071701
if not inprocess:
17081702
self._run(self.test_command, workdir=self.builddir, override_envvars=override_envvars)
17091703
else:
1710-
if override_envvars is not None:
1711-
old_envvars = os.environ.copy()
1712-
os.environ.update(override_envvars)
1713-
try:
1704+
with mock.patch.dict(os.environ, override_envvars):
17141705
run_mtest_inprocess(['-C', self.builddir])
1715-
finally:
1716-
if override_envvars is not None:
1717-
os.environ.clear()
1718-
os.environ.update(old_envvars)
17191706

17201707
def install(self, *, use_destdir=True, override_envvars=None):
17211708
if self.backend is not Backend.ninja:

0 commit comments

Comments
 (0)