Files
auto_agent/tests/verify_terminal_tasks.py
T

113 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""terminal_tasks / terminal_execute 后台挂起 + 资源边界 验证脚本(独立运行,非 pytest)。
覆盖:
1. 后台挂起 → terminal_info 运行中/尾部输出 → wait 超时返回运行中 → kill → wait 返回已终止
2. 后台任务自然完成 → wait 返回最终输出 + 退出码 0
3. 异常退出(exit 3)→ wait 返回"异常退出(退出码: 3)"
4. 前台命令超时 → 杀进程树(含 Start-Process 后代),端口不再监听(资源边界)
5. 前台命令正常回归(python --version)
"""
import os
import socket
import sys
import time
sys.path.insert(0, r"C:\Users\86166\Desktop\Agent_Learning_minor\Agent\src")
from agent.tools import terminal_tasks as tt # noqa: E402
from agent.tools.terminal_execute import TerminalExecute # noqa: E402
FAILS = []
def check(name, cond, extra=""):
status = "PASS" if cond else "FAIL"
print(f"[{status}] {name} {extra}")
if not cond:
FAILS.append(name)
def port_open(port, timeout=1.0):
try:
with socket.create_connection(("127.0.0.1", port), timeout=timeout):
return True
except OSError:
return False
def main():
cwd = r"C:\Users\86166\Desktop\Agent_Learning_minor\Agent"
sid = "verify_session"
# ---- 1) 挂起 2s 打印脚本:info → wait 超时 → 完成 wait ----
print("=== 测试1: 后台挂起 + terminal_info + wait ===")
pid = tt.start_background_task(
sid, 'python -c "import time;time.sleep(2);print(\'TASK_DONE_MARK\')"',
cwd, use_venv=False,
)
check("启动返回正数PID", pid > 0, f"pid={pid}")
time.sleep(1.2)
info = tt.task_info_text(pid, max_chars=1000)
check("terminal_info 运行中+头部提示", "仍在运行" in info or "运行中" in info, info[:80].replace("\n", " "))
wait_short = tt.wait_task(pid, 1)
check("wait 超时返回运行中摘要", "仍在运行" in wait_short, wait_short[:60].replace("\n", " "))
wait_final = tt.wait_task(pid, 15)
check("wait 等到完成+最终输出", "TASK_DONE_MARK" in wait_final and "退出码: 0" in wait_final, wait_final[:80].replace("\n", " "))
# ---- 2) kill 路径:先挂起长驻 http 服务,kill 后 wait 返回已终止 ----
print("=== 测试2: kill 杀树(http.server 依赖端口) ===")
pid2 = tt.start_background_task(sid, "python -m http.server 8090", cwd, use_venv=False)
check("挂起http服务", pid2 > 0)
time.sleep(2)
check("端口8090已监听", port_open(8090))
ok = tt.kill_task(pid2)
check("kill_task 成功", ok)
time.sleep(1.5)
check("kill后端口8090不再监听", not port_open(8090))
after = tt.wait_task(pid2, 3)
check("kill后wait返回已终止", "已终止" in after, after[:60].replace("\n", " "))
# ---- 3) 异常退出 ----
print("=== 测试3: 异常退出(exit 3) ===")
pid3 = tt.start_background_task(sid, 'python -c "print(\'before boom\'); raise SystemExit(3)"', cwd, use_venv=False)
res3 = tt.wait_task(pid3, 15)
check("异常退出识别", "异常退出(退出码: 3)" in res3 and "before boom" in res3, res3[:100].replace("\n", " "))
# ---- 4) 前台工具超时 → 杀进程树(Start-Process 后代) ----
print("=== 测试4: 前台超时杀进程树 ===")
tool = TerminalExecute()
out = tool._run(
"Start-Process python.exe -m http.server 8092; Start-Sleep 30",
working_dir=cwd, timeout=2, use_venv=False,
)
check("前台超时返回错误文本", "命令执行超时" in out, out[:80].replace("\n", " "))
time.sleep(2.5)
check("超时后端口8092不再监听(进程树已清)", not port_open(8092))
# ---- 5) 前台回归 ----
print("=== 测试5: 前台正常执行 ===")
out5 = tool._run("python --version", working_dir=cwd, use_venv=False)
check("前台python --version", "退出码: 0" in out5 and "Python" in out5, out5[:80].replace("\n", " "))
# ---- 6) 多任务并行 ----
print("=== 测试6: 多开两个后台任务 ===")
a = tt.start_background_task(sid, "python -m http.server 8093", cwd, use_venv=False)
b = tt.start_background_task(sid, "python -m http.server 8094", cwd, use_venv=False)
time.sleep(2)
check("双端口同时监听", port_open(8093) and port_open(8094))
tt.kill_all_session(sid)
time.sleep(1.5)
check("kill_all_session 后均未监听", (not port_open(8093)) and (not port_open(8094)))
check("运行中计数归零", tt.get_running_count() == 0, f"count={tt.get_running_count()}")
print()
if FAILS:
print("FAILED:", FAILS)
sys.exit(1)
print("ALL PASS")
if __name__ == "__main__":
main()