From cd04c01efb1006b8cc36ea5be6750e5684f94a87 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Sep 2016 23:38:23 +0000 Subject: [PATCH] [lit] Add a --max-failures option. - This is primarily useful as a "fail fast" mode for lit, where it will stop running tests after the first failure. - Patch by Max Moiseev. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282452 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lit/lit/LitConfig.py | 4 +++- utils/lit/lit/main.py | 12 ++++++++++-- utils/lit/lit/run.py | 14 ++++++++++++++ utils/lit/tests/max-failures.py | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 utils/lit/tests/max-failures.py diff --git a/utils/lit/lit/LitConfig.py b/utils/lit/lit/LitConfig.py index f5d41b16781..c26c08ef048 100644 --- a/utils/lit/lit/LitConfig.py +++ b/utils/lit/lit/LitConfig.py @@ -23,7 +23,8 @@ class LitConfig(object): useValgrind, valgrindLeakCheck, valgrindArgs, noExecute, debug, isWindows, params, config_prefix = None, - maxIndividualTestTime = 0): + maxIndividualTestTime = 0, + maxFailures = None): # The name of the test runner. self.progname = progname # The items to add to the PATH environment variable. @@ -60,6 +61,7 @@ class LitConfig(object): self.valgrindArgs.extend(self.valgrindUserArgs) self.maxIndividualTestTime = maxIndividualTestTime + self.maxFailures = maxFailures @property def maxIndividualTestTime(self): diff --git a/utils/lit/lit/main.py b/utils/lit/lit/main.py index ad5416ebde4..53f026dde18 100755 --- a/utils/lit/lit/main.py +++ b/utils/lit/lit/main.py @@ -232,6 +232,9 @@ def main_with_tmp(builtinParameters): help="Maximum time to spend running a single test (in seconds)." "0 means no time limit. [Default: 0]", type=int, default=None) + group.add_option("", "--max-failures", dest="maxFailures", + help="Stop execution after the given number of failures.", + action="store", type=int, default=None) parser.add_option_group(group) group = OptionGroup(parser, "Test Selection") @@ -291,6 +294,9 @@ def main_with_tmp(builtinParameters): else: opts.numThreads = 1 + if opts.maxFailures == 0: + parser.error("Setting --max-failures to 0 does not have any effect.") + inputs = args # Create the user defined parameters. @@ -324,7 +330,8 @@ def main_with_tmp(builtinParameters): isWindows = isWindows, params = userParams, config_prefix = opts.configPrefix, - maxIndividualTestTime = maxIndividualTestTime) + maxIndividualTestTime = maxIndividualTestTime, + maxFailures = opts.maxFailures) # Perform test discovery. run = lit.run.Run(litConfig, @@ -477,7 +484,8 @@ def main_with_tmp(builtinParameters): ('Expected Failing Tests', lit.Test.XFAIL), ('Timed Out Tests', lit.Test.TIMEOUT)): if (lit.Test.XFAIL == code and not opts.show_xfail) or \ - (lit.Test.UNSUPPORTED == code and not opts.show_unsupported): + (lit.Test.UNSUPPORTED == code and not opts.show_unsupported) or \ + (lit.Test.UNRESOLVED == code and (opts.maxFailures is not None)): continue elts = byCode.get(code) if not elts: diff --git a/utils/lit/lit/run.py b/utils/lit/lit/run.py index bbf644ef7db..6bcca012a5f 100644 --- a/utils/lit/lit/run.py +++ b/utils/lit/lit/run.py @@ -152,6 +152,19 @@ def run_one_tester(run, provider, display): ### +def handleFailures(provider, consumer, maxFailures): + class _Display(object): + def __init__(self, display): + self.display = display + self.maxFailures = maxFailures or object() + self.failedCount = 0 + def update(self, test): + self.display.update(test) + self.failedCount += (test.result.code == lit.Test.FAIL) + if self.failedCount == self.maxFailures: + provider.cancel() + consumer.display = _Display(consumer.display) + class Run(object): """ This class represents a concrete, configured testing run. @@ -232,6 +245,7 @@ class Run(object): # Create the test provider. provider = TestProvider(queue_impl, canceled_flag) + handleFailures(provider, consumer, self.lit_config.maxFailures) # Queue the tests outside the main thread because we can't guarantee # that we can put() all the tests without blocking: diff --git a/utils/lit/tests/max-failures.py b/utils/lit/tests/max-failures.py new file mode 100644 index 00000000000..5cc258dd08a --- /dev/null +++ b/utils/lit/tests/max-failures.py @@ -0,0 +1,14 @@ +# Check the behavior of --max-failures option. +# +# RUN: not %{lit} -j 1 -v %{inputs}/shtest-shell > %t.out +# RUN: not %{lit} --max-failures=1 -j 1 -v %{inputs}/shtest-shell >> %t.out +# RUN: not %{lit} --max-failures=2 -j 1 -v %{inputs}/shtest-shell >> %t.out +# RUN: not %{lit} --max-failures=0 -j 1 -v %{inputs}/shtest-shell 2>> %t.out +# RUN: FileCheck < %t.out %s +# +# END. + +# CHECK: Failing Tests (3) +# CHECK: Failing Tests (1) +# CHECK: Failing Tests (2) +# CHECK: error: Setting --max-failures to 0 does not have any effect. -- 2.11.0