diff --git a/llvm/docs/CommandGuide/lit.rst b/llvm/docs/CommandGuide/lit.rst --- a/llvm/docs/CommandGuide/lit.rst +++ b/llvm/docs/CommandGuide/lit.rst @@ -154,6 +154,10 @@ suite take the most time to execute. Note that this option is most useful with ``-j 1``. +.. option:: --ignore-fail + + Exit with status zero even if some tests fail. + .. option:: --no-indirectly-run-check Do not error if a test would not be run if the user had specified the diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py --- a/llvm/utils/lit/lit/cl_arguments.py +++ b/llvm/utils/lit/lit/cl_arguments.py @@ -130,6 +130,10 @@ execution_group.add_argument("--allow-empty-runs", help="Do not fail the run if all tests are filtered out", action="store_true") + execution_group.add_argument("--ignore-fail", + dest="ignoreFail", + action="store_true", + help="Exit with status zero even if some tests fail") execution_group.add_argument("--no-indirectly-run-check", dest="indirectlyRunCheck", help="Do not error if a test would not be run if the user had " diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py --- a/llvm/utils/lit/lit/main.py +++ b/llvm/utils/lit/lit/main.py @@ -122,8 +122,11 @@ has_failure = any(t.isFailure() for t in discovered_tests) if has_failure: - sys.exit(1) - + if opts.ignoreFail: + sys.stderr.write("\nExiting with status 0 instead of 1 because " + "'--ignore-fail' was specified.\n") + else: + sys.exit(1) def create_params(builtin_params, user_params): def parse(p): diff --git a/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt b/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt new file mode 100644 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt @@ -0,0 +1 @@ +RUN: false diff --git a/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg b/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg new file mode 100644 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg @@ -0,0 +1,6 @@ +import lit.formats +config.name = 'ignore-fail' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None diff --git a/llvm/utils/lit/tests/Inputs/ignore-fail/unresolved.txt b/llvm/utils/lit/tests/Inputs/ignore-fail/unresolved.txt new file mode 100644 diff --git a/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt b/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt new file mode 100644 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt @@ -0,0 +1,2 @@ +RUN: false +XFAIL: * diff --git a/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt b/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt new file mode 100644 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt @@ -0,0 +1,2 @@ +RUN: true +XFAIL: * diff --git a/llvm/utils/lit/tests/ignore-fail.py b/llvm/utils/lit/tests/ignore-fail.py new file mode 100644 --- /dev/null +++ b/llvm/utils/lit/tests/ignore-fail.py @@ -0,0 +1,19 @@ +# Check that --ignore-fail produces exit status 0 despite various kinds of +# test failures but doesn't otherwise suppress those failures. + +# RUN: not %{lit} -j 1 %{inputs}/ignore-fail | FileCheck %s +# RUN: %{lit} -j 1 --ignore-fail %{inputs}/ignore-fail | FileCheck %s + +# END. + +# CHECK: FAIL: ignore-fail :: fail.txt +# CHECK: UNRESOLVED: ignore-fail :: unresolved.txt +# CHECK: XFAIL: ignore-fail :: xfail.txt +# CHECK: XPASS: ignore-fail :: xpass.txt + +# CHECK: Testing Time: +# CHECK-NEXT: Expectedly Failed : 1 +# CHECK-NEXT: Unresolved : 1 +# CHECK-NEXT: Failed : 1 +# CHECK-NEXT: Unexpectedly Passed: 1 +# CHECK-NOT: {{.}}