[llvm] r330755 - [lit] Report line number for failed RUN command

Joel E. Denny via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 24 11:43:25 PDT 2018


Author: jdenny
Date: Tue Apr 24 11:43:25 2018
New Revision: 330755

URL: http://llvm.org/viewvc/llvm-project?rev=330755&view=rev
Log:
[lit] Report line number for failed RUN command

When debugging test failures with -vv (or -v in the case of the
internal shell), this makes it easier to locate the RUN line that
failed.  For example, clang's test/Driver/linux-ld.c has 892 total RUN
lines, and clang's test/Driver/arm-cortex-cpus.c has 424 RUN lines
after concatenation for line continuations.

When reading the generated shell script, this also makes it easier to
locate the RUN line that produced each command.

To support reporting RUN line numbers in the case of the internal
shell, this patch extends the internal shell to support the null
command, ":", except pipelines are not supported.

Reviewed By: asmith, delcypher

Differential Revision: https://reviews.llvm.org/D44598

Added:
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/basic.txt
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/line-continuation.txt
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/basic.txt
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/line-continuation.txt
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
    llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/lit.cfg
    llvm/trunk/utils/lit/tests/Inputs/shtest-shell/colon-error.txt
    llvm/trunk/utils/lit/tests/shtest-run-at-line.py
Modified:
    llvm/trunk/docs/CommandGuide/lit.rst
    llvm/trunk/utils/lit/lit/TestRunner.py
    llvm/trunk/utils/lit/tests/max-failures.py
    llvm/trunk/utils/lit/tests/shtest-format.py
    llvm/trunk/utils/lit/tests/shtest-output-printing.py
    llvm/trunk/utils/lit/tests/shtest-shell.py
    llvm/trunk/utils/lit/tests/unit/TestRunner.py

Modified: llvm/trunk/docs/CommandGuide/lit.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/lit.rst?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/lit.rst (original)
+++ llvm/trunk/docs/CommandGuide/lit.rst Tue Apr 24 11:43:25 2018
@@ -85,6 +85,8 @@ OUTPUT OPTIONS
  Echo all commands to stdout, as they are being executed.
  This can be valuable for debugging test failures, as the last echoed command
  will be the one which has failed.
+ To help you find the source RUN line, :program:`lit` inserts a no-op ``:``
+ command with argument ``'RUN: at line N'`` before each command pipeline.
  This option implies ``--verbose``.
 
 .. option:: -a, --show-all

Modified: llvm/trunk/utils/lit/lit/TestRunner.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/TestRunner.py (original)
+++ llvm/trunk/utils/lit/lit/TestRunner.py Tue Apr 24 11:43:25 2018
@@ -789,6 +789,13 @@ def _executeShCmd(cmd, shenv, results, t
         results.append(cmdResult)
         return cmdResult.exitCode
 
+    if cmd.commands[0].args[0] == ':':
+        if len(cmd.commands) != 1:
+            raise InternalShellError(cmd.commands[0], "Unsupported: ':' "
+                                     "cannot be part of a pipeline")
+        results.append(ShellCommandResult(cmd.commands[0], '', '', 0, False))
+        return 0;
+
     procs = []
     default_stdin = subprocess.PIPE
     stderrTempFiles = []
@@ -1318,7 +1325,8 @@ class IntegratedTestKeywordParser(object
     def parseLine(self, line_number, line):
         try:
             self.parsed_lines += [(line_number, line)]
-            self.value = self.parser(line_number, line, self.value)
+            self.value = self.parser(line_number, line, self.value,
+                                     self.keyword)
         except ValueError as e:
             raise ValueError(str(e) + ("\nin %s directive on test line %d" %
                                        (self.keyword, line_number)))
@@ -1327,12 +1335,12 @@ class IntegratedTestKeywordParser(object
         return self.value
 
     @staticmethod
-    def _handleTag(line_number, line, output):
+    def _handleTag(line_number, line, output, keyword):
         """A helper for parsing TAG type keywords"""
         return (not line.strip() or output)
 
     @staticmethod
-    def _handleCommand(line_number, line, output):
+    def _handleCommand(line_number, line, output, keyword):
         """A helper for parsing COMMAND type keywords"""
         # Trim trailing whitespace.
         line = line.rstrip()
@@ -1351,11 +1359,15 @@ class IntegratedTestKeywordParser(object
         else:
             if output is None:
                 output = []
+            line = ": '{keyword} at line {line}'; {real_command}".format(
+                keyword=keyword,
+                line=line_number,
+                real_command=line)
             output.append(line)
         return output
 
     @staticmethod
-    def _handleList(line_number, line, output):
+    def _handleList(line_number, line, output, keyword):
         """A parser for LIST type keywords"""
         if output is None:
             output = []
@@ -1363,7 +1375,7 @@ class IntegratedTestKeywordParser(object
         return output
 
     @staticmethod
-    def _handleBooleanExpr(line_number, line, output):
+    def _handleBooleanExpr(line_number, line, output, keyword):
         """A parser for BOOLEAN_EXPR type keywords"""
         if output is None:
             output = []
@@ -1376,17 +1388,18 @@ class IntegratedTestKeywordParser(object
         return output
 
     @staticmethod
-    def _handleRequiresAny(line_number, line, output):
+    def _handleRequiresAny(line_number, line, output, keyword):
         """A custom parser to transform REQUIRES-ANY: into REQUIRES:"""
 
         # Extract the conditions specified in REQUIRES-ANY: as written.
         conditions = []
-        IntegratedTestKeywordParser._handleList(line_number, line, conditions)
+        IntegratedTestKeywordParser._handleList(line_number, line, conditions,
+                                                keyword)
 
         # Output a `REQUIRES: a || b || c` expression in its place.
         expression = ' || '.join(conditions)
-        IntegratedTestKeywordParser._handleBooleanExpr(line_number,
-                                                       expression, output)
+        IntegratedTestKeywordParser._handleBooleanExpr(line_number, expression,
+                                                       output, keyword)
         return output
 
 def parseIntegratedTestScript(test, additional_parsers=[],

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/basic.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/basic.txt?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/basic.txt (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/basic.txt Tue Apr 24 11:43:25 2018
@@ -0,0 +1,3 @@
+# RUN: true
+# RUN: false
+# RUN: true

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/line-continuation.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/line-continuation.txt?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/line-continuation.txt (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/line-continuation.txt Tue Apr 24 11:43:25 2018
@@ -0,0 +1,11 @@
+# RUN: : first line continued \
+# RUN:   to second line
+# RUN: echo 'foo bar' \
+# RUN: | FileCheck %s
+# RUN: echo \
+# RUN: 'foo baz' \
+# RUN: | FileCheck %s
+# RUN: echo 'foo bar' \
+# RUN: | FileCheck %s
+
+# CHECK: foo bar

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg Tue Apr 24 11:43:25 2018
@@ -0,0 +1,2 @@
+import lit.formats
+config.test_format = lit.formats.ShTest(execute_external=True)

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/basic.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/basic.txt?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/basic.txt (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/basic.txt Tue Apr 24 11:43:25 2018
@@ -0,0 +1,3 @@
+# RUN: true
+# RUN: false
+# RUN: true

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/line-continuation.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/line-continuation.txt?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/line-continuation.txt (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/line-continuation.txt Tue Apr 24 11:43:25 2018
@@ -0,0 +1,11 @@
+# RUN: : first line continued \
+# RUN:   to second line
+# RUN: echo 'foo bar' \
+# RUN: | FileCheck %s
+# RUN: echo \
+# RUN: 'foo baz' \
+# RUN: | FileCheck %s
+# RUN: echo 'foo bar' \
+# RUN: | FileCheck %s
+
+# CHECK: foo bar

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg Tue Apr 24 11:43:25 2018
@@ -0,0 +1,2 @@
+import lit.formats
+config.test_format = lit.formats.ShTest(execute_external=False)

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/lit.cfg?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/lit.cfg (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-run-at-line/lit.cfg Tue Apr 24 11:43:25 2018
@@ -0,0 +1,3 @@
+import lit.formats
+config.name = 'shtest-run-at-line'
+config.suffixes = ['.txt']

Added: llvm/trunk/utils/lit/tests/Inputs/shtest-shell/colon-error.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/Inputs/shtest-shell/colon-error.txt?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/Inputs/shtest-shell/colon-error.txt (added)
+++ llvm/trunk/utils/lit/tests/Inputs/shtest-shell/colon-error.txt Tue Apr 24 11:43:25 2018
@@ -0,0 +1,3 @@
+# Check error on an unsupported ":". (cannot be part of a pipeline)
+#
+# RUN: : | echo "hello"

Modified: llvm/trunk/utils/lit/tests/max-failures.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/max-failures.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/max-failures.py (original)
+++ llvm/trunk/utils/lit/tests/max-failures.py Tue Apr 24 11:43:25 2018
@@ -8,7 +8,7 @@
 #
 # END.
 
-# CHECK: Failing Tests (26)
+# CHECK: Failing Tests (27)
 # CHECK: Failing Tests (1)
 # CHECK: Failing Tests (2)
 # CHECK: error: Setting --max-failures to 0 does not have any effect.

Modified: llvm/trunk/utils/lit/tests/shtest-format.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/shtest-format.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/shtest-format.py (original)
+++ llvm/trunk/utils/lit/tests/shtest-format.py Tue Apr 24 11:43:25 2018
@@ -39,6 +39,7 @@
 #
 # CHECK: Command Output (stdout):
 # CHECK-NEXT: --
+# CHECK-NEXT: $ ":" "RUN: at line 1"
 # CHECK-NEXT: $ "printf"
 # CHECK-NEXT: # command output:
 # CHECK-NEXT: line 1: failed test output on stdout

Modified: llvm/trunk/utils/lit/tests/shtest-output-printing.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/shtest-output-printing.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/shtest-output-printing.py (original)
+++ llvm/trunk/utils/lit/tests/shtest-output-printing.py Tue Apr 24 11:43:25 2018
@@ -16,12 +16,15 @@
 #
 # CHECK:      Command Output
 # CHECK-NEXT: --
+# CHECK-NEXT: $ ":" "RUN: at line 1"
 # CHECK-NEXT: $ "true"
+# CHECK-NEXT: $ ":" "RUN: at line 2"
 # CHECK-NEXT: $ "echo" "hi"
 # CHECK-NEXT: # command output:
 # CHECK-NEXT: hi
 #
-# CHECK:      $ "wc" "missing-file"
+# CHECK:      $ ":" "RUN: at line 3"
+# CHECK-NEXT: $ "wc" "missing-file"
 # CHECK-NEXT: # redirected output from '{{.*(/|\\\\)}}basic.txt.tmp.out':
 # CHECK-NEXT: missing-file{{.*}} No such file or directory
 # CHECK:      note: command had no output on stdout or stderr

Added: llvm/trunk/utils/lit/tests/shtest-run-at-line.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/shtest-run-at-line.py?rev=330755&view=auto
==============================================================================
--- llvm/trunk/utils/lit/tests/shtest-run-at-line.py (added)
+++ llvm/trunk/utils/lit/tests/shtest-run-at-line.py Tue Apr 24 11:43:25 2018
@@ -0,0 +1,74 @@
+# Check that -vv makes the line number of the failing RUN command clear.
+# (-v is actually sufficient in the case of the internal shell.)
+#
+# RUN: not %{lit} -j 1 -vv %{inputs}/shtest-run-at-line > %t.out
+# RUN: FileCheck --input-file %t.out %s
+#
+# END.
+
+
+# CHECK: Testing: 4 tests
+
+
+# In the case of the external shell, we check for only RUN lines in stderr in
+# case some shell implementations format "set -x" output differently.
+
+# CHECK-LABEL: FAIL: shtest-run-at-line :: external-shell/basic.txt
+
+# CHECK:      Script:
+# CHECK:      : 'RUN: at line 1';  true
+# CHECK-NEXT: : 'RUN: at line 2';  false
+# CHECK-NEXT: : 'RUN: at line 3';  true
+
+# CHECK:     Command Output (stderr)
+# CHECK:     RUN: at line 1
+# CHECK:     RUN: at line 2
+# CHECK-NOT: RUN
+
+# CHECK-LABEL: FAIL: shtest-run-at-line :: external-shell/line-continuation.txt
+
+# CHECK:      Script:
+# CHECK:      : 'RUN: at line 1';  : first line continued    to second line
+# CHECK-NEXT: : 'RUN: at line 3';  echo 'foo bar'  | FileCheck
+# CHECK-NEXT: : 'RUN: at line 5';  echo  'foo baz'  | FileCheck
+# CHECK-NEXT: : 'RUN: at line 8';  echo 'foo bar'  | FileCheck
+
+# CHECK:     Command Output (stderr)
+# CHECK:     RUN: at line 1
+# CHECK:     RUN: at line 3
+# CHECK:     RUN: at line 5
+# CHECK-NOT: RUN
+
+
+# CHECK-LABEL: FAIL: shtest-run-at-line :: internal-shell/basic.txt
+
+# CHECK:      Script:
+# CHECK:      : 'RUN: at line 1';  true
+# CHECK-NEXT: : 'RUN: at line 2';  false
+# CHECK-NEXT: : 'RUN: at line 3';  true
+
+# CHECK:      Command Output (stdout)
+# CHECK:      $ ":" "RUN: at line 1"
+# CHECK-NEXT: $ "true"
+# CHECK-NEXT: $ ":" "RUN: at line 2"
+# CHECK-NEXT: $ "false"
+# CHECK-NOT:  RUN
+
+# CHECK-LABEL: FAIL: shtest-run-at-line :: internal-shell/line-continuation.txt
+
+# CHECK:      Script:
+# CHECK:      : 'RUN: at line 1';  : first line continued to second line
+# CHECK-NEXT: : 'RUN: at line 3';  echo 'foo bar'  | FileCheck
+# CHECK-NEXT: : 'RUN: at line 5';  echo  'foo baz'  | FileCheck
+# CHECK-NEXT: : 'RUN: at line 8';  echo 'foo bar'  | FileCheck
+
+# CHECK:      Command Output (stdout)
+# CHECK:      $ ":" "RUN: at line 1"
+# CHECK-NEXT: $ ":" "first" "line" "continued" "to" "second" "line"
+# CHECK-NEXT: $ ":" "RUN: at line 3"
+# CHECK-NEXT: $ "echo" "foo bar"
+# CHECK-NEXT: $ "FileCheck" "{{.*}}"
+# CHECK-NEXT: $ ":" "RUN: at line 5"
+# CHECK-NEXT: $ "echo" "foo baz"
+# CHECK-NEXT: $ "FileCheck" "{{.*}}"
+# CHECK-NOT:  RUN

Modified: llvm/trunk/utils/lit/tests/shtest-shell.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/shtest-shell.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/shtest-shell.py (original)
+++ llvm/trunk/utils/lit/tests/shtest-shell.py Tue Apr 24 11:43:25 2018
@@ -26,6 +26,14 @@
 # CHECK: error: command failed with exit status: 1
 # CHECK: ***
 
+# CHECK: FAIL: shtest-shell :: colon-error.txt
+# CHECK: *** TEST 'shtest-shell :: colon-error.txt' FAILED ***
+# CHECK: $ ":"
+# CHECK: # command stderr:
+# CHECK: Unsupported: ':' cannot be part of a pipeline
+# CHECK: error: command failed with exit status: 127
+# CHECK: ***
+
 # CHECK: FAIL: shtest-shell :: diff-error-0.txt
 # CHECK: *** TEST 'shtest-shell :: diff-error-0.txt' FAILED ***
 # CHECK: $ "diff" "diff-error-0.txt" "diff-error-0.txt"
@@ -153,7 +161,7 @@
 #
 # CHECK: FAIL: shtest-shell :: error-1.txt
 # CHECK: *** TEST 'shtest-shell :: error-1.txt' FAILED ***
-# CHECK: shell parser error on: 'echo "missing quote'
+# CHECK: shell parser error on: ': \'RUN: at line 3\'; echo "missing quote'
 # CHECK: ***
 
 # CHECK: FAIL: shtest-shell :: error-2.txt
@@ -219,4 +227,4 @@
 # CHECK: PASS: shtest-shell :: sequencing-0.txt
 # CHECK: XFAIL: shtest-shell :: sequencing-1.txt
 # CHECK: PASS: shtest-shell :: valid-shell.txt
-# CHECK: Failing Tests (26)
+# CHECK: Failing Tests (27)

Modified: llvm/trunk/utils/lit/tests/unit/TestRunner.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/unit/TestRunner.py?rev=330755&r1=330754&r2=330755&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/unit/TestRunner.py (original)
+++ llvm/trunk/utils/lit/tests/unit/TestRunner.py Tue Apr 24 11:43:25 2018
@@ -47,7 +47,7 @@ class TestIntegratedTestKeywordParser(un
 
     @staticmethod
     def make_parsers():
-        def custom_parse(line_number, line, output):
+        def custom_parse(line_number, line, output, keyword):
             if output is None:
                 output = []
             output += [part for part in line.split(' ') if part.strip()]
@@ -99,8 +99,8 @@ class TestIntegratedTestKeywordParser(un
         cmd_parser = self.get_parser(parsers, 'MY_RUN:')
         value = cmd_parser.getValue()
         self.assertEqual(len(value), 2)  # there are only two run lines
-        self.assertEqual(value[0].strip(), 'baz')
-        self.assertEqual(value[1].strip(), 'foo  bar')
+        self.assertEqual(value[0].strip(), ": 'MY_RUN: at line 4';  baz")
+        self.assertEqual(value[1].strip(), ": 'MY_RUN: at line 7';  foo  bar")
 
     def test_custom(self):
         parsers = self.make_parsers()




More information about the llvm-commits mailing list