https://github.com/vitalybuka created https://github.com/llvm/llvm-project/pull/199996
Simplify LitConfig initialization and setter to allow None values. TestingConfig.maxIndividualTestTime is initialized to 0 (or resolved to 0 if None) strictly during initialization. This fixes an issue where the aggressive BOLT timeout of 60s (previously set globally on lit_config) was leaking and affecting libc++ tests. By moving the timeout configuration from the global lit_config to the individual test suite config, we ensure that timeouts are isolated and respect suite-local settings without leaking. PR Stack: * ➤ https://github.com/llvm/llvm-project/pull/198192 * https://github.com/llvm/llvm-project/pull/198193 Assisted-by: Gemini >From 632e25f8313033a141e25f788ded9c4154a782f0 Mon Sep 17 00:00:00 2001 From: Vitaly Buka <[email protected]> Date: Tue, 26 May 2026 22:26:51 -0700 Subject: [PATCH] [lit] Move maxIndividualTestTime from global to test suite config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify LitConfig initialization and setter to allow None values. TestingConfig.maxIndividualTestTime is initialized to 0 (or resolved to 0 if None) strictly during initialization. This fixes an issue where the aggressive BOLT timeout of 60s (previously set globally on lit_config) was leaking and affecting libc++ tests. By moving the timeout configuration from the global lit_config to the individual test suite config, we ensure that timeouts are isolated and respect suite-local settings without leaking. PR Stack: * ➤ https://github.com/llvm/llvm-project/pull/198192 * https://github.com/llvm/llvm-project/pull/198193 Assisted-by: Gemini --- bolt/test/lit.cfg.py | 2 +- libsycl/test/lit.cfg.py | 2 +- lldb/test/API/lit.cfg.py | 2 +- lldb/test/Shell/lit.cfg.py | 2 +- llvm/utils/lit/lit/LitConfig.py | 5 ++++- llvm/utils/lit/lit/TestRunner.py | 8 ++++---- llvm/utils/lit/lit/TestingConfig.py | 16 ++++++++++++++++ llvm/utils/lit/lit/formats/googletest.py | 4 ++-- llvm/utils/lit/lit/main.py | 13 +------------ .../lit/tests/Inputs/googletest-timeout/lit.cfg | 2 +- .../lit/tests/Inputs/shtest-timeout/lit.cfg | 2 +- 11 files changed, 33 insertions(+), 25 deletions(-) diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py index 3299051db4983..a3a49444156b2 100644 --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -69,7 +69,7 @@ supported, errormsg = lit_config.maxIndividualTestTimeIsSupported if supported: config.available_features.add("lit-max-individual-test-time") - lit_config.maxIndividualTestTime = 60 + config.maxIndividualTestTime = 60 else: lit_config.warning( "Setting a timeout per test not supported. " diff --git a/libsycl/test/lit.cfg.py b/libsycl/test/lit.cfg.py index 377be90791ef0..2610f23ba90a8 100644 --- a/libsycl/test/lit.cfg.py +++ b/libsycl/test/lit.cfg.py @@ -205,7 +205,7 @@ def __exit__(self, exc_type, exc_value, exc_traceback): import psutil # Set timeout for a single test - lit_config.maxIndividualTestTime = 600 + config.maxIndividualTestTime = 600 except ImportError: pass diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 359d45a0c724e..2662a77199641 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -199,7 +199,7 @@ def delete_module_cache(path): # lit complains if the value is set but it is not supported. supported, errormsg = lit_config.maxIndividualTestTimeIsSupported if supported: - lit_config.maxIndividualTestTime = 600 + config.maxIndividualTestTime = 600 else: lit_config.warning("Could not set a default per-test timeout. " + errormsg) diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py index 3bff8b087c5a4..1b7532d12ce4a 100644 --- a/lldb/test/Shell/lit.cfg.py +++ b/lldb/test/Shell/lit.cfg.py @@ -120,7 +120,7 @@ def calculate_arch_features(arch_string): # lit complains if the value is set but it is not supported. supported, errormsg = lit_config.maxIndividualTestTimeIsSupported if supported: - lit_config.maxIndividualTestTime = 600 + config.maxIndividualTestTime = 600 else: lit_config.warning("Could not set a default per-test timeout. " + errormsg) diff --git a/llvm/utils/lit/lit/LitConfig.py b/llvm/utils/lit/lit/LitConfig.py index be8596f0ccdc4..4696a0fda1243 100644 --- a/llvm/utils/lit/lit/LitConfig.py +++ b/llvm/utils/lit/lit/LitConfig.py @@ -35,7 +35,7 @@ def __init__( order, params, config_prefix=None, - maxIndividualTestTime=0, + maxIndividualTestTime=None, maxRetriesPerTest=None, parallelism_groups={}, per_test_coverage=False, @@ -123,6 +123,9 @@ def maxIndividualTestTime(self, value): Interface for setting maximum time to spend executing a single test """ + if value is None: + self._maxIndividualTestTime = None + return if not isinstance(value, int): self.fatal("maxIndividualTestTime must set to a value of type int.") self._maxIndividualTestTime = value diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 0159028f36723..66450f5fa6b81 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -703,7 +703,7 @@ def executeScriptInternal( shenv.env["LIT_CURRENT_TESTCASE"] = test.getFullName() exitCode, timeoutInfo = executeShCmd( - cmd, shenv, results, timeout=litConfig.maxIndividualTestTime + cmd, shenv, results, timeout=test.config.maxIndividualTestTime ) out = err = "" @@ -747,7 +747,7 @@ def executeScriptInternal( # If nothing interesting happened, move on. if ( - litConfig.maxIndividualTestTime == 0 + test.config.maxIndividualTestTime == 0 and result.exitCode == 0 and not result.stdout.strip() and not result.stderr.strip() @@ -776,7 +776,7 @@ def executeScriptInternal( else: codeStr = str(result.exitCode) out += "# error: command failed with exit status: %s\n" % (codeStr,) - if litConfig.maxIndividualTestTime > 0 and result.timeoutReached: + if test.config.maxIndividualTestTime > 0 and result.timeoutReached: out += "# error: command reached timeout: %s\n" % ( str(result.timeoutReached), ) @@ -900,7 +900,7 @@ def executeScript( command, cwd=cwd, env=env, - timeout=litConfig.maxIndividualTestTime, + timeout=test.config.maxIndividualTestTime, ) return (out, err, exitCode, None, None) except lit.util.ExecuteCommandTimeoutException as e: diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index a6b4fa212ae35..7c7d51ddaf48d 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -125,6 +125,7 @@ def fromdefaults(litConfig): available_features=available_features, pipefail=True, standalone_tests=False, + maxIndividualTestTime=litConfig.maxIndividualTestTime, ) def load_from_path(self, path, litConfig): @@ -185,6 +186,7 @@ def __init__( is_early=False, parallelism_group=None, standalone_tests=False, + maxIndividualTestTime=0, ): self.parent = parent self.name = str(name) @@ -199,6 +201,7 @@ def __init__( self.available_features = set(available_features) self.pipefail = pipefail self.standalone_tests = standalone_tests + self.maxIndividualTestTime = maxIndividualTestTime or 0 # This list is used by TestRunner.py to restrict running only tests that # require one of the features in this list if this list is non-empty. # Configurations can set this list to restrict the set of tests to run. @@ -247,6 +250,19 @@ def finish(self, litConfig): and getattr(self, "test_retry_attempts", None) is None ): self.test_retry_attempts = litConfig.maxRetriesPerTest + # Global config is from LIT_OPTS and must override site-specific settings. + if litConfig.maxIndividualTestTime is not None: + suite_timeout = self.maxIndividualTestTime + if suite_timeout > 0 and suite_timeout != litConfig.maxIndividualTestTime: + litConfig.note( + ( + "The test suite {0!r} configuration requested an individual" + " test timeout of {1} seconds but a timeout of {2} seconds was" + " requested on the command line. Forcing timeout to be {2}" + " seconds." + ).format(self.name, suite_timeout, litConfig.maxIndividualTestTime) + ) + self.maxIndividualTestTime = litConfig.maxIndividualTestTime @property def root(self): diff --git a/llvm/utils/lit/lit/formats/googletest.py b/llvm/utils/lit/lit/formats/googletest.py index 5d60da509bdb7..e567cce541beb 100644 --- a/llvm/utils/lit/lit/formats/googletest.py +++ b/llvm/utils/lit/lit/formats/googletest.py @@ -191,7 +191,7 @@ def get_shard_header(shard_env): out, _, exitCode = lit.util.executeCommand( cmd, env=test.config.environment, - timeout=litConfig.maxIndividualTestTime, + timeout=test.config.maxIndividualTestTime, redirect_stderr=True, ) except lit.util.ExecuteCommandTimeoutException as e: @@ -199,7 +199,7 @@ def get_shard_header(shard_env): return ( lit.Test.TIMEOUT, f"{shard_header}{stream_msg}Reached " - f"timeout of {litConfig.maxIndividualTestTime} seconds", + f"timeout of {test.config.maxIndividualTestTime} seconds", ) if not os.path.exists(test.gtest_json_file): diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py index d1e16b28bea26..a3bd153040a69 100755 --- a/llvm/utils/lit/lit/main.py +++ b/llvm/utils/lit/lit/main.py @@ -44,6 +44,7 @@ def main(builtin_params={}): gtest_sharding=opts.gtest_sharding, maxRetriesPerTest=opts.maxRetriesPerTest, update_tests=opts.update_tests, + maxIndividualTestTime=opts.maxIndividualTestTime, ) discovered_tests = lit.discovery.find_tests_for_inputs( @@ -68,18 +69,6 @@ def main(builtin_params={}): print(" ".join(sorted(features))) sys.exit(0) - # Command line overrides configuration for maxIndividualTestTime. - if opts.maxIndividualTestTime is not None: # `not None` is important (default: 0) - if opts.maxIndividualTestTime != lit_config.maxIndividualTestTime: - lit_config.note( - ( - "The test suite configuration requested an individual" - " test timeout of {0} seconds but a timeout of {1} seconds was" - " requested on the command line. Forcing timeout to be {1}" - " seconds." - ).format(lit_config.maxIndividualTestTime, opts.maxIndividualTestTime) - ) - lit_config.maxIndividualTestTime = opts.maxIndividualTestTime determine_order(discovered_tests, opts.order) diff --git a/llvm/utils/lit/tests/Inputs/googletest-timeout/lit.cfg b/llvm/utils/lit/tests/Inputs/googletest-timeout/lit.cfg index c1eab40f47e8d..200347aaf85c7 100644 --- a/llvm/utils/lit/tests/Inputs/googletest-timeout/lit.cfg +++ b/llvm/utils/lit/tests/Inputs/googletest-timeout/lit.cfg @@ -8,4 +8,4 @@ config.environment["GTEST_FILTER"] = lit_config.params.get("gtest_filter") if configSetTimeout == "1": # Try setting the max individual test time in the configuration - lit_config.maxIndividualTestTime = 1 + config.maxIndividualTestTime = 1 diff --git a/llvm/utils/lit/tests/Inputs/shtest-timeout/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-timeout/lit.cfg index b78c0eac31d88..3a72f35024eb2 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-timeout/lit.cfg +++ b/llvm/utils/lit/tests/Inputs/shtest-timeout/lit.cfg @@ -19,7 +19,7 @@ configSetTimeout = lit_config.params.get("set_timeout", "0") if configSetTimeout != "0": # Try setting the max individual test time in the configuration - lit_config.maxIndividualTestTime = int(configSetTimeout) + config.maxIndividualTestTime = int(configSetTimeout) config.test_format = lit.formats.ShTest(execute_external=externalShell) config.suffixes = [".py"] _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
