Skip to content

Commit e1ff432

Browse files
authored
Reland "[Utils] Add new --update-tests flag to llvm-lit" (#153821)
This reverts commit e495231 to reland the --update-tests feature, originally landed in #108425.
1 parent c8c2218 commit e1ff432

File tree

9 files changed

+103
-3
lines changed

9 files changed

+103
-3
lines changed

clang/test/lit.cfg.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,13 @@ def calculate_arch_features(arch_string):
410410
# possibly be present in system and user configuration files, so disable
411411
# default configs for the test runs.
412412
config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1"
413+
414+
if lit_config.update_tests:
415+
import sys
416+
import os
417+
418+
utilspath = os.path.join(config.llvm_src_root, "utils")
419+
sys.path.append(utilspath)
420+
from update_any_test_checks import utc_lit_plugin
421+
422+
lit_config.test_updaters.append(utc_lit_plugin)

llvm/docs/CommandGuide/lit.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ ADDITIONAL OPTIONS
399399
Show all features used in the test suite (in ``XFAIL``, ``UNSUPPORTED`` and
400400
``REQUIRES``) and exit.
401401

402+
.. option:: --update-tests
403+
404+
Pass failing tests to functions in the ``lit_config.test_updaters`` list to
405+
check whether any of them know how to update the test to make it pass.
406+
402407
EXIT STATUS
403408
-----------
404409

llvm/test/lit.cfg.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,3 +715,13 @@ def host_unwind_supports_jit():
715715

716716
if config.has_logf128:
717717
config.available_features.add("has_logf128")
718+
719+
if lit_config.update_tests:
720+
import sys
721+
import os
722+
723+
utilspath = os.path.join(config.llvm_src_root, "utils")
724+
sys.path.append(utilspath)
725+
from update_any_test_checks import utc_lit_plugin
726+
727+
lit_config.test_updaters.append(utc_lit_plugin)

llvm/utils/lit/lit/LitConfig.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def __init__(
3939
parallelism_groups={},
4040
per_test_coverage=False,
4141
gtest_sharding=True,
42+
update_tests=False,
4243
):
4344
# The name of the test runner.
4445
self.progname = progname
@@ -91,6 +92,8 @@ def __init__(
9192
self.parallelism_groups = parallelism_groups
9293
self.per_test_coverage = per_test_coverage
9394
self.gtest_sharding = bool(gtest_sharding)
95+
self.update_tests = update_tests
96+
self.test_updaters = []
9497

9598
@property
9699
def maxIndividualTestTime(self):

llvm/utils/lit/lit/TestRunner.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,18 @@ def executeScriptInternal(
11921192
str(result.timeoutReached),
11931193
)
11941194

1195+
if litConfig.update_tests:
1196+
for test_updater in litConfig.test_updaters:
1197+
try:
1198+
update_output = test_updater(result, test)
1199+
except Exception as e:
1200+
out += f"Exception occurred in test updater: {e}"
1201+
continue
1202+
if update_output:
1203+
for line in update_output.splitlines():
1204+
out += f"# {line}\n"
1205+
break
1206+
11951207
return out, err, exitCode, timeoutInfo
11961208

11971209

llvm/utils/lit/lit/cl_arguments.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ def parse_args():
230230
action="store_true",
231231
help="Exit with status zero even if some tests fail",
232232
)
233+
execution_group.add_argument(
234+
"--update-tests",
235+
dest="update_tests",
236+
action="store_true",
237+
help="Try to update regression tests to reflect current behavior, if possible",
238+
)
233239
execution_test_time_group = execution_group.add_mutually_exclusive_group()
234240
execution_test_time_group.add_argument(
235241
"--skip-test-time-recording",

llvm/utils/lit/lit/llvm/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,17 @@ def __init__(self, lit_config, config):
6464
self.with_environment("_TAG_REDIR_ERR", "TXT")
6565
self.with_environment("_CEE_RUNOPTS", "FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)")
6666

67+
if lit_config.update_tests:
68+
self.use_lit_shell = True
69+
6770
# Choose between lit's internal shell pipeline runner and a real shell.
6871
# If LIT_USE_INTERNAL_SHELL is in the environment, we use that as an
6972
# override.
7073
lit_shell_env = os.environ.get("LIT_USE_INTERNAL_SHELL")
7174
if lit_shell_env:
7275
self.use_lit_shell = lit.util.pythonize_bool(lit_shell_env)
76+
if not self.use_lit_shell and lit_config.update_tests:
77+
print("note: --update-tests is not supported when using external shell")
7378

7479
if not self.use_lit_shell:
7580
features.add("shell")

llvm/utils/lit/lit/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def main(builtin_params={}):
4343
per_test_coverage=opts.per_test_coverage,
4444
gtest_sharding=opts.gtest_sharding,
4545
maxRetriesPerTest=opts.maxRetriesPerTest,
46+
update_tests=opts.update_tests,
4647
)
4748

4849
discovered_tests = lit.discovery.find_tests_for_inputs(

llvm/utils/update_any_test_checks.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ def find_utc_tool(search_path, utc_name):
3434
return None
3535

3636

37-
def run_utc_tool(utc_name, utc_tool, testname):
37+
def run_utc_tool(utc_name, utc_tool, testname, environment):
3838
result = subprocess.run(
39-
[utc_tool, testname], stdout=subprocess.PIPE, stderr=subprocess.PIPE
39+
[utc_tool, testname],
40+
stdout=subprocess.PIPE,
41+
stderr=subprocess.PIPE,
42+
env=environment,
4043
)
4144
return (result.returncode, result.stdout, result.stderr)
4245

@@ -60,6 +63,42 @@ def expand_listfile_args(arg_list):
6063
return exp_arg_list
6164

6265

66+
def utc_lit_plugin(result, test):
67+
testname = test.getFilePath()
68+
if not testname:
69+
return None
70+
71+
script_name = os.path.abspath(__file__)
72+
utc_search_path = os.path.join(os.path.dirname(script_name), os.path.pardir)
73+
74+
with open(testname, "r") as f:
75+
header = f.readline().strip()
76+
77+
m = RE_ASSERTIONS.search(header)
78+
if m is None:
79+
return None
80+
81+
utc_name = m.group(1)
82+
utc_tool = find_utc_tool([utc_search_path], utc_name)
83+
if not utc_tool:
84+
return f"update-utc-tests: {utc_name} not found"
85+
86+
return_code, stdout, stderr = run_utc_tool(
87+
utc_name, utc_tool, testname, test.config.environment
88+
)
89+
90+
stderr = stderr.decode(errors="replace")
91+
if return_code != 0:
92+
if stderr:
93+
return f"update-utc-tests: {utc_name} exited with return code {return_code}\n{stderr.rstrip()}"
94+
return f"update-utc-tests: {utc_name} exited with return code {return_code}"
95+
96+
stdout = stdout.decode(errors="replace")
97+
if stdout:
98+
return f"update-utc-tests: updated {testname}\n{stdout.rstrip()}"
99+
return f"update-utc-tests: updated {testname}"
100+
101+
63102
def main():
64103
from argparse import RawTextHelpFormatter
65104

@@ -78,6 +117,11 @@ def main():
78117
nargs="*",
79118
help="Additional directories to scan for update_*_test_checks scripts",
80119
)
120+
parser.add_argument(
121+
"--path",
122+
help="""Additional directories to scan for executables invoked by the update_*_test_checks scripts,
123+
separated by the platform path separator""",
124+
)
81125
parser.add_argument("tests", nargs="+")
82126
config = parser.parse_args()
83127

@@ -88,6 +132,10 @@ def main():
88132
script_name = os.path.abspath(__file__)
89133
utc_search_path.append(os.path.join(os.path.dirname(script_name), os.path.pardir))
90134

135+
local_env = os.environ.copy()
136+
if config.path:
137+
local_env["PATH"] = config.path + os.pathsep + local_env["PATH"]
138+
91139
not_autogenerated = []
92140
utc_tools = {}
93141
have_error = False
@@ -117,7 +165,7 @@ def main():
117165
continue
118166

119167
future = executor.submit(
120-
run_utc_tool, utc_name, utc_tools[utc_name], testname
168+
run_utc_tool, utc_name, utc_tools[utc_name], testname, local_env
121169
)
122170
jobs.append((testname, future))
123171

0 commit comments

Comments
 (0)