"""run_python/shell 超时返回部分输出(失败面板 #8:批量 I/O 超时丢进度反复重跑)。""" from __future__ import annotations import tempfile import unittest from tools.base import format_timeout_result from tools.run_python import RunPythonTool class TestFormatTimeoutResult(unittest.TestCase): def test_includes_partial_stdout_and_hint(self): out = format_timeout_result("[OK] journal 1\n[OK] journal 2\n", "", 120) self.assertIn("[stdout]", out) self.assertIn("[OK] journal 1", out) self.assertIn("[OK] journal 2", out) self.assertIn("timed out after 120s", out) self.assertIn("续跑", out) # 续跑提示 self.assertIn("background=true", out) # 后台指路 def test_includes_partial_stderr(self): out = format_timeout_result("", "warn: slow\n", 60) self.assertIn("[stderr]", out) self.assertIn("warn: slow", out) self.assertIn("timed out after 60s", out) def test_empty_output_still_reports_timeout(self): out = format_timeout_result("", "", 30) self.assertNotIn("[stdout]", out) self.assertNotIn("[stderr]", out) self.assertIn("timed out after 30s", out) class TestHostTimeoutPartial(unittest.TestCase): def test_partial_progress_returned_on_timeout(self): """前台跑到一半超时:-u 无缓冲让进度落盘,超时结果带上 → 模型可据此续跑。""" code = ( "print('[OK] item 1')\n" "print('[OK] item 2')\n" "import time\n" "time.sleep(30)\n" ) with tempfile.TemporaryDirectory() as tmp: out = RunPythonTool(base_dir=tmp).execute(code=code, timeout=1) self.assertIn("timed out after 1s", out) self.assertIn("[OK] item 1", out) # -u 无缓冲,部分输出被捕获 self.assertIn("[OK] item 2", out) self.assertIn("续跑", out) if __name__ == "__main__": unittest.main()