[llvm] 809b4cf - [llvm-lit] Error on malformed `.lit_test_times` entries instead of stack trace (#191305)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 11:49:27 PDT 2026
Author: Jonathan Thackray
Date: 2026-04-17T19:49:22+01:00
New Revision: 809b4cfa2b15f1e5699ff00c842266e5362ccd32
URL: https://github.com/llvm/llvm-project/commit/809b4cfa2b15f1e5699ff00c842266e5362ccd32
DIFF: https://github.com/llvm/llvm-project/commit/809b4cfa2b15f1e5699ff00c842266e5362ccd32.diff
LOG: [llvm-lit] Error on malformed `.lit_test_times` entries instead of stack trace (#191305)
When running `llvm-lit`, I sometimes hit a traceback, because a
`.lit_test_times.txt` file has got corrupted (not sure how).
However, it's non-obvious what the issue is (you just get a traceback),
so I've fixed this as follows:
`read_test_times()` currently assumes every line in
`.lit_test_times.txt`
contains a floating-point time followed by a test path. If the file
contains a blank line, a line without a path, or a non-numeric time,
`llvm-lit` will now error with: `fatal: found malformed timing data in`
+ filename.
Add test coverage for this too.
Added:
llvm/utils/lit/tests/Inputs/malformed-test-times/a.txt
llvm/utils/lit/tests/Inputs/malformed-test-times/b.txt
llvm/utils/lit/tests/Inputs/malformed-test-times/lit.cfg
llvm/utils/lit/tests/Inputs/malformed-test-times/lit_test_times
llvm/utils/lit/tests/malformed-test-times.py
Modified:
llvm/utils/lit/lit/Test.py
llvm/utils/lit/lit/TestTimes.py
llvm/utils/lit/lit/discovery.py
Removed:
################################################################################
diff --git a/llvm/utils/lit/lit/Test.py b/llvm/utils/lit/lit/Test.py
index 23fc61756afcf..daba14a898c4c 100644
--- a/llvm/utils/lit/lit/Test.py
+++ b/llvm/utils/lit/lit/Test.py
@@ -222,14 +222,14 @@ class TestSuite:
A test suite groups together a set of logically related tests.
"""
- def __init__(self, name, source_root, exec_root, config):
+ def __init__(self, name, source_root, exec_root, config, lit_config=None):
self.name = name
self.source_root = source_root
self.exec_root = exec_root
# The test suite configuration.
self.config = config
- self.test_times = read_test_times(self)
+ self.test_times = read_test_times(self, lit_config)
def getSourcePath(self, components):
return os.path.join(self.source_root, *components)
diff --git a/llvm/utils/lit/lit/TestTimes.py b/llvm/utils/lit/lit/TestTimes.py
index 7ec1a1b97b717..02820016e1d96 100644
--- a/llvm/utils/lit/lit/TestTimes.py
+++ b/llvm/utils/lit/lit/TestTimes.py
@@ -1,16 +1,35 @@
import os
-def read_test_times(suite):
- test_times = {}
+def _get_test_times_path(suite):
test_times_file = os.path.join(suite.exec_root, ".lit_test_times.txt")
if not os.path.exists(test_times_file):
test_times_file = os.path.join(suite.source_root, ".lit_test_times.txt")
+ return test_times_file
+
+
+def read_test_times(suite, lit_config=None):
+ test_times = {}
+ test_times_file = _get_test_times_path(suite)
if os.path.exists(test_times_file):
+ malformed_data = False
with open(test_times_file, "r") as time_file:
for line in time_file:
- time, path = line.split(maxsplit=1)
- test_times[path.strip("\n")] = float(time)
+ fields = line.split(maxsplit=1)
+ if len(fields) != 2:
+ malformed_data = True
+ continue
+ time, path = fields
+ try:
+ test_times[path.strip("\n")] = float(time)
+ except ValueError:
+ malformed_data = True
+ continue
+ if malformed_data and lit_config:
+ lit_config.fatal(
+ "found malformed timing data in %r; remove the file to "
+ "regenerate it" % (test_times_file,)
+ )
return test_times
@@ -21,7 +40,7 @@ def record_test_times(tests, lit_config):
if t.result.elapsed is None:
continue
if not t.suite.exec_root in times_by_suite:
- times_by_suite[t.suite.exec_root] = read_test_times(t.suite)
+ times_by_suite[t.suite.exec_root] = read_test_times(t.suite, lit_config)
# Mark the elapsed time for failed tests as negative so LIT can distingiush failed from
# successful test runs just based on the time value. For this heuristic to work for tests
diff --git a/llvm/utils/lit/lit/discovery.py b/llvm/utils/lit/lit/discovery.py
index ac06223b45345..bede6300fb031 100644
--- a/llvm/utils/lit/lit/discovery.py
+++ b/llvm/utils/lit/lit/discovery.py
@@ -68,7 +68,7 @@ def search1(path):
cfg.load_from_path(cfgpath, litConfig)
source_root = util.abs_path_preserve_drive(cfg.test_source_root or path)
exec_root = util.abs_path_preserve_drive(cfg.test_exec_root or path)
- return Test.TestSuite(cfg.name, source_root, exec_root, cfg), ()
+ return Test.TestSuite(cfg.name, source_root, exec_root, cfg, litConfig), ()
def search(path):
# Check for an already instantiated test suite.
diff --git a/llvm/utils/lit/tests/Inputs/malformed-test-times/a.txt b/llvm/utils/lit/tests/Inputs/malformed-test-times/a.txt
new file mode 100644
index 0000000000000..b80b60b7a2794
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/malformed-test-times/a.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/llvm/utils/lit/tests/Inputs/malformed-test-times/b.txt b/llvm/utils/lit/tests/Inputs/malformed-test-times/b.txt
new file mode 100644
index 0000000000000..b80b60b7a2794
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/malformed-test-times/b.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/llvm/utils/lit/tests/Inputs/malformed-test-times/lit.cfg b/llvm/utils/lit/tests/Inputs/malformed-test-times/lit.cfg
new file mode 100644
index 0000000000000..0558595a8c305
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/malformed-test-times/lit.cfg
@@ -0,0 +1,7 @@
+import lit.formats
+
+config.name = "malformed-test-times"
+config.suffixes = [".txt"]
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
diff --git a/llvm/utils/lit/tests/Inputs/malformed-test-times/lit_test_times b/llvm/utils/lit/tests/Inputs/malformed-test-times/lit_test_times
new file mode 100644
index 0000000000000..28c0b7da7aba0
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/malformed-test-times/lit_test_times
@@ -0,0 +1,5 @@
+4.798174e-03 b.txt
+missing-path
+
+not-a-float ignored.txt
+1.412153e-03 a.txt
diff --git a/llvm/utils/lit/tests/malformed-test-times.py b/llvm/utils/lit/tests/malformed-test-times.py
new file mode 100644
index 0000000000000..95e98139404c2
--- /dev/null
+++ b/llvm/utils/lit/tests/malformed-test-times.py
@@ -0,0 +1,12 @@
+## Check that malformed .lit_test_times.txt aborts discovery with a
+## clear diagnostic.
+
+# RUN: cp %{inputs}/malformed-test-times/lit_test_times %{inputs}/malformed-test-times/.lit_test_times.txt
+# RUN: not %{lit-no-order-opt} %{inputs}/malformed-test-times > %t.out 2> %t.err
+# RUN: FileCheck --allow-empty --check-prefix=OUT < %t.out %s
+# RUN: FileCheck --check-prefix=ERR < %t.err %s
+
+# OUT-NOT: -- Testing:
+
+# ERR: fatal: found malformed timing data in
+# ERR-SAME: ; remove the file to regenerate it
More information about the llvm-commits
mailing list