[llvm] c3ef971 - [lit] Improve handling of timeouts and max failures
Julian Lettner via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 2 01:24:16 PDT 2020
Author: Julian Lettner
Date: 2020-04-02T01:24:02-07:00
New Revision: c3ef971d36b7f7c37a0f5cedb5c64fef7420bfea
URL: https://github.com/llvm/llvm-project/commit/c3ef971d36b7f7c37a0f5cedb5c64fef7420bfea
DIFF: https://github.com/llvm/llvm-project/commit/c3ef971d36b7f7c37a0f5cedb5c64fef7420bfea.diff
LOG: [lit] Improve handling of timeouts and max failures
This work prepares us for the overall goal of clean shutdown on user
keyboard interrupt [Ctrl+C].
Added:
Modified:
llvm/utils/lit/lit/main.py
llvm/utils/lit/lit/run.py
Removed:
################################################################################
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 8c675c0e5ba4..a329115fafd0 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -189,8 +189,8 @@ def filter_by_shard(tests, run, shards, lit_config):
return selected_tests
-def run_tests(tests, lit_config, opts, numTotalTests):
- display = lit.display.create_display(opts, len(tests), numTotalTests,
+def run_tests(tests, lit_config, opts, discovered_tests):
+ display = lit.display.create_display(opts, len(tests), discovered_tests,
opts.workers)
def progress_callback(test):
display.update(test)
@@ -201,12 +201,22 @@ def progress_callback(test):
opts.max_failures, opts.timeout)
display.print_header()
+
+ interrupted = False
+ error = None
try:
execute_in_tmp_dir(run, lit_config)
- display.clear(interrupted=False)
except KeyboardInterrupt:
- display.clear(interrupted=True)
- print(' [interrupted by user]')
+ interrupted = True
+ error = ' interrupted by user'
+ except lit.run.MaxFailuresError:
+ error = 'warning: reached maximum number of test failures'
+ except lit.run.TimeoutError:
+ error = 'warning: reached timeout'
+
+ display.clear(interrupted)
+ if error:
+ sys.stderr.write('%s, skipping remaining tests\n' % error)
def execute_in_tmp_dir(run, lit_config):
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index d69121195c63..4b91294ea8c2 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -14,6 +14,12 @@ def acquire(self): pass
def release(self): pass
+class MaxFailuresError(Exception):
+ pass
+class TimeoutError(Exception):
+ pass
+
+
class Run(object):
"""A concrete, configured testing run."""
@@ -45,8 +51,7 @@ def execute(self):
computed. Tests which were not actually executed (for any reason) will
be given an UNRESOLVED result.
"""
- self.failure_count = 0
- self.hit_max_failures = False
+ self.failures = 0
# Larger timeouts (one year, positive infinity) don't work on Windows.
one_week = 7 * 24 * 60 * 60 # days * hours * minutes * seconds
@@ -80,40 +85,37 @@ def _execute(self, deadline):
async_results = [
pool.apply_async(lit.worker.execute, args=[test],
- callback=lambda t, i=idx: self._process_completed(t, i))
- for idx, test in enumerate(self.tests)]
+ callback=self._process_completed)
+ for test in self.tests]
pool.close()
- for ar in async_results:
- timeout = deadline - time.time()
+ try:
+ self._wait_for(async_results, deadline)
+ except:
+ pool.terminate()
+ raise
+ finally:
+ pool.join()
+
+ def _wait_for(self, async_results, deadline):
+ timeout = deadline - time.time()
+ for idx, ar in enumerate(async_results):
try:
- ar.get(timeout)
+ test = ar.get(timeout)
except multiprocessing.TimeoutError:
- # TODO(yln): print timeout error
- pool.terminate()
- break
- if self.hit_max_failures:
- pool.terminate()
- break
- pool.join()
-
- # TODO(yln): as the comment says.. this is racing with the main thread waiting
- # for results
- def _process_completed(self, test, idx):
- # Don't add any more test results after we've hit the maximum failure
- # count. Otherwise we're racing with the main thread, which is going
- # to terminate the process pool soon.
- if self.hit_max_failures:
+ raise TimeoutError()
+ else:
+ self.tests[idx] = test
+ if test.isFailure():
+ self.failures += 1
+ if self.failures == self.max_failures:
+ raise MaxFailuresError()
+
+ def _process_completed(self, test):
+ # Avoid racing with the main thread, which is going to terminate the
+ # process pool soon.
+ if self.failures == self.max_failures:
return
-
- self.tests[idx] = test
-
- # Use test.isFailure() for correct XFAIL and XPASS handling
- if test.isFailure():
- self.failure_count += 1
- if self.failure_count == self.max_failures:
- self.hit_max_failures = True
-
self.progress_callback(test)
# TODO(yln): interferes with progress bar
More information about the llvm-commits
mailing list