mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-01 14:57:38 +00:00
## 为什么还要再加一条
前两条 commit 之后,B2 的「原子写」在判据侧其实是哑的 —— 我复核时实测
过:把 MarkPendingUpgrade 的 `tmp := p + ".tmp"` 改成 `tmp := p`
(退回最初的原地覆写 bug),以及把整个函数退回 os.WriteFile,
`TestMarkPendingUpgrade_IsAtomic` **都照样绿**。
因为它断言的是「最终状态对」:不留 .tmp 残留、内容可解析、可覆写。
os.WriteFile 这三条全都满足。也就是说那条用例证明的是「结果正确」,
没证明「写的过程不会毁掉已有数据」—— 而后者才是 B2 要防的事故。
## 这条用例钉什么
用它逼出两者唯一可观测的差异:**失败路径上旧文件还在不在**。
① 先写一个完好的旧 marker(FromVer=1.0.0)
② 把 pendingPath+".tmp" 占成**目录** ⇒ OpenFile 必 EISDIR
(稳定可复现,不依赖权限/磁盘/平台;失败点与「磁盘满/掉电」同类:
已打开目标、还没写完全部内容)
③ MarkPendingUpgrade 必须返回 error(不能假装标记已就绪)
④ 旧 marker 必须原样保留:FromVer 仍为 1.0.0、ToVer 仍为 1.1.0
③④ 都用 Error 而非 Fatal:让两个症状一起报出来。
## 语义差异
原子写(现状):新内容写进 .tmp 时失败 ⇒ 目标文件仍是完整旧版本
原地覆写 :O_TRUNC 先清空再写,中途失败 ⇒ 目标文件被截断,
旧 marker 永久丢失 ⇒ 不知道上次升了什么,也没了回滚依据
## 变异(已实测)
B2c-M1 rollback.go `tmp := p + ".tmp"` → `tmp := p` ⇒ RED
实际输出:旧 marker 被破坏了:FromVer 应为 1.0.0,实际 "2.0.0"
零用例假绿也堵住了:判据脚本对 `no tests to run` 直接 FATAL。
仅动 internal/update/kernel_apply_test.go(测试文件),生产代码零改动。