- 测试完成:是(2026-10-04)
- 测试日期:2026-10-04
- 测试内容:单元测试(plugins 钩子代码解析/清单容错、sandbox 路径穿越规范化、securefile 加密往返/MAC 篡改、http_api 鉴权、agent 协议解析等);注入测试 4(sandbox
../路径穿越逃逸根目录);钩子测试 5(pluginsresolve_code文件优先/回退/空值、缺 id 清单解析、非法 JSON 拒绝)。本 crate 为 Tauri bin-only,无独立 tests/ 集成目录,测试按惯例落在src-tauri/src各模块#[cfg(test)]。 - 运行命令:
cd src-tauri; cargo test --no-fail-fast - 测试框架:Rust
#[cfg(test)] - 模型:豆包(Doubao)生成
BIT 是一个 Tauri 2 桌面应用,Rust crate 位于 src-tauri/,是单一 bin crate(src/main.rs,无 lib.rs 库目标)。因此它没有 tests/ 集成测试目录——Rust 的 tests/ 只能链接库目标,而为这个 Tauri bin 强行拆出 lib.rs 会把整套模块声明复制一份、显著拖慢编译并可能破坏 tauri::App 的初始化路径。该 crate 的测试按 Rust 惯例全部放在各模块内的 #[cfg(test)] 单元测试中,这对 bin crate 是标准做法。
cd src-tauri
cargo test --no-fail-fast首次编译会拉取并编译数百个依赖(tauri 2、axum 0.8、reqwest、calamine、jieba-rs、rhai、scraper、qrcode …),耗时数分钟;之后增量编译约 30 秒。
只跑某个模块:
cargo test --bin bit plugins:: # 只跑插件相关
cargo test --bin bit sandbox:: # 只跑沙箱路径相关
cargo test --bin bit securefile:: # 只跑加密存储相关- 协议解析(
agent.rs):OpenAI/函数式/数组式工具调用的解析、残缺/未闭合 JSON 的修复与截断、字符串内花括号不误判。 - 模型响应适配(
ai.rs):OpenAI/Claude/Gemini/Responses API 的多段文本、tool_call 载荷不泄露、瞬时网络错误分类、SSE 跨 chunk 切分。 - HTTP API 鉴权(
http_api.rs):bearer/query client key 接受与拒绝、未配置 client key 时拒绝全部、debug 端点双因子、health 旁路、worker IP 前缀语义。 - MCP(
mcp.rs):JSON/RPC/SSE body 解析、非 MCP server 拒绝、UTF-8 边界截断。 - 安全/加密(
securefile.rs/security.rs):BITENC1 加密往返、随机盐不泄露明文、MAC 篡改与错误密钥检测、明文/密文透明兼容、bitsign/bitcrypt 往返与篡改、HMAC 已知向量、nonce 重放/过期。 - 沙箱路径(
sandbox.rs):normalize消解./..,../逃逸根目录被拒,相互抵消的src/../src仍在根内。 - 插件/钩子(
plugins.rs):parse_schedule定时表达式、sanitize模型友好名、resolve_code文件优先于内联 code、缺失 id 的plugin.json仍可解析(sync 时用目录名覆盖)、非法 JSON 被收集为错误而非 panic。 - 其它:guardian 事件日志/签名轮换、session 预览与归一、update 的受信 host 白名单与二进制回滚、repetition 循环检测、shell
&检测、toolenv shell 解析。
位于 src/sandbox.rs 的单元测试,验证 AI 提供的路径在沙箱规范化下不逃逸:
dotdot_climbing_above_root_is_rejected:../../../etc/passwd规范化后不以根为前缀 → 拒绝。dotdot_that_cancels_out_stays_inside:src/../src/main.rs抵消后仍落在根内(不误伤合法路径)。current_dir_segments_are_collapsed:././a/./b.txt折叠为a/b.txt。root_itself_is_allowed:根目录本身合法。
外加 http_api.rs 的鉴权强制(未配置 client key 时拒绝所有 API 请求)与 securefile.rs 的密文不泄露明文密钥,共同构成不可信输入的防线。
位于 src/plugins.rs 的单元测试,覆盖插件代码解析与清单容错:
resolve_code_prefers_file_over_inline_code:声明了file且文件存在时,用文件内容、忽略内联 code。resolve_code_falls_back_to_inline_when_file_missing:file指向不存在文件时回退内联 code。resolve_code_empty_inline_is_none:无文件且内联为空白/缺失时返回None(不注册空工具)。plugin_manifest_without_id_still_parses:按文档编写、省略id的plugin.json仍能解析(kind默认interpreter、jobs默认空)。plugin_manifest_rejects_garbage_json:非法 JSON 被serde_json拒绝,供scan收集为错误列表(不 panic、不静默丢弃整个插件)。
说明:插件的实际
scan/sync需要构造重型Arc<Ctx>(含 workspace_root、config、各种运行时状态),属集成态,未在单元测试中拉起;此处覆盖其纯函数(代码解析、清单容错、定时/命名规范化)。
cargo test 全绿:199 passed / 0 failed(原有 190 + 本次新增 9,其中注入/路径穿越 4、插件钩子 5)。