diff --git a/infra/deploy/release_source.py b/infra/deploy/release_source.py index d53df60..bdb6d7d 100644 --- a/infra/deploy/release_source.py +++ b/infra/deploy/release_source.py @@ -50,11 +50,12 @@ def run_api_helper(command: list[str], *, env: dict | None, timeout: int, try: process.wait(timeout=2) except subprocess.TimeoutExpired: - try: - os.killpg(process.pid, signal.SIGKILL) - except ProcessLookupError: - pass - process.wait() + pass + try: + os.killpg(process.pid, signal.SIGKILL) + except ProcessLookupError: + pass + process.wait() raise ValueError("Gitea helper request timed out") from error if return_code: raise ValueError("Gitea helper request failed") diff --git a/infra/deploy/test_release_source.py b/infra/deploy/test_release_source.py index 87120ef..bcfc525 100644 --- a/infra/deploy/test_release_source.py +++ b/infra/deploy/test_release_source.py @@ -1,6 +1,7 @@ import hashlib import json import stat +import sys import tempfile import unittest from urllib.parse import parse_qs, urlsplit @@ -263,6 +264,13 @@ class ReleaseSourceTests(unittest.TestCase): with self.assertRaisesRegex(ValueError, "size limit"): release_source.api_json("/repos/admin/akyldash") + def test_api_helper_timeout_is_bounded_and_fails_closed(self): + with self.assertRaisesRegex(ValueError, "timed out"): + release_source.run_api_helper( + [sys.executable, "-c", "import time; time.sleep(10)"], env=None, + timeout=0.05, max_stdout_bytes=32, max_file_bytes=32, + ) + if __name__ == "__main__": unittest.main()