8.3 KiB
8.3 KiB
P2-04 证据:跨平台聚合测试入口
状态:COMPLETE 日期:2026-07-17(本机执行时间) 平台:Windows 11 10.0.26200 x64(主)+ WSL Ubuntu-22.04 / CPython 3.12.3(Linux 路径验证)
交付物
tests/run_all.py(新增,唯一新文件):跨平台聚合测试入口。python tests/run_all.py --group logic|offscreen|all(默认 all)--list只列条目;--only <id,子串>跑子集(调试);--keep-logs保留全部子日志(默认只留失败/超时)。- 设计:每个子测试 = 独立子进程 + 独立临时目录(
haocode_RUN_<id>/haocode_CONF_<id>,POSIX 走 TMPDIR、Windows 走 TEMP)+ 显式秒级 timeout(subprocess.run(timeout=...));offscreen 组子进程注入QT_QPA_PLATFORM=offscreen、HAOCODE_RENDER=software、QTWEBENGINE_CHROMIUM_FLAGS=--disable-gpu(均 setdefault,不覆盖外层)。 - 退出码语义:任一 FAIL/TIMEOUT → 退出码 1(并打印"失败命令"清单);SKIP 不影响退出码。
- SKIP 双闸门:①依赖探测(
importlib.util.find_spec:node/openai/PyMuPDF/PyQt6,缺失即 SKIP 并给理由);②平台令牌(platform:win32等,平台不适用即 SKIP 并给理由)。 - 聚合鲁棒性:子进程崩溃/超时只记 FAIL/TIMEOUT,不中断后续;输出统一 UTF-8(
errors=replace,Windows cp936/cp1252 宿主安全);WSL 时钟回拨保护(耗时 clamp ≥0)。 - 不要求 pytest / npm / 网络;聚合器自身零第三方依赖。
默认聚合范围(25 条)与排除项
- logic 12 条:run_tests.py(agent core 41)、test_tool_params、test_bash_stream、test_copy_session、test_compaction_persist、test_file_attach、test_cross_platform_shell、test_global_hotkey_platforms、test_wv2_guard、test_pdf_reader、test_math_extract.js、test_render_window.js。
- offscreen 13 条:smoke_offscreen、smoke_mode、smoke_copy_session、smoke_bash_panel、smoke_timeline、smoke_midswitch、test_main_window_event_filter、test_config_isolation、test_error_persist、test_think_code_neutral、test_debug_window、test_renderer_matrix、test_screen_capture_platforms。
- 默认排除(有注释理由,不进默认聚合):
diag_*(rename_overlay / panel_scrollbar / render_scale):人工/像素诊断,需真机或交互。verify_*:人工验证脚本。tune_model_popup.py:调参实验。smoke_offscreen.py之外的旧式 real-DB 冒烟(引用真实data/haocode.db,未接临时库)。diag_live_agent.py、probe_agent_loop.py:需真实 API 凭据。_probe_*、_test_env.py:探针/工具模块(被其他测试 import,非独立用例)。run_all.py自身:聚合器不入聚合。
汇总结果(硬约束要求:Windows/Linux 各一份)
Windows 11 / CPython 3.10.21(.venv,PyQt6+openai+PyMuPDF 齐全)
| 组 | 结果 | 耗时 |
|---|---|---|
--group logic |
PASS 12 / FAIL 0 / SKIP 0(EXIT=0) | 43.9s |
--group offscreen |
PASS 13 / FAIL 0 / SKIP 0(EXIT=0) | 81.9s |
--group all |
25/25 PASS(EXIT=0,两组顺序执行) | ~126s |
- 日志样例:
D:/tmp/runall_win_logic2.log、D:/tmp/runall_win_offscreen.log。 - offscreen 明细:smoke_offscreen 8.3s、smoke_bash_panel 30.3s、smoke_midswitch 8.7s、test_think_code_neutral 9.3s 等 13 条全 PASS。
WSL Ubuntu-22.04 / CPython 3.12.3(系统 python3,无 PyQt6/openai/PyMuPDF,离线环境)
| 组 | 结果 | 耗时 |
|---|---|---|
--group all |
PASS 4 / FAIL 0 / SKIP 21(EXIT=0) | 0.9s |
- PASS 4 = test_copy_session、test_file_attach、test_math_extract.js、test_render_window.js(纯 stdlib/node)。
- SKIP 21 全部带明确理由:无 openai(5,禁止联网安装)、无 PyQt6(14,offscreen 组整体)、无 PyMuPDF(1)、平台不适用 win32-only(1,test_wv2_guard:msvcrt 单实例互斥是 WebView2 守卫的 Windows 专属机制,Linux 无 WebView2 链路)、无 PyQt6 的 GUI 逻辑(1,test_global_hotkey_platforms 含 QShortcut 构造)。
- 证明:聚合器在 Linux/3.12 上可运行、隔离约定在 POSIX(TMPDIR)成立、诚实 SKIP 不伪装通过、JS 条目跨平台运行。
- 注:WSL 无 .venv 且离线,依赖型条目按硬约束 SKIP;在按 VERIFICATION 矩阵备齐依赖的 Linux 真机上同命令即可执行全部条目(offscreen 组仍需真实 Linux 桌面环境完成 P1-03/P1-04 的平台验证,状态不变)。
故意失败夹具演示(硬约束:崩溃/超时不阻断汇总、退出码反映失败)
- 临时夹具(用后即删,未提交):
- 崩溃夹具(
raise RuntimeError)→ 聚合器记 FAIL 并继续跑后续健康测试。 - 超时夹具(
time.sleep(60)+ budget 5s)→ 聚合器记 TIMEOUT 并继续。
- 崩溃夹具(
- 演示运行:
总计 3: PASS 1 FAIL 1 TIMEOUT 1,退出码 1,完整汇总 + 失败命令清单正常打印。 - 演示日志:
D:/tmp/runall_fixture_demo.log;夹具文件已删除,仓库无残留(已 rg 复核)。
等价性(硬约束:单文件命令仍可直接运行,输出与聚合子进程一致)
test_copy_session.py:- 独立运行:
===== 54/54 PASS ===== / ALL PASS - 聚合子进程(保留子日志 tail):
===== 54/54 PASS ===== / ALL PASS—— 逐字一致。
- 独立运行:
- 其余条目同理(聚合即
subprocess.run([sys.executable, ...原命令...]),命令形态未变)。
聚合入口暴露并修复的两个真实缺陷
tests/test_compaction_persist.pyT9 陈旧断言(跨平台共同项,Windows 上 FAIL):- 断言用
assertIn('msg["role"] not in', src)硬编码变量名,而ui/views/main_window.py现行代码用m["role"] not in(P1-01/P2-01 期间变量名演化,测试未跟进)。 - 修复:改为变量名无关的语义断言(同时接受
msg["role"] not in/m["role"] not in两种等价写法,检查"摘要标记行被过滤"这一语义本身)。 - 验证:单跑 41/41 PASS;聚合 logic 组 12/12 PASS。
- 断言用
core/agent/compaction.pydataclass 不可哈希默认值(Python 3.11+ 崩溃,真跨平台 bug):CompactionPreparation.settings: CompactionSettings = DEFAULT_COMPACTION_SETTINGS:默认值是 eq-dataclass 实例(__hash__=None)。Python ≤3.10 的 dataclass 只拒 list/dict/set 默认值 → 合法;Python 3.11+ 追加"不可哈希默认值"检查 → import 即 ValueError。- 影响面:Ubuntu 24.04 自带 CPython 3.12(VERIFICATION 矩阵明确支持的 Linux 目标)—— 任何 import
core.agent的模块/测试在 3.11+ 全灭。由聚合入口在 WSL/3.12 上首次系统性暴露。 - 修复(1 行,语义完全等价):
settings: CompactionSettings = field(default_factory=lambda: DEFAULT_COMPACTION_SETTINGS)—— 仍返回同一共享默认实例,3.10 行为不变。 - 验证:3.10 本地
test_compaction_persist41/41 +run_tests41/41 无回归;WSL/3.12 上core.agent链 import 通过(3 个 openai 依赖条目越过 compaction 后才在 openai 处 SKIP,证明 3.12 兼容)。
注册表元数据修正(诚实 SKIP 的前提)
test_tool_params.py/test_bash_stream.py/test_cross_platform_shell.py:补openai依赖(均 importcore.agent.tools→ 顶层from openai import OpenAI)。test_global_hotkey_platforms.py:补pyqt6依赖(含 QShortcut/overlay 构造)。test_wv2_guard.py:标platform:win32(T4 msvcrt 跨进程互斥为 Windows 专属;非 win32 上acquire_instance_lock()按设计返回 None)。
边界遵守
- 未动任何独立测试命令与既有入口(
run_tests.py原样保留)。 - 未要求 pytest/npm/网络;聚合器零第三方依赖。
- 默认聚合未启动任何真实 API / 人工诊断 / 真实桌面 / 凭据脚本(见排除清单)。
- 未读取真实配置(
data/config.json零访问);未删除用户运行数据;夹具用后即删。 - 产品代码改动仅 2 处且均为聚合暴露的缺陷修复:
tests/test_compaction_persist.py(测试断言更新)+core/agent/compaction.py(1 行 3.11+ 兼容)。
复现命令
python tests/run_all.py --list
python tests/run_all.py --group logic
python tests/run_all.py --group offscreen
python tests/run_all.py --group all
python tests/run_all.py --only test_copy_session --keep-logs