Repository navigation
TSI-4314: test(acceptance): 覆盖缓存淘汰、删除清理与停顿诊断 - #156
Conversation
|
Sorry @multica-tsic404[bot], you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 21 hours and 6 minutes by commenting |
Reviewer's GuideExpands acceptance coverage for cache eviction and re-downloads, torrent-removal cleanup, and stalled-cache diagnostics with ENODATA mapping, using live torrent infrastructure and production service paths; the cases are registered in the acceptance suite. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
tsic404
left a comment
There was a problem hiding this comment.
规模 L2 · 795 行新增 / 4 文件,类型:验收载体(无产品代码改动)。
覆盖维度:代码质量 ✓ | 安全 ✓ | 架构一致性 ✓ | 并发与资源 ✓ | 编码规范 ✓ | 测试判别力 ✓ | 设计符合性 ✓
点赞
- 三条载体断言的都是真实渲染器与真实错误出口,没有自造第二套格式:
generate_torrent_stats/generate_global_stats(src/fuse/stats.rs:255,454)、TorrentError → FsError → errno(src/fuse/errno.rs:46)。片标记的is_cached取自cache.has_piece(src/infrastructure/download/engine.rs:3237),所以「重读后被重新缓存」不是自证 —— 用内部has_piece选片、再用.stats断言,这一步做得对。 - TC-cache-05 覆盖两种 stall 形态与两个 evidence 枚举值,
evidence_span ^ evidence_gone与stalls.len() == 2互相约束,判据没有被放宽。 - TC-cache-04 按 C-5.2.4 用 10s 轮询 + 关停后读取兜底,没有对存活 daemon 做单次即时断言;只调
TorrentService::remove_torrent(src/fuse/fs_service.rs:1148的同一条 unlink 路径),不是测试自造的清理。 - 子进程捕获 fd 2 沿用
test_tc_read_05/test_tc_config_07的既有形态;TORRENTFS_TC_CACHE_05_CHILD是重入标记而非 CI 跳过(env 存在时仍执行两条 stall 场景,父进程再断言 stderr),不构成 CI 造假。
其他审查者:gh pr view --json reviews 为空,无既有 CHANGES_REQUESTED 需并入。
安全:无密钥 / 外部网络 / 路径穿越;Command::new(current_exe()) 固定参数、无 shell;只写本机临时目录与 127.0.0.1 tracker。通过。
提交信息:test(acceptance): 覆盖缓存淘汰、删除清理与停顿诊断 —— 无 TSI / C-x / AC-x / TC-x 编号、未照抄 issue 标题、正文写了为什么与可观察变化、无署名 trailer,合规。
发现 3 条(1 条 🟡 + 2 条 💭),均已行内提交,改动只在测试内。
8664397 to
d76c549
Compare
tsic404
left a comment
There was a problem hiding this comment.
概述:本次修订(d76c549,相对上一轮 9b4edb2 仅 +123/−30,全部落在 tests/acceptance/test_tc_cache_0{3,4}.rs)逐条闭合了上一轮的 1 🟡 + 2 💭,无新增发现。规模 L2(888 行新增 / 4 文件,src/ 零改动)。通过维度:判据正确性与可失败性、设计合规(01-scope / 02-contracts @ 5b622b6)、安全、提交信息。其它审查者:无 CHANGES_REQUESTED。CI:Acceptance FUSE E2E 及 Cargo Test amd64/arm64 全绿。
点赞:修复没有换形,而是把三条「假证据」换成了「可失败证据」——root_evictions 从 Option 变 Result 并把「解析失败」的 panic 文案与「计数未增长」的预算超时文案彻底分开(test_tc_cache_03.rs:260-311);orphaned_paths 改成真正的全树遍历且 ? 传播 I/O 错误(test_tc_cache_04.rs:178-200);read_metadata 用一个入口同时服务轮询见证与 shutdown 见证(test_tc_cache_04.rs:136,146)。此外每一条修复都配了会被修复前的实现打回的回归用例。
逐项复核:
-
test_tc_cache_03.rs:260root_evictions去千分位后parse✅ 闭合。渲染源是src/fuse/stats.rs:254-260,驱逐次数经format_num(src/fuse/stats.rs:36-47),只插逗号、不做 K/M 缩写,所以replace(',', "")是完整解。两类失败不可混淆::289-295解析失败直接panic!("{reason}\n{text}")(文案cannot parse the eviction count …),:302-306预算超时断言文案是root .stats reported no eviction growth within …,且后者回显已解析值。两条回归用例都直接调用被测函数(:314、:321),不是代理断言。「Evictions: 1,024→ 1024」正是渲染器的真实行形态(同stats.rs:255的字段顺序与双空格),「Evictions: —→Err」覆盖旧的None被当成「从未驱逐」的路径。 -
test_tc_cache_04.rs:178orphaned_paths✅ 闭合。pieces/全树 DFS,两处布局都会被命中:pieces/<info_hash>(名字相等,任意深度)与pieces/<info_hash>/<info_hash>:piece:N(前缀,任意深度),后者与产品布局一致(src/infrastructure/cache/mod.rs:657-661的piece_path、:791的pieces_dir_for)。I/O 错误不再被吞:read_dir(&dir)?、entry?、file_type()?三处都用?,用例侧:110-111以expect把错误变成失败。断言已非恒真::107的wait_until只保证<info_hash>顶层目录消失,:110-115的遍历额外覆盖「片文件被平铺到pieces/或写进别的目录」这类残留,回归用例:202用嵌套残留 + 不可读树证明了它既能检出也能报错。 -
test_tc_cache_04.rs:160read_metadata✅ 闭合。NotFound→ 空串(缓存清空后文件消失属合法收敛),其它错误panic!;:136轮询见证与:146shutdown 见证共用该入口,没有第二份吞错读取。覆盖边界记录:NotFound分支有回归用例(:170,该用例在修复前的unwrap_or_default()下同样通过),panic分支目前由代码阅读核对、无独立should_panic断言;该分支是单行 match 臂,且同一「错误不得读成空集」原则在orphaned_paths侧有断言(:214-218),不构成发现。 -
test_tc_cache_03.rs:54read_timeout_secs15s → 60s:判定为「仅消除环境抖动」,不构成判据放宽。理由三条:(a) AC-32 的可观察判据只有「叶子.stats出现标记 + 驱逐计数增长」(docs/03-acceptance.md:49),无任何时延判据;(b) 决定成败的三个预算都是与被改项无关的字面量且本修订未动——标记20s(:131-137)、驱逐计数10s(:146)、整段读READ_BUDGET=120s(:33);(c)read_timeout_secs只决定单次读在等片/发现上最多阻塞多久(src/infrastructure/config/timeouts.rs:50-52),它把发现窗口压到min(read_timeout_secs, peer_discovery_wait_secs)(timeouts.rs:59-61,后者默认 30s,timeouts.rs:23),所以 15s 是把窗口从 30s 掐到 15s、60s 是回到产品默认(timeouts.rs:72)。判据仍会失败:不重新下载的实现拿不到[x]/[X n],也会在:302的 10s 预算里被驱逐计数打回,无论单次读等多久。 -
cache-01单次既有断言失败:判定为新增用例未引入共享资源/时序干扰,不构成驳回理由。证据:每个用例独立tempfile::TempDir;tracker 每次TcpListener::bind("127.0.0.1:0")由内核分配端口(tests/common/mod.rs:74);tests/acceptance全目录无std::env::set_var,TORRENTFS_TC_CACHE_05_CHILD只挂在被 spawn 的Command上(test_tc_cache_05.rs:56-60),不污染父进程;种子名逐用例唯一且 03/04/05 都关 LSD(main.rs注释同源,test_tc_cache_05.rs:226-231);并发上限仍是MAX_CONCURRENT_TESTS = 4(tests/acceptance/common.rs:30),本修订没有抬高它。cache-01首个用例只取 wave slot、不取 session lock(test_tc_cache_01.rs:24),因此它会与持锁的新用例共跑,多出来的是 CPU 秒数而非共享状态;而cache-01最容易在负载下失效的恰是它自己的墙钟判据(test_tc_cache_01.rs:89-107:4096 次单字节读< 5s),该判据未在本 PR 中改动。附记一条残余事实(非本 PR 引入、不针对cache-01):cache-05的子进程以current_exe()重入,ACTIVE_TESTS是进程内静态量(common.rs:32),子进程不吃父进程的配额,最多使整机同时存在的 session 数为 5;这与既有test_tc_read_05同形,且与cache-01无共享状态。同一 CI 运行的 Acceptance 作业(8m6s)全绿,与「单次负载抖动」一致。
安全维度:通过。仅新增测试载体:无密钥/凭据、无外部网络(tracker 与对端均 127.0.0.1)、无路径穿越(orphaned_paths 只做只读遍历,pieces_dir_for 另有 leaf-name 防护 src/infrastructure/cache/mod.rs:781-796)、Command::new(std::env::current_exe()) 固定参数无 shell、stderr 重定向到临时文件。
提交信息(commit-message-standard):test(acceptance): 覆盖缓存淘汰、删除清理与停顿诊断,正文非空,无设计/验收编号、未照抄 issue 标题、无 Co-authored-by/Signed-off-by 等 trailer —— 合规。
设计锚点:tsic/torrentfs-design@5b622b6(= issue 冻结 design_anchor);设计仓 HEAD 已到 ed05aa1,按锚点评审。## 设计变更 声明「无」属实:src/ 零改动,无外部可观察行为变化,无需 D1–D4 设计 PR。
零发现,故无行内评论。
缓存上限、种子删除与缓存停顿诊断此前没有可执行的验收载体,QA 只能按文档逐条手工核对。新增三条用例分别驱动小容量缓存下的淘汰与重读、metadata 删除后的缓存目录与元数据收敛、缓存无法服务的读返回 ENODATA 并落冻结诊断前缀;断言走产品现有的引擎、服务与 .stats 渲染路径。载体读取缓存元数据时只把文件缺失读作空串,其它 I/O 错误必须显形,该分支由单测钉住,回退为吞错即失败。
d76c549 to
eae6d4d
Compare
tsic404
left a comment
There was a problem hiding this comment.
概述:在 新 head eae6d4d 上重新出判决。相对上一轮批准的 d76c549 只多 tests/acceptance/test_tc_cache_04.rs 的 +20 行(一个 #[should_panic] 用例),src/ 零改动,整仓 diff 仍 4 文件。规模 L2。通过维度:判据钉定与判别力、设计合规(01-scope / 02-contracts @ 5b622b6)、安全、提交信息。其它审查者:无 CHANGES_REQUESTED(此前的批准因新推送被平台置为 DISMISSED,故本判决重新 pin 到 eae6d4d)。CI:run 40238090523 的 headSha = eae6d4d15f3…,14 项 SUCCESS + 1 项 SKIPPED(Sourcery),无失败。
点赞:这 +20 行补的正是上一轮我记录的覆盖边界——read_metadata 的「其它 I/O 错误 → panic」一支。注入手段选得对:chmod 000 在 CI 的 root 容器里不生效,而「把元数据路径做成目录」在 root 与非 root 下都稳定报错;用例还先用 expect_err + assert_ne!(kind, NotFound) 自证夹具形态,避免夹具退化后静默变成恒真。
逐项复核:
-
钉的是 panic 支而非被 NotFound 短接 ✅
test_tc_cache_04.rs:186对同一路径同一操作取expect_err,:187-191断言error.kind() != NotFound;因此read_metadata(:160)里Err(e) if e.kind() == NotFound(:163)的守卫对这条路径必为假,只能落到:164的panic!。注入面是目录,read_to_string在 Linux 上返回 EISDIR,root 下同样成立,不存在权限位失灵的空过路径。 -
expected与实现消息对得上,且不可被别的 panic 冒充 ✅ 属性写作#[should_panic(expected = "read cache metadata")](:179),实现消息是"read cache metadata {path}: {error}"(:164)——expected是其子串,should_panic的子串语义成立。测试体内其余五个可能 panic 的点(:183temp dir、:185create_dir、:186expect_err、:187-191断言消息、:192之前的 join)文案都不含read cache metadata,所以只有被测 arm 能满足期望。 -
判别力 ✅(静态证明;按审查职责只读,未做 scratch 执行)。把
read_metadata函数体回退为std::fs::read_to_string(path).unwrap_or_default()时:目录读取返回Err(EISDIR)被吞成"",unwrap_or_default不 panic,:192的调用不可能 panic,而#[should_panic]在没有 panic 时必然判失败 ⇒ 该用例必 FAIL,且同文件其余三条不受影响(它们不依赖该 arm)。这与 Verity 探针 3(修复前三条全绿、判别力缺失)和作者自述(修复后:176处test did not panic as expected、exit 101)方向一致;此处结构上只有一条可达 panic 路径,静态结论比一次探针采样更强。 -
影响面 ✅ 新用例无 session、无 wave slot、无 session lock、无全局 env,只用独立
TempDir,因此不可能对并发时序产生干扰。CI 实测:test_tc_cache_04四条全ok(含tc_cache_04_unreadable_metadata_is_not_swallowed - should panic ... ok),test_tc_cache_03三条与test_tc_cache_05一条全ok,registry_tests四条门禁全ok,acceptance 二进制80 passed; 0 failed(156.35s)。registry_tests的四条门禁只枚举模块声明、TC_ID常量、未登记模块与脚本存在性,不枚举模块内的#[test]数量,故新增同模块用例不影响门禁。
安全维度:通过。仅新增测试代码:无密钥/凭据、无外部网络、无路径穿越(临时目录内自建目录);目录注入不触碰权限位,也不写任何产品路径。
提交信息(commit-message-standard):单 commit amend,subject test(acceptance): 覆盖缓存淘汰、删除清理与停顿诊断 无设计/验收编号、未照抄 issue 标题,正文非空并说明了该分支的钉定,无 Co-authored-by/Signed-off-by 等 trailer —— 合规。
设计锚点:tsic/torrentfs-design@5b622b6(= issue 冻结 design_anchor),与 Dev 声明一致;设计仓 HEAD 同为 5b622b6,docs/03-acceptance.md/docs/02-contracts.md 无漂移。src/ 零改动 ⇒ 无外部可观察行为变化,## 设计变更 声明「无」属实,不需要 D1–D4 设计 PR。
零发现,故无行内评论。
Closes TSI-4314
设计依据:
tsic/torrentfs-design@5b622b6设计实现
docs/03-acceptance.md§D AC-32;docs/02-contracts.md§C-5.1.5、§C-6.2.5、§C-6.3.1tests/acceptance/test_tc_cache_03.rstc_cache_03_evicted_piece_is_cached_again_on_rereaddocs/03-acceptance.md§D AC-33;docs/02-contracts.md§C-5.2.3、§C-5.2.4、§C-5.4.4tests/acceptance/test_tc_cache_04.rstc_cache_04_removing_a_torrent_purges_cache_and_metadata;见证的读取辅助由tc_cache_04_missing_metadata_reads_as_empty与tc_cache_04_unreadable_metadata_is_not_swallowed钉住docs/03-acceptance.md§D AC-34;docs/02-contracts.md§C-4.4.2、§C-4.4.6、§C-4.4.7tests/acceptance/test_tc_cache_05.rstc_cache_05_cache_stall_diagnosis_and_enodatadocs/03-acceptance.md编号与可执行形态注册tests/acceptance/main.rs(mod+LANDED)验证
cargo test --test acceptance -- tc_cache_0:10 passed, 0 failed(cache-01/03/04/05)。cargo test --test acceptance -- registry_tests:4 passed, 0 failed。read_metadata回退为read_to_string(path).unwrap_or_default()后tc_cache_04_unreadable_metadata_is_not_swallowedFAILED(exit 101),其余三条 TC-cache-04 仍绿 ⇒ 该分支判别力有实测证据。Summary by Sourcery
Expand acceptance coverage for cache lifecycle behavior and stalled-read diagnostics.
New Features:
Enhancements:
Tests: