aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mtest.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/mtest.py')
-rw-r--r--mesonbuild/mtest.py38
1 files changed, 27 insertions, 11 deletions
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index a92b5cc..4f687a5 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -45,6 +45,7 @@ from .coredata import major_versions_differ, MesonVersionMismatchException
from .coredata import version as coredata_version
from .dependencies import ExternalProgram
from .mesonlib import MesonException, get_wine_shortpath, split_args, join_args
+from .mintro import get_infodir, load_info_file
from .backend.backends import TestProtocol, TestSerialisation
# GNU autotools interprets a return code of 77 from tests it executes to
@@ -1019,13 +1020,21 @@ class TestHarness:
def total_failure_count(self) -> int:
return self.fail_count + self.unexpectedpass_count + self.timeout_count
- def doit(self) -> int:
+ def doit(self, options: argparse.Namespace) -> int:
if self.is_run:
raise RuntimeError('Test harness object can only be used once.')
self.is_run = True
tests = self.get_tests()
if not tests:
return 0
+ if not options.no_rebuild and not rebuild_deps(options.wd, tests):
+ # We return 125 here in case the build failed.
+ # The reason is that exit code 125 tells `git bisect run` that the current
+ # commit should be skipped. Thus users can directly use `meson test` to
+ # bisect without needing to handle the does-not-build case separately in a
+ # wrapper script.
+ sys.exit(125)
+
self.run_tests(tests)
return self.total_failure_count()
@@ -1272,7 +1281,7 @@ def list_tests(th: TestHarness) -> bool:
print(th.get_pretty_suite(t))
return not tests
-def rebuild_all(wd: str) -> bool:
+def rebuild_deps(wd: str, tests: T.List[TestSerialisation]) -> bool:
if not (Path(wd) / 'build.ninja').is_file():
print('Only ninja backend is supported to rebuild tests before running them.')
return True
@@ -1282,7 +1291,21 @@ def rebuild_all(wd: str) -> bool:
print("Can't find ninja, can't rebuild test.")
return False
- ret = subprocess.run(ninja + ['-C', wd]).returncode
+ depends = set() # type: T.Set[str]
+ targets = set() # type: T.Set[str]
+ intro_targets = dict() # type: T.Dict[str, T.List[str]]
+ for target in load_info_file(get_infodir(wd), kind='targets'):
+ intro_targets[target['id']] = [
+ os.path.relpath(f, wd)
+ for f in target['filename']]
+ for t in tests:
+ for d in t.depends:
+ if d in depends:
+ continue
+ depends.update(d)
+ targets.update(intro_targets[d])
+
+ ret = subprocess.run(ninja + ['-C', wd] + sorted(targets)).returncode
if ret != 0:
print('Could not rebuild {}'.format(wd))
return False
@@ -1318,18 +1341,11 @@ def run(options: argparse.Namespace) -> int:
print('Could not find requested program: {!r}'.format(check_bin))
return 1
- if not options.list and not options.no_rebuild:
- if not rebuild_all(options.wd):
- # We return 125 here in case the build failed.
- # The reason is that exit code 125 tells `git bisect run` that the current commit should be skipped.
- # Thus users can directly use `meson test` to bisect without needing to handle the does-not-build case separately in a wrapper script.
- return 125
-
with TestHarness(options) as th:
try:
if options.list:
return list_tests(th)
- return th.doit()
+ return th.doit(options)
except TestException as e:
print('Meson test encountered an error:\n')
if os.environ.get('MESON_FORCE_BACKTRACE'):