aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-10-13 18:12:40 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2020-11-15 14:12:43 +0100
commit8cf90e63707261c09564a6f641d3439e9040f871 (patch)
tree500013a810b967f173767b4437f7935f00ded519
parent659a5cbaa31e7a66e3ba3e17f9f31be78cec8b18 (diff)
downloadmeson-8cf90e63707261c09564a6f641d3439e9040f871.zip
meson-8cf90e63707261c09564a6f641d3439e9040f871.tar.gz
meson-8cf90e63707261c09564a6f641d3439e9040f871.tar.bz2
mtest: add back SIGINT handling
-rw-r--r--mesonbuild/mtest.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 2caa367..59ddec1 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -608,6 +608,13 @@ def load_tests(build_dir: str) -> T.List[TestSerialisation]:
# Custom waiting primitives for asyncio
+async def complete(future: asyncio.Future) -> None:
+ """Wait for completion of the given future, ignoring cancellation."""
+ try:
+ await future
+ except asyncio.CancelledError:
+ pass
+
async def complete_all(futures: T.Iterable[asyncio.Future]) -> None:
"""Wait for completion of all the given futures, ignoring cancellation."""
while futures:
@@ -1161,10 +1168,11 @@ class TestHarness:
if self.options.wd:
os.chdir(self.options.wd)
self.build_data = build.load(os.getcwd())
+ interrupted = False
async def run_test(test: SingleTestRunner,
name: str, index: int) -> None:
- if self.options.repeat > 1 and self.fail_count:
+ if interrupted or (self.options.repeat > 1 and self.fail_count):
return
res = await asyncio.get_event_loop().run_in_executor(executor, test.run)
self.process_test_result(res)
@@ -1175,6 +1183,17 @@ class TestHarness:
f.result()
futures.remove(f)
+ def cancel_all_futures() -> None:
+ nonlocal interrupted
+ if interrupted:
+ return
+ interrupted = True
+ mlog.warning('CTRL-C detected, interrupting')
+ for f in futures:
+ f.cancel()
+
+ if sys.platform != 'win32':
+ asyncio.get_event_loop().add_signal_handler(signal.SIGINT, cancel_all_futures)
try:
for _ in range(self.options.repeat):
for i, test in enumerate(tests, 1):
@@ -1183,11 +1202,11 @@ class TestHarness:
if not test.is_parallel or single_test.options.gdb:
await complete_all(futures)
- await run_test(single_test, visible_name, i)
- else:
- future = asyncio.ensure_future(run_test(single_test, visible_name, i))
- futures.append(future)
- future.add_done_callback(test_done)
+ future = asyncio.ensure_future(run_test(single_test, visible_name, i))
+ futures.append(future)
+ future.add_done_callback(test_done)
+ if not test.is_parallel or single_test.options.gdb:
+ await complete(future)
if self.options.repeat > 1 and self.fail_count:
break
@@ -1198,6 +1217,8 @@ class TestHarness:
if self.logfilename:
print('Full log written to {}'.format(self.logfilename))
finally:
+ if sys.platform != 'win32':
+ asyncio.get_event_loop().remove_signal_handler(signal.SIGINT)
os.chdir(startdir)
def list_tests(th: TestHarness) -> bool: