[llvm] [lit] Fix shell commands with newlines (PR #67898)

Joel E. Denny via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 2 08:56:48 PDT 2023


https://github.com/jdenny-ornl updated https://github.com/llvm/llvm-project/pull/67898

>From 57e35950d4e0b07b2d00638bf662ffda88226b5f Mon Sep 17 00:00:00 2001
From: "Joel E. Denny" <jdenny.ornl at gmail.com>
Date: Sat, 30 Sep 2023 21:42:46 -0400
Subject: [PATCH 1/2] [lit] Fix shell commands with newlines

In PR #65242 (landed as 9e739fdb85ac672f3e25e971d96e71823e07ebda), I
claimed that RUN lines cannot contain newlines.  Actually, they can
after substitution expansion.  More generally, a lit config file can
define substitutions or preamble commands containing newlines.  While
both of those cases seem unlikely in practice,
[D154987](https://reviews.llvm.org/D154987) proposes PYTHON directives
where it seems very likely.

Regardless of the use case, without this patch, such newlines break
expansion of `%dbg(RUN: at line N)`, and the fix is simple.
---
 llvm/utils/lit/lit/TestRunner.py              |  2 +-
 .../lit/tests/Inputs/shtest-inject/lit.cfg    |  3 ++-
 .../external-shell/lit.local.cfg              |  5 ++++
 .../external-shell/run-line-with-newline.txt  |  2 ++
 .../internal-shell/lit.local.cfg              |  5 ++++
 .../internal-shell/run-line-with-newline.txt  |  2 ++
 llvm/utils/lit/tests/shtest-inject.py         |  3 ++-
 llvm/utils/lit/tests/shtest-run-at-line.py    | 24 ++++++++++++++++++-
 8 files changed, 42 insertions(+), 4 deletions(-)
 create mode 100644 llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
 create mode 100644 llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt

diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 528694b07f03300..a6314e35c1a045c 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -55,7 +55,7 @@ def __init__(self, command, message):
 #
 # COMMAND that follows %dbg(ARG) is also captured. COMMAND can be
 # empty as a result of conditinal substitution.
-kPdbgRegex = "%dbg\\(([^)'\"]*)\\)(.*)"
+kPdbgRegex = "%dbg\\(([^)'\"]*)\\)((?:.|\\n)*)"
 
 
 def buildPdbgCommand(msg, cmd):
diff --git a/llvm/utils/lit/tests/Inputs/shtest-inject/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-inject/lit.cfg
index b3a86e73d21ac99..6454e22ce2145f7 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-inject/lit.cfg
+++ b/llvm/utils/lit/tests/Inputs/shtest-inject/lit.cfg
@@ -1,6 +1,7 @@
 import lit
 
-preamble_commands = ['echo "THIS WAS"', 'echo "INJECTED"']
+# Check multiple commands, and check newlines.
+preamble_commands = ['echo "THIS WAS"', 'echo\n"INJECTED"']
 
 config.name = "shtest-inject"
 config.suffixes = [".txt"]
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
index 4cc234df4fcaaf8..0bc85e213ec390f 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
@@ -1,3 +1,8 @@
 import lit.formats
 
 config.test_format = lit.formats.ShTest(execute_external=True)
+config.substitutions.append(("%{cmds-with-newlines}", """
+true &&
+echo abc |
+FileCheck %s
+"""))
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
new file mode 100644
index 000000000000000..32be84d530419b0
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
@@ -0,0 +1,2 @@
+# RUN: %{cmds-with-newlines}
+# CHECK: bac
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
index 3002a11ed23c5e9..960e5dc0e77ac95 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
@@ -1,3 +1,8 @@
 import lit.formats
 
 config.test_format = lit.formats.ShTest(execute_external=False)
+config.substitutions.append(("%{cmds-with-newlines}", """
+true &&
+echo abc |
+FileCheck %s
+"""))
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt
new file mode 100644
index 000000000000000..32be84d530419b0
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt
@@ -0,0 +1,2 @@
+# RUN: %{cmds-with-newlines}
+# CHECK: bac
diff --git a/llvm/utils/lit/tests/shtest-inject.py b/llvm/utils/lit/tests/shtest-inject.py
index 3d34eb7161d462b..5ba9d2f81268f3d 100644
--- a/llvm/utils/lit/tests/shtest-inject.py
+++ b/llvm/utils/lit/tests/shtest-inject.py
@@ -14,7 +14,8 @@
 #  CHECK-TEST1-NEXT: # | THIS WAS
 #  CHECK-TEST1-NEXT: # `---{{-*}}
 #  CHECK-TEST1-NEXT: # preamble command line
-#  CHECK-TEST1-NEXT: echo "INJECTED"
+#  CHECK-TEST1-NEXT: echo
+#  CHECK-TEST1-NEXT: "INJECTED"
 #  CHECK-TEST1-NEXT: # executed command: echo INJECTED
 #  CHECK-TEST1-NEXT: # .---command stdout{{-*}}
 #  CHECK-TEST1-NEXT: # | INJECTED
diff --git a/llvm/utils/lit/tests/shtest-run-at-line.py b/llvm/utils/lit/tests/shtest-run-at-line.py
index 18086f6fa10d650..fd729ddd8f27fba 100644
--- a/llvm/utils/lit/tests/shtest-run-at-line.py
+++ b/llvm/utils/lit/tests/shtest-run-at-line.py
@@ -7,7 +7,7 @@
 # END.
 
 
-# CHECK: Testing: 6 tests
+# CHECK: Testing: 8 tests
 
 
 # In the case of the external shell, we check for only RUN lines in stderr in
@@ -48,6 +48,15 @@
 #   CHECK-NOT: RUN
 #       CHECK: --
 
+# CHECK-LABEL: FAIL: shtest-run-at-line :: external-shell/run-line-with-newline.txt
+
+#      CHECK: Command Output (stderr)
+# CHECK-NEXT: --
+# CHECK-NEXT: {{^}}RUN: at line 1: true &&
+# CHECK-NEXT: echo abc |
+# CHECK-NEXT: FileCheck {{.*}}
+#  CHECK-NOT: RUN
+
 
 # CHECK-LABEL: FAIL: shtest-run-at-line :: internal-shell/basic.txt
 
@@ -87,3 +96,16 @@
 # CHECK-NEXT: # executed command: echo 'foo baz'
 # CHECK-NEXT: # executed command: FileCheck {{.*}}
 # CHECK-NOT:  RUN
+
+# CHECK-LABEL: FAIL: shtest-run-at-line :: internal-shell/run-line-with-newline.txt
+
+#      CHECK: Command Output (stdout)
+# CHECK-NEXT: --
+# CHECK-NEXT: # RUN: at line 1
+# CHECK-NEXT: true &&
+# CHECK-NEXT: echo abc |
+# CHECK-NEXT: FileCheck {{.*}}
+# CHECK-NEXT: # executed command: true
+# CHECK-NEXT: # executed command: echo abc
+# CHECK-NEXT: # executed command: FileCheck {{.*}}
+#  CHECK-NOT: RUN

>From 020c0d723df611dd2659285f71f30acb31889e30 Mon Sep 17 00:00:00 2001
From: "Joel E. Denny" <jdenny.ornl at gmail.com>
Date: Mon, 2 Oct 2023 11:55:42 -0400
Subject: [PATCH 2/2] Make the desire to fail tests clearer

---
 .../shtest-run-at-line/external-shell/lit.local.cfg  |  4 ++--
 .../external-shell/run-line-with-newline.txt         |  2 +-
 .../shtest-run-at-line/internal-shell/lit.local.cfg  |  4 ++--
 .../internal-shell/run-line-with-newline.txt         |  2 +-
 llvm/utils/lit/tests/shtest-run-at-line.py           | 12 ++++++------
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
index 0bc85e213ec390f..913495fbb3fe335 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/lit.local.cfg
@@ -2,7 +2,7 @@ import lit.formats
 
 config.test_format = lit.formats.ShTest(execute_external=True)
 config.substitutions.append(("%{cmds-with-newlines}", """
-true &&
 echo abc |
-FileCheck %s
+FileCheck %s &&
+false
 """))
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
index 32be84d530419b0..a9cf51be9cb9a41 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/external-shell/run-line-with-newline.txt
@@ -1,2 +1,2 @@
 # RUN: %{cmds-with-newlines}
-# CHECK: bac
+# CHECK: abc
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
index 960e5dc0e77ac95..6b8e6244c1ae2a0 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/lit.local.cfg
@@ -2,7 +2,7 @@ import lit.formats
 
 config.test_format = lit.formats.ShTest(execute_external=False)
 config.substitutions.append(("%{cmds-with-newlines}", """
-true &&
 echo abc |
-FileCheck %s
+FileCheck %s &&
+false
 """))
diff --git a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt
index 32be84d530419b0..a9cf51be9cb9a41 100644
--- a/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt
+++ b/llvm/utils/lit/tests/Inputs/shtest-run-at-line/internal-shell/run-line-with-newline.txt
@@ -1,2 +1,2 @@
 # RUN: %{cmds-with-newlines}
-# CHECK: bac
+# CHECK: abc
diff --git a/llvm/utils/lit/tests/shtest-run-at-line.py b/llvm/utils/lit/tests/shtest-run-at-line.py
index fd729ddd8f27fba..dc0b78c6b81cad0 100644
--- a/llvm/utils/lit/tests/shtest-run-at-line.py
+++ b/llvm/utils/lit/tests/shtest-run-at-line.py
@@ -52,9 +52,9 @@
 
 #      CHECK: Command Output (stderr)
 # CHECK-NEXT: --
-# CHECK-NEXT: {{^}}RUN: at line 1: true &&
-# CHECK-NEXT: echo abc |
-# CHECK-NEXT: FileCheck {{.*}}
+# CHECK-NEXT: {{^}}RUN: at line 1: echo abc |
+# CHECK-NEXT: FileCheck {{.*}} &&
+# CHECK-NEXT: false
 #  CHECK-NOT: RUN
 
 
@@ -102,10 +102,10 @@
 #      CHECK: Command Output (stdout)
 # CHECK-NEXT: --
 # CHECK-NEXT: # RUN: at line 1
-# CHECK-NEXT: true &&
 # CHECK-NEXT: echo abc |
-# CHECK-NEXT: FileCheck {{.*}}
-# CHECK-NEXT: # executed command: true
+# CHECK-NEXT: FileCheck {{.*}} &&
+# CHECK-NEXT: false
 # CHECK-NEXT: # executed command: echo abc
 # CHECK-NEXT: # executed command: FileCheck {{.*}}
+# CHECK-NEXT: # executed command: false
 #  CHECK-NOT: RUN



More information about the llvm-commits mailing list