From 98b433083ec1f9dab8343191ac1c2451cac3373b Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 13 Sep 2025 21:44:58 +0000 Subject: [PATCH 1/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 --- llvm/docs/CommandGuide/lit.rst | 1 + llvm/test/tools/llvm-cgdata/empty.test | 1 + llvm/utils/lit/lit/TestRunner.py | 17 +++++++++++++++++ .../Inputs/shtest-readfile/.lit_test_times.txt | 1 + .../Output/absolute-paths.txt.tmp | 1 + .../Inputs/shtest-readfile/absolute-paths.txt | 6 ++++++ .../lit/tests/Inputs/shtest-readfile/lit.cfg | 8 ++++++++ .../Inputs/shtest-readfile/relative-paths.txt | 7 +++++++ .../Inputs/shtest-readfile/two-same-line.txt | 8 ++++++++ llvm/utils/lit/tests/shtest-readfile.py | 17 +++++++++++++++++ 10 files changed, 67 insertions(+) create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt create mode 100644 llvm/utils/lit/tests/shtest-readfile.py diff --git a/llvm/docs/CommandGuide/lit.rst b/llvm/docs/CommandGuide/lit.rst index 15c249d8e6d31..359e0c3e81d0e 100644 --- a/llvm/docs/CommandGuide/lit.rst +++ b/llvm/docs/CommandGuide/lit.rst @@ -664,6 +664,7 @@ TestRunner.py: Otherwise, %t but with a single leading ``/`` removed. %:T On Windows, %/T but a ``:`` is removed if its the second character. Otherwise, %T but with a single leading ``/`` removed. + %{readfile:} Reads the file specified. ======================= ============== Other substitutions are provided that are variations on this base set and diff --git a/llvm/test/tools/llvm-cgdata/empty.test b/llvm/test/tools/llvm-cgdata/empty.test index 52d0dfb87623f..7e42db5ed8512 100644 --- a/llvm/test/tools/llvm-cgdata/empty.test +++ b/llvm/test/tools/llvm-cgdata/empty.test @@ -35,3 +35,4 @@ RUN: printf '\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: diff %t_header.cgdata %t_emptyheader.cgdata +RUN: echo %{readfile:/tmp/test} > /tmp/test diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 90c2c6479b004..8d565e8bad53a 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -719,6 +719,20 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): return std_fds +def _expandLateSubstitutions(arguments, cwd): + for i, arg in enumerate(arguments): + if not isinstance(arg, str): + continue + def _replaceReadFile(match): + filePath = match.group(1) + if not os.path.isabs(filePath): + filePath = os.path.join(cwd, filePath) + with open(filePath) as fileHandle: + return fileHandle.read() + + arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) + + return arguments def _executeShCmd(cmd, shenv, results, timeoutHelper): if timeoutHelper.timeoutReached(): @@ -834,6 +848,9 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper): # Ensure args[0] is hashable. args[0] = expand_glob(args[0], cmd_shenv.cwd)[0] + # Expand all late substitutions + args = _expandLateSubstitutions(args, cmd_shenv.cwd) + inproc_builtin = inproc_builtins.get(args[0], None) if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1): # env calling an in-process builtin is useless, so we take the safe diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt new file mode 100644 index 0000000000000..9802a6bcd406a --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt @@ -0,0 +1 @@ +-4.514933e-03 absolute-paths.txt diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp b/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp new file mode 100644 index 0000000000000..b6fc4c620b67d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp @@ -0,0 +1 @@ +hello \ No newline at end of file diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt new file mode 100644 index 0000000000000..4246064cf7bfc --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt @@ -0,0 +1,6 @@ +## Tests that readfile works with absolute paths +# RUN: echo -n "hello" > %t +# RUN: echo %{readfile:%t} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg new file mode 100644 index 0000000000000..25651f2cd4832 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg @@ -0,0 +1,8 @@ +import lit.formats + +config.name = "shtest-readfile" +config.suffixes = [".txt"] +config.test_format = lit.formats.ShTest(execute_external=False) +config.test_source_root = None +config.test_exec_root = None +config.substitutions.append(("%{python}", '"%s"' % (sys.executable))) diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt new file mode 100644 index 0000000000000..3d203d411379d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt @@ -0,0 +1,7 @@ +## Tests that readfile works with relative paths +# RUN: mkdir -p rel_path_test_folder +# RUN: echo -n "hello" > rel_path_test_folder/test_file +# RUN: echo %{readfile:rel_path_test_folder/test_file} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt new file mode 100644 index 0000000000000..6855d27d66d35 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt @@ -0,0 +1,8 @@ +## Tests that readfile works with two substitutions on the same line to ensure the +## regular expressions are setup correctly. +# RUN: echo -n "hello" > %t.1 +# RUN: echo -n "bye" > %t.2 +# RUN: echo %{readfile:%t.1} %{readfile:%t.2} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py new file mode 100644 index 0000000000000..8ba8e53b32966 --- /dev/null +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -0,0 +1,17 @@ +## Tests the readfile substitution + +# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines %s + +# CHECK: -- Testing: 3 tests{{.*}} + +# CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:{{.*}}}' + +# CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:rel_path_test_folder/test_file}' + +# CHECK-LABEL: FAIL: shtest-readfile :: two-same-line.txt ({{[^)]*}}) +# CHECK: echo hello bye +# CHECK: # executed command: echo '%{readfile:{{.*}}.1}' '%{readfile:{{.*}}.2}' From 7901d972ce08bf10617f9e07c90d2f83746dc52e Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 13 Sep 2025 21:51:22 +0000 Subject: [PATCH 2/7] formatting Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 6 ++++-- .../lit/tests/Inputs/shtest-readfile/.lit_test_times.txt | 1 - .../Inputs/shtest-readfile/Output/absolute-paths.txt.tmp | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt delete mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 8d565e8bad53a..0268c4801aa07 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -719,19 +719,21 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): return std_fds + def _expandLateSubstitutions(arguments, cwd): for i, arg in enumerate(arguments): if not isinstance(arg, str): continue + def _replaceReadFile(match): filePath = match.group(1) if not os.path.isabs(filePath): filePath = os.path.join(cwd, filePath) with open(filePath) as fileHandle: return fileHandle.read() - + arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) - + return arguments def _executeShCmd(cmd, shenv, results, timeoutHelper): diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt deleted file mode 100644 index 9802a6bcd406a..0000000000000 --- a/llvm/utils/lit/tests/Inputs/shtest-readfile/.lit_test_times.txt +++ /dev/null @@ -1 +0,0 @@ --4.514933e-03 absolute-paths.txt diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp b/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp deleted file mode 100644 index b6fc4c620b67d..0000000000000 --- a/llvm/utils/lit/tests/Inputs/shtest-readfile/Output/absolute-paths.txt.tmp +++ /dev/null @@ -1 +0,0 @@ -hello \ No newline at end of file From 82bf25b01ade95c5a44d22677d19eda10f7257b8 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 13 Sep 2025 21:57:05 +0000 Subject: [PATCH 3/7] formatting Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 0268c4801aa07..5daa8887e4c80 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -736,6 +736,7 @@ def _replaceReadFile(match): return arguments + def _executeShCmd(cmd, shenv, results, timeoutHelper): if timeoutHelper.timeoutReached(): # Prevent further recursion if the timeout has been hit From 1599e056b4f11f1b61a050b5907b0bbfc3e66d9a Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Wed, 17 Sep 2025 16:18:30 +0000 Subject: [PATCH 4/7] feedback Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 12 ++++++++---- .../Inputs/shtest-readfile/file-does-not-exist.txt | 4 ++++ llvm/utils/lit/tests/shtest-readfile.py | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/file-does-not-exist.txt diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 19462431e7deb..daa051dcfc4b1 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -720,7 +720,7 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): return std_fds -def _expandLateSubstitutions(arguments, cwd): +def _expandLateSubstitutions(cmd, arguments, cwd): for i, arg in enumerate(arguments): if not isinstance(arg, str): continue @@ -729,8 +729,12 @@ def _replaceReadFile(match): filePath = match.group(1) if not os.path.isabs(filePath): filePath = os.path.join(cwd, filePath) - with open(filePath) as fileHandle: - return fileHandle.read() + try: + with open(filePath) as fileHandle: + return fileHandle.read() + except FileNotFoundError as error: + print(error) + raise InternalShellError(cmd, "File does not exist: %s" % filePath) arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) @@ -852,7 +856,7 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper): args[0] = expand_glob(args[0], cmd_shenv.cwd)[0] # Expand all late substitutions. - args = _expandLateSubstitutions(args, cmd_shenv.cwd) + args = _expandLateSubstitutions(j, args, cmd_shenv.cwd) inproc_builtin = inproc_builtins.get(args[0], None) if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1): diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/file-does-not-exist.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/file-does-not-exist.txt new file mode 100644 index 0000000000000..1151b75f2fa00 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/file-does-not-exist.txt @@ -0,0 +1,4 @@ +## Test that readfile reports information appropriately when the file specified +## does not exist. + +# RUN: echo %{readfile:/file/does/not/exist} diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py index 245ea371bc14d..c25a643b4eff8 100644 --- a/llvm/utils/lit/tests/shtest-readfile.py +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -2,12 +2,16 @@ # RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S/Inputs/shtest-readfile/Output %s -# CHECK: -- Testing: 3 tests{{.*}} +# CHECK: -- Testing: 4 tests{{.*}} # CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}}) # CHECK: echo hello # CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]/absolute-paths.txt.tmp}' +# CHECK-LABEL: FAIL: shtest-readfile :: file-does-not-exist.txt ({{[^)]*}}) +# CHECK: # executed command: @echo 'echo %{readfile:/file/does/not/exist}' +# CHECK: # | File does not exist: /file/does/not/exist + # CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}}) # CHECK: echo hello # CHECK: # executed command: echo '%{readfile:rel_path_test_folder/test_file}' From c1d1b843b2b2856ce55822ec7e5f1144a814750b Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Wed, 17 Sep 2025 16:19:35 +0000 Subject: [PATCH 5/7] Remove print Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index daa051dcfc4b1..63be162f4e84f 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -733,7 +733,6 @@ def _replaceReadFile(match): with open(filePath) as fileHandle: return fileHandle.read() except FileNotFoundError as error: - print(error) raise InternalShellError(cmd, "File does not exist: %s" % filePath) arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) From 77fccd4c8898a1f5346cc8729da1618203a86b66 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Wed, 17 Sep 2025 16:20:56 +0000 Subject: [PATCH 6/7] remove unused variable Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 63be162f4e84f..045472429b6e4 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -732,7 +732,7 @@ def _replaceReadFile(match): try: with open(filePath) as fileHandle: return fileHandle.read() - except FileNotFoundError as error: + except FileNotFoundError: raise InternalShellError(cmd, "File does not exist: %s" % filePath) arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) From c547d48233c4fdd71df695ce4bd3f048345e86a7 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 19 Sep 2025 05:12:14 +0000 Subject: [PATCH 7/7] fix Windows CI Created using spr 1.3.6 --- llvm/utils/lit/lit/TestRunner.py | 6 +++++- llvm/utils/lit/tests/shtest-readfile.py | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 045472429b6e4..b4d7c98692337 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -733,7 +733,11 @@ def _replaceReadFile(match): with open(filePath) as fileHandle: return fileHandle.read() except FileNotFoundError: - raise InternalShellError(cmd, "File does not exist: %s" % filePath) + raise InternalShellError( + cmd, + "File specified in readfile substitution does not exist: %s" + % filePath, + ) arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py index c25a643b4eff8..91250b2afb3f2 100644 --- a/llvm/utils/lit/tests/shtest-readfile.py +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -1,16 +1,16 @@ ## Tests the readfile substitution. -# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S/Inputs/shtest-readfile/Output %s +# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S%{fs-sep}Inputs%{fs-sep}shtest-readfile%{fs-sep}Output %s # CHECK: -- Testing: 4 tests{{.*}} # CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}}) # CHECK: echo hello -# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]/absolute-paths.txt.tmp}' +# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]{{[\\\/]}}absolute-paths.txt.tmp}' # CHECK-LABEL: FAIL: shtest-readfile :: file-does-not-exist.txt ({{[^)]*}}) # CHECK: # executed command: @echo 'echo %{readfile:/file/does/not/exist}' -# CHECK: # | File does not exist: /file/does/not/exist +# CHECK: # | File specified in readfile substitution does not exist: /file/does/not/exist # CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}}) # CHECK: echo hello @@ -18,4 +18,4 @@ # CHECK-LABEL: FAIL: shtest-readfile :: two-same-line.txt ({{[^)]*}}) # CHECK: echo hello bye -# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]/two-same-line.txt.tmp.1}' '%{readfile:[[TEMP_PATH]]/two-same-line.txt.tmp.2}' +# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]{{[\\\/]}}two-same-line.txt.tmp.1}' '%{readfile:[[TEMP_PATH]]{{[\\\/]}}two-same-line.txt.tmp.2}'