From 80ec7ec6810dfd8b8bf84f089d59b9320b6da36c Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 14 Sep 2020 16:32:39 -0700 Subject: [PATCH] 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. --- run_tests.py | 38 +++++++++++++------------------------- run_unittests.py | 17 ++--------------- 2 files changed, 15 insertions(+), 40 deletions(-) diff --git a/run_tests.py b/run_tests.py index b3bcee20f..6e9c6ce9d 100755 --- a/run_tests.py +++ b/run_tests.py @@ -26,6 +26,7 @@ from io import StringIO from enum import Enum from glob import glob from pathlib import Path +from unittest import mock from mesonbuild import compilers from mesonbuild import dependencies from mesonbuild import mesonlib @@ -255,16 +256,11 @@ def ensure_backend_detects_changes(backend): time.sleep(1) def run_mtest_inprocess(commandlist): - old_stdout = sys.stdout - sys.stdout = mystdout = StringIO() - old_stderr = sys.stderr - sys.stderr = mystderr = StringIO() - try: + stderr = StringIO() + stdout = StringIO() + with mock.patch.object(sys, 'stdout', stdout), mock.patch.object(sys, 'stderr', stderr): returncode = mtest.run_with_args(commandlist) - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - return returncode, mystdout.getvalue(), mystderr.getvalue() + return returncode, stdout.getvalue(), stderr.getvalue() def clear_meson_configure_class_caches(): compilers.CCompiler.library_dirs_cache = {} @@ -275,22 +271,14 @@ def clear_meson_configure_class_caches(): dependencies.PkgConfigDependency.class_pkgbin = mesonlib.PerMachine(None, None) def run_configure_inprocess(commandlist, env=None): - old_stdout = sys.stdout - sys.stdout = mystdout = StringIO() - old_stderr = sys.stderr - sys.stderr = mystderr = StringIO() - old_environ = os.environ.copy() - if env is not None: - os.environ.update(env) - try: - returncode = mesonmain.run(commandlist, get_meson_script()) - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - clear_meson_configure_class_caches() - os.environ.clear() - os.environ.update(old_environ) - return returncode, mystdout.getvalue(), mystderr.getvalue() + stderr = StringIO() + stdout = StringIO() + with mock.patch.dict(os.environ, env or {}), mock.patch.object(sys, 'stdout', stdout), mock.patch.object(sys, 'stderr', stderr): + try: + returncode = mesonmain.run(commandlist, get_meson_script()) + finally: + clear_meson_configure_class_caches() + return returncode, stdout.getvalue(), stderr.getvalue() def run_configure_external(full_command, env=None): pc, o, e = mesonlib.Popen_safe(full_command, env=env) diff --git a/run_unittests.py b/run_unittests.py index 0bcf617ea..da0bf50ce 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1657,13 +1657,7 @@ class BasePlatformTests(unittest.TestCase): self.privatedir = os.path.join(self.builddir, 'meson-private') if inprocess: try: - if override_envvars is not None: - old_envvars = os.environ.copy() - os.environ.update(override_envvars) - (returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args) - if override_envvars is not None: - os.environ.clear() - os.environ.update(old_envvars) + (returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args, override_envvars) if 'MESON_SKIP_TEST' in out: raise unittest.SkipTest('Project requested skipping.') if returncode != 0: @@ -1707,15 +1701,8 @@ class BasePlatformTests(unittest.TestCase): if not inprocess: self._run(self.test_command, workdir=self.builddir, override_envvars=override_envvars) else: - if override_envvars is not None: - old_envvars = os.environ.copy() - os.environ.update(override_envvars) - try: + with mock.patch.dict(os.environ, override_envvars): run_mtest_inprocess(['-C', self.builddir]) - finally: - if override_envvars is not None: - os.environ.clear() - os.environ.update(old_envvars) def install(self, *, use_destdir=True, override_envvars=None): if self.backend is not Backend.ninja: