test(core): mtime 探针改用显式 set_modified,update-e2e 失败升注解(M275)

tree_snapshot_sees_new_nodes_and_mtime_changes 的「同内容重写」时间维度断言在
Windows/NTFS 上不可靠:同一系统时钟 tick 内的两次写、或时间戳只在句柄关闭时按
粗粒度落盘,都会让 mtime 与写之前逐字节相同 —— main 上 test (windows-latest)
偶发红在这行 assert_ne!(check-run 130965734990)。改成显式时间戳:
File::options().write(true).open + set_modified(基线 + 5s),值由测试指定、
与 tick/落盘粒度无关;不用 sleep、不用重试。用例原本的目的(快照必须看得见
mtime 变化)保持不变,另附 4s 下界断言把「我们推的那一下」与 stat 抖动分开。

ci.yml 的 update-e2e 步骤原本是裸 cargo test,失败只留一句 exit code 1、
check-run 上零注解,匿名侧等于信息为零。改成与 test 作业同款:pwsh +
Tee-Object 存 $RUNNER_TEMP 日志、失败把 panicked at / error / test result:
FAILED / failures: 行以 ::error:: 输出(% → %25)、打印并 exit $LASTEXITCODE
(cargo 真码,不是 Tee 的码)。步骤名 update-e2e 与 --test update_e2e_test
逐字保留(check_test_source_off.py 的 ALLOWED_STEP 钉死这两点)。

行数不变(ci.yml 397 → 398,≤400):注释块等价压缩腾出的行给运行时逻辑。
This commit is contained in:
AskaEth committed 2026-11-12 18:44:51 +08:00
1 parent a0a35596c8
commit 686dd9335a
2 files changed
+69 -36

No files matched your search

+30 -29
View File
@@ -109,8 +109,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.os }}
# `--workspace` 现在是 8 个 crate,不含 `unlucky-app`(M118 的 workspace exclude),
# 所以这条命令不会拉起 slint / usvg / i-slint-*。
# `--workspace` 现在是 8 个 crate,不含 `unlucky-app`(M118 的 exclude)⇒ 不拉起 slint / usvg / i-slint-*。
- run: cargo clippy --workspace --all-targets -- -D warnings
test:
@@ -187,16 +186,15 @@ jobs:
# 只会打一条 `excluded package(s) … not found in workspace` 的警告然后空转(实测 exit 0,不报错)。
#
# ---- 取证(M147):下面是同一件事的两个平台版本,不是两条不同的测试 ----
# M144 的第三条红 `test (windows)` 只留下 `Process completed with exit code 1`,而 cargo 自己的失败码
# 是 **101** ⇒ 那个 1 的来源不明(包装层洗码 / 进程被杀,两说都未排除);job log 要登录才能读
# (匿名 403),但**注解匿名可读**(`GET /check-runs/<id>/annotations` → 200,M144 实证)。三件事
# 各对准一种「看不见」:
# 1) `--no-fail-fast`:cargo 默认在第一个失败的 target 就停(M144 实测 Linux 只跑 7 个 test
# binary 就退出),后面还有没有第二条失败完全看不到;
# 2) `error` / `failures:` / panicked 行升成 `::error::` 注解:拿不到 job log 时,注解是匿名侧
# 唯一能取到的失败正文;
# 3) 显式打印 cargo 的退出码:把「包装层把码洗成 1」「cargo 真失败(101)」「进程被杀只给码、零诊断」
# 分开——这正是 M144 没定的那一半。
# M144 的 `test (windows)` 只留 `Process completed with exit code 1`(cargo 自己的失败码是 **101**)
# ⇒ 那个 1 来源不明;job log 要登录才能读(匿名 403),但**注解匿名可读**
# (`GET /check-runs/<id>/annotations` → 200,M144 实证)。三件事各对准一种「看不见」:
# 1) `--no-fail-fast`:cargo 默认首个失败即停(M144 实测 Linux 只跑 7 个 test binary 就退出),
# 后面还有没有第二条失败看不到;
# 2) `error` / `failures:` / panicked 行升成 `::error::`:拿不到 job log 时注解是匿名侧唯一正文
# (M275 把同一手法补到末尾的 `update-e2e` 步骤);
# 3) 显式打印 cargo 退出码:把「包装层把码洗成 1」「cargo 真失败(101)」「进程被杀只给码、
# 零诊断」分开——这正是 M144 没定的那一半。
- name: cargo test --workspace --all-targets(ubuntu,失败升注解)
if: runner.os == 'Linux'
run: |
@@ -364,20 +362,14 @@ jobs:
path: ${{ runner.temp }}/smoke/
if-no-files-found: warn
# M169:更新链路的**端到端验收**(发现新版本 → 下载 → 长度/SHA256 双检 → 就位;篡改摘要 /
# 篡改包体 / 截断必须拒绝且不动现有安装;重复 apply 的幂等终态)。
#
# 独立 job、只在 Windows:夹具的「真形状」只在 Windows 成立——真实产物是裸 `.exe` +
# `portable-exe`,而 Linux/macOS 是 `.tar.gz` + `portable-zip`(会被 `ensure_self_replaceable`
# 直接拒)。在 ubuntu 上跑绿只能证明「一个世上不存在的 linux portable-exe 能装上」,是假绿
# (r1 复审 P2-4)。
#
# 本 job 的步骤名 `update-e2e` 是**唯一**被允许出现 `update-test-source` 的地方,判据在
# `packaging/check_test_source_off.py` 的 `ALLOWED_STEP`:文件名 / 步骤名 / `--test
# update_e2e_test` 三者任一不符即红——改这里的 name 或 run 之前先读那段注释。
#
# 慢是已知的(release + fat LTO,本机实测 7 分钟;不发 debug 档:`debug_assertions`、优化与
# panic 行为都不一样,用 debug 跑这条 E2E 就失去了它存在的理由)。tower 明确:能跑起来比跑得快重要。
# M169:更新链路的**端到端验收**(发现新版本 → 下载 → 长度/SHA256 双检 → 就位;篡改摘要 / 篡改包体 /
# 截断必须拒绝且不动现有安装;重复 apply 的幂等终态)。只在 Windows:真实产物是裸 `.exe` +
# `portable-exe`,Linux/macOS 是 `.tar.gz` + `portable-zip`(`ensure_self_replaceable` 直接拒),
# 在 ubuntu 上跑绿只证明「世上不存在的 linux portable-exe 能装上」(r1 复审 P2-4)。
# 步骤名 `update-e2e` 与 run 里的 `--test update_e2e_test` 被 `packaging/check_test_source_off.py` 的
# `ALLOWED_STEP` 钉死(`update-test-source` 只许在这一项里出现)——改这里的 name / run 之前先读那段注释。
# 慢是已知的(release + fat LTO,本机实测 7 分钟;不发 debug 档:`debug_assertions` / 优化 / panic 行为
# 都不同,用 debug 跑这条 E2E 就失去它存在的理由)。能跑起来比跑得快重要。
update-e2e:
name: update-e2e (windows x64)
runs-on: windows-latest
@@ -391,7 +383,16 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
key: windows-latest
# M275:裸 `cargo test` 失败只留一句 `exit code 1`、check-run 上零注解(匿名侧等于信息为零),所以照
# test 作业同一手法升注解:`$LASTEXITCODE` 是 cargo 的真码(Tee-Object 是 cmdlet,不改它)、`%` → `%25`。
- name: update-e2e
run: >
cargo test --release -p unlucky-cli --features update-test-source
--test update_e2e_test --test update_e2e_tamper_test
shell: pwsh
run: |
$log = Join-Path $env:RUNNER_TEMP 'update-e2e.log'
cargo test --release -p unlucky-cli --features update-test-source --test update_e2e_test --test update_e2e_tamper_test 2>&1 | Tee-Object -FilePath $log
$code = $LASTEXITCODE; Write-Host "cargo exit=$code"
if ($code -ne 0) {
Select-String -Path $log -Pattern '(error(\[E\d+\])?:|^failures:|test result: FAILED|thread .* panicked at|^\s+--> )' | Select-Object -First 40 |
ForEach-Object { Write-Host "::error::$($_.Line.Replace('%', '%25'))" }
}
exit $code