diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 00432b8d31778..5d8c8b5ed16d5 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -201,7 +201,14 @@ def executeShCmd(cmd, shenv, results, timeout=0): timeoutHelper = TimeoutHelper(timeout) if timeout > 0: timeoutHelper.startTimer() - finalExitCode = _executeShCmd(cmd, shenv, results, timeoutHelper) + try: + finalExitCode = _executeShCmd(cmd, shenv, results, timeoutHelper) + except InternalShellError: + e = sys.exc_info()[1] + finalExitCode = 127 + results.append( + ShellCommandResult(e.command, "", e.message, finalExitCode, False) + ) timeoutHelper.cancel() timeoutInfo = None if timeoutHelper.timeoutReached(): @@ -1105,15 +1112,10 @@ def executeScriptInternal( results = [] timeoutInfo = None - try: - shenv = ShellEnvironment(cwd, test.config.environment) - exitCode, timeoutInfo = executeShCmd( - cmd, shenv, results, timeout=litConfig.maxIndividualTestTime - ) - except InternalShellError: - e = sys.exc_info()[1] - exitCode = 127 - results.append(ShellCommandResult(e.command, "", e.message, exitCode, False)) + shenv = ShellEnvironment(cwd, test.config.environment) + exitCode, timeoutInfo = executeShCmd( + cmd, shenv, results, timeout=litConfig.maxIndividualTestTime + ) out = err = "" for i, result in enumerate(results): diff --git a/llvm/utils/lit/tests/Inputs/timeout-hang/lit.cfg b/llvm/utils/lit/tests/Inputs/timeout-hang/lit.cfg new file mode 100644 index 0000000000000..1019d94898b6d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/timeout-hang/lit.cfg @@ -0,0 +1,7 @@ +import lit.formats + +config.name = "timeout-hang" +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/timeout-hang/run-nonexistent.txt b/llvm/utils/lit/tests/Inputs/timeout-hang/run-nonexistent.txt new file mode 100644 index 0000000000000..fd7ed210baee0 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/timeout-hang/run-nonexistent.txt @@ -0,0 +1 @@ +RUN: nonexistent diff --git a/llvm/utils/lit/tests/timeout-hang.py b/llvm/utils/lit/tests/timeout-hang.py new file mode 100644 index 0000000000000..486f07983708f --- /dev/null +++ b/llvm/utils/lit/tests/timeout-hang.py @@ -0,0 +1,27 @@ +# REQUIRES: lit-max-individual-test-time + +# Python has some issues dealing with exceptions when multiprocessing, +# which can cause hangs. Previously this could occur when we encountered +# an internal shell exception, and had a timeout set. + +# This test runs a lit test that tries to launch a non-existent file, +# throwing an exception. We expect this to fail immediately, rather than +# timeout. + +# DEFINE: %{timeout}=1 + +# RUN: not %{lit} %{inputs}/timeout-hang/run-nonexistent.txt \ +# RUN: --timeout=%{timeout} --param external=0 | %{python} %s %{timeout} + +import sys +import re + +timeout_time = float(sys.argv[1]) +testing_time = float(re.search(r"Testing Time: (.*)s", sys.stdin.read()).group(1)) + +if testing_time < timeout_time: + print("Testing took less than timeout") + sys.exit(0) +else: + print("Testing took as long or longer than timeout") + sys.exit(1) diff --git a/sycl/test-e2e/format.py b/sycl/test-e2e/format.py index de08ca4f6bff6..116579c21f825 100644 --- a/sycl/test-e2e/format.py +++ b/sycl/test-e2e/format.py @@ -374,15 +374,10 @@ def get_extra_env(sycl_devices): recursion_limit=test.config.recursiveExpansionLimit, ) - # TODO: workaround for lit hanging when executing non-existent binary - # inside our containers if len(script) == 0: return lit.Test.Result(lit.Test.UNSUPPORTED, "Lit script is empty") - useExternalSh = test.config.test_mode == "run-only" - result = lit.TestRunner._runShTest( - test, litConfig, useExternalSh, script, tmpBase - ) + result = lit.TestRunner._runShTest(test, litConfig, False, script, tmpBase) # Single triple/device - might be an XFAIL. def map_result(features, code):