diff options
-rw-r--r-- | docs/CommandGuide/lit.rst | 4 | ||||
-rw-r--r-- | docs/ReleaseNotes.rst | 4 | ||||
-rw-r--r-- | test/Other/pipefail.txt | 2 | ||||
-rw-r--r-- | utils/lit/lit/ShUtil.py | 5 | ||||
-rw-r--r-- | utils/lit/lit/TestRunner.py | 5 | ||||
-rw-r--r-- | utils/lit/lit/TestingConfig.py | 1 |
6 files changed, 18 insertions, 3 deletions
diff --git a/docs/CommandGuide/lit.rst b/docs/CommandGuide/lit.rst index 2f6d9a1556..a4681fb34c 100644 --- a/docs/CommandGuide/lit.rst +++ b/docs/CommandGuide/lit.rst @@ -316,6 +316,10 @@ executed, two important global variables are predefined: *on_clone* function will generally modify), and (3) the test path to the new directory being scanned. + **pipefail** Normally a test using a shell pipe fails if any of the commands + on the pipe fail. If this is not desired, setting this variable to false + makes the test fail only if the last command in the pipe fails. + TEST DISCOVERY ~~~~~~~~~~~~~~ diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 93f12e5974..e776dce29a 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -41,6 +41,10 @@ Non-comprehensive list of changes in this release functionality, or simply have a lot to talk about), see the `NOTE` below for adding a new subsection. +* The regression tests now fail if any command in a pipe fails. To disable it in + a directory, just add ``config.pipefail = False`` to its ``lit.local.cfg``. + See :doc:`Lit <CommandGuide/lit>` for the details. + * Support for exception handling has been removed from the old JIT. Use MCJIT if you need EH support. diff --git a/test/Other/pipefail.txt b/test/Other/pipefail.txt new file mode 100644 index 0000000000..241080aab6 --- /dev/null +++ b/test/Other/pipefail.txt @@ -0,0 +1,2 @@ +REQUIRES: shell +RUN: ((false | true) && echo true || echo false) | grep false diff --git a/utils/lit/lit/ShUtil.py b/utils/lit/lit/ShUtil.py index 50f7910319..00bb40255c 100644 --- a/utils/lit/lit/ShUtil.py +++ b/utils/lit/lit/ShUtil.py @@ -166,8 +166,9 @@ class ShLexer: ### class ShParser: - def __init__(self, data, win32Escapes = False): + def __init__(self, data, win32Escapes = False, pipefail = False): self.data = data + self.pipefail = pipefail self.tokens = ShLexer(data, win32Escapes = win32Escapes).lex() def lex(self): @@ -224,7 +225,7 @@ class ShParser: while self.look() == ('|',): self.lex() commands.append(self.parse_command()) - return Pipeline(commands, negate) + return Pipeline(commands, negate, self.pipefail) def parse(self): lhs = self.parse_pipeline() diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py index 84176996a8..daa9b7dfbb 100644 --- a/utils/lit/lit/TestRunner.py +++ b/utils/lit/lit/TestRunner.py @@ -245,7 +245,8 @@ def executeScriptInternal(test, litConfig, tmpBase, commands, cwd): cmds = [] for ln in commands: try: - cmds.append(ShUtil.ShParser(ln, litConfig.isWindows).parse()) + cmds.append(ShUtil.ShParser(ln, litConfig.isWindows, + test.config.pipefail).parse()) except: return (Test.FAIL, "shell parser error on: %r" % ln) @@ -284,6 +285,8 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): if isWin32CMDEXE: f.write('\nif %ERRORLEVEL% NEQ 0 EXIT\n'.join(commands)) else: + if test.config.pipefail: + f.write('set -o pipefail;') f.write('{ ' + '; } &&\n{ '.join(commands) + '; }') f.write('\n') f.close() diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py index a1f79a3bfc..5d5832e9bb 100644 --- a/utils/lit/lit/TestingConfig.py +++ b/utils/lit/lit/TestingConfig.py @@ -92,6 +92,7 @@ class TestingConfig: self.test_source_root = test_source_root self.excludes = set(excludes) self.available_features = set(available_features) + self.pipefail = True def clone(self, path): # FIXME: Chain implementations? |