Skip to content

补齐 C1/C5 端到端判据:默认关闭的设备错误注入点 - #111

Merged
wt159 merged 3 commits into
masterfrom
implement/c1-c5-error-injection
Nov 8, 2026
Merged

wt159 merged 3 commits into
masterfrom
implement/c1-c5-error-injection

Conversation

@wt159

@wt159 wt159 commented Nov 8, 2026

Copy link
Copy Markdown
Owner

背景

doc/player-state-contract.md §10.4 登记的唯一残留技术缺口:C1 的 error→state 顺序、C5 的「设备错误不跳轨」缺端到端判据。用户 2026-11-08 拍板「启动补齐 effort」,按一次性批量授权选最保守方案:#109 先重审 §8「不新造接缝」并批准一次限定例外、#110 实现,两票设原生阻塞边。

实现(只加一个默认关闭的注入点)

  • AudioDevice::open() 包装层加文件级 std::atomic<bool>(默认 false,release/acquire),命中时直接 return -1,不进 Impl::open()、不碰 SDL;播放链走的是生产里真实存在的设备失败分支(MusicPlayer.cpp:326-330 → onMusicPlayListError:707),sdk/MusicPlayer.cpp 播放逻辑零改动。
  • 读点只在控制线程调用 open() 时,绝不落解码线程 / 10 ms 消费主循环 / 判据主循环(O1 -j4 假红教训)。AudioDevice 是 SDK 内部类型,钩子不进入 soundbridge::Player 公开 API;七个 void 控制入口、三态、回调契约一字未动。
  • 一条 AudioDeviceOpenFailed(StopPlayback)序列同时覆盖 C1(onError 早于 onStateChanged(Stopped)、发且仅发一次、错误码正确)与 C5(默认 autoSkip 开启也不跳到第二首、不触发第二次播放尝试)。双曲目列表 + 队列稳定窗口做屏障,RAII guard 保证异常时也恢复开关。

证据

项目 结果
单用例 12 / 12 断言绿
变异:去掉 SkipTrack 检查 6 条断言红(含 C5「索引不变」「只报一次 error」)
变异:onError 挪到 state 之后 errAt < stAt 精确红
变异还原 12 / 12 绿,MusicPlayer.cpp 零改动
ctest -j4 集成分支 10 / 10 轮全绿 14/14(56.65–59.17 s)
ctest -j4 master 基线 9 / 10 轮全绿(第 9 轮 sdk_interaction_tests 既有低概率 flake,与本用例无关)

分支假红率不高于基线 → O1 稳定性闸门通过。逐轮耗时与反悔通道见规格 §10.4。

零改动声明

sdk/MusicPlayer.cpp、sdk/include/soundbridge/、.github/、sdk/test/CMakeLists.txt 全部零改动;不新增 add_test 分组,不改 14 个 sdk_* 目标 / 7 组 TIMEOUT / BadInput 55 例 / 覆盖度 15 行矩阵 / 任何既有判据数值;#104「不设数值阈值」与 §3.2 第 5 步永久生效不变。

待验证(合并条件)

本地 Windows 全绿按 AGENTS.md 不算完成:须等 Linux sdk-coverage 与 Windows sdk-windows 双绿;之后关闭 #110 并留完整 resolution,规格里「落地」措辞才升级为「已收口」。一次两轴 code-review 提出的问题已在 fix 提交里全部修完(Standards 0 硬违规)。

票正文两处偏差(目标名 sdk_interaction_tests → 实际 sdk_unit_tests;C5 判据形态按实测调整)已在 #110 comment 更正,票正文不改。

Closes #110

wt159 added 3 commits November 8, 2026 21:14
- AudioDevice 加 setForceOpenFailureForTest():文件级 atomic<bool> 默认 false,只在 open() 包装层读一次,命中直接 return -1、不进 Impl::open() / 不碰 SDL;MusicPlayer.cpp 播放逻辑零改动,播放链走的是生产里真实存在的设备失败分支(:326-330 → onMusicPlayListError:707)
- 开关只在控制线程 _play()→open() 路径被读,不落解码线程 / 10 ms 消费主循环 / 判据主循环(O1 对照实验:额外写曾把 -j4 假红率从 0 抬到约 30%)
- 新增一条用例同时覆盖 C1(error→state 顺序、发且仅发一次状态、Stopped、错误码 AudioDeviceOpenFailed)与 C5(默认 autoSkip 开启也不跳到第二首、不触发第二次播放尝试)
- 双曲目列表 + 队列稳定窗口做屏障,不靠裸 sleep / 绝对时长窗口 / 特定 demuxer 行为;RAII guard 保证 REQUIRE 抛异常时也恢复进程级开关
- 变异验证:去掉 SkipTrack 检查 → 6 条断言红(含 C5 的「索引不变」「只报一次 error」);把 onError 挪到 state 之后 → errAt < stAt 精确红;还原后 12/12 断言绿
- 不碰 soundbridge::Player 公开头 / 七个 void 控制入口 / CI 配置 / CMakeLists / 任何既有判据数值;不改 14 个 sdk_* 目标与 TIMEOUT
- player-state-contract §8 补 #109 条款重审:区分「为验证另造可测替身 / 另立判据数值」(仍禁止)与「契约已有但无法注入错误」(本次一次限定例外),明确不推广为新接缝惯例
- §10.3 把「唯一仍保留的判据缺口 / 须人拍板」标注为收口前历史状态,终态改为缺口已补齐;§10.4 用完整落点替换原「已知判据缺口」条目:注入点形态、变异验证(6 条红 / errAt<stAt 精确红 / 还原 12/12 绿)、ctest -j4 对照(分支 10/10、master 9/10)、用例归属 sdk_unit_tests、反悔通道
- observability-contract §1 界外清单与「不可推翻前提」补 2026-11-08 例外与终态指针;§7.4 补「本洞已补齐」,保留 #94 起图时原句作留痕,观测口径本身未变
- 票 #110 加 comment 更正两处票面偏差(目标名 sdk_interaction_tests → sdk_unit_tests;C5 判据形态按实测调整),票正文不改
- 纯文档:不改代码、用例、CI 配置与任何既有判据数值
- Standards:AudioDevice.h 注释不再自相矛盾(明确 AudioDevice 是 SDK 内部类型、钩子不进入 soundbridge::Player 公开 API);注入开关改用 release/acquire,注释写明写端为测试线程 / 读端为控制线程、每次 open() 都读、误跳轨二次 open 同样命中
- Spec:三处规格把「终态 / 已补齐」降级为「集成分支落地、收口待 CI 双绿」;补待验证条款(PR 合并 → Linux sdk-coverage + Windows sdk-windows 双绿 → 关闭 #110 留 resolution),本地 Windows 全绿不算完成
- 补 O1 闸门逐轮耗时对照表(分支 10/10、master 9/10)与跨规格反悔通道指针;§10.4 起图时的 fog 行标注为历史留痕
- 不采纳 ScopeGuard 替换(判断项):手写 6 行 RAII guard 自包含、无新依赖,通用件语义需额外验证;其余 smell 均为判断项,无硬违规
- 重编译后新增用例 12/12 断言绿;不改既有判据数值 / CI 配置 / 14 个 sdk_* 目标与 TIMEOUT
@wt159
wt159 marked this pull request as ready for review November 8, 2026 13:57
@wt159
wt159 merged commit 8b36430 into master Nov 8, 2026
2 checks passed
wt159 added a commit that referenced this pull request Nov 8, 2026
- PR #111 合并为 8b36430,pull_request 阶段 Linux sdk-coverage 42487403007 与 Windows sdk-windows 42487403112 均 success、attempt=1(14m15s / 4m34s);票 #110 已 CLOSED 并留完整 resolution
- player-state-contract §10.3 / §10.4 把「集成分支落地、收口待 CI」升级为「缺口已补齐」,待验证条款改为收口证据;observability-contract §1 / §7.4 同步
- 纯文档:不改代码、用例、CI 配置与任何既有判据数值;按 workflow paths 过滤不触发新 CI,合并后 master 的 push run 另作同代码复核
wt159 added a commit that referenced this pull request Nov 8, 2026
- Linux sdk-coverage push run 42488656322 attempt=1 实为 failure:sdk_interaction_tests 的既有 seek 用例 test_player_integration.cpp:726 偶发 SIGSEGV,14 条断言全过。
- gh run rerun --failed 后 attempt=2 success,100% tests passed 0 failed out of 14,同目标 12.24s。
- 判偶发 flake:merge commit 与 PR 分支头 tree 完全相同且 PR run 已绿;失败用例与新增 C1/C5 用例零交集;注入点默认关闭时无新增崩溃路径。
- 如实登记「失败目标不在改动文件」本例不成立,补替代证据;不改判据 / TIMEOUT / 坏输入基线,仅观测记录、不是待办。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[实现] C1 / C5 端到端判据:设备错误 error→state 且不跳轨

1 participant