@@ -37,7 +37,7 @@ class PatchtestParser(object):
help='The patch to be tested')
target_patch_group.add_argument('--directory', metavar='DIRECTORY', dest='patch_path',
- help='The directory containing patches to be tested')
+ help='The directory containing patches to be tested. CTRL+C aborts the entire directory test.')
parser.add_argument('--repodir', metavar='REPO',
default=default_repodir,
@@ -85,6 +85,10 @@ class PatchTestRepo(object):
self._patchmerged = True
def clean(self):
+ try:
+ self.repo.git.execute(['git', 'am', '--abort'])
+ except git.exc.GitCommandError:
+ pass
self.repo.git.execute(['git', 'checkout', self.current_branch if self.current_branch else self.current_commit])
self.repo.git.execute(['git', 'branch', '-D', self._workingbranch])
self._patchmerged = False
@@ -12,6 +12,7 @@
import json
import logging
import os
+import signal
import subprocess
import sys
import traceback
@@ -133,8 +134,6 @@ def _runner(resultklass, prefix=None):
def run(patch, logfile=None):
""" Load, setup and run pre and post-merge tests """
- unittest.installHandler()
-
premerge_result = _runner(make_result_class(patch, False, logfile), 'pretest')
postmerge_result = _runner(make_result_class(patch, True, logfile), 'test')
@@ -183,10 +182,26 @@ def main():
else:
patch_list = [patch_path]
+ interrupted = False
+ previous_sigint = signal.getsignal(signal.SIGINT)
+
+ def _sigint_handler(signum, frame):
+ nonlocal interrupted
+ interrupted = True
+ # Restore previous handler so a second CTRL+C exits immediately
+ signal.signal(signal.SIGINT, previous_sigint)
+ signal.default_int_handler(signum, frame)
+
+ signal.signal(signal.SIGINT, _sigint_handler)
+
ret = 0
for patch in patch_list:
+ if interrupted:
+ break
+
if os.path.getsize(patch) == 0:
logger.error('patchtest: patch is empty')
+ signal.signal(signal.SIGINT, previous_sigint)
return 1
logger.info('Testing patch %s' % patch)
@@ -197,8 +212,18 @@ def main():
with open(log_path, "a") as f:
f.write("Patchtest results for patch '%s':\n\n" % patch)
- ret = run(patch, log_path)
+ try:
+ result = run(patch, log_path)
+ ret = ret or result
+ except KeyboardInterrupt:
+ interrupted = True
+
+ if interrupted:
+ logger.error('\npatchtest: interrupted')
+ signal.signal(signal.SIGINT, previous_sigint)
+ return 1
+ signal.signal(signal.SIGINT, previous_sigint)
return ret
if __name__ == '__main__':
Currently, patchtest run with --directory responds to a CTRL+C press by aborting only the current patch being tested, and moves onto the next. Instead, this key press should stop the test entirely. Remove usage of the unittest.installHandler() function (which intercepts the signal) and handle it ourselves. Also make sure that the branch is properly reset with git am --abort afterwards, and that the return code is properly set in the sigint handler function. Finally, update patchtest_parser.py so that the helper info reflects this change. AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> --- meta/lib/patchtest/patchtest_parser.py | 2 +- meta/lib/patchtest/repo.py | 4 ++++ scripts/patchtest | 31 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-)