docs: coverage plan and review reports; drop the stray artifact
Adds the 90/80 coverage plan and the two-round review report, updates the M5 backfill and plan index, moves finished plans to completed/, and removes the machine-specific tarpaulin HTML report from the tree.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -8,13 +8,16 @@
|
||||
| 文档 | 内容 | 启动前提 |
|
||||
|---|---|---|
|
||||
| [`ai-agent-design.md`](ai-agent-design.md) | **AI Agent 插件设计**(已按 OPP/1 重写):多模态 LLM 作为外部插件经策展工具面自动剪辑,`render.*` 取帧回喂形成"编辑→看图→再编辑"视觉闭环;事务化编辑、双层确认、声明式 AI 面板、Mock LLM/回放夹具测试、A1–A5 里程碑 | external-plugin-system P1–P3 完成(面板需 P4) |
|
||||
| [`external-plugin-system.md`](external-plugin-system.md) | **外部功能插件系统**:插件=独立进程(非库加载),JSON-RPC over stdio 控制面 + shm 数据面(泛化 M15 render-worker 传输);策展宿主 API(事务化可撤销编辑、取帧回喂 AI)、声明式/像素面双 UI 路径、能力位与确认模式;含与 ai-agent-design.md 的关系与 P1–P6 里程碑 | 已解锁(RIIR + M15 完成),随时启动 |
|
||||
| [`external-plugin-protocol.md`](external-plugin-protocol.md) | **插件协议规范 OPP/1**:NDJSON 分帧 + JSON-RPC 2.0 双向信封、握手/心跳/关闭、全量方法/事件/错误码、编辑事务协议、shm 数据面(无头部无锁)、声明式与像素面 UI 协议、限流配额、版本演进规则、AI 粗剪报文示例 | 随 external-plugin-system 启动 |
|
||||
| [`completed/external-plugin-system.md`](completed/external-plugin-system.md) | **外部功能插件系统**:插件=独立进程(非库加载),JSON-RPC over stdio 控制面 + shm 数据面(泛化 M15 render-worker 传输);策展宿主 API(事务化可撤销编辑、取帧回喂 AI)、声明式/像素面双 UI 路径、能力位与确认模式;含与 ai-agent-design.md 的关系与 P1–P6 里程碑 | 已解锁(RIIR + M15 完成),随时启动 |
|
||||
| [`completed/external-plugin-protocol.md`](completed/external-plugin-protocol.md) | **插件协议规范 OPP/1**:NDJSON 分帧 + JSON-RPC 2.0 双向信封、握手/心跳/关闭、全量方法/事件/错误码、编辑事务协议、shm 数据面(无头部无锁)、声明式与像素面 UI 协议、限流配额、版本演进规则、AI 粗剪报文示例 | 随 external-plugin-system 启动 |
|
||||
| [`render-pipeline-threads.md`](render-pipeline-threads.md) | **渲染管线改造**:单解码线程 + 单渲染线程 + 主进程上屏(GPU 单队列,多进程无意义);解码硬解优先且零拷贝(FFmpeg hwaccel 经 DMA-BUF/DXGI/IOSurface/CUDA 导入,CPU 解码上传仅 fallback,手写 GPU 解码为次选);OpenFX 收编进唯一隔离进程;decode→render→present 三队列流水线;内置效果全 GPU 零拷贝;resolve 重写为 match+Job 单循环并升级为 Job 图(GraphInput/GraphOutput 虚拟端点可见、禁删,从输入节点 Kahn 形态 BFS 至全部分支汇聚输出节点);M0a–M5 里程碑 | 已解锁,随时启动(M0a 独立先行) |
|
||||
| [`test-coverage-90-80.md`](test-coverage-90-80.md) | **测试覆盖率提升(行 ≥90% / 分支 ≥80%)**:测试分两层——单元测试 + 模块边界集成测试;层 2 要求每个模块边界 API 都有正常/异常全矩阵;层 1 可豁免过于简单的函数但仍覆盖正常/异常;覆盖率进 CI(cargo-llvm-cov + nightly `--branch`,逐 crate 地板 + PR diff coverage ratchet);M0 度量基建 → M1 单测 → M2 边界 → M3 app → M4 平台 → M5 收官 | render-pipeline-threads M5 完成(已有基线留档 `render-pipeline-threads-m5-branch-coverage.txt`) |
|
||||
|
||||
|
||||
## 其他参考
|
||||
|
||||
- 覆盖率批次未提交测试的 review 报告(假测试与实现语义核查):
|
||||
[`test-coverage-90-80-review.md`](test-coverage-90-80-review.md)
|
||||
- 构建:`docs/zh/build.md`、`docs/zh/build_macos-zh.md`
|
||||
- 工程文件:`docs/zh/project-file-reference.md`
|
||||
- 代码风格与 Google Test 要求:`CONTRIBUTING.md`(仓库根)
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
> AI 能力现在是一个**外部功能插件**:独立进程、经 OPP/1 协议操作 Oak。
|
||||
>
|
||||
> 依赖文档(冲突时以它们为准):
|
||||
> - [`external-plugin-system.md`](external-plugin-system.md)——插件系统总体设计
|
||||
> - [`completed/external-plugin-system.md`](completed/external-plugin-system.md)——插件系统总体设计
|
||||
> (进程模型、能力位、确认模式、里程碑 P1–P6)
|
||||
> - [`external-plugin-protocol.md`](external-plugin-protocol.md)——**OPP/1 协议全文**
|
||||
> - [`completed/external-plugin-protocol.md`](completed/external-plugin-protocol.md)——**OPP/1 协议全文**
|
||||
> (方法/事件/事务/shm/UI 的冻结定义,本文引用的 §n 均指该文档)
|
||||
>
|
||||
> **一句话**:多模态 LLM 跑在一个独立插件进程里,经 OPP/1 的策展宿主 API
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
> (Wayland color-management-v1 / macOS layer.colorspace / Windows
|
||||
> SetColorSpace1),UI 保持 sRGB 不进 ACEScg。实际色彩数学在
|
||||
> `crates/oak-common/src/colormath.rs`,显示策略在
|
||||
> `crates/oak-app/src/oakui/displaycolor.rs`,内容色域声明 API 在 gpui 的
|
||||
> `../../../../crates/oak-app/src/oakui/displaycolor.rs`,内容色域声明 API 在 gpui 的
|
||||
> `WindowContentColorspace`/`set_content_colorspace`。本文档仅作历史参考,
|
||||
> 以代码为准。
|
||||
|
||||
+5
-5
@@ -141,7 +141,7 @@ Oak ◄── {"result":{"name":"ai-cut","api":1,"capabilities":[...],
|
||||
不引入 tokio)。
|
||||
- `HostApi`:把插件请求翻译成内部调用(§3),执行前查能力位(§5)。
|
||||
- `PluginPanel`:实现 gpui `DockPanel` 的通用面板壳,注册进
|
||||
`AppPanelRegistry`(`crates/oak-app/src/panels/mod.rs` 目前是硬编码
|
||||
`AppPanelRegistry`(`../../../../crates/oak-app/src/panels/mod.rs` 目前是硬编码
|
||||
panel ids——需加一处"动态 panel 注册"扩展点,这是 app 侧唯一的新机制)。
|
||||
- `ShmPool`:泛化自 `oak-render/src/ipc.rs`。
|
||||
|
||||
@@ -182,7 +182,7 @@ Oak ◄── {"result":{"name":"ai-cut","api":1,"capabilities":[...],
|
||||
| `ui.*` | 见 §4 | `PluginPanel` + gpui_widgets | `ui.panel` |
|
||||
| `edit.*` | `begin` / `commit` / `abort` / `undo` / `redo` | `oak_undo` | 随变更方法 |
|
||||
|
||||
**取帧→AI 通路**(旗舰用例的关键路径,对齐 `ai-agent-design.md` §2.2):
|
||||
**取帧→AI 通路**(旗舰用例的关键路径,对齐 `../ai-agent-design.md` §2.2):
|
||||
`render.get_frame {sequence, time, max_size}` → 引擎经 ticket/进程池渲染 →
|
||||
BGRA 进 shm 槽 → 返回 `{shm_slot, width, height, format}`;插件侧 SDK 一行
|
||||
`frame.to_png_bytes()`(OIIO/stb_image_write 或 Pillow)即可回喂多模态模型。
|
||||
@@ -265,7 +265,7 @@ AI 剪辑插件的聊天面板、操作日志、确认按钮,这套完全够
|
||||
- **能力位**:manifest `capabilities` 声明,安装/升级时向用户展示差异;
|
||||
`HostApi` 在每次调用入口检查,越权调用返回 `CAPABILITY_DENIED` 并记日志。
|
||||
v1 能力集合即 §3.2 表右列。
|
||||
- **确认模式**(继承 `ai-agent-design.md` §6):`*.edit` 与 `export` 类调用
|
||||
- **确认模式**(继承 `../ai-agent-design.md` §6):`*.edit` 与 `export` 类调用
|
||||
默认弹"插件 X 请求执行:split_clip n17 @ 3/25 [允许] [允许本会话] [拒绝]";
|
||||
用户可在插件设置里改为自动。
|
||||
- **可撤销**:事务分组进 UndoStack,历史面板里显示为"插件名:事务标签",
|
||||
@@ -295,12 +295,12 @@ AI 剪辑插件的聊天面板、操作日志、确认按钮,这套完全够
|
||||
"聊天指令 → get_thumbnails 扫时间线 → 事务化 split/ripple_delete →
|
||||
get_frame 验证"的 AI 粗剪闭环——**它就是 ai-agent-design.md 的落地形态**。
|
||||
|
||||
### 与 `ai-agent-design.md` 的关系
|
||||
### 与 `../ai-agent-design.md` 的关系
|
||||
|
||||
该文档写于 RIIR 拆分前,假设"C ABI 小库 + 引擎内置 MCP server"。RIIR 与
|
||||
M15(渲染进程隔离)完成后,更优路径是:**AI 能力不进引擎,作为一个外部
|
||||
插件**跑在本系统上;MCP 仍可作为该插件对外的协议(插件自己起 MCP server
|
||||
连 LLM 客户端),Oak 内核始终对 AI 无感知。本文落地后,`ai-agent-design.md`
|
||||
连 LLM 客户端),Oak 内核始终对 AI 无感知。本文落地后,`../ai-agent-design.md`
|
||||
的 M1/M2(工具面、取帧通路)由 §3.2 取代,M3(AI 面板)由 §4.1 取代。
|
||||
|
||||
---
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
### 1.1 节点/渲染管线(完全够用)
|
||||
|
||||
- 内置特效 = `oak-node/src/nodes/*.rs` 的 `NodeBehavior` 实现:声明输入(`Input`),
|
||||
`value()` 推 `ShaderJobPayload`(`crates/oak-node/src/jobs.rs`),`shader_code()`
|
||||
`value()` 推 `ShaderJobPayload`(`../../../../crates/oak-node/src/jobs.rs`),`shader_code()`
|
||||
返回 GLSL 片段。渲染端 `crates/oak-render/src/eval.rs::process_shader_job`:
|
||||
编译(naga→WGSL,**不支持 GLSL switch**——新 shader 一律 if/else,教训见提交
|
||||
`37df1d3d3`)、按名绑定全部纹理参数、嵌套 payload 递归(深度上限 8)、
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
- `crates/oak-app/src/oakui/effectchain.rs::addable_effects`:内置(`group: None`)
|
||||
+ OFX 动态条目(`group: Some(子类)`),排序已按组+名字。
|
||||
- `crates/oak-app/src/panels/effect_library.rs`:渲染时组头已存在
|
||||
- `../../../../crates/oak-app/src/panels/effect_library.rs`:渲染时组头已存在
|
||||
(`group_header()`,内置统一一个 "Built-in" 头),**不可折叠**;有搜索框。
|
||||
- 检查器"添加特效"菜单(`panels/inspector.rs:157`)吃同一张 `addable_effects` 表。
|
||||
|
||||
@@ -102,7 +102,7 @@ ClipTest(斑马纹超范围指示)、Matrix3x3/Matrix5x5(通用卷积)
|
||||
像素尺寸参数用 `resolution_in`;采样偏移用中心原点像素空间与否按特效语义——
|
||||
颜色类与坐标无关,几何类参照 transform 的中心原点)。
|
||||
4. `register()` 进 `nodes/mod.rs` 的注册表。
|
||||
5. 单元测试(输入默认值/隐藏标志/job 参数)+ **`crates/oak-render/src/eval.rs`
|
||||
5. 单元测试(输入默认值/隐藏标志/job 参数)+ **`../../../../crates/oak-render/src/eval.rs`
|
||||
GPU 像素测试**(eval_node_row 模式,无 GPU 自动跳过)。颜色类用纯色输入断言
|
||||
输出值;几何/模糊类用点/块图案断言位移/扩散。
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@
|
||||
## 0. 已先行修复(不在本计划范围)
|
||||
|
||||
- 输入框无法输入:参数视图每个引擎 tick 都把引擎值重刷进输入框,击键下一帧即被清掉。
|
||||
已改为聚焦期间跳过重同步(`crates/oak-app/src/panels/ofx_params.rs` sync_values 的
|
||||
已改为聚焦期间跳过重同步(`../../../../crates/oak-app/src/panels/ofx_params.rs` sync_values 的
|
||||
Text 分支,与曲线编辑器拖拽保护同款),含回归测试
|
||||
`text_field_keeps_in_progress_edits_while_focused`。**已提交**(`5f8db8e31`)。
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
### 1.1 节点层
|
||||
|
||||
- `crates/oak-node/src/nodes/textv3.rs`(type id `org.olivevideoeditor.Olive.text3`):
|
||||
- `../../../../crates/oak-node/src/nodes/textv3.rs`(type id `org.olivevideoeditor.Olive.text3`):
|
||||
当前"Text"特效。输入仅 `text_in`(**HTML 原文**,默认值是
|
||||
`<p style='font-size: 72pt; color: white;'>Sample Text</p>`)、`valign_in`、
|
||||
`use_args_in`、`args_in`,外加 ShapeNodeBase 继承的 `pos_in`/`size_in`/`color_in`。
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
### 1.2 素材/时间轴层
|
||||
|
||||
- bin 条目 = 项目根文件夹 `FolderBehavior.children`(`crates/oak-app/src/oakui/projectbrowser.rs`,
|
||||
- bin 条目 = 项目根文件夹 `FolderBehavior.children`(`../../../../crates/oak-app/src/oakui/projectbrowser.rs`,
|
||||
`roots()/children()`,条目 id = 节点 identity,名称 = `core.label`)。
|
||||
- 时间轴接受 bin 拖放:footage 走 `engine.drop_footage_at` →
|
||||
`graphops::place_footage_clip`(footage 节点连到 clip `tex_in`)。**没有**非 footage
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
### 3.2 文本后端(cosmic-text)
|
||||
|
||||
- 新增 `crates/oak-app/src/oakui/textengine.rs`(app 层安装 hook,oak-node 不加依赖):
|
||||
- 新增 `../../../../crates/oak-app/src/oakui/textengine.rs`(app 层安装 hook,oak-node 不加依赖):
|
||||
- 用 lockfile 已有的 `cosmic-text`(在 oak-app 的 Cargo.toml 提升为直接依赖,
|
||||
版本与 gpui 一致 0.19,避免双版本)。
|
||||
- 实现 `measure`/`render` 两个 `fn`,在 `RealEngine::create`(或 app 启动)
|
||||
@@ -0,0 +1,450 @@
|
||||
# M5 阶段性验收:分支覆盖率(branch coverage)留档(平台行未验证)
|
||||
|
||||
> 生成日期:2026-09-17(管线改造 M0a–M5 **阶段性**;M5 未完全关闭)
|
||||
>
|
||||
> **状态说明(2026-09-17 审计后补注)**:
|
||||
>
|
||||
> - 本轮采集在当天的 M5 审计修复(montage staging、导入计数器三态、
|
||||
> planar 表面驻留上限)**之前**;修复后的数字将在下一轮覆盖率门禁重测。
|
||||
> - Windows(D3D11VA)/macOS(IOSurface)两行只有 cfg 代码,**尚未在
|
||||
> 对应平台编译过**,也无硬件实测;平台编译 + 真机测试是 M5 关闭前置。
|
||||
> - P010/HDR 导入未单独实测;平台错误回退分支单机走不到。
|
||||
> - 因此本文件是**阶段性质量快照**,不构成 M5 收官证明。
|
||||
> - **口径勘误(2026-09-17 晚)**:本文件的数字是**陈旧对象集拉低的
|
||||
> 下界**——`target/coverage-obj` 累积了多次构建的测试二进制,同一
|
||||
> 源文件的新旧副本 region 被合并,未执行的旧副本显著拉低行/分支
|
||||
> 比例(实测同一文件:多对象 51% vs 干净对象 95%)。清空测试二进制
|
||||
> 重测后的干净基线为**行 81.72% / 分支 55.45%**
|
||||
> (2026-09-17 干净基线),后续覆盖率门禁一律使用干净对象集;
|
||||
> 详见 `test-coverage-90-80.md` §4.1。
|
||||
>
|
||||
> 工具链:`nightly-2026-07-21`(rustc 1.99.0-nightly,`-Zcoverage-options=branch`)
|
||||
> 采集命令:
|
||||
|
||||
```sh
|
||||
RUSTFLAGS="-Cinstrument-coverage -Zcoverage-options=branch" \
|
||||
LLVM_PROFILE_FILE="$PWD/target/coverage/%p-%m.profraw" \
|
||||
CARGO_TARGET_DIR=target/coverage-obj \
|
||||
cargo +nightly-2026-07-21 test --workspace --no-fail-fast
|
||||
|
||||
~/.rustup/toolchains/nightly-2026-07-21-*/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata \
|
||||
merge -sparse target/coverage/*.profraw -o target/coverage.profdata
|
||||
|
||||
~/.rustup/toolchains/nightly-2026-07-21-*/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov report \
|
||||
-instr-profile=target/coverage.profdata --show-branch-summary \
|
||||
--ignore-filename-regex="(\.cargo|registry/src|rustlib|/gpui/|target/coverage-obj|/tooling/|\.rustup)" \
|
||||
$(find target/coverage-obj/debug/deps -maxdepth 1 -type f -executable)
|
||||
```
|
||||
|
||||
> 口径:仅统计本仓库 `crates/oak-*` 源码(vendored gpui、ocio-rs、Rust 标准库与
|
||||
> 目标目录均已排除)。分支列来自 `-Zcoverage-options=branch` 的分支区域计数;
|
||||
> 硬件导入的真机路径(VAAPI/DMA-BUF)由 `oak-render/tests/footage_import_test.rs`
|
||||
> 覆盖(该二进制随后单独串行补采,保证导入分支计入),其平台错误回退分支
|
||||
> 单机无法全部走到,因此 `gpuinterop.rs` 的分支覆盖率天然偏低。
|
||||
> 本次汇总(项目源码):区域 53.60% / 函数 49.90% / 行 53.15% / **分支 27.94%**。
|
||||
|
||||
> **管线改造关键文件(Regions / Lines / Branches):**
|
||||
|
||||
|
||||
crates/oak-codec/src/gpuinterop.rs 471 164 65.18% 34 7 79.41% 300 98 67.33% 36 18 50.00%
|
||||
crates/oak-codec/src/hwdecode.rs 408 217 46.81% 28 14 50.00% 256 138 46.09% 12 5 58.33%
|
||||
crates/oak-core/src/backend.rs 5977 2997 49.86% 279 142 49.10% 4941 2423 50.96% 178 97 45.51%
|
||||
crates/oak-core/src/backend/external.rs 293 45 84.64% 11 2 81.82% 268 28 89.55% 18 10 44.44%
|
||||
crates/oak-core/src/texture.rs 589 263 55.35% 57 19 66.67% 412 159 61.41% 24 11 54.17%
|
||||
crates/oak-render/src/eval.rs 9865 5441 44.85% 450 261 42.00% 5742 3311 42.34% 510 288 43.53%
|
||||
crates/oak-render/src/pipeline.rs 1226 41 96.66% 78 9 88.46% 807 25 96.90% 108 59 45.37%
|
||||
|
||||
## 全量报告(项目源码过滤后)
|
||||
|
||||
|
||||
|
||||
```
|
||||
Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
crates/oak-app/src/actions.rs 1721 903 47.53% 135 75 44.44% 1027 544 47.03% 48 48 0.00%
|
||||
crates/oak-app/src/app.rs 15900 10379 34.72% 1464 974 33.47% 8754 5782 33.95% 286 286 0.00%
|
||||
crates/oak-app/src/dialogs.rs 10313 6952 32.59% 823 587 28.68% 6336 4284 32.39% 194 194 0.00%
|
||||
crates/oak-app/src/i18n.rs 882 408 53.74% 79 45 43.04% 490 237 51.63% 34 34 0.00%
|
||||
crates/oak-app/src/lib.rs 4 4 0.00% 1 1 0.00% 4 4 0.00% 0 0 -
|
||||
crates/oak-app/src/logging.rs 202 58 71.29% 15 5 66.67% 104 36 65.38% 16 16 0.00%
|
||||
crates/oak-app/src/main.rs 3 3 0.00% 1 1 0.00% 3 3 0.00% 0 0 -
|
||||
crates/oak-app/src/manager.rs 903 450 50.17% 65 36 44.62% 575 291 49.39% 26 26 0.00%
|
||||
crates/oak-app/src/oakui/audio_thread.rs 154 3 98.05% 11 1 90.91% 104 2 98.08% 6 6 0.00%
|
||||
crates/oak-app/src/oakui/component/controls.rs 1233 546 55.72% 78 30 61.54% 782 299 61.76% 122 122 0.00%
|
||||
crates/oak-app/src/oakui/component/menu.rs 1345 678 49.59% 92 52 43.48% 822 401 51.22% 14 14 0.00%
|
||||
crates/oak-app/src/oakui/component/text_input.rs 67 7 89.55% 7 1 85.71% 44 4 90.91% 0 0 -
|
||||
crates/oak-app/src/oakui/displaycolor.rs 595 475 20.17% 46 34 26.09% 378 298 21.16% 50 50 0.00%
|
||||
crates/oak-app/src/oakui/effectchain.rs 3372 1580 53.14% 193 93 51.81% 1726 774 55.16% 98 98 0.00%
|
||||
crates/oak-app/src/oakui/engine.rs 1072 1017 5.13% 215 201 6.51% 1109 1051 5.23% 14 14 0.00%
|
||||
crates/oak-app/src/oakui/frames.rs 219 3 98.63% 8 0 100.00% 120 2 98.33% 8 8 0.00%
|
||||
crates/oak-app/src/oakui/gpu.rs 293 157 46.42% 22 14 36.36% 232 139 40.09% 28 28 0.00%
|
||||
crates/oak-app/src/oakui/graphops.rs 11296 5702 49.52% 792 489 38.26% 5995 3100 48.29% 466 466 0.00%
|
||||
crates/oak-app/src/oakui/icons.rs 70 0 100.00% 6 0 100.00% 57 0 100.00% 2 2 0.00%
|
||||
crates/oak-app/src/oakui/mock.rs 7864 4670 40.62% 777 437 43.76% 5499 3215 41.53% 248 248 0.00%
|
||||
crates/oak-app/src/oakui/mod.rs 54 28 48.15% 6 3 50.00% 24 13 45.83% 0 0 -
|
||||
crates/oak-app/src/oakui/multicam.rs 1135 89 92.16% 64 7 89.06% 646 41 93.65% 92 92 0.00%
|
||||
crates/oak-app/src/oakui/nodegraph.rs 1876 1238 34.01% 133 89 33.08% 1116 731 34.50% 92 92 0.00%
|
||||
crates/oak-app/src/oakui/ofx.rs 1945 1187 38.97% 121 71 41.32% 1079 632 41.43% 74 71 4.05%
|
||||
crates/oak-app/src/oakui/projectbrowser.rs 81 9 88.89% 8 0 100.00% 49 6 87.76% 12 12 0.00%
|
||||
crates/oak-app/src/oakui/real.rs 28448 17333 39.07% 2411 1389 42.39% 16413 10102 38.45% 1180 1180 0.00%
|
||||
crates/oak-app/src/oakui/renderops.rs 6005 3186 46.94% 209 128 38.76% 3461 1921 44.50% 182 182 0.00%
|
||||
crates/oak-app/src/oakui/scopes.rs 180 1 99.44% 7 0 100.00% 96 0 100.00% 0 0 -
|
||||
crates/oak-app/src/oakui/timecode.rs 126 0 100.00% 14 0 100.00% 70 0 100.00% 4 4 0.00%
|
||||
crates/oak-app/src/oakui/transport.rs 244 4 98.36% 25 1 96.00% 138 4 97.10% 6 6 0.00%
|
||||
crates/oak-app/src/oakui/waveform.rs 407 324 20.39% 19 13 31.58% 229 176 23.14% 24 17 29.17%
|
||||
crates/oak-app/src/oakui/waveformsync.rs 167 0 100.00% 10 0 100.00% 91 0 100.00% 12 12 0.00%
|
||||
crates/oak-app/src/panels/commands.rs 877 856 2.39% 88 85 3.41% 459 442 3.70% 8 8 0.00%
|
||||
crates/oak-app/src/panels/effect_library.rs 977 347 64.48% 80 30 62.50% 563 207 63.23% 20 20 0.00%
|
||||
crates/oak-app/src/panels/history.rs 365 141 61.37% 31 12 61.29% 208 75 63.94% 16 16 0.00%
|
||||
crates/oak-app/src/panels/inspector.rs 787 569 27.70% 54 41 24.07% 522 386 26.05% 18 18 0.00%
|
||||
crates/oak-app/src/panels/mod.rs 29 5 82.76% 2 0 100.00% 19 2 89.47% 4 4 0.00%
|
||||
crates/oak-app/src/panels/multicam.rs 736 160 78.26% 48 9 81.25% 413 94 77.24% 54 54 0.00%
|
||||
crates/oak-app/src/panels/node_editor.rs 1961 990 49.52% 148 77 47.97% 1077 550 48.93% 48 48 0.00%
|
||||
crates/oak-app/src/panels/ofx_params.rs 7801 4542 41.78% 467 267 42.83% 4365 2464 43.55% 218 218 0.00%
|
||||
crates/oak-app/src/panels/program_viewer.rs 1907 1430 25.01% 148 114 22.97% 1068 778 27.15% 44 44 0.00%
|
||||
crates/oak-app/src/panels/project_explorer.rs 987 629 36.27% 65 41 36.92% 608 384 36.84% 46 46 0.00%
|
||||
crates/oak-app/src/panels/source_viewer.rs 434 403 7.14% 41 37 9.76% 226 200 11.50% 4 4 0.00%
|
||||
crates/oak-app/src/panels/status_bar.rs 137 9 93.43% 5 1 80.00% 85 11 87.06% 6 6 0.00%
|
||||
crates/oak-app/src/panels/timeline.rs 4453 3064 31.19% 339 255 24.78% 2665 1778 33.28% 96 96 0.00%
|
||||
crates/oak-app/tests/waveform_e2e.rs 52 0 100.00% 3 0 100.00% 24 0 100.00% 0 0 -
|
||||
crates/oak-audio/src/config.rs 69 50 27.54% 4 2 50.00% 31 21 32.26% 0 0 -
|
||||
crates/oak-audio/src/error.rs 61 0 100.00% 5 0 100.00% 41 0 100.00% 0 0 -
|
||||
crates/oak-audio/src/levelmeter.rs 82 1 98.78% 4 0 100.00% 66 1 98.48% 0 0 -
|
||||
crates/oak-audio/src/manager.rs 915 509 44.37% 76 44 42.11% 605 322 46.78% 0 0 -
|
||||
crates/oak-audio/src/outputdevice.rs 435 277 36.32% 30 22 26.67% 296 199 32.77% 0 0 -
|
||||
crates/oak-audio/src/params.rs 78 17 78.21% 7 1 85.71% 54 17 68.52% 0 0 -
|
||||
crates/oak-audio/src/previewdevice.rs 178 47 73.60% 18 4 77.78% 120 29 75.83% 0 0 -
|
||||
crates/oak-audio/src/processor.rs 587 313 46.68% 34 20 41.18% 382 204 46.60% 0 0 -
|
||||
crates/oak-audio/src/synchronizer.rs 32 0 100.00% 2 0 100.00% 38 0 100.00% 10 3 70.00%
|
||||
crates/oak-audio/src/waveform.rs 785 88 88.79% 29 2 93.10% 478 45 90.59% 0 0 -
|
||||
crates/oak-audio/src/waveformsync.rs 268 10 96.27% 6 0 100.00% 201 13 93.53% 0 0 -
|
||||
crates/oak-audio/tests/common/mod.rs 255 127 50.20% 13 7 46.15% 103 51 50.49% 0 0 -
|
||||
crates/oak-audio/tests/golden_test.rs 211 4 98.10% 12 0 100.00% 97 4 95.88% 0 0 -
|
||||
crates/oak-audio/tests/levelmeter_test.rs 123 0 100.00% 8 0 100.00% 63 0 100.00% 0 0 -
|
||||
crates/oak-audio/tests/manager_test.rs 571 248 56.57% 21 8 61.90% 291 120 58.76% 8 4 50.00%
|
||||
crates/oak-audio/tests/processor_test.rs 616 290 52.92% 28 9 67.86% 272 117 56.99% 0 0 -
|
||||
crates/oak-audio/tests/sync_test.rs 252 0 100.00% 16 0 100.00% 131 0 100.00% 2 0 100.00%
|
||||
crates/oak-audio/tests/waveform_test.rs 290 5 98.28% 11 0 100.00% 118 1 99.15% 0 0 -
|
||||
crates/oak-cli/src/cmd/info.rs 234 40 82.91% 17 12 29.41% 119 23 80.67% 22 11 50.00%
|
||||
crates/oak-cli/src/cmd/probe.rs 101 5 95.05% 3 0 100.00% 72 1 98.61% 16 5 68.75%
|
||||
crates/oak-cli/src/cmd/render.rs 256 63 75.39% 7 3 57.14% 150 53 64.67% 44 23 47.73%
|
||||
crates/oak-cli/src/cmd/transcode.rs 345 118 65.80% 14 6 57.14% 229 92 59.83% 64 32 50.00%
|
||||
crates/oak-cli/src/engine.rs 998 328 67.13% 87 33 62.07% 699 253 63.81% 88 52 40.91%
|
||||
crates/oak-cli/src/fmt.rs 148 4 97.30% 18 0 100.00% 149 3 97.99% 10 4 60.00%
|
||||
crates/oak-cli/src/main.rs 66 0 100.00% 2 0 100.00% 38 0 100.00% 10 1 90.00%
|
||||
crates/oak-cli/src/ppm.rs 212 11 94.81% 11 3 72.73% 113 4 96.46% 12 1 91.67%
|
||||
crates/oak-cli/src/wav.rs 238 39 83.61% 17 7 58.82% 114 10 91.23% 8 3 62.50%
|
||||
crates/oak-cli/tests/cli.rs 326 0 100.00% 27 0 100.00% 201 0 100.00% 0 0 -
|
||||
crates/oak-codec/src/audioparams.rs 7 4 42.86% 2 1 50.00% 6 3 50.00% 0 0 -
|
||||
crates/oak-codec/src/conformmanager.rs 276 4 98.55% 17 0 100.00% 202 3 98.51% 10 3 70.00%
|
||||
crates/oak-codec/src/decoder.rs 905 491 45.75% 91 54 40.66% 613 358 41.60% 14 3 78.57%
|
||||
crates/oak-codec/src/encoder.rs 239 74 69.04% 30 19 36.67% 157 58 63.06% 24 9 62.50%
|
||||
crates/oak-codec/src/encodingparams.rs 1046 46 95.60% 47 0 100.00% 770 31 95.97% 142 28 80.28%
|
||||
crates/oak-codec/src/error.rs 68 0 100.00% 5 0 100.00% 45 0 100.00% 0 0 -
|
||||
crates/oak-codec/src/exportcodec.rs 179 0 100.00% 7 0 100.00% 96 0 100.00% 0 0 -
|
||||
crates/oak-codec/src/exportformat.rs 408 24 94.12% 14 0 100.00% 225 17 92.44% 2 0 100.00%
|
||||
crates/oak-codec/src/ffmpeg.rs 7068 4052 42.67% 373 223 40.21% 4328 2442 43.58% 422 215 49.05%
|
||||
crates/oak-codec/src/footagedescription.rs 205 0 100.00% 32 0 100.00% 159 0 100.00% 0 0 -
|
||||
crates/oak-codec/src/frame.rs 449 14 96.88% 41 0 100.00% 253 12 95.26% 32 7 78.12%
|
||||
crates/oak-codec/src/framemanager.rs 221 24 89.14% 18 5 72.22% 109 20 81.65% 4 1 75.00%
|
||||
crates/oak-codec/src/gpuinterop.rs 471 164 65.18% 34 7 79.41% 300 98 67.33% 36 18 50.00%
|
||||
crates/oak-codec/src/hwdecode.rs 408 217 46.81% 28 14 50.00% 256 138 46.09% 12 5 58.33%
|
||||
crates/oak-codec/src/lib.rs 24 14 41.67% 8 5 37.50% 18 10 44.44% 0 0 -
|
||||
crates/oak-codec/src/oiio.rs 239 9 96.23% 35 4 88.57% 200 6 97.00% 0 0 -
|
||||
crates/oak-codec/src/oiioframebridge.rs 394 7 98.22% 12 0 100.00% 240 4 98.33% 20 5 75.00%
|
||||
crates/oak-codec/src/planarfiledevice.rs 338 4 98.82% 16 1 93.75% 154 4 97.40% 16 2 87.50%
|
||||
crates/oak-codec/src/proxymanager.rs 1351 713 47.22% 99 50 49.49% 814 427 47.54% 58 23 60.34%
|
||||
crates/oak-codec/src/realmedia_tests.rs 824 39 95.27% 28 4 85.71% 348 17 95.11% 20 9 55.00%
|
||||
crates/oak-codec/src/task.rs 374 189 49.47% 26 13 50.00% 280 141 49.64% 2 0 100.00%
|
||||
crates/oak-codec/src/testmedia.rs 236 18 92.37% 7 2 71.43% 114 5 95.61% 20 13 35.00%
|
||||
crates/oak-codec/src/timecodemetadata.rs 363 14 96.14% 27 1 96.30% 203 4 98.03% 34 6 82.35%
|
||||
crates/oak-core/src/backend.rs 5977 2997 49.86% 279 142 49.10% 4941 2423 50.96% 178 97 45.51%
|
||||
crates/oak-core/src/backend/external.rs 293 45 84.64% 11 2 81.82% 268 28 89.55% 18 10 44.44%
|
||||
crates/oak-core/src/cancelatom.rs 58 2 96.55% 9 1 88.89% 38 1 97.37% 2 0 100.00%
|
||||
crates/oak-core/src/color.rs 2394 1360 43.19% 175 105 40.00% 1381 757 45.18% 122 64 47.54%
|
||||
crates/oak-core/src/colormath.rs 2904 1335 54.03% 171 76 55.56% 1570 688 56.18% 66 13 80.30%
|
||||
crates/oak-core/src/colortransform.rs 132 0 100.00% 13 0 100.00% 77 0 100.00% 0 0 -
|
||||
crates/oak-core/src/commandlineparser.rs 1245 18 98.55% 59 2 96.61% 517 7 98.65% 26 0 100.00%
|
||||
crates/oak-core/src/commonutil.rs 70 5 92.86% 10 2 80.00% 40 2 95.00% 4 3 25.00%
|
||||
crates/oak-core/src/configstore.rs 5199 2469 52.51% 206 97 52.91% 2151 1000 53.51% 118 15 87.29%
|
||||
crates/oak-core/src/debug.rs 415 181 56.39% 38 16 57.89% 270 116 57.04% 6 1 83.33%
|
||||
crates/oak-core/src/displayicc.rs 1416 824 41.81% 78 47 39.74% 802 462 42.39% 66 16 75.76%
|
||||
crates/oak-core/src/error.rs 67 3 95.52% 7 1 85.71% 47 3 93.62% 0 0 -
|
||||
crates/oak-core/src/ffmpegutils.rs 296 1 99.66% 27 0 100.00% 258 1 99.61% 14 1 92.86%
|
||||
crates/oak-core/src/filefunctions.rs 1784 736 58.74% 81 29 64.20% 911 358 60.70% 72 21 70.83%
|
||||
crates/oak-core/src/frame.rs 68 2 97.06% 8 0 100.00% 54 2 96.30% 8 4 50.00%
|
||||
crates/oak-core/src/handle.rs 58 40 31.03% 13 10 23.08% 58 37 36.21% 8 8 0.00%
|
||||
crates/oak-core/src/lib.rs 3 0 100.00% 1 0 100.00% 3 0 100.00% 0 0 -
|
||||
crates/oak-core/src/lut.rs 227 6 97.36% 14 1 92.86% 120 6 95.00% 2 1 50.00%
|
||||
crates/oak-core/src/miscutils.rs 472 9 98.09% 41 4 90.24% 244 4 98.36% 16 1 93.75%
|
||||
crates/oak-core/src/ocioutils.rs 309 124 59.87% 34 18 47.06% 197 66 66.50% 0 0 -
|
||||
crates/oak-core/src/oiioutils.rs 601 34 94.34% 38 4 89.47% 318 19 94.03% 20 2 90.00%
|
||||
crates/oak-core/src/qtutils.rs 197 10 94.92% 20 1 95.00% 109 5 95.41% 6 3 50.00%
|
||||
crates/oak-core/src/rational.rs 453 27 94.04% 29 0 100.00% 283 19 93.29% 114 65 42.98%
|
||||
crates/oak-core/src/samplefmt.rs 46 7 84.78% 6 0 100.00% 42 7 83.33% 2 2 0.00%
|
||||
crates/oak-core/src/subtitleparams.rs 2368 1021 56.88% 111 43 61.26% 1322 568 57.03% 122 24 80.33%
|
||||
crates/oak-core/src/texture.rs 589 263 55.35% 57 19 66.67% 412 159 61.41% 24 11 54.17%
|
||||
crates/oak-core/src/timerange.rs 190 4 97.89% 22 0 100.00% 131 3 97.71% 36 36 0.00%
|
||||
crates/oak-core/src/videoparams.rs 2772 179 93.54% 171 7 95.91% 1581 99 93.74% 298 83 72.15%
|
||||
crates/oak-core/src/xmlutils.rs 1664 18 98.92% 79 0 100.00% 773 12 98.45% 100 18 82.00%
|
||||
crates/oak-core/tests/core_test.rs 637 0 100.00% 14 0 100.00% 256 0 100.00% 0 0 -
|
||||
crates/oak-ffmpeg-link/src/lib.rs 2 2 0.00% 1 1 0.00% 1 1 0.00% 0 0 -
|
||||
crates/oak-node/src/block.rs 1396 617 55.80% 121 58 52.07% 972 442 54.53% 30 30 0.00%
|
||||
crates/oak-node/src/colormanager.rs 62 5 91.94% 10 1 90.00% 55 5 90.91% 10 1 90.00%
|
||||
crates/oak-node/src/error.rs 57 0 100.00% 6 0 100.00% 42 0 100.00% 0 0 -
|
||||
crates/oak-node/src/factory.rs 104 21 79.81% 19 4 78.95% 72 14 80.56% 10 10 0.00%
|
||||
crates/oak-node/src/folder.rs 133 30 77.44% 19 2 89.47% 105 22 79.05% 20 20 0.00%
|
||||
crates/oak-node/src/footage.rs 1002 151 84.93% 76 17 77.63% 665 97 85.41% 104 104 0.00%
|
||||
crates/oak-node/src/graph.rs 2049 942 54.03% 134 57 57.46% 1149 523 54.48% 108 108 0.00%
|
||||
crates/oak-node/src/handle.rs 52 1 98.08% 6 0 100.00% 59 1 98.31% 8 3 62.50%
|
||||
crates/oak-node/src/id.rs 25 0 100.00% 6 0 100.00% 23 0 100.00% 2 2 0.00%
|
||||
crates/oak-node/src/input.rs 17 3 82.35% 4 1 75.00% 20 3 85.00% 0 0 -
|
||||
crates/oak-node/src/jobs.rs 88 37 57.95% 16 6 62.50% 87 44 49.43% 0 0 -
|
||||
crates/oak-node/src/keyframe.rs 606 297 50.99% 28 12 57.14% 299 147 50.84% 62 62 0.00%
|
||||
crates/oak-node/src/node.rs 495 12 97.58% 87 2 97.70% 418 7 98.33% 36 34 5.56%
|
||||
crates/oak-node/src/nodes/blur.rs 1011 478 52.72% 48 25 47.92% 531 243 54.24% 32 32 0.00%
|
||||
crates/oak-node/src/nodes/checkerboard.rs 371 10 97.30% 19 2 89.47% 221 10 95.48% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/chromakey.rs 807 415 48.57% 39 23 41.03% 485 254 47.63% 0 0 -
|
||||
crates/oak-node/src/nodes/clamp.rs 293 5 98.29% 19 1 94.74% 170 5 97.06% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/colorbars.rs 293 7 97.61% 19 1 94.74% 179 7 96.09% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/colorcorrect.rs 394 5 98.73% 20 1 95.00% 233 5 97.85% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/colordifferencekey.rs 569 301 47.10% 37 22 40.54% 359 193 46.24% 0 0 -
|
||||
crates/oak-node/src/nodes/colormatrix.rs 351 7 98.01% 22 1 95.45% 191 7 96.34% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/compositesource.rs 140 8 94.29% 13 2 84.62% 86 7 91.86% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/cornerpindistortnode.rs 932 496 46.78% 60 35 41.67% 566 305 46.11% 10 10 0.00%
|
||||
crates/oak-node/src/nodes/cropdistortnode.rs 645 228 64.65% 35 15 57.14% 385 114 70.39% 8 8 0.00%
|
||||
crates/oak-node/src/nodes/despill.rs 488 265 45.70% 34 20 41.18% 314 170 45.86% 0 0 -
|
||||
crates/oak-node/src/nodes/dilate.rs 310 5 98.39% 22 1 95.45% 184 5 97.28% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/dirblur.rs 350 4 98.86% 23 1 95.65% 203 4 98.03% 0 0 -
|
||||
crates/oak-node/src/nodes/displaytransform.rs 724 377 47.93% 62 34 45.16% 446 235 47.31% 8 8 0.00%
|
||||
crates/oak-node/src/nodes/dissolve.rs 405 4 99.01% 26 1 96.15% 228 4 98.25% 0 0 -
|
||||
crates/oak-node/src/nodes/dropshadowfilter.rs 531 196 63.09% 28 11 60.71% 300 103 65.67% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/edgedetect.rs 277 4 98.56% 22 1 95.45% 171 4 97.66% 0 0 -
|
||||
crates/oak-node/src/nodes/erode.rs 310 5 98.39% 22 1 95.45% 184 5 97.28% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/flipdistortnode.rs 511 212 58.51% 30 12 60.00% 276 104 62.32% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/gamma.rs 294 5 98.30% 20 1 95.00% 176 5 97.16% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/generatorwithmerge.rs 199 27 86.43% 7 1 85.71% 146 17 88.36% 0 0 -
|
||||
crates/oak-node/src/nodes/grade.rs 355 5 98.59% 19 1 94.74% 211 5 97.63% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/graphendpoints.rs 361 10 97.23% 25 2 92.00% 213 8 96.24% 6 6 0.00%
|
||||
crates/oak-node/src/nodes/group.rs 221 70 68.33% 30 4 86.67% 179 45 74.86% 18 18 0.00%
|
||||
crates/oak-node/src/nodes/invert.rs 294 5 98.30% 18 1 94.44% 200 5 97.50% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/keymix.rs 333 4 98.80% 23 1 95.65% 190 4 97.89% 0 0 -
|
||||
crates/oak-node/src/nodes/mask.rs 712 365 48.74% 33 19 42.42% 453 233 48.57% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/math.rs 950 509 46.42% 54 32 40.74% 592 320 45.95% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/mathbase.rs 3493 1772 49.27% 136 65 52.21% 2358 1198 49.19% 90 90 0.00%
|
||||
crates/oak-node/src/nodes/matrix.rs 844 269 68.13% 48 16 66.67% 508 151 70.28% 18 18 0.00%
|
||||
crates/oak-node/src/nodes/merge.rs 523 270 48.37% 39 22 43.59% 329 173 47.42% 0 0 -
|
||||
crates/oak-node/src/nodes/mirror.rs 346 10 97.11% 19 2 89.47% 198 8 95.96% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/mod.rs 254 112 55.91% 8 7 12.50% 138 66 52.17% 0 0 -
|
||||
crates/oak-node/src/nodes/mosaicfilternode.rs 365 141 61.37% 26 10 61.54% 230 83 63.91% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/multicamnode.rs 1024 550 46.29% 80 44 45.00% 630 339 46.19% 32 32 0.00%
|
||||
crates/oak-node/src/nodes/noise.rs 373 148 60.32% 26 10 61.54% 228 82 64.04% 0 0 -
|
||||
crates/oak-node/src/nodes/ociobase.rs 162 5 96.91% 13 2 84.62% 111 3 97.30% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/ociogradingtransformlinear.rs 1934 1017 47.41% 85 48 43.53% 1238 671 45.80% 26 26 0.00%
|
||||
crates/oak-node/src/nodes/ociogradingtransformlog.rs 1779 948 46.71% 84 47 44.05% 1145 634 44.63% 26 26 0.00%
|
||||
crates/oak-node/src/nodes/ociolut.rs 1464 795 45.70% 87 48 44.83% 883 483 45.30% 26 26 0.00%
|
||||
crates/oak-node/src/nodes/opacity.rs 482 136 71.78% 31 12 61.29% 326 113 65.34% 6 6 0.00%
|
||||
crates/oak-node/src/nodes/pan.rs 665 283 57.44% 29 12 58.62% 341 145 57.48% 14 14 0.00%
|
||||
crates/oak-node/src/nodes/plugin.rs 1167 599 48.67% 97 51 47.42% 726 374 48.48% 22 22 0.00%
|
||||
crates/oak-node/src/nodes/polygon.rs 599 245 59.10% 30 12 60.00% 346 134 61.27% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/position.rs 262 8 96.95% 19 2 89.47% 164 8 95.12% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/premult.rs 325 4 98.77% 23 1 95.65% 192 4 97.92% 0 0 -
|
||||
crates/oak-node/src/nodes/ramp.rs 365 10 97.26% 19 2 89.47% 221 10 95.48% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/rippledistortnode.rs 632 332 47.47% 42 25 40.48% 404 215 46.78% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/saturation.rs 294 5 98.30% 20 1 95.00% 180 5 97.22% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/shapenode.rs 744 392 47.31% 40 23 42.50% 505 269 46.73% 8 8 0.00%
|
||||
crates/oak-node/src/nodes/shapenodebase.rs 96 43 55.21% 11 5 54.55% 61 27 55.74% 0 0 -
|
||||
crates/oak-node/src/nodes/sharpen.rs 270 4 98.52% 21 1 95.24% 167 4 97.60% 0 0 -
|
||||
crates/oak-node/src/nodes/solid.rs 248 100 59.68% 24 9 62.50% 165 59 64.24% 0 0 -
|
||||
crates/oak-node/src/nodes/stroke.rs 563 216 61.63% 30 12 60.00% 299 103 65.55% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/swirldistortnode.rs 683 351 48.61% 40 22 45.00% 402 208 48.26% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/textbackend.rs 119 50 57.98% 10 3 70.00% 131 58 55.73% 0 0 -
|
||||
crates/oak-node/src/nodes/textv1.rs 886 466 47.40% 52 30 42.31% 528 281 46.78% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/textv2.rs 1138 594 47.80% 60 34 43.33% 714 375 47.48% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/textv3.rs 3217 952 70.41% 160 55 65.62% 1837 592 67.77% 78 78 0.00%
|
||||
crates/oak-node/src/nodes/threewaycolor.rs 613 315 48.61% 37 21 43.24% 399 208 47.87% 0 0 -
|
||||
crates/oak-node/src/nodes/tiledistortnode.rs 676 372 44.97% 44 27 38.64% 438 247 43.61% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/timeformat.rs 605 13 97.85% 30 2 93.33% 337 10 97.03% 46 46 0.00%
|
||||
crates/oak-node/src/nodes/timeinput.rs 110 6 94.55% 12 2 83.33% 71 6 91.55% 0 0 -
|
||||
crates/oak-node/src/nodes/timeoffsetnode.rs 395 19 95.19% 29 3 89.66% 235 17 92.77% 6 6 0.00%
|
||||
crates/oak-node/src/nodes/timeremap.rs 337 18 94.66% 25 3 88.00% 212 17 91.98% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/transformdistortnode.rs 1327 721 45.67% 74 41 44.59% 928 499 46.23% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/transitionfx.rs 642 4 99.38% 33 1 96.97% 349 4 98.85% 4 4 0.00%
|
||||
crates/oak-node/src/nodes/transitions.rs 505 4 99.21% 30 1 96.67% 271 4 98.52% 0 0 -
|
||||
crates/oak-node/src/nodes/trigonometry.rs 598 267 55.35% 30 13 56.67% 331 141 57.40% 0 0 -
|
||||
crates/oak-node/src/nodes/unpremult.rs 306 4 98.69% 22 1 95.45% 184 4 97.83% 0 0 -
|
||||
crates/oak-node/src/nodes/valuenode.rs 347 150 56.77% 24 10 58.33% 206 88 57.28% 8 8 0.00%
|
||||
crates/oak-node/src/nodes/volume.rs 657 277 57.84% 29 12 58.62% 337 141 58.16% 6 6 0.00%
|
||||
crates/oak-node/src/nodes/wavedistortnode.rs 576 303 47.40% 40 23 42.50% 358 191 46.65% 2 2 0.00%
|
||||
crates/oak-node/src/nodes/whitebalance.rs 730 379 48.08% 44 24 45.45% 433 226 47.81% 8 8 0.00%
|
||||
crates/oak-node/src/ops.rs 508 397 21.85% 44 39 11.36% 290 229 21.03% 26 16 38.46%
|
||||
crates/oak-node/src/project.rs 735 421 42.72% 51 30 41.18% 440 254 42.27% 20 20 0.00%
|
||||
crates/oak-node/src/sequence.rs 183 9 95.08% 17 1 94.12% 149 7 95.30% 12 12 0.00%
|
||||
crates/oak-node/src/serializer.rs 2046 794 61.19% 116 44 62.07% 1204 493 59.05% 164 164 0.00%
|
||||
crates/oak-node/src/track.rs 427 21 95.08% 51 2 96.08% 322 18 94.41% 48 42 12.50%
|
||||
crates/oak-node/src/traverser.rs 1638 338 79.37% 87 32 63.22% 818 189 76.89% 66 66 0.00%
|
||||
crates/oak-node/src/value.rs 1205 648 46.22% 69 31 55.07% 793 420 47.04% 30 30 0.00%
|
||||
crates/oak-node/tests/engine_units_test.rs 1428 27 98.11% 29 9 68.97% 677 22 96.75% 2 1 50.00%
|
||||
crates/oak-node/tests/factory_smoke_test.rs 102 51 50.00% 6 3 50.00% 44 22 50.00% 0 0 -
|
||||
crates/oak-node/tests/graph_test.rs 656 10 98.48% 17 3 82.35% 184 9 95.11% 28 14 50.00%
|
||||
crates/oak-node/tests/phase2_units_test.rs 1112 13 98.83% 23 3 86.96% 581 10 98.28% 0 0 -
|
||||
crates/oak-node/tests/serializer_test.rs 2736 1214 55.63% 118 55 53.39% 1739 777 55.32% 0 0 -
|
||||
crates/oak-node/tests/structure_test.rs 725 299 58.76% 18 8 55.56% 419 177 57.76% 0 0 -
|
||||
crates/oak-node/tests/traverser_test.rs 554 71 87.18% 39 21 46.15% 278 65 76.62% 0 0 -
|
||||
crates/oak-node/tests/value_keyframe_test.rs 341 8 97.65% 10 0 100.00% 202 4 98.02% 0 0 -
|
||||
crates/oak-otio/src/error.rs 74 2 97.30% 4 0 100.00% 36 0 100.00% 0 0 -
|
||||
crates/oak-otio/src/fcpxml.rs 3009 1165 61.28% 136 50 63.24% 1535 551 64.10% 148 47 68.24%
|
||||
crates/oak-otio/src/lib.rs 11 2 81.82% 2 0 100.00% 6 0 100.00% 0 0 -
|
||||
crates/oak-otio/src/model.rs 920 88 90.43% 99 7 92.93% 634 53 91.64% 18 10 44.44%
|
||||
crates/oak-otio/tests/fcpxml.rs 1384 719 48.05% 28 14 50.00% 720 366 49.17% 0 0 -
|
||||
crates/oak-otio/tests/parity.rs 65 3 95.38% 11 3 72.73% 39 3 92.31% 0 0 -
|
||||
crates/oak-otio/tests/save_parity.rs 100 0 100.00% 3 0 100.00% 62 0 100.00% 0 0 -
|
||||
crates/oak-otio/tests/semantic.rs 225 12 94.67% 5 0 100.00% 102 3 97.06% 0 0 -
|
||||
crates/oak-plugin/src/clip.rs 387 153 60.47% 17 7 58.82% 252 90 64.29% 0 0 -
|
||||
crates/oak-plugin/src/descriptor.rs 89 9 89.89% 9 3 66.67% 49 8 83.67% 0 0 -
|
||||
crates/oak-plugin/src/error.rs 60 0 100.00% 6 0 100.00% 38 0 100.00% 0 0 -
|
||||
crates/oak-plugin/src/gl_bridge.rs 437 383 12.36% 44 32 27.27% 225 175 22.22% 0 0 -
|
||||
crates/oak-plugin/src/host.rs 2578 1421 44.88% 143 90 37.06% 1433 792 44.73% 0 0 -
|
||||
crates/oak-plugin/src/image.rs 432 29 93.29% 23 1 95.65% 253 19 92.49% 0 0 -
|
||||
crates/oak-plugin/src/instance.rs 1553 759 51.13% 94 58 38.30% 1077 565 47.54% 0 0 -
|
||||
crates/oak-plugin/src/lib.rs 15 1 93.33% 1 0 100.00% 13 1 92.31% 2 0 100.00%
|
||||
crates/oak-plugin/src/node.rs 580 26 95.52% 36 7 80.56% 422 14 96.68% 0 0 -
|
||||
crates/oak-plugin/src/node_factory.rs 1986 829 58.26% 101 48 52.48% 1146 450 60.73% 0 0 -
|
||||
crates/oak-plugin/src/param.rs 828 122 85.27% 39 12 69.23% 456 60 86.84% 0 0 -
|
||||
crates/oak-plugin/src/param_curve.rs 812 17 97.91% 43 0 100.00% 474 12 97.47% 0 0 -
|
||||
crates/oak-plugin/src/progress.rs 107 49 54.21% 17 7 58.82% 78 32 58.97% 0 0 -
|
||||
crates/oak-plugin/src/property.rs 98 2 97.96% 19 1 94.74% 69 1 98.55% 0 0 -
|
||||
crates/oak-plugin/src/render.rs 226 31 86.28% 20 10 50.00% 140 38 72.86% 0 0 -
|
||||
crates/oak-plugin/src/render_driver.rs 574 229 60.10% 30 13 56.67% 376 164 56.38% 0 0 -
|
||||
crates/oak-plugin/src/suites/draw.rs 400 7 98.25% 32 1 96.88% 232 5 97.84% 0 0 -
|
||||
crates/oak-plugin/src/suites/gl_render.rs 848 776 8.49% 65 60 7.69% 569 522 8.26% 0 0 -
|
||||
crates/oak-plugin/src/suites/image_effect.rs 1043 580 44.39% 86 46 46.51% 725 387 46.62% 0 0 -
|
||||
crates/oak-plugin/src/suites/interact.rs 1229 506 58.83% 60 18 70.00% 730 315 56.85% 0 0 -
|
||||
crates/oak-plugin/src/suites/memory.rs 125 50 60.00% 18 8 55.56% 104 45 56.73% 0 0 -
|
||||
crates/oak-plugin/src/suites/message.rs 293 12 95.90% 24 5 79.17% 195 7 96.41% 0 0 -
|
||||
crates/oak-plugin/src/suites/mod.rs 441 207 53.06% 35 13 62.86% 275 138 49.82% 0 0 -
|
||||
crates/oak-plugin/src/suites/multithread.rs 399 224 43.86% 56 31 44.64% 272 152 44.12% 0 0 -
|
||||
crates/oak-plugin/src/suites/param.rs 1995 1134 43.16% 131 72 45.04% 1292 715 44.66% 0 0 -
|
||||
crates/oak-plugin/src/suites/parametric.rs 1305 391 70.04% 75 27 64.00% 749 238 68.22% 0 0 -
|
||||
crates/oak-plugin/src/suites/progress.rs 153 30 80.39% 29 6 79.31% 116 25 78.45% 0 0 -
|
||||
crates/oak-plugin/src/suites/property.rs 1064 537 49.53% 97 41 57.73% 747 352 52.88% 0 0 -
|
||||
crates/oak-plugin/src/suites/timeline.rs 136 15 88.97% 20 4 80.00% 101 8 92.08% 0 0 -
|
||||
crates/oak-plugin/tests/colour_test.rs 155 10 93.55% 15 0 100.00% 109 7 93.58% 0 0 -
|
||||
crates/oak-plugin/tests/common/mod.rs 158 100 36.71% 16 11 31.25% 106 67 36.79% 6 3 50.00%
|
||||
crates/oak-plugin/tests/gl_render_test.rs 474 378 20.25% 27 21 22.22% 301 239 20.60% 9 4 55.56%
|
||||
crates/oak-plugin/tests/golden_test.rs 12 12 0.00% 6 6 0.00% 12 12 0.00% 0 0 -
|
||||
crates/oak-plugin/tests/handle_test.rs 35 0 100.00% 3 0 100.00% 23 0 100.00% 0 0 -
|
||||
crates/oak-plugin/tests/interact_test.rs 442 184 58.37% 31 4 87.10% 249 96 61.45% 13 6 53.85%
|
||||
crates/oak-plugin/tests/negotiation_test.rs 204 25 87.75% 18 0 100.00% 137 16 88.32% 16 8 50.00%
|
||||
crates/oak-plugin/tests/node_e2e_test.rs 752 368 51.06% 41 21 48.78% 450 232 48.44% 0 0 -
|
||||
crates/oak-plugin/tests/ofx_roundtrip.rs 74 69 6.76% 5 4 20.00% 35 30 14.29% 0 0 -
|
||||
crates/oak-plugin/tests/property_test.rs 314 4 98.73% 12 0 100.00% 114 0 100.00% 0 0 -
|
||||
crates/oak-plugin/tests/push_button_test.rs 74 6 91.89% 2 0 100.00% 33 4 87.88% 0 0 -
|
||||
crates/oak-plugin/tests/suites_test.rs 1570 787 49.87% 40 20 50.00% 913 458 49.84% 0 0 -
|
||||
crates/oak-render/src/autocacher.rs 891 397 55.44% 80 38 52.50% 538 237 55.95% 22 8 63.64%
|
||||
crates/oak-render/src/cache.rs 1166 166 85.76% 72 13 81.94% 594 93 84.34% 88 28 68.18%
|
||||
crates/oak-render/src/copier.rs 131 27 79.39% 19 3 84.21% 113 31 72.57% 8 3 62.50%
|
||||
crates/oak-render/src/error.rs 36 0 100.00% 3 0 100.00% 26 0 100.00% 0 0 -
|
||||
crates/oak-render/src/eval.rs 9865 5441 44.85% 450 261 42.00% 5742 3311 42.34% 510 288 43.53%
|
||||
crates/oak-render/src/frameio.rs 324 24 92.59% 20 4 80.00% 188 20 89.36% 28 12 57.14%
|
||||
crates/oak-render/src/handle.rs 132 52 60.61% 12 4 66.67% 87 29 66.67% 6 1 83.33%
|
||||
crates/oak-render/src/ipc.rs 3672 1819 50.46% 203 101 50.25% 2282 1111 51.31% 66 22 66.67%
|
||||
crates/oak-render/src/manager.rs 1005 550 45.27% 77 46 40.26% 661 360 45.54% 52 19 63.46%
|
||||
crates/oak-render/src/ofxhost.rs 791 106 86.60% 52 12 76.92% 544 75 86.21% 68 39 42.65%
|
||||
crates/oak-render/src/pipeline.rs 1226 41 96.66% 78 9 88.46% 807 25 96.90% 108 59 45.37%
|
||||
crates/oak-render/src/procpool.rs 4622 2718 41.19% 264 156 40.91% 3059 1792 41.42% 264 241 8.71%
|
||||
crates/oak-render/src/scheduler.rs 1689 893 47.13% 98 55 43.88% 925 495 46.49% 46 7 84.78%
|
||||
crates/oak-render/src/shaderfx.rs 1839 132 92.82% 65 7 89.23% 969 75 92.26% 124 43 65.32%
|
||||
crates/oak-render/src/textengine.rs 856 17 98.01% 48 2 95.83% 508 11 97.83% 108 32 70.37%
|
||||
crates/oak-render/src/ticket.rs 1355 698 48.49% 117 61 47.86% 955 494 48.27% 26 13 50.00%
|
||||
crates/oak-render/src/worker.rs 1227 651 46.94% 98 61 37.76% 822 438 46.72% 38 10 73.68%
|
||||
crates/oak-render/tests/adjustment_layer.rs 378 4 98.94% 9 0 100.00% 223 2 99.10% 0 0 -
|
||||
crates/oak-render/tests/common/mod.rs 272 246 9.56% 51 47 7.84% 210 193 8.10% 2 2 0.00%
|
||||
crates/oak-render/tests/copier_test.rs 313 156 50.16% 18 9 50.00% 196 98 50.00% 0 0 -
|
||||
crates/oak-render/tests/footage_decode_test.rs 149 14 90.60% 6 1 83.33% 87 15 82.76% 0 0 -
|
||||
crates/oak-render/tests/footage_import_test.rs 261 26 90.04% 8 2 75.00% 141 17 87.94% 24 12 50.00%
|
||||
crates/oak-render/tests/graph_render.rs 1566 698 55.43% 40 17 57.50% 962 389 59.56% 26 12 53.85%
|
||||
crates/oak-render/tests/ofxmisc_blur.rs 392 13 96.68% 20 0 100.00% 152 0 100.00% 0 0 -
|
||||
crates/oak-render/tests/ofxmisc_color.rs 318 15 95.28% 15 0 100.00% 166 12 92.77% 16 8 50.00%
|
||||
crates/oak-render/tests/ofxmisc_gen.rs 367 15 95.91% 15 0 100.00% 173 12 93.06% 0 0 -
|
||||
crates/oak-render/tests/ofxmisc_matrix.rs 357 13 96.36% 17 0 100.00% 120 0 100.00% 0 0 -
|
||||
crates/oak-render/tests/ofxmisc_merge.rs 301 17 94.35% 15 0 100.00% 136 14 89.71% 0 0 -
|
||||
crates/oak-render/tests/pipeline_test.rs 224 7 96.88% 4 0 100.00% 121 7 94.21% 0 0 -
|
||||
crates/oak-render/tests/render_threads_test.rs 1674 72 95.70% 91 19 79.12% 996 37 96.29% 0 0 -
|
||||
crates/oak-render/tests/text_outline_glow.rs 331 34 89.73% 17 2 88.24% 127 12 90.55% 0 0 -
|
||||
crates/oak-render/tests/ticket_worker_test.rs 638 301 52.82% 37 15 59.46% 296 131 55.74% 8 2 75.00%
|
||||
crates/oak-render/tests/transition_render.rs 696 19 97.27% 12 0 100.00% 397 7 98.24% 26 9 65.38%
|
||||
crates/oak-render/tests/transitionfx.rs 420 17 95.95% 16 0 100.00% 156 0 100.00% 18 9 50.00%
|
||||
crates/oak-storage/src/backend.rs 9 0 100.00% 3 0 100.00% 18 0 100.00% 0 0 -
|
||||
crates/oak-storage/src/backends/database/migration.rs 25 5 80.00% 3 1 66.67% 17 6 64.71% 0 0 -
|
||||
crates/oak-storage/src/backends/database/mod.rs 3700 2015 45.54% 247 136 44.94% 2220 1155 47.97% 0 0 -
|
||||
crates/oak-storage/src/backends/mod.rs 6 0 100.00% 1 0 100.00% 6 0 100.00% 0 0 -
|
||||
crates/oak-storage/src/backends/otio.rs 749 243 67.56% 60 16 73.33% 450 147 67.33% 0 0 -
|
||||
crates/oak-storage/src/backends/ove_xml.rs 137 17 87.59% 14 3 78.57% 86 9 89.53% 0 0 -
|
||||
crates/oak-storage/src/error.rs 75 0 100.00% 6 0 100.00% 47 0 100.00% 0 0 -
|
||||
crates/oak-storage/src/nodeutil.rs 106 8 92.45% 9 2 77.78% 72 4 94.44% 0 0 -
|
||||
crates/oak-storage/src/registry.rs 199 32 83.92% 31 11 64.52% 133 31 76.69% 0 0 -
|
||||
crates/oak-storage/src/session.rs 14 0 100.00% 4 0 100.00% 12 0 100.00% 0 0 -
|
||||
crates/oak-storage/src/uri.rs 172 3 98.26% 12 0 100.00% 96 1 98.96% 0 0 -
|
||||
crates/oak-storage/src/writethrough.rs 509 440 13.56% 54 46 14.81% 296 255 13.85% 0 0 -
|
||||
crates/oak-storage/tests/common/mod.rs 711 84 88.19% 53 15 71.70% 432 56 87.04% 0 0 -
|
||||
crates/oak-storage/tests/database_pg_test.rs 1444 1382 4.29% 79 64 18.99% 750 701 6.53% 0 0 -
|
||||
crates/oak-storage/tests/database_test.rs 3313 1431 56.81% 127 50 60.63% 1648 708 57.04% 0 0 -
|
||||
crates/oak-storage/tests/storage_test.rs 2267 983 56.64% 98 42 57.14% 1172 505 56.91% 12 3 75.00%
|
||||
crates/oak-task/src/codecbridge.rs 95 95 0.00% 9 9 0.00% 58 58 0.00% 0 0 -
|
||||
crates/oak-task/src/conform.rs 133 102 23.31% 6 5 16.67% 88 69 21.59% 16 10 37.50%
|
||||
crates/oak-task/src/customcache.rs 90 8 91.11% 11 3 72.73% 63 6 90.48% 8 1 87.50%
|
||||
crates/oak-task/src/error.rs 73 0 100.00% 5 0 100.00% 47 0 100.00% 0 0 -
|
||||
crates/oak-task/src/export.rs 728 455 37.50% 29 19 34.48% 481 302 37.21% 58 33 43.10%
|
||||
crates/oak-task/src/handle.rs 51 23 54.90% 6 3 50.00% 51 20 60.78% 6 2 66.67%
|
||||
crates/oak-task/src/manager.rs 266 266 0.00% 34 34 0.00% 175 175 0.00% 2 2 0.00%
|
||||
crates/oak-task/src/nodeops.rs 2390 1832 23.35% 259 194 25.10% 1639 1260 23.12% 176 130 26.14%
|
||||
crates/oak-task/src/precache.rs 69 69 0.00% 5 5 0.00% 41 41 0.00% 0 0 -
|
||||
crates/oak-task/src/project/format.rs 16 1 93.75% 2 0 100.00% 13 3 76.92% 0 0 -
|
||||
crates/oak-task/src/project/import.rs 460 460 0.00% 24 24 0.00% 274 274 0.00% 0 0 -
|
||||
crates/oak-task/src/project/load.rs 51 51 0.00% 6 6 0.00% 39 39 0.00% 0 0 -
|
||||
crates/oak-task/src/project/loadotio.rs 487 487 0.00% 15 15 0.00% 307 307 0.00% 0 0 -
|
||||
crates/oak-task/src/project/save.rs 47 47 0.00% 4 4 0.00% 33 33 0.00% 0 0 -
|
||||
crates/oak-task/src/project/saveotio.rs 874 532 39.13% 48 30 37.50% 512 323 36.91% 56 27 51.79%
|
||||
crates/oak-task/src/proxy.rs 1356 725 46.53% 85 42 50.59% 838 450 46.30% 78 66 15.38%
|
||||
crates/oak-task/src/render.rs 2002 1316 34.27% 110 72 34.55% 1415 919 35.05% 182 98 46.15%
|
||||
crates/oak-task/src/task.rs 184 72 60.87% 26 10 61.54% 129 50 61.24% 16 11 31.25%
|
||||
crates/oak-task/tests/bridge_test.rs 49 2 95.92% 4 0 100.00% 38 3 92.11% 2 1 50.00%
|
||||
crates/oak-task/tests/customcache_test.rs 133 3 97.74% 7 1 85.71% 59 1 98.31% 0 0 -
|
||||
crates/oak-task/tests/export_test.rs 197 8 95.94% 3 0 100.00% 151 3 98.01% 10 5 50.00%
|
||||
crates/oak-task/tests/parity_test.rs 93 0 100.00% 6 0 100.00% 73 0 100.00% 0 0 -
|
||||
crates/oak-task/tests/saveotio_test.rs 317 11 96.53% 7 0 100.00% 205 5 97.56% 0 0 -
|
||||
crates/oak-timeline/src/common.rs 19 19 0.00% 3 3 0.00% 18 18 0.00% 0 0 -
|
||||
crates/oak-timeline/src/error.rs 67 0 100.00% 5 0 100.00% 43 0 100.00% 0 0 -
|
||||
crates/oak-timeline/src/handle.rs 69 22 68.12% 7 2 71.43% 55 17 69.09% 10 8 20.00%
|
||||
crates/oak-timeline/src/marker.rs 566 147 74.03% 91 33 63.74% 426 125 70.66% 0 0 -
|
||||
crates/oak-timeline/src/multicam.rs 2903 1483 48.91% 148 85 42.57% 1409 691 50.96% 0 0 -
|
||||
crates/oak-timeline/src/undocommon.rs 84 24 71.43% 17 5 70.59% 62 15 75.81% 0 0 -
|
||||
crates/oak-timeline/src/undogeneral.rs 2033 1288 36.65% 171 124 27.49% 1346 855 36.48% 0 0 -
|
||||
crates/oak-timeline/src/undopointer.rs 573 396 30.89% 26 16 38.46% 444 326 26.58% 0 0 -
|
||||
crates/oak-timeline/src/undoripple.rs 799 591 26.03% 54 44 18.52% 567 414 26.98% 0 0 -
|
||||
crates/oak-timeline/src/undosplit.rs 382 96 74.87% 35 17 51.43% 236 68 71.19% 0 0 -
|
||||
crates/oak-timeline/src/undotrack.rs 112 84 25.00% 24 18 25.00% 85 63 25.88% 0 0 -
|
||||
crates/oak-timeline/src/util.rs 1866 1145 38.64% 208 128 38.46% 1020 624 38.82% 0 0 -
|
||||
crates/oak-timeline/src/workarea.rs 205 66 67.80% 39 14 64.10% 157 47 70.06% 0 0 -
|
||||
crates/oak-timeline/tests/domain_test.rs 1953 826 57.71% 49 22 55.10% 817 339 58.51% 0 0 -
|
||||
crates/oak-timeline/tests/handle_test.rs 81 1 98.77% 6 0 100.00% 41 0 100.00% 0 0 -
|
||||
crates/oak-timeline/tests/marker_test.rs 1299 658 49.35% 44 23 47.73% 616 308 50.00% 0 0 -
|
||||
crates/oak-timeline/tests/workarea_test.rs 208 8 96.15% 12 1 91.67% 93 1 98.92% 0 0 -
|
||||
crates/oak-undo/src/error.rs 66 9 86.36% 7 1 85.71% 51 9 82.35% 0 0 -
|
||||
crates/oak-undo/src/global.rs 448 21 95.31% 54 8 85.19% 231 10 95.67% 0 0 -
|
||||
crates/oak-undo/src/undocommand.rs 167 2 98.80% 40 0 100.00% 147 2 98.64% 0 0 -
|
||||
crates/oak-undo/src/undostack.rs 160 7 95.62% 18 2 88.89% 127 4 96.85% 0 0 -
|
||||
crates/oak-undo/tests/edge_coverage_test.rs 232 123 46.98% 34 24 29.41% 117 65 44.44% 0 0 -
|
||||
crates/oak-undo/tests/undo_safe_test.rs 1017 498 51.03% 39 18 53.85% 392 186 52.55% 0 0 -
|
||||
crates/oak-worker/src/framecache.rs 331 13 96.07% 24 4 83.33% 182 8 95.60% 12 4 66.67%
|
||||
crates/oak-worker/src/main.rs 144 71 50.69% 11 5 54.55% 98 48 51.02% 8 2 75.00%
|
||||
crates/oak-worker/src/ofx_host.rs 513 417 18.71% 26 20 23.08% 339 272 19.76% 68 65 4.41%
|
||||
crates/oak-worker/src/worker.rs 4699 2534 46.07% 180 106 41.11% 2782 1533 44.90% 188 68 63.83%
|
||||
crates/oak-worker/tests/ofx_host.rs 367 21 94.28% 23 7 69.57% 186 10 94.62% 6 3 50.00%
|
||||
crates/oak-worker/tests/procpool_integration.rs 2627 1402 46.63% 126 89 29.37% 1686 876 48.04% 0 0 -
|
||||
crates/oak-worker/tests/worker.rs 55 0 100.00% 3 0 100.00% 31 0 100.00% 0 0 -
|
||||
examples/simple_player/src/main.rs 3 3 0.00% 1 1 0.00% 3 3 0.00% 0 0 -
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 362437 168169 53.60% 23749 11899 49.90% 214877 100668 53.15% 10714 7720 27.94%
|
||||
```
|
||||
@@ -426,6 +426,127 @@ fallback。** 解码上传与上屏共用一层 `gpuinteop` 抽象,按后端
|
||||
> 可真机验证;CI(lavapipe,无 hwaccel)只跑 fallback、计数器与
|
||||
> 接口单测。
|
||||
|
||||
> **M5 落地回填(2026-09-17)**:
|
||||
>
|
||||
> - **数据面**:`Texture` 新增瞬态变体 `Texture::Planar`(`PlanarFormat`
|
||||
> = NV12/P010,携带 luma/chroma 两个 registry token、YUV 矩阵/范围、
|
||||
> 源 primaries/trc 与 keep-alive guard);`GpuContext::run_planar_yuv_to_rgb`
|
||||
> 是 M2 三平面 pass 的双平面(NV12/P010)变体,8 位输入的窄范围展开由
|
||||
> `YuvTransform::from_matrix_depth(matrix, full_range, 8)` 精确给出
|
||||
> (16 位构造与原公式逐位一致)。
|
||||
> - **解码侧**(`oak-codec/src/gpuinterop.rs`):`try_import_hw_frame` 在
|
||||
> `transfer_to_cpu` **之前**尝试导入;计数器 `HW_IMPORTS` /
|
||||
> `HW_IMPORT_FALLBACKS`,硬解导入路径 `HW_TRANSFERS` 保持 0;连续 8 次
|
||||
> 失败后进程内熔断(单帧失败不污染后续帧)。开关:全局
|
||||
> `GpuDecodeImport` + `OAK_GPU_IMPORT=0`,逐平台
|
||||
> `GpuDecodeImportVaapi` / `GpuDecodeImportD3d11` /
|
||||
> `GpuDecodeImportVideotoolbox`(各自 `OAK_GPU_IMPORT_*` 环境变量)。
|
||||
> **只有 host 安装的共享设备**(`GpuContext::host_gpu_installed`,即 app
|
||||
> 的上屏 device)才走导入:worker/CLI/测试里惰性创建的私有 device 继续
|
||||
> CPU 路径,避免把进程池/导出悄悄拉上 GPU。零拷贝只服务原生尺寸 + F32
|
||||
> 请求(不能缩放/改格式);代理尺寸等按帧回退 staging(解码器会话缓存
|
||||
> 复用同一帧,回退不重解)。
|
||||
> - **平台实现**:
|
||||
> - **Linux(真机验证)**:VAAPI → `av_hwframe_map`(DRM_PRIME) → 每层
|
||||
> dup fd + `VkImportMemoryFdInfoKHR`(`VK_EXT_external_memory_dma_buf`
|
||||
> + `VK_EXT_image_drm_format_modifier`,显式 plane layout)→
|
||||
> `wgpu_hal::vulkan::texture_from_raw` + `create_texture_from_hal`;
|
||||
> 导入的 VkImage/内存由 wgpu-hal 的 drop callback 释放,AVFrame 的引用
|
||||
> 作为 guard 一并持有到 GPU 用完。NVDEC/CUDA 表面没有公开句柄导出,按
|
||||
> 帧回退 staging;因此 Linux 设备候选顺序改为 **VAAPI 优先、CUDA 兜底**
|
||||
> (§3.6 的"优先通用 DMA-BUF"),本机 RTX 5070 Ti + nvidia-vaapi-driver
|
||||
> 实测 NV12 block-linear modifier 导入可用。
|
||||
> - **Windows(cfg 隔离,待 CI 编译验证)**:D3D11VA 纹理经
|
||||
> `IDXGIResource1::CreateSharedHandle` 取 NT 句柄 → 手建多平面
|
||||
> NV12/P010 VkImage(`VK_KHR_external_memory_win32` 导入句柄)→
|
||||
> 同一纹理注册 `Plane0`/`Plane1` 两个 token;COM 侧在 oak-codec,
|
||||
> Vulkan 侧在 oak-core。
|
||||
> - **macOS(cfg 隔离,待 CI 编译验证)**:VideoToolbox 的 CVPixelBuffer
|
||||
> → `CVPixelBufferGetIOSurface` → `newTextureWithDescriptor:iosurface:plane:`
|
||||
> 两个平面 Metal 纹理 → `wgpu_hal::metal::texture_from_raw`;Metal 纹理
|
||||
> 无 drop callback,帧引用经 `ImportedHwFrame::keep_alive` 挂在
|
||||
> `PlanarTexture` 上随纹理释放。
|
||||
> - **渲染侧**(`oak-render/eval.rs`):`render_footage_frame` 把 planar
|
||||
> 变体在渲染线程解析为工作空间 RGBA —— YUV→RGB pass + 源→工作空间变换
|
||||
> (legacy sRGB 直通;ACEScg 下按 (primaries, trc) 把
|
||||
> `colormath::decode_to_acescg` 烘焙成 3D LUT 在 GPU 应用,缓存 16 个);
|
||||
> 解析失败按帧回退 CPU staging(import 关掉重解一次,解码器缓存兜底)。
|
||||
> 图/蒙太奇/导出等消费者只会看到 `Gpu`/`Cpu`。
|
||||
> - **一个必要修复**:ffmpeg-next 的 `Video::clone` 用 `av_frame_copy` 深拷
|
||||
> 数据,**不会**复制硬件表面引用(克隆的 VAAPI 帧 transfer 报 EINVAL)。
|
||||
> 硬解帧缓存改用内部 `RefFrame`(`av_frame_ref` 语义)持有。
|
||||
> - **验收**:`oak-render/tests/footage_import_test.rs`(真机 RTX 5070 Ti):
|
||||
> 导入路径 `HW_TRANSFERS==0`、结果 `Texture::Gpu`、与 staging 逐像素
|
||||
> max diff < 0.15(swscale 色度滤波差异,同硬解/软解测试口径);ACEScg
|
||||
> 下与 CPU 精确变换 max diff 0.011(LUT 三线性插值);已知红蓝图案断言。
|
||||
> `gpuinterop` 单测覆盖"无 host device 不导入/开关关闭/位深";oak-core
|
||||
> 单测覆盖 8/16 位变换系数;montage 原生尺寸 + host GPU 回归测试见下。
|
||||
> 全 workspace `cargo test --workspace` 全绿(全部测试套件)。
|
||||
> - **遗留(M5 未完全关闭)**:Windows(D3D11VA 共享句柄)/macOS
|
||||
> (IOSurface)两行是 cfg 代码,**从未在对应平台编译过**;host 可达性
|
||||
> 与 Windows 数组 slice/feature 门已在桌面审查后修复(见下面"审计修复"
|
||||
> 第 4 条),但平台编译与真机硬件测试仍待补;P010 与 HDR 元数据未单独
|
||||
> 实测;代理尺寸的 GPU 缩放导入(省掉 native→proxy 的回退)未立项。
|
||||
> 本节的"阶段性验收"不等于 M5 收官。
|
||||
|
||||
|
||||
|
||||
> **M5 审计修复(2026-09-17)**:对 M5 落地的自审发现并修复以下问题:
|
||||
>
|
||||
> 1. **montage 静默黑帧(严重,已实机复现并修复)**:`render_footage_frame`
|
||||
> 可返回解析后的 `Texture::Gpu`,而 CPU 蒙太奇合成器只接
|
||||
> `Texture::Cpu`,其余 `_ => continue` 直接跳过该 clip——序列尺寸 ==
|
||||
> 素材原生尺寸 + host GPU 已装 + 硬解 + 线程管线(导出最常见情形)时
|
||||
> 整条序列输出全透明黑且无任何报错。修复:新增
|
||||
> `render_footage_frame_staged`(`DecodeRequest.allow_import=false`
|
||||
> 进 cache key),montage 一律走 staging;合成器遇到意外的 `Gpu`
|
||||
> 纹理显式回读而不是丢弃,`Planar` 则报错。回归测试
|
||||
> `footage_import_test::montage_native_size_with_host_gpu_composites_the_clip`
|
||||
> (先按单素材原生尺寸导入并缓存 planar,再合成 montage,断言图案 +
|
||||
> "无新导入 + 发生 staging transfer")。
|
||||
> 2. **计数器/熔断语义**:NVDEC 设备、平台开关关闭、不可导入的表面布局
|
||||
> 原本都被记成"失败"并喂给连续失败熔断(NVDEC 8 帧后熔断、
|
||||
> `HW_IMPORT_FALLBACKS` 无界增长)。现在平台导入是三态结果:
|
||||
> `Imported / Unsupported / Failed`;只有真正尝试后失败才计
|
||||
> `HW_IMPORT_FALLBACKS` 并参与熔断,新增 `HW_IMPORT_UNSUPPORTED`
|
||||
> 单独观测(含单测)。
|
||||
> 3. **硬件表面驻留**:eval 帧 LRU 只允许最多
|
||||
> `MAX_CACHED_PLANAR_FRAMES = 4` 个 planar 条目(每张经 keep-alive
|
||||
> pin 一个解码器表面);淘汰只丢弃导入,解码器会话缓存仍在,不重解码。
|
||||
> 4. **平台状态如实标注 + 桌面审查修复(2026-09-17 二次)**:
|
||||
> Windows/macOS 两行仍未在对应平台编译;符号级复核(对照本机 registry
|
||||
> 里的 windows 0.62.2 / objc2-metal 0.3.2 / ash 0.38)发现并修复:
|
||||
> - **macOS**:IOSurface/Metal 路径符号全部匹配(`RG8Unorm`/`RG16Unorm`
|
||||
> 命名无误——审查中"应为小写 Rg"的说法经源码核对不成立);
|
||||
> `newTextureWithDescriptor_iosurface_plane`、`texture_from_raw`
|
||||
> 六参签名、`MTLStorageMode::Shared`、P010 MSB 容器与
|
||||
> `from_matrix_depth(16)` 均核对一致。**仍未编译/实测**。
|
||||
> - **Windows 三重失效**(能编译但不可用)已修:
|
||||
> i. **不可达**:`install_shared` 唯一生产调用点(adopt gpui 设备)
|
||||
> 只在 Linux/FreeBSD 编译,Windows/macOS 上 `host_gpu_installed()`
|
||||
> 恒 false,导入路径是死代码。新增
|
||||
> `GpuContext::mark_host_context()` + `oakui::gpu::register_engine_context()`:
|
||||
> 非 Linux 平台的窗口建立时把引擎自建的 shared 上下文登记为 host
|
||||
> 设备(worker/CLI/测试不调用,保持 CPU 路径)。
|
||||
> ii. **feature 门互斥**:host 设备现在是引擎 `create()` 建的,
|
||||
> 会按适配器能力请求 `TEXTURE_FORMAT_NV12/P010`;将来若仍是
|
||||
> adopt 设备而缺 feature,`import_d3d11_shared_texture` 的
|
||||
> State/Invalid 错误现在归类为 `Unsupported`(不计数、不熔断)。
|
||||
> iii. **array slice 丢帧**:FFmpeg D3D11VA 帧是表面数组的 slice
|
||||
> (`data[1]` 在 0..ArraySize-1 循环),原实现只收 slice 0。
|
||||
> 现在导入按 `arrayLayers = ArraySize` 建 VkImage,registry 条目
|
||||
> 携带 `layer`(`GpuTexture.layer`),采样视图用
|
||||
> `base_array_layer`/`array_layer_count: 1` 选中该 slice;视图必须
|
||||
> 显式 `dimension: D2`(wgpu-core 按纹理层数推导 D2Array,不看
|
||||
> view range,否则与 planar pass 的 D2 布局校验冲突);UV token 的
|
||||
> 登记尺寸用 chroma 半尺寸(planar pass 由它推采样比例)。
|
||||
> - **二次桌面复核追加修复**:`DmaBufPlane` 的 re-export 曾漏 cfg
|
||||
> (非 Linux 上 `cargo check` 直接 E0432);`import_iosurface_plane`
|
||||
> 改为 `unsafe fn`(解引用调用方裸 IOSurface 指针,附 `# Safety`)。
|
||||
> 平台编译 + 真机实测仍是 M5 关闭的前置。
|
||||
> 5. **口径与小项**:"94 个测试目标"改称"全部测试套件";P010/HDR 未实测;
|
||||
> Vulkan `initial_layout: UNDEFINED` 的首次 transition 属驱动依赖行为
|
||||
> (本机正确,异驱动出伪影时优先排查这里)。
|
||||
|
||||
### 3.7 resolve 重写(M0a,独立先行)
|
||||
|
||||
@@ -512,6 +633,20 @@ M1(与 M2 可并行);M4 依赖 M2;M5 依赖 M2(YUV→RGB pass 与互
|
||||
|
||||
**全程验收(用户要求)**:M5 完成、整个任务收官后,跑一轮**分支覆盖率**
|
||||
(branch coverage)测量并留档,作为管线改造整体的质量闸门。
|
||||
**阶段性测量已完成(2026-09-17,审计修复之前)**:nightly
|
||||
`-Zcoverage-options=branch` 全 workspace 采集,项目源码(排除 vendored
|
||||
gpui/ocio/标准库)TOTAL = 区域 53.60% / 函数 49.90% / 行 53.15% /
|
||||
**分支 27.94%**;关键文件分支覆盖率:`pipeline.rs` 45.37%、`backend.rs`
|
||||
45.51%、`texture.rs` 54.17%、`eval.rs` 43.53%、`gpuinterop.rs` 50.00%
|
||||
(硬件导入的真机分支;平台错误回退分支单机走不到)。完整报告与采集/合并
|
||||
命令见 `docs/zh/plans/render-pipeline-threads-m5-branch-coverage.txt`。
|
||||
**该轮采集早于 2026-09-17 审计修复(montage/计数器/驻留),且
|
||||
Windows/macOS 行尚未在对应平台编译——它是阶段性质量快照,不构成 M5
|
||||
收官证明;M5 关闭以平台编译与真机平台测试完成为准,届时重测。**
|
||||
另经 2026-09-17 复查:该留档的多对象合并被**陈旧测试二进制**拉低
|
||||
(同文件多对象 51% vs 干净对象 95%),干净重测的基线是
|
||||
**行 81.72% / 分支 55.45%**(见 `test-coverage-90-80.md` §4.1 勘误);
|
||||
覆盖率门禁以干净对象集为准。
|
||||
|
||||
## 5. 不变量与边界
|
||||
|
||||
|
||||
@@ -0,0 +1,722 @@
|
||||
# 未提交测试 Review 报告:假测试与实现语义核查
|
||||
|
||||
> 审查对象:工作区全部未提交改动(HEAD `800011ef7`,2026-09-20 快照;
|
||||
> 63 个修改文件 + 11 个新测试文件,+38180 / −254 行)。
|
||||
> 审查重点(用户指定):**假测试**、**修改实现语义以匹配测试的行为**。
|
||||
> 报告落笔:2026-09-22。配套计划文档:[`test-coverage-90-80.md`](test-coverage-90-80.md)。
|
||||
>
|
||||
> 标注约定:**[实证]** = 审查会话直接核对过代码原文/手算过数值;
|
||||
> **[子代理]** = 深查子代理报告、审查会话抽样复核过关键链条。
|
||||
|
||||
## 0. 结论摘要
|
||||
|
||||
**问题一:是否修改了实现语义以匹配测试?——未发现。**
|
||||
全部 254 行删除/修改逐条核对:生产侧改动要么是有设计文档回填的 M5
|
||||
零拷贝功能开发,要么是与文档契约对齐的**真 bug 修复**(`ForceParams`
|
||||
默认值、`clip.rs::store_output_image`),没有一处是"为了让测试通过而
|
||||
扭曲实现"。
|
||||
|
||||
**问题二:是否存在假测试?——大部分是真测试,但确认 4 组高危 + 10 项中危。**
|
||||
最严重的不是传统意义的"无断言测试",而是两类更隐蔽的模式:
|
||||
|
||||
1. **测试固化既有实现缺陷**:约 12 个 `undocommands_test.rs` /
|
||||
`graphops.rs` 测试把 `block.rs` setter 语义互换缺陷的反向行为
|
||||
(roll 不 roll、slide 不 slide、负时间线坐标、块重叠)写成精确期望值
|
||||
(§3.1)——测试向实现投降,而非实现向契约收敛。
|
||||
2. **"环境容忍"逃逸路径**:`Ok|Err` 双向接受、饥饿即跳过、CI 恒跳过
|
||||
(§3.2–§3.4)——产品回归与环境污染不可区分,验收测试在门禁 job
|
||||
里静默空转。
|
||||
|
||||
统计:高危 4 组(含 1 个活的产品缺陷)、中危 10 项、低危约 12 项;
|
||||
正面确认(合格项)9 项,见 §6。
|
||||
|
||||
## 1. 审查范围与方法
|
||||
|
||||
- **删除行全查**:`git diff` 的 254 行删除是既有实现语义变更的唯一可能
|
||||
载体,逐条核对并手算验证数值等价性(§2)。
|
||||
- **新测试文件全文审查**:11 个 untracked 测试文件(约 6300 行)由三个
|
||||
深查子代理全文通读,审查会话对全部高危论断做了原文复核。
|
||||
- **内联测试**(约 3 万行新增):模式扫描(静默 return、`let _ =` 丢弃
|
||||
结果、`#[ignore]`、sleep、同义反复 matches!、Ok|Err 全收)+ 高风险区
|
||||
抽样精读(`eval.rs`、`ffmpeg.rs`、`worker.rs`、`instance.rs`、
|
||||
`history.rs`、`dialogs.rs`、`controls.rs`)。
|
||||
- **交叉验证**:与 `test-coverage-90-80.md` §7.5 六批自述、
|
||||
`render-pipeline-threads.md` M5 回填逐条对账;CI 配置
|
||||
(`.github/workflows/ci.yml`)核对跳过条件在门禁 job 上是否成立。
|
||||
- 未重新运行测试套件(计划文档声称 3069 passed / 0 failed;静态审查
|
||||
未发现与该声称矛盾之处)。
|
||||
|
||||
## 2. 生产语义核查:全部 254 行删除的定性
|
||||
|
||||
| 改动 | 定性 | 证据 |
|
||||
|---|---|---|
|
||||
| `oak-core/backend.rs`:YUV 矩阵常数(`65535/56064` 等)删除 | **合法泛化** [实证] | 新 `from_matrix_depth` 在 16-bit 下与旧常数逐位一致(`ay = max/(y_white−y_black) = 65535/56064`;full-range 分支 `(1.0, 0.0, 1.0, 32768/65535)` 亦一致),为 M5 NV12/P010 平面导入服务 |
|
||||
| `oak-codec/hwdecode.rs`:Linux 设备顺序 CUDA 优先 → VAAPI 优先 | **有意行为变更** [实证] | CUDA/NVDEC 表面无公开句柄导出,零拷贝只能走 VAAPI DMA-BUF;`render-pipeline-threads.md` M5 回填记录了真机(RTX 5070 Ti + nvidia-vaapi-driver)验证 |
|
||||
| `oak-codec/ffmpeg.rs`:hw transfer / 色彩范围判定 / 帧缓存删除 | **等价重构 + 真修复** [实证] | 范围判定抽成 `frame_colorimetry`(force 优先、YUVJ 判定、`AVCOL_RANGE_JPEG` 分支逐一保留,CPU/GPU 两路共享);`RefFrame`(`av_frame_ref` 语义)修复 ffmpeg-next `Video::clone` 用 `av_frame_copy` 深拷、丢失硬件表面引用(克隆 VAAPI 帧 transfer 报 EINVAL)的真 bug |
|
||||
| `oak-task/render.rs`:`ForceParams` 去 derive、手写 `Default` | **真 bug 修复** [实证] | `derive(Default)` 给出 `force_format = 0`(= `PixelFormat::U8`),违反文档契约 `-1 = off`,会把 F32 管线推向 U8 并在 footage 帧上 panic;测试断言的是文档契约(`render_test.rs:348-351`,注释明示 "not 0 = U8"),非实现现状 |
|
||||
| `oak-plugin/clip.rs`:`store_output_image` 重写 | **真 bug 修复** [实证] | 原实现把像素写入 `texture_get_frame` 的深拷贝,CPU 纹理的插件输出被静默丢弃;现在 CPU 直接回写 `f.data`、GPU 走 upload、Planar 显式报错,与 `render_driver::write_output_frame` 既有修复一致 |
|
||||
| `oak-render/eval.rs`:`DECODED_FRAMES` LRU 值类型 `Frame`→`Texture`、`render_footage_frame_inner`→`_opts(allow_import)` | **M5 功能** [实证] | planar 条目独立上限 4(硬件表面驻留约束);resolve 失败按帧回退 CPU staging(解码器会话缓存兜底,不重解码) |
|
||||
| `oak-render/pipeline.rs`:`DecodeRequest.allow_import` | **M5 功能** [实证] | montage 合成器(CPU 消费者)`false`、footage 路径 `true`,且入缓存键——正面落实计划 §5.2 "staged 请求不得命中导入缓存" 的 M5 审计项 |
|
||||
| `oak-app/dialogs.rs` 测试期望 180→184 | **合法期望修正** [实证] | 高度 SpinBox 的 `SliderModel`(gpui_widgets)以 step=8、min=120 建网格,180 恰在 176/184 中点、向上吸附;控件自身测试已固化 "snapped to the model's step" 契约(`controls.rs:1654/1720`) |
|
||||
| `oak-app/oakui/real.rs` / `worker.rs` / `node_factory.rs` / `ofx.rs` 删除行 | **测试改写**,见 §3.3 / §6 | 回放验收测试弱化(高危);其余为等价重构或断言保留 |
|
||||
|
||||
**流程问题**:M5 功能开发(`gpuinterop.rs`、`backend/external.rs`、
|
||||
`PlanarTexture`、hwdecode 顺序)与六批覆盖率测试**混在同一未提交工作
|
||||
区**。计划 §9 承诺"覆盖率改造不得引入行为变更",混提使该不变量无法被
|
||||
review 验证——本次是人工逐行核对全部删除行才得出"功能与测试可分离"
|
||||
的结论。建议分开提交。
|
||||
|
||||
## 3. 高危问题(合并前应处理)
|
||||
|
||||
### 3.1 🔴 undopointer 族测试固化了一个活的产品缺陷 [实证 + 子代理]
|
||||
|
||||
**根因**(已提交代码,本次 diff 未改动):`oak-node/src/block.rs:93-107`
|
||||
的 `set_length_and_media_out` / `set_length_and_media_in` 相对其声称的
|
||||
C++ parity 语义**正好互换**:
|
||||
|
||||
```rust
|
||||
/// Set the length, keeping the media out anchored (C++
|
||||
/// `Block::set_length_and_media_out`): ...
|
||||
pub fn set_length_and_media_out(&mut self, length: Rational) {
|
||||
let out = self.in_() + self.length();
|
||||
self.range = TimeRange::new(out - length, out); // ← 实际锚定 OUT、移动 IN
|
||||
self.media_in = self.range.in_(); // ← 时间线 in 写进 media_in(坐标空间混淆)
|
||||
}
|
||||
```
|
||||
|
||||
C++ Olive 的 `set_length_and_media_out` 是 IN 锚定、OUT(及 media_out)
|
||||
移动。该互换同时违反三处成文契约:block.rs 自己的 C++ parity 注释、
|
||||
`oak-timeline/src/common.rs:39`("`k_trim_out`: trim the out point")、
|
||||
`graphops.rs:2703-2707`(roll_edit 文档:"the boundary moves without
|
||||
disturbing anything else")。附带缺陷:`media_in := range.in_()` 把媒体
|
||||
入点写成时间线入点;真锚定 media_out 应为 `media_in = media_out - length`。
|
||||
|
||||
**净效果**(`undopointer.rs` 的机械移植在互换后的 setter 上运行):
|
||||
|
||||
- **roll edit 不 roll**:`undocommands_test.rs:625-648`
|
||||
`block_trim_roll_edit_resizes_adjacent_clip` 断言 first=[0,50)、
|
||||
second=[50,100) roll 到 25 后得 **first=[25,50)、second=[50,125)**
|
||||
——接缝 50 纹丝不动,first 的 IN 移动、second 的 OUT 外扩。真 roll
|
||||
应为 first=[0,25)、second=[25,100)。**无偏差标注**;doc 只描述
|
||||
"没有插 gap" 这一表层现象。
|
||||
- **slide 不 slide**:`:736-760` 断言被滑块不动([50,100)),两个邻居
|
||||
反向膨胀,previous 出现**负时间线入点 [-20,50)**。
|
||||
- graphops 内联测试(`graphops.rs:6048-6071`)是**自觉固化**:NOTE 明说
|
||||
"Assert the actual outcome so a future semantic fix has to update this
|
||||
expectation deliberately",并把 `media_in = -2` 写进期望——诚实且有价值
|
||||
(修复时强制改写),但 NOTE 自身措辞也不准(称锚定 follower 的 OUT,
|
||||
断言显示其 OUT 从 20 移到 18、锚定的是 IN)。
|
||||
- 数值例(与 graphops 测试一致):a=[0,10)、b=[10,20) roll 到 12 →
|
||||
a=[-2,10)(负入点、media_in=-2)、b=[10,18),接缝仍在 10,b 尾部反被
|
||||
截掉 2 秒。若 b 还有后继,会产生块重叠/留洞(`undopointer.rs:160-174`
|
||||
的补偿 gap 按 C++ 假设放在 `[out, out+diff)`,与实际移动方向矛盾)。
|
||||
- **缺陷是活的**:`real.rs:4772-4798` 把 UI 事件
|
||||
`TimelineEvent::ClipRollRequested` 直接接到 `graphops::roll_edit`。
|
||||
- 仓库内 `undosplit.rs:200-214`、`undoripple.rs:342-358`、
|
||||
`undogeneral.rs:865-872` 的作者显然发现了互换并做了补偿性选边 + 注释,
|
||||
唯独 undopointer 的 BlockTrim/TrackSlide 与 undogeneral 的
|
||||
Resize/InsertGaps 未补偿。[子代理]
|
||||
|
||||
**加重项** [子代理]:
|
||||
|
||||
- 4 处测试**恰好省略了唯一能暴露矛盾的断言**:`:593-620`(gap=[50,75)
|
||||
与 second=[50,100) 重叠,只断言序号不断言 span)、`:653-708` 两处
|
||||
(被 trim 块 redo 后实为 [-25,50),不断言)、`:861-889`(gap 与 tail
|
||||
重叠,tail 只断言 id)。
|
||||
- **全文件(1488 行、38 测试)无一处断言 trim/slide/ripple/split 后的
|
||||
media_in**,夹具一律 media_in=0、timeline in=0,使两个内容损坏缺陷
|
||||
不可见:(a) `media_in := range.in_()`;(b) `undoripple.rs:342-346`
|
||||
splice 修剪不动 media_in——删除 [25,50) 后余块 [25,75) 实际播放**被删
|
||||
内容**而非后移内容。
|
||||
- `:565-588` 普通 trim 测试的注释把反转当规范写("Trim-out is
|
||||
out-anchored: the clip's in shifts to 25"),与 `common.rs:39` 直接
|
||||
矛盾,会误导后来者。
|
||||
- `:1108-1122` ResizeWithMediaIn:注释说 "keeping the out point fixed",
|
||||
断言却是 in 锚定、out 移动;实现与命令名 `WithMediaIn` 及其 doc
|
||||
(`undogeneral.rs:105-107`)相反。
|
||||
- `:1173-1216` InsertGaps 两测试:既有 gap 向左生长越过插入点并与前块
|
||||
重叠,注释把左向生长表述为预期,而 `undogeneral.rs:866-872` 在另一
|
||||
命令里明说 out-anchored "would push the in point negative"。
|
||||
|
||||
**定性**:作为产品缺陷 **高**(指针编辑族整体反向 + 负坐标 + 重叠 +
|
||||
内容损坏,挂在真实 UI 路径);作为测试问题 **中-高**(graphops 一处是
|
||||
诚实的 characterization test;undocommands_test 多处无标注固化且回避
|
||||
关键断言)。计划文档第四批"记录(未改生产代码)"只登记了 roll_edit
|
||||
一条,实际波及面大得多。
|
||||
|
||||
**修复顺序建议**:先补 `RippleInfo` 公开构造器与 media_in 断言维度,再
|
||||
统一裁决 block.rs:93-107 的语义互换,届时上述期望值按 graphops NOTE 的
|
||||
意图 "deliberately" 改写。
|
||||
|
||||
### 3.2 🔴 `oak-task/tests/render_test.rs:932-951`:全批次唯一"永不失败"的测试 [实证]
|
||||
|
||||
`private_dispatcher_renders_frames_and_audio_through_workers` 对两次真实
|
||||
渲染的结果做双向接受:
|
||||
|
||||
```rust
|
||||
match outcome {
|
||||
Ok(()) => { /* 真断言:order、size、audio */ }
|
||||
Err(error) => {
|
||||
eprintln!("private dispatcher worker render unavailable: {error}; skipping");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`f32_outcome` 同构。Err 分支不区分**环境缺失**(worker 池起不来)与
|
||||
**产品失败**(`"Frame render ticket failed"`、`shm_frame_to_texture` 的
|
||||
BGRA8/F32 转换回归、poll pump 超时、解码失败)——全部放行。一旦 worker
|
||||
二进制存在,本测试**不可能失败**,恰好掩盖它名义上要测的 ShmFrame/
|
||||
ShmAudio 交付缝与 dispatcher teardown 的任何回归。
|
||||
|
||||
叠加 `:881-884` 的"缺二进制即 return"(`locate_oak_worker` 依赖
|
||||
`target/{debug,release}/oak-worker` 已存在,而 `cargo test -p oak-task`
|
||||
不构建同 workspace 的 oak-worker 二进制):定向运行/干净 CI 下长期静默
|
||||
跳过,私有 dispatcher 路径**实际覆盖可能为零**——覆盖率数字虚高的典型
|
||||
来源。
|
||||
|
||||
**修法**:Err 分支按错误内容分流——环境性错误(pool 启动失败)才跳过,
|
||||
产品性错误必须失败;或至少断言 `error` 匹配已知环境错误串。
|
||||
|
||||
### 3.3 🔴 `oak-app/oakui/real.rs`:三个回放验收测试的"饥饿即跳过→通过" [实证]
|
||||
|
||||
program-window、display、source-window 三个验收测试均新增
|
||||
`eprintln! + return`(计为 pass)的逃逸路径:
|
||||
|
||||
- program-window:`pumps == 2000 && filled == 0` 跳过;pump 上限
|
||||
5000→15000。
|
||||
- display:`pumps >= 1200 && peak < 0 && slots == 0` 跳过;原"playhead
|
||||
60→120 间 peak 严格增长"的两点采样断言弱化为"任意时刻 advances > 0
|
||||
一次";pump 上限 9000。
|
||||
- source-window:**跳过条件仅 `pumps == 2000`,不检查槽位数**(real.rs
|
||||
约 :16396)——注释声称 "skip only when the shared pool delivered
|
||||
nothing",但若帧已交付而 `preview_slot_frame` 服务侧有 bug(candidate
|
||||
存在、hit 恒 None),同样被伪装成池饥饿跳过。program-window 至少有
|
||||
`filled == 0` 判别,此处没有。
|
||||
|
||||
**产品真坏(worker 永远交不出帧)与环境保护不可区分**——验收测试失去
|
||||
回归守卫功能。计划文档声称"聚焦运行仍严格断言",但**代码里没有任何
|
||||
机制区分聚焦/全量运行**,该声称不成立。
|
||||
|
||||
**复合隐患** [实证]:`WorkerBinGuard`(`real.rs:8044-8056`、
|
||||
`renderops.rs:3659-3671`)硬编码 `../../target/debug/oak-worker`:
|
||||
|
||||
- coverage job 的 target 目录是 `target/llvm-cov-target/`,干净环境下
|
||||
`target/debug/oak-worker` 不存在;
|
||||
- `procpool.rs:2402` `resolve_worker_bin` 对 `OAK_WORKER_BIN` **不检查
|
||||
存在性**直接采用 → spawn 失败 → 槽位恒空 → 跳过路径必然触发;
|
||||
- 即普通 CI(`cargo test --workspace` 会把 oak-worker 建到
|
||||
`target/debug`)能真跑,**coverage job 里这组验收测试静默空转**——
|
||||
恰好在产出覆盖率数字的那次运行里。
|
||||
|
||||
对照:`procpool.rs:2922` 测试侧 `find_real_worker` 对 env 覆盖做了
|
||||
`p.exists()` 检查,守卫没有。
|
||||
|
||||
**修法**:跳过条件补"槽位已交付但未服务→必须失败"判别(source-window
|
||||
尤其);给严格模式一个真实机制(如 CI 设 `OAK_STRICT_PLAYBACK=1` 时禁止
|
||||
跳过);`WorkerBinGuard` 改为从 `current_exe()` 推导(与
|
||||
`find_real_worker` 一致)。
|
||||
|
||||
### 3.4 🔴 CI 门禁 job 上永久跳过的两组测试 [实证]
|
||||
|
||||
**(a) ICC 门控(`oak-core/color.rs`,17 处跳过)**:`system_icc()`
|
||||
(color.rs:770-783)只探测固定系统路径(macOS ColorSync、Linux
|
||||
colord/ghostscript),而 `ci.yml:46-53` 的 apt 列表**不含任何 ICC 包**
|
||||
→ Linux CI(唯一聚合门禁 job)上恒 None → `display_icc_bgra8_never_outputs_black`
|
||||
(文档自称"viewer 黑屏回归守卫")等测试**永久跳过**,只在非门禁的
|
||||
macOS 周更 job 上真跑。修复便宜:`apt-get install icc-profiles-free`
|
||||
(或 colord),或仓库内置一个小 sRGB ICC 测试资产。
|
||||
|
||||
**(b) footage_import(`oak-render/tests/footage_import_test.rs`)** [子代理,关键链条已复核]:
|
||||
CI 是 lavapipe、无 `/dev/dri`,VAAPI/CUDA 设备创建必败且负缓存进程级
|
||||
粘滞(`hwdecode.rs:197-201`)→ `HW_IMPORTS == 0` → 三个测试恒跳过、
|
||||
cargo 计为 passed、**零断言执行**。加重项:
|
||||
|
||||
- `common/mod.rs:61-71` 的 `gpu_context_for_import()` 直接 `?` 返回
|
||||
None,**绕过了仓库自己的 `OAK_REQUIRE_GPU=1` 硬失败策略**(对照
|
||||
`backend.rs` 的 `gpu_or_skip`/`shared_gpu_or_skip` 会 panic;同目录
|
||||
`render_threads_test.rs:776/824` 用的是合规版本);
|
||||
- 计划文档承诺"跳过不等于通过(报告里单列)"**未实现**——无 `#[ignore]`、
|
||||
无 skip 上报机制,CI 报表里与真跑过的测试不可区分。
|
||||
|
||||
测试本体质量不错(见 §6),问题在门禁信号缺失。M5 真机验收已留档
|
||||
(`render-pipeline-threads-m5-branch-coverage.txt`),但 PR 门禁对该
|
||||
文件恒零信号,应在 CI 报告侧显式标注(warning annotation)或接入计划
|
||||
M4 的平台/真机 job。
|
||||
|
||||
## 4. 中危问题
|
||||
|
||||
| # | 位置 | 问题 | 标注 |
|
||||
|---|---|---|---|
|
||||
| M1 | `manager_test.rs:164-182` ↔ `manager.rs:84-99` | `init()` doc 声称 "Create the singleton **and register the codec task submitter**",实现只置 `codec_submitter_registered: false`;`register_codec_task_submitter` 全仓库**零生产调用点**(仅 codecbridge.rs:94 定义)。测试断言 `Some(false)` 把矛盾固化为"契约"。结合 codecbridge "submission is synchronous" 的过渡契约,判断为文档过期(或注册逻辑缺失),需裁决 | [实证] |
|
||||
| M2 | `render_test.rs:471-494` | `forced_size_and_format_are_applied`:设置了 `force_format = F32`,断言只有 `recorder.frames == vec![(32,32)]`(尺寸);Recorder 不记录像素格式,format 是否应用到交付纹理**不可证伪** | [子代理] |
|
||||
| M3 | `render_test.rs:621-676` | `clip_effect_chain_is_walked_and_bypassed`:enabled=false 与 true 两分支断言**完全相同**(order、frames);若 `clip_effects()` 回归为完全不收集效果链,测试照过。fixture sanity 只验证测试自建图 | [子代理] |
|
||||
| M4 | `writethrough_test.rs:126-161` | `backend_enabled_by_config_binds_and_round_trips` 名义 "round_trips",但**从不读回 sqlite、不断言 `library.db` 文件存在**;write-through 成功仅以 `last_error == None` 反推。`save_project` 退化为静默 no-op 不可检出 | [子代理] |
|
||||
| M5 | `undocommands_test.rs:528-556` | `RippleInfo` 字段私有且**全仓库无公开构造器** → 只能构造空 info → `ripple()` 在 `is_empty()` 守卫处立即 return → "断言状态未变"**不可能失败**;`TrackListRippleToolCommand` 主体约 125 行对集成测试不可达,行为覆盖为 0。测试注释与计划文档均有诚实标注,但覆盖率数字(oak-timeline 90.1%)因此有误导性。根修:给 `RippleInfo` 加公开构造器 | [子代理,构造器缺失已 grep 复核] |
|
||||
| M6 | `loadotio_test.rs:294-310`、`otio_backend_test.rs:388-401` | 两处 FCPXML round-trip 只断言 `sequence_labels == ["Edited"]`;轨道/块/footage 全丢也过(对照 OTIO 版有完整结构断言) | [子代理] |
|
||||
| M7 | `footage_import_test.rs:165` | 导入 on/off 容差 `max_diff < 0.15`,注释两处声称"the same tolerance the hardware-vs-software decode test uses",实际先例(`oak-codec/src/realmedia_tests.rs:567`,未被本次修改)是 **0.08**——引用失实,容差约为先例 2 倍。测试不空洞(图案通道间距 ≥0.65、逐像素 max、test2 ACEScg 用 0.05 且实测 0.011),但应改注释论证放宽理由(swscale 色度滤波 vs GPU 双线性)或对齐 0.08 | [实证:两处阈值均已 grep 核对] |
|
||||
| M8 | 无断言/弱断言冒烟测试 | `worker.rs:3188` `renderer_create_variants_are_tolerant`(**零断言**,纯"不 panic"遍历);`worker.rs:2391` `renderer_creation_falls_back_or_succeeds_headless`(expect + 丢弃 `has_renderer()` 结果);`instance.rs:2123` `trace_probe_branches`(5 个调用仅 1 个断言);`history.rs` `rows_render_and_interact`(`on_menu(MENU_UNDO/REDO)` 只调用不断言效果,如 undo 后条目数应减少);`writethrough_test.rs:232-244`(零断言 + 依赖不受保护的"无残留 binding"前提)。注释均有坦白,但这正是计划 §8.2 自己警告的"为行数写无意义 case"。CI 有 lavapipe + `OAK_REQUIRE_GPU=1`,本可断言确定结果而非"两种结局都接受" | [实证:前四个已读原文] |
|
||||
| M9 | `footage_import_test.rs:136/145、217/226` | `OAK_GPU_IMPORT` 用裸 `set_var`/`remove_var` 非 RAII:中途 `expect("staging decode")` panic 会泄漏 `"0"`;串行锁下**把后续测试的真失败掩蔽成静默跳过**。同文件(render_threads_test)明明有 `SoftwareDecodeGuard` 先例可仿。另 `remove_var` 不恢复外部预设值 | [子代理] |
|
||||
| M10 | `oak-core/src/backend/external.rs` | 611 行 unsafe 平台 FFI(DMA-BUF/D3D11 handle/IOSurface 导入)**零单测**;唯一覆盖是恒跳过的 footage_import(§3.4b)。计划 M4 的平台门禁 job 未接线 | [实证:grep 无 #[test]] |
|
||||
|
||||
## 5. 低危问题(简列)
|
||||
|
||||
- `render_test.rs:352-355`:configurator 边界段(`set_max_inflight(0/
|
||||
usize::MAX)` 等)调用后零断言;`max.max(1)` 钳制无公开 getter 可验。
|
||||
- `render_test.rs:405-428`:名义 "generated **(transparent)** frame"
|
||||
只断言尺寸,不检查像素透明。
|
||||
- `import_test.rs:219-220`:断言消息声称 "fails with Cancelled",实际
|
||||
只 `is_err()`,未 `matches!(Err(Error::Cancelled))`(源码确实返回
|
||||
Cancelled,测试弱化了它)。
|
||||
- `codecbridge_test.rs:142/162/185/205`:失败路径仅 `is_err()` 不断言
|
||||
错误变体/消息,无法区分失败原因(如 bad-output-name 若因 probe 失败
|
||||
而 err 也会通过)。
|
||||
- `precache_test.rs:254-282`:doc 声称验证 window/progress
|
||||
configurators,`set_max_inflight(1)`/`set_native_progress_signalling(false)`
|
||||
设置后零对应断言,其余断言与相邻测试重复。
|
||||
- `task_test.rs:266-292`:setter/getter 回环、`system_time_ms() > 0`、
|
||||
结尾无断言的 `emit_progress(2.0)`。
|
||||
- `writethrough_test.rs:95-105`:null 句柄断言是真的,其后四次
|
||||
bind/unbind/flush 调用零断言。
|
||||
- `otio_backend_test.rs:296-317`:三种非法 URI 仅 `is_err()`,不区分
|
||||
错误原因。
|
||||
- `undocommands_test.rs:428-487`:ripple 删 gap 仅摘成员关系(util.rs
|
||||
文档化偏差),时间线净效果为零;删区域后洞从 [60,80) 迁到 [50,70)、
|
||||
可见时间线无变化——注释只描述机制不评语义。
|
||||
- `gpuinterop.rs:649-652`:`OAK_GPU_IMPORT` set/remove 不恢复外部预设值
|
||||
(有 `lock_tests` 守卫,实际风险低)。
|
||||
- `footage_import_test.rs` `sample()` 未断言 `frame.format == F32` 就按
|
||||
f32 解释字节(对照 render_threads_test.rs:232 有此断言)。
|
||||
- `render_test.rs:891-930`:测试中途 `RenderManager::shutdown()` +
|
||||
env 覆盖,恢复在断言之前——render panic 会泄漏全局状态(后续
|
||||
`render_serial()` 自愈)。
|
||||
|
||||
## 6. 合格项(正面确认,防止误伤)
|
||||
|
||||
1. **`render_threads_test.rs` +30/−0 纯新增**(`git diff --stat` 核对):
|
||||
`assert_same_frame` 仍是严格逐字节相等、无容差;计数器期望
|
||||
(`(6,6,0)`、lru_hits=1/decodes=4)、双侧地面真值图案、时间戳逐帧
|
||||
断言全部保留。旧 flake 靠**消除解码路径分歧**修复(hwdecode 设备负
|
||||
缓存进程级粘滞 → 同进程两侧走不同解码路径),不是放宽容差。
|
||||
2. **`OAK_HWACCEL=0` 软解守卫合规**:该二进制全部 13 个测试第一条语句
|
||||
都是 `let _lock = lock()`,守卫在锁内设置、drop 逆序先恢复 env 再
|
||||
放锁;`hwdecode.rs` 每次开流实时读 env,守卫真实生效。代价(记录):
|
||||
硬解下的管线字节一致性从此无测试,hw/sw 像素等价仅剩
|
||||
`realmedia_tests.rs:504` 一处(0.08 容差,无硬解机器同样跳过)。
|
||||
3. **逐字节比对不是"自己比自己"**:inline 与 pipeline 是两条真实执行
|
||||
机器,两侧用不同文件名隔离 eval/decode 缓存键;footage_import 的
|
||||
on/off 对比同样用 `fs::copy` 换文件名隔离缓存。
|
||||
4. **`worker.rs` "needs 16000 bytes" 断言**:只是提取变量重排,未弱化;
|
||||
`node_factory.rs` 曲线 JSON 断言等价重构 + 补 helper 双分支覆盖。
|
||||
5. **ForceParams 测试断言的是文档契约**(`-1`,注释明示 "not 0 = U8"),
|
||||
与手写 `Default` 及 doc 完全一致——契约验证,非投降。
|
||||
6. **codecbridge 真实 conform 测试是真断言**:两通道 `.pcm` 存在
|
||||
(metadata 失败即 panic)、非空(len>0)、`.working` 已重命名消失;
|
||||
提交为源码确认的同步路径,无竞态。不足(低):未校验 PCM 字节数
|
||||
是否等于预期样本量。
|
||||
7. **loadotio 的 CALLBACK_LOCK 真消除了竞态**:锁覆盖全部回调消费点
|
||||
(XML 路径测试不持锁是正确的——源码确认不触碰回调);`take()`
|
||||
一次性消费 + 毒化锁 `into_inner()` 恢复,残留回调会导致后续测试
|
||||
**响亮失败**(`.expect("loaded project")`)而非静默通过。
|
||||
8. **`eval.rs` OCIO 内联测试抽查质量高**:真 LUT(红通道加倍)、真
|
||||
resolve 管线、逐像素数值断言(0.25→0.5、green 不变、alpha 保持);
|
||||
跳过仅在 OCIO 库缺失时触发,CI 有真实静态 OCIO(`ocio-env.sh` +
|
||||
`OCIO_RS_ENABLE_REAL=1`);GPU 跳过经 `shared_gpu_or_skip` 在
|
||||
`OAK_REQUIRE_GPU=1` 下硬失败,设计正确。
|
||||
9. **`ffmpeg.rs` 内联测试抽查合格**:像素格式映射矩阵、声道布局回退、
|
||||
RefFrame 几何/缓冲共享、打开状态机、跨流检索错误——均有具体期望值。
|
||||
新测试文件无 `#[ignore]`、无 sleep。
|
||||
|
||||
## 7. 建议行动(按优先级)
|
||||
|
||||
1. **裁决 `block.rs:93-107` setter 互换**(产品缺陷,§3.1):修复时按
|
||||
graphops NOTE 的意图 "deliberately" 改写约 12 个期望值;先给
|
||||
`undocommands_test.rs` 的无标注固化处补偏差 NOTE、给全文件补
|
||||
media_in 断言维度、给 `RippleInfo` 加公开构造器(M5)。
|
||||
2. **消灭"双向接受"**(§3.2):`render_test.rs:932` 的 Err 分支按错误
|
||||
内容分流,产品性错误必须失败。
|
||||
3. **修回放验收测试的跳过判别**(§3.3):source-window 补槽位检查;
|
||||
给严格模式真实机制(CI 设 env 禁止跳过);`WorkerBinGuard` 改从
|
||||
`current_exe()` 推导。
|
||||
4. **修 CI 恒跳过**(§3.4):apt 装 ICC 包;`gpu_context_for_import`
|
||||
尊重 `OAK_REQUIRE_GPU`;实现计划承诺的"跳过单列"(CI annotation
|
||||
或汇总)。
|
||||
5. **对齐 `manager.rs::init()` 文档与实现**(M1)。
|
||||
6. 小修批次:M2/M3 补格式与效果链断言、M4 补读回、M7 改容差注释、
|
||||
M9 改 RAII、M8 在 CI 断言确定结果、§5 各项。
|
||||
7. **流程**:M5 功能与覆盖率测试分开提交(§2 末)。
|
||||
|
||||
## 8. 审查局限
|
||||
|
||||
- 内联测试约 3 万行,采取"删除行全查 + 模式扫描全查 + 高风险区抽样
|
||||
精读"策略,未逐行读完;[子代理] 标注项中未注明"已复核"的细节以
|
||||
子代理报告为准。
|
||||
- 未重新运行测试套件与覆盖率;文中覆盖率数字引自计划文档 §7.5 自述。
|
||||
- `block.rs` 互换缺陷的 C++ Olive 原始语义对照基于代码注释与仓库内
|
||||
其他模块(undosplit/undoripple/undogeneral)的补偿性注释推断,未
|
||||
直接核对 C++ 源码。
|
||||
|
||||
## 9. 处理记录(2026-09-22)
|
||||
|
||||
本报告的高/中危与 §5 条目已按下列状态处理;仅 §3.1 的语义裁决按报告
|
||||
建议延后(准备项已落地,修复清单已细化)。
|
||||
|
||||
### §3.1(准备项已落地,语义裁决延后)
|
||||
|
||||
**已用仓库内 C++ 上游源码核准语义**(此前报告 §8 的局限已解除):
|
||||
|
||||
- `.cache/olive-upstream/app/node/block/block.cpp`:`Block::set_length_and_media_out/in`
|
||||
只调用 `set_length_internal(length)`,**从不移动时间线 in/out**;
|
||||
in/out(`in_point_`/`out_point_`)由 Track 的布局(`track.cpp:469-470,514-515,575-579`)
|
||||
按前后块与长度推导。
|
||||
- `.cache/olive-upstream/app/node/block/clip/clip.cpp`(非 reverse 剪辑):
|
||||
- `set_length_and_media_out`:`media_in` **不变**(media out 随长度移动);
|
||||
- `set_length_and_media_in`:`media_in += old_length - length`(media out 固定)。
|
||||
- `.cache/olive-upstream/app/timeline/timelineundopointer.cpp` / `timelineundogeneral.cpp`:
|
||||
`BlockTrimCommand` 的 TrimIn/TrimOut 与 `BlockResize*` 的调用与本仓库一一对应,
|
||||
因此缺陷只在 Rust 的两个 setter(绝对 range 模型把 Track 布局效果错误地编码进
|
||||
setter)。
|
||||
|
||||
**结论:不是两个函数简单对调即可**。同一 C++ 函数在不同命令里需要不同的净时间线
|
||||
锚定:
|
||||
|
||||
| 命令 | 时间线锚定 | media 调整 |
|
||||
|---|---|---|
|
||||
| `BlockResizeCommand` | in 固定、out 移动 | 无 |
|
||||
| `BlockResizeWithMediaInCommand` | in 固定、out 移动 | `media_in += old−new` |
|
||||
| `BlockTrimCommand`(TrimIn) | out 固定、in 移动 | `media_in += old−new` |
|
||||
| `BlockTrimCommand`(TrimOut) | in 固定、out 移动 | 无 |
|
||||
|
||||
另有 `TrackSlide`、`TrackListInsertGaps`、`TrackListRippleToolCommand`、multicam 等
|
||||
调用点与 undosplit/undoripple/undogeneral 的补偿性选边需要一并裁决;应作为独立
|
||||
PR 处理(先按 §7 第 7 条把 M5 与覆盖率测试分开提交)。
|
||||
|
||||
**本批已落地**:
|
||||
|
||||
- `RippleInfo::new(block, append_gap)` + `block()`/`append_gap()` 访问器;
|
||||
`undocommands_test.rs` 新增 2 个真实 info 测试(resize 往返、append_gap
|
||||
插入/撤销),使 `TrackListRippleToolCommand::ripple()` 主体可达(§M5)。
|
||||
- 补齐 `media_in` 断言维度:roll-edit、`BlockResizeWithMediaInCommand` 往返;
|
||||
相关期望值加 **KNOWN-SWAP** 标注(roll、slide、insert-gaps、
|
||||
ResizeWithMediaIn),语义修复时按标注"故意"改写。
|
||||
- 修正 `graphops.rs` 内联测试 NOTE 的措辞(follower 锚定的是 IN,不是 OUT)。
|
||||
|
||||
### 高危(其余三项)
|
||||
|
||||
- **§3.2 ✅**:`render_test.rs` 私有调度器测试的 Err 分支按错误内容分流——
|
||||
仅 `Error::Failed` 且消息以 `"render worker pool"` 开头(池创建/启动失败)
|
||||
或缺少 worker 二进制(`locate_oak_worker` 提前打印跳过)才跳过;产品性错误
|
||||
(`"Frame render ticket failed"`、shm 转换、时间戳等)一律 panic。管理器/
|
||||
环境用 RAII `DispatcherEnvGuard` 恢复,断言前显式 `restore()`;两个交付腿
|
||||
均断言 `formats == [F32]`。
|
||||
- **§3.3 ✅**:三个回放验收测试的跳过条件收紧为**零交付**(`filled`/`delivered`
|
||||
为历史最大值,一旦有过交付就禁用跳过);"交付过但服务/显示从未取用" 走有界
|
||||
失败上限并打印 `serve_misses` 等诊断。新增 `OAK_STRICT_PLAYBACK=1` 严格模式
|
||||
(跳过改为 panic,含 `#[should_panic]` 自测)。`WorkerBinGuard` 改用
|
||||
`renderops::test_worker_bin()` 解析链(已有 env → `current_exe()` 同级 →
|
||||
`target/{debug,release}` 兜底),仅在文件真实存在时设置变量并恢复旧值;
|
||||
`process_backend_preview_path_is_zero_copy` 不再硬编码路径。
|
||||
- **§3.4 ✅**:CI apt 增加 `icc-profiles-free`;同时给 `system_icc()` 补
|
||||
Ubuntu 实际路径 `/usr/share/color/icc/sRGB.icc`(实测 5 个 display-ICC
|
||||
测试真跑,BGRA8 中灰精确为 `[128,128,128,255]`)。`gpu_context_for_import`
|
||||
尊重 `OAK_REQUIRE_GPU=1`(硬失败),所有跳过路径打印 `SKIP:` 标记;文件头注
|
||||
记录 lavapipe CI 恒跳过与真机验收出处。
|
||||
|
||||
### 中危
|
||||
|
||||
- **M1 ✅(裁决:文档化同步契约)**:证据为 C++ `taskmanager.cpp` 仅创建
|
||||
管理器、移植版 codecbridge 的 "submission is synchronous" 契约与
|
||||
`TaskManager::init` 无生产调用点。已把 `manager.rs` 模块/`init`/`shutdown`
|
||||
文档与字段说明改为"不注册",测试断言 `init` 后未注册、且手工翻标志不会安装
|
||||
oakcodec 回调。
|
||||
- **M2 ✅**:`Recorder` 记录 `formats`/首像素;新增生成帧路径的强制 **U8**
|
||||
测试(可证伪),另断言 F32 腿的交付格式。
|
||||
- **M3 ✅**:夹具效果从 Invert 换成 **Opacity = 0**;enabled=true 必须全透明、
|
||||
enabled=false 必须非透明——效果链丢失或忽略 enable 标志都会失败。
|
||||
- **M4 ✅**:writethrough 往返测试插入 `"Written Through"` 文件夹后写穿,断言
|
||||
`library.db` 存在且非空,并用全新 `backend().load_project` 读回 uuid 与标记。
|
||||
- **M5 ✅**:`RippleInfo::new` + `block()`/`append_gap()`,新增 2 个真实 info
|
||||
测试(resize 往返、append_gap 插入/撤销),`ripple()` 主体可达。
|
||||
- **M6 ✅**:两处 FCPXML 往返补齐轨道/块/footage/转场偏移断言
|
||||
(转场居中偏移 `3/8`)。
|
||||
- **M7 ✅**:容差对齐先例 0.08;真机实测 sRGB 0.00878 / ACEScg 0.01141,注释
|
||||
改为正确论证(GPU 双线性色度 vs swscale 滤波)并打印实测值。
|
||||
- **M8 ✅**:`worker.rs` 渲染器变体测试改为结果不变量断言(成功↔`is_open_gl`、
|
||||
失败↔阶段错误串)、`has_renderer()` 与工厂结果一致、崩溃钩子 env 用 RAII、
|
||||
一次性告警补并发存活断言;`instance.rs` 的 5 个 trace 调用全部断言返回值;
|
||||
`history.rs` 断言 undo/redo 后 `history_index` 与 `done` 变化(行数按面板
|
||||
契约保持不变,已在注释说明)。
|
||||
- **M9 ✅**:`StagingDecodeGuard` RAII + 显式 drop;外部预设的 `OAK_GPU_IMPORT`
|
||||
值会被恢复。
|
||||
- **M10 ✅**:`external.rs` 新增测试模块:顶部文档列明未单测的 unsafe 平台体与
|
||||
对应平台 job;4 个测试覆盖纯映射(Vulkan/IOSurface 格式)、参数校验(DMA-BUF
|
||||
零尺寸/非平面格式)与 D2 别名视图回归。
|
||||
|
||||
### 低危 / §5
|
||||
|
||||
- oak-task:`import_test` 断言 `Err(Error::Cancelled)`;`codecbridge_test` 同时
|
||||
断言桥接层消息与直接驱动 `ConformTask`/`ProxyTask` 的路径原因;
|
||||
`precache_test` 用真实运行兑现"窗口/进度"声明;`task_test` 观测进度钳制;
|
||||
`render_test` 的配置器边界、透明帧、shutdown 恢复顺序均已修正。
|
||||
- `gpuinterop.rs`/`footage_import_test.rs` 的 env 泄漏改 RAII(含恢复外部预设)。
|
||||
|
||||
### 追加修复
|
||||
|
||||
- **新暴露 flake**:`app::tests::preferences_general_tab_writes_cache_ahead_and_storage`
|
||||
在满载并行下"点击→按键"焦点交接竞态(1/4 次读到 120)。点击后补一次
|
||||
effect flush + 一帧绘制再派发按键;通过。
|
||||
|
||||
### 验证
|
||||
|
||||
- 各 crate:oak-task 133、oak-storage 74、oak-core 456+12、oak-render 全部、
|
||||
oak-worker 全部、oak-plugin 208+、oak-app lib 544(含 `OAK_STRICT_PLAYBACK=1`
|
||||
一次)、oak-timeline 全部。
|
||||
- 全 workspace 终验(2026-09-22):**104 个测试目标、3179 passed / 0 failed /
|
||||
7 ignored**(ignored 为既有 GPU 门控)。
|
||||
- 覆盖率(插桩终测,干净对象集同口径):区域 93.96%、函数 89.59%、行
|
||||
**93.49%**(180742/193331)、分支 **71.58%**(11805/16491)。分支较修复前
|
||||
微降 0.37pp——本批刻意移除了若干"容忍型/同义反复"的执行路径(§3.3 交付即
|
||||
失败、M3 夹具更换、M8 去重),属测试质量的预期代价。
|
||||
|
||||
## 10. 第二轮全量审查(2026-09-22)
|
||||
|
||||
> 触发:§9 修复完成后,用户要求全量复审。范围:全部未提交改动
|
||||
> (66 文件,+38731/−281),含第七批修复自身。方法:五个深查子代理
|
||||
> 分区逐行通读(oak-app 面板群 19 文件、real.rs/renderops、
|
||||
> oak-render/oak-worker 269 个测试、oak-plugin/oak-codec 约 250 个测试、
|
||||
> oak-task/core/timeline/storage),审查会话对全部高危论断与 24 条修复
|
||||
> 声称的关键链条做了原文实证。标注约定同前([实证]/[子代理])。
|
||||
|
||||
### 10.1 修复声称验证总裁定
|
||||
|
||||
**24 条声称:20 条完全属实,4 条部分属实,0 条虚假陈述。**
|
||||
所有核对到的新断言均为可证伪的真断言。上一轮四个高危全部实质化解:
|
||||
|
||||
- **§3.1**:语义裁决延后**有据**——`.cache/olive-upstream` 的
|
||||
`block.cpp:62-79`(C++ setter 只调 `set_length_internal`,时间线位置
|
||||
由 Track 布局推导)与 `clip.cpp:95-124`(非 reverse 时 media_out 版
|
||||
不动 media_in、media_in 版 `+= old−new`)经原文核对,支持"不是简单
|
||||
对调、需逐命令裁决"的结论;§8 原局限(未核对 C++ 源码)解除。准备
|
||||
项落地:`RippleInfo::new` 被 2 个真实测试使用(resize 往返断言
|
||||
`[-10,100)`+`media_in==-10`、append_gap 断言块数 1→2+Gap 类型,
|
||||
ripple 主体确认可达);KNOWN-SWAP 标注 6 处;`clip_media_in` 断言
|
||||
1→11 处。[实证]
|
||||
- **§3.2**:`worker_pool_environment_error` 分流精确(`Error::Failed` +
|
||||
`"render worker pool"` 前缀,全仓库仅池创建/启动两处产生该前缀,
|
||||
产品错误消息穷举核对均不匹配);`DispatcherEnvGuard` RAII + 断言前
|
||||
显式 restore;两腿断言 `formats == [F32]`。**"永不失败"测试已消灭。**
|
||||
固有残留:worker 存在但握手/协议回归导致 `start()` 失败仍归环境跳过
|
||||
(有打印)。[实证+子代理]
|
||||
- **§3.3**:三验收测试统一"历史零交付才可跳过"(`filled/delivered`
|
||||
取历史最大值,一旦有交付跳过分支永久不可达;source-window 旧缺陷已
|
||||
修);"交付但未服务"走有界 `assert!(pumps < FAIL_PUMPS)` 失败并携
|
||||
`serve_misses` 诊断;`OAK_STRICT_PLAYBACK=1` 严格模式 + 设计正确的
|
||||
`#[should_panic]` 自测;`test_worker_bin()` 解析链(env 存在性过滤→
|
||||
current_exe 同级→target 兜底,`None` 时不动 env)修掉了硬编码复合
|
||||
隐患;早期 playhead 断言修复与生产 prune 语义精确匹配。**残留:
|
||||
ci.yml/cd.yml 均未设置 `OAK_STRICT_PLAYBACK`**——门禁 job 上零交付
|
||||
仍为绿色跳过(可辩护的权衡:全量并行下池饥饿本征 flaky,且兄弟测试
|
||||
对管理器启动失败一律硬失败、worker 全坏会在别处红;但应在文档显式
|
||||
登记该取舍)。[实证+子代理]
|
||||
- **§3.4**:ci.yml 增 `icc-profiles-free`(注释精确指向黑屏守卫)+
|
||||
`system_icc()` 补 `/usr/share/color/icc/sRGB.icc`(该包实际落点)
|
||||
[实证];`gpu_context_for_import` 经 `require_gpu_adapter()` 在
|
||||
`OAK_REQUIRE_GPU=1` 下硬失败,footage_import 三处跳过均带 `SKIP:`,
|
||||
头注如实登记 lavapipe 恒跳过与真机验收出处 [子代理,头注已实证]。
|
||||
残留(低):color.rs(15)/eval.rs(4)/procpool.rs(2) 的旧式 `skipping`
|
||||
打印未统一为 `SKIP:` 标记(CI 上因 ICC/OCIO/二进制修复均不再触发)。
|
||||
- **M1–M10 与低危批**:M1(文档改为事实 + 真注册表查询断言)、M2
|
||||
(Recorder formats + 强制 U8 可证伪测试)、M3(Opacity=0 夹具,双分支
|
||||
断言互斥)、M4(sqlite 落盘 + load_project 读回 uuid/label)、M5、
|
||||
M7(0.08 对齐先例,实测值打印)、M8(history.rs 真撤销栈三维断言;
|
||||
instance.rs 5 个 trace 调用全断言且分支敏感;worker.rs 渲染器不变量
|
||||
+`has_renderer` 一致性+EnvGuard+并发存活)、M9(StagingDecodeGuard
|
||||
恢复外部预设)全部属实。[实证+子代理]
|
||||
- **部分属实 4 条**:
|
||||
1. **M6**:otio_backend_test 全齐(轨道/块/footage/转场 3/8 居中
|
||||
偏移,算术核对正确);loadotio_test 补了轨道/块/footage 但无转场
|
||||
断言(夹具本就无转场)——声称"两处"只兑现一处。
|
||||
2. **M10**:external.rs 顶部文档如实列明未单测平台体;4 测试中 3 个
|
||||
完全真实(Vulkan/IOSurface 格式映射、DMA-BUF 参数校验精确变体);
|
||||
**"D2 别名视图回归"守卫不可证伪**——只对三种别名 `.expect()` 视图
|
||||
创建成功,而删掉生产修复行(external.rs:607 `dimension: Some(D2)`)
|
||||
后 `create_view` 照样成功(派生 D2Array 合法),真正的回归(planar
|
||||
pass 的 D2 layout 校验拒绝 bind group)只在**创建 bind group** 时
|
||||
显现,测试未建 bind group。[实证]
|
||||
3. **M8-worker 残留**:渲染器两测试仍是 Ok|Err 双向接受(错误串前缀
|
||||
对即过),未按 `OAK_REQUIRE_GPU` 分流成确定断言——CI(lavapipe)上
|
||||
"渲染器创建失败"回归不可检出。比 §3.4 已实现的硬失败策略弱一档。
|
||||
4. **§3.3-CI 接线**:见上。
|
||||
- 追加修复核实:`source_monitor` 早期 playhead(属实,与生产 prune
|
||||
语义逐值核对);`preferences_general_tab` 点击→按键竞态(属实,补
|
||||
`run_until_parked`+整帧 draw+再 park 的同步节拍,断言保持严格
|
||||
`==128` 无容差,非弱化;配置键 RAII Restore)。[实证+子代理]
|
||||
- dialogs 184 期望值再确认:gpui_widgets `SliderModel` 吸附实现为
|
||||
`((raw−min)/step).round()`(半值远离零)→ (180−120)/8=7.5→8→184,
|
||||
与控件既有测试固化的契约自洽。[子代理,公式已核对]
|
||||
|
||||
### 10.2 全量深查新发现(第一轮未覆盖区域)
|
||||
|
||||
**高(1 项)**
|
||||
|
||||
| 位置 | 问题 |
|
||||
|---|---|
|
||||
| `panels/inspector.rs:564-568` | **恒真断言**:`assert!(debug_bounds(..).is_none() \|\| ..is_some())` 逻辑上永不失败;该测试设置 `pending_add=Some(0)` 并 draw 后本应断言 add 菜单 `.is_some()`。全工作区唯一一处恒真断言。[实证] |
|
||||
|
||||
**中(12 项)**
|
||||
|
||||
| 位置 | 问题 |
|
||||
|---|---|
|
||||
| `oak-render/cache.rs:999-1023` | mtime 守卫测试同义反复:`validate` 先污染内存使文件与内存恒同构,`load_state` no-op/守卫反转/真跳过三种实现均通过;名义两个行为均不可证伪。修法:两次 load 间 invalidate 内存范围或用干净实例。[实证] |
|
||||
| `pipeline.rs:959` ↔ `eval.rs:5636` | 进程级 working-space 竞态:pipeline 10 个测试 `pin_legacy_working_space` 不取 eval 的模块私有 `WORKING_SPACE_TEST_LOCK`,同一 lib 测试二进制并行——`footage_working_lut` 的 `is_some()` 有真实 flake 窗口。修法:锁提为 crate 级。[实证] |
|
||||
| `eval.rs:1371-1390`(生产) | **M5 planar-resolve 失败→staging 回退分支零覆盖**,且现有测试缝(`decoded_frames` 全局缓存 + `planar_texture()` helper)本可单元级注入;留档"单机走不到"对该分支不成立。M5 最重要容错路径之一。[子代理] |
|
||||
| `oak-app/mock.rs` ↔ `ofx_params.rs:4886/4825` | MockEngine 未实现 `set_effect_param`/`effect_push_button` 的记录与失败注入(计划 M3.4 缺口)→ 两个"路由/点击触发"名义测试不可证伪;生产侧 `let _ =` 丢弃 Err 加剧不可观测。[子代理] |
|
||||
| `controls.rs:1842-1856`(及 1424-1434) | checkbox 键盘测试不订阅 `CheckBoxEvent::Toggled`,只断"状态不变"——space/enter 处理整体失效不可检出(同仓库 ofx_params.rs:2489 有正确示范)。[子代理] |
|
||||
| `displaycolor.rs:558-578` | 缓存/generation 测试用恒真 `>=` 断言,"同 key 命中不重建/换 key 重建"语义均未验证;:594-599 五个指纹调用零断言。[子代理] |
|
||||
| `oakui/gpu.rs` | **全文件零测试**(M5 功能文件):`upload_rgba16f` 参数校验分支(触碰 GPU 前返回)与 `build_display_lut` 纯 CPU 色彩数学均可确定性测试而未测。[子代理] |
|
||||
| `project_explorer.rs:677-733` | RealEngine 菜单/打开/导入段:注释声称四种效果,整段零断言(同文件 mock 版对相同行为逐一断言,证明可断)。[子代理] |
|
||||
| `real.rs:14789` + `:16234` | 代理 drain `matches!(Ready\|Failed)` 双向接受**原样保留**(§9 未声称处理),叠加弱断言后两文件内**无任何测试断言真实转码产出 Ready**——代理生成 happy path 无守卫。[子代理] |
|
||||
| `real.rs:16147-16155` | "注释声称-结果丢弃"假断言:声称"删除后 name/path 查找 miss",两个查询结果 `let _ =` 丢弃。[子代理] |
|
||||
| `renderops.rs:3749` | `ensure_render_manager()` 失败→SKIP+return;同情形 real.rs 一律 panic(10 处)——同仓库双标,管理器 init 回归可被静默跳过。[子代理] |
|
||||
| `undocommands_test.rs:647-648` | KNOWN-SWAP 漏网:注释仍把互换行为写成规范("Trim-out is out-anchored: the clip's in shifts to 25"),与 common.rs:39 及 §9 C++ 裁决表直接矛盾。另 :874/:907、:659-687 三处固化无标注;:820 slide 标注措辞("grow into each other")与断言(next 缩短)不符。[实证] |
|
||||
|
||||
**中低/低(择要)**
|
||||
|
||||
- `hwdecode.rs:331` 全局 `CREATE_ATTEMPTS` 计数器断言未取 `lock_tests`
|
||||
——并发的 ffmpeg 真实媒体测试会递增它,唯一可能产生 CI 间歇红的
|
||||
竞态(VDPAU 选型已封死污染面,仅剩自身受竞态)。[实证+子代理]
|
||||
- `decoder.rs:899`/`encoder.rs:362` 注册表注入还原非 panic 安全
|
||||
(`registry_guard()` 只是锁、Drop 不还原;断言 panic 则 stub 注册表
|
||||
残留进程,后续测试经 poison 恢复静默用假解码器)。[实证]
|
||||
- `node_factory.rs:2206` 只测自建 mock 入口的边界分支(零生产代码);
|
||||
`:1672` 读两次全局计数断言相等(近同义反复 + 无锁 flake);`:2350`
|
||||
无断言尾段;`gl_render.rs:1200` 零断言(注释诚实)。[实证+子代理]
|
||||
- `external.rs:715` DMA-BUF 校验测试自建软跳过不受 `OAK_REQUIRE_GPU`
|
||||
约束(Linux CI 是 Vulkan,不触发)。
|
||||
- `backend.rs:2886` `user_config_env_override` 非 RAII(M9 同类未修到
|
||||
此处);`:3579` `OAK_REQUIRE_GPU` 翻转窗口与 16 个 GPU 测试竞态(仅
|
||||
无 GPU 主机);`:2951` shared-slot 测试锁纪律不一致(潜在)。
|
||||
- `color.rs:1164/1332` if-let 包裹全部断言的静默逃逸(CI 有真 OCIO,
|
||||
应硬断言);OCIO 缺失跳过仍静默(无 eprintln);`:1420` 不持
|
||||
config_lock 且恢复非 RAII。
|
||||
- 裸 `is_err()` 无消息断言(系统性偏弱,非个别假测试):graphops 23
|
||||
个错误矩阵(分支隔离夹具 + 精确成功腿维持可失败性)、real.rs 无工程
|
||||
守卫约 35 处(同文件 :11490 有正确示范)、encodingparams 11 个非法
|
||||
XML(生产明确区分两种失败原因而未断)。
|
||||
- "结果丢弃/弱断言"群:source_viewer.rs:375-454(config 动作前后读取
|
||||
全丢弃、transport 9 个只断 handled)、program_viewer.rs:843(workarea
|
||||
三事件未断)、timeline.rs:2410(约 20 个命令只断 handled 布尔)、
|
||||
app.rs:8786(`exit_action_quits` 零断言)、eval.rs:5467/5557(无断言)
|
||||
/6087(OAK_PERF 名义不符)/5585("and_clears" 半截)、procpool.rs
|
||||
:4752/:4764(smoke/半验注入)、worker.rs:2179(frame_failed 不断错误
|
||||
文本,同族 :2339 证明可断)、nodeops.rs:1332(零断言,名称诚实)、
|
||||
writethrough_test.rs:96/277(§5 指出未修,未声称)、precache "窗口"
|
||||
半边仅 liveness 间接兑现。
|
||||
- env 非 RAII 残留(与已修 M9 同款):ofx.rs:926 `MARKER_ENV`、
|
||||
program_viewer.rs:964 `HOME`、eval.rs:6095 `OAK_PERF`、
|
||||
renderops.rs:2881 配置开关、worker.rs:1992 颜色设置。
|
||||
- 卫生:`crates/oak-task/tarpaulin-report.html` 覆盖率工件混入源码树
|
||||
(内嵌他机绝对路径,不应提交);计划文档"nodeops 32 个"实为 24 个、
|
||||
node_factory/render_driver 的批次计数为组合计(文档口径应注明)。
|
||||
- `ofx_host.rs:68-77` 生产 `emit` 的 `cfg!(test)` 早退:为测试改形的
|
||||
轻微实例(shipping 行为不变,集成测试真管道补偿),记录在案。
|
||||
|
||||
### 10.3 正面确认(防误伤)
|
||||
|
||||
- **无成建制造假**:约 500+ 个新测试中,纯假(恒真/零断言/零生产代码)
|
||||
共 6 个,均有诚实注释或属笔误级;无 `#[ignore]`、无理由 sleep(全部
|
||||
有界轮询+deadline+超时 panic);故障注入类全部真注入且断言注入生效
|
||||
(真 SIGSEGV+marker、/bin/false OFX host→紫帧、假 nvidia-smi 六形态)。
|
||||
- **修复未引入弱化**:preferences 竞态修复是补同步节拍而非放宽容差;
|
||||
render_threads 逐字节断言原样;分支覆盖 −0.37pp 是移除容忍路径的
|
||||
如实代价且已留档解释。
|
||||
- 教科书级真测试代表(各区各选):node_editor.rs:844(绕过面板证明
|
||||
守卫在产品代码)、procpool.rs:4780(PATH 注入六形态+精确换算)、
|
||||
worker.rs:1757(跨进程 shm 游标环游+0xAB 传播)、eval.rs:4415(GPU
|
||||
旋转单像素精确+全帧 lit==1)、clip.rs:600(f16 −0 位级保留)、
|
||||
encodingparams.rs:1096(C ABI offset_of 18 项冻结锁)、app.rs:6610
|
||||
("全分支"名副其实)、dialogs.rs:6483(按键改派+磁盘内容往返)、
|
||||
ofx.rs:920(真插件 marker 参数串+生命周期顺序)、history.rs:325
|
||||
(真引擎撤销栈三维断言)。
|
||||
|
||||
### 10.4 最终判定与建议
|
||||
|
||||
**判定:修复批次诚信且实质有效;工作区达到可提交状态,但下列 8 项
|
||||
建议先修(均为小改动):**
|
||||
|
||||
1. `inspector.rs:564` 恒真断言改 `.is_some()`(一行)。
|
||||
2. `undocommands_test.rs:647` 补 KNOWN-SWAP 标注(并顺手修 :820 措辞、
|
||||
补 :874/:907、:659-687 三处)。
|
||||
3. `cache.rs:999` mtime 测试改为可证伪构造。
|
||||
4. pipeline/eval 的 working-space 锁提为 crate 级共享。
|
||||
5. `external.rs:744` D2 守卫补 bind group 创建(或改名去掉"回归守卫"
|
||||
声称)。
|
||||
6. `real.rs:14789` 代理 drain:至少在转码可用的环境断言 Ready(可按
|
||||
ffmpeg 可用性分流,不可用才容忍 Failed)。
|
||||
7. `renderops.rs:3749` SKIP 改 panic(与 real.rs 对齐)。
|
||||
8. 删除 `crates/oak-task/tarpaulin-report.html`。
|
||||
|
||||
**登记事项(不阻塞提交)**:`OAK_STRICT_PLAYBACK` 的 CI 接线取舍;
|
||||
`hwdecode.rs:331` 补 `lock_tests`(CI 间歇红风险);decoder/encoder
|
||||
注册表还原改 RAII;M5 planar 回退分支注入测试;gpu.rs 纯 CPU 分支
|
||||
补测;MockEngine `set_effect_param` 族记录缺口;旧式 `skipping` 打印
|
||||
统一 `SKIP:` 标记;block.rs setter 语义裁决独立 PR(§9 清单)。
|
||||
|
||||
**提交拆分(重申 §2 末建议)**:M5 功能(gpuinterop/external/Planar/
|
||||
hwdecode 顺序/RefFrame)与覆盖率批次(测试+两处 bug 修复+文档)分开
|
||||
提交;tarpaulin 工件与本报告/计划文档更新可并入文档提交。
|
||||
|
||||
### 10.5 §10.2/§10.4 处理记录(2026-09-22)
|
||||
|
||||
**"建议先修 8 项":全部完成。**
|
||||
|
||||
1. ✅ `inspector.rs` 恒真断言 → 以具有 debug selector 的分组头断言菜单
|
||||
已渲染,并断言 `pending_add == Some(0)` 生效。
|
||||
2. ✅ `undocommands_test.rs` KNOWN-SWAP 标注补齐::647 措辞改为与
|
||||
`common.rs:39`/§9 裁决表一致,:659-687、:874、:907 补标,slide 处
|
||||
措辞修正(next 缩短)。
|
||||
3. ✅ `cache.rs` mtime 守卫测试改为可证伪构造(干净实例装载 + 内存/文件
|
||||
不再恒同构),守卫反转或真跳过都会失败。
|
||||
4. ✅ working-space 锁提升为 crate 级 `eval::working_space_test_lock`,
|
||||
pipeline 与 eval 两侧共同持锁。
|
||||
5. ✅ `external.rs` D2 守卫补 bind group 创建(临时删修复行可复现失败,
|
||||
已还原)。
|
||||
6. ✅ `real.rs` 代理 drain 按 ffmpeg 可达性分流:可达硬断言 `Ready` +
|
||||
`ProxyBadge::Ready`;不可达打印 `SKIP:` 并容忍 `Failed`(两种环境均
|
||||
实测)。
|
||||
7. ✅ `renderops` 的 `ensure_render_manager` 失败测试改为硬断言(仅
|
||||
"管理器已初始化" 保留自保护跳过)。
|
||||
8. ✅ 删除 `crates/oak-task/tarpaulin-report.html`(及其绝对路径泄漏)。
|
||||
|
||||
**中危 12 项:**
|
||||
|
||||
- ✅ MockEngine 记录 `set_effect_param`/`effect_push_button` 调用(含
|
||||
失败注入开关),`ofx_params` 生产侧改错误日志;两个名义测试改为完整
|
||||
路由矩阵 + 类型转换值断言(曲线 JSON 先 `set_points` 再发事件)。
|
||||
- ✅ `controls.rs` checkbox 键盘测试订阅 `CheckBoxEvent::Toggled` 并断言
|
||||
事件序列;space/enter 处理整体失效会失败。
|
||||
- ✅ `displaycolor.rs` generation/链缓存改为精确断言(同 key 不重建、
|
||||
换 key 恰好 +1、指针同一/不同),5 个指纹逐一断言。
|
||||
- ✅ `oakui/gpu.rs` 补 4 个测试:`upload_rgba16f` 参数校验、f16 打包
|
||||
(钳制/字节序/256 对齐行距)、display LUT 网格完整性与确定性、key
|
||||
跟随色彩设置。
|
||||
- ✅ `project_explorer.rs` RealEngine 段补断言(序列切换、导入计数、
|
||||
菜单选择与开关状态、引擎分支前置条件)。
|
||||
- ✅ `real.rs` 两处丢弃的 name/path 查询改为断言;删除后 rename no-op
|
||||
一并断言。
|
||||
- ✅ `hwdecode.rs:331` 取 `lock_tests`;decoder/encoder 注册表注入改
|
||||
RAII `RegistryGuard`(panic 不再泄漏假解码器)。
|
||||
- ✅ `color.rs` if-let 逃逸改硬断言(OCIO 缺失才打印跳过);配置锁
|
||||
RAII。`backend.rs` env 覆盖 RAII、共享上下文测试锁纪律统一、
|
||||
`OAK_REQUIRE_GPU` 竞态窗口消除。
|
||||
- ✅ env 残留 RAII:`ofx.rs` MARKER_ENV、`program_viewer.rs` HOME、
|
||||
`eval.rs` OAK_PERF、`worker.rs` 颜色设置、`renderops.rs` 配置开关。
|
||||
- ✅ 计划文档计数修正(nodeops 32 → 24,组合批次注明口径)。
|
||||
|
||||
**登记(不阻塞提交,遗留项)**:`eval.rs` M5 planar 回退分支注入测试
|
||||
(需要专用测试缝);`node_factory.rs` 三处弱断言与 `gl_render.rs` 零断言;
|
||||
旧式 `skipping` 打印统一 `SKIP:`;`OAK_STRICT_PLAYBACK` 的 CI 接线取舍;
|
||||
`block.rs` setter 语义裁决独立 PR(§9 清单)。
|
||||
|
||||
**验收(2026-09-22)**:全 workspace **104 个测试目标、3185 passed /
|
||||
0 failed / 7 ignored**(ignored 为既有 GPU 门控)。本批生产改动仅
|
||||
`MockEngine` 记录字段与 `ofx_params` 错误日志两处可观测性增强。
|
||||
@@ -0,0 +1,829 @@
|
||||
# 测试覆盖率提升计划:行 ≥90% / 分支 ≥80%(单元 + 模块边界集成双层)
|
||||
|
||||
> 面向实现者的任务书(2026-09-17)。本文只描述方案与工作项,不含已执行的代码修改。
|
||||
>
|
||||
> 用户要求(原文要点):
|
||||
> 1. 测试分两层:**单元测试** + **模块边界处集成测试**。
|
||||
> 2. 层 2:**每个模块边界 API 都要有**集成测试,且覆盖**所有正常和异常情况**。
|
||||
> 3. 层 1:可以排除过于简单的函数,但也要覆盖所有正常和异常情况。
|
||||
> 4. **总体行覆盖率提升至 90% 左右、分支覆盖率提升至 80% 左右**。
|
||||
>
|
||||
> 现状基线(2026-09-17 干净对象集重测,含内联测试):
|
||||
> **行 81.72% / 分支 55.45%**(区域 82.73% / 函数 76.67%),
|
||||
> 全 workspace 全部测试套件全绿,但覆盖率从未进 CI。
|
||||
>
|
||||
> **口径勘误**:此前 M5 留档的 53.15%/27.94% 是在累积了多次构建的
|
||||
> `target/coverage-obj` 上测的——`llvm-cov report` 对同一源文件的多份
|
||||
> 新旧测试二进制副本按 region 合并,大量陈旧副本的未执行 region 拉低
|
||||
> 数字(同一个 `oak-render/src/ipc.rs`:多对象报告 51%,仅该 crate 的
|
||||
> lib 测试对象 95%)。**覆盖率必须在干净对象集上测量**(清空测试
|
||||
> 二进制后重跑,或交给 cargo-llvm-cov 的默认清理),本计划全部数字以
|
||||
> 干净基线为准。
|
||||
|
||||
## 1. 背景与为什么
|
||||
|
||||
M0a–M5 的测试策略是"每个里程碑配验收测试",没有统一的质量闸门:
|
||||
|
||||
- **覆盖面不均**:`oak-cli` 行覆盖 76.7%,而 `oak-app` 只有 40.7%、
|
||||
`oak-task` 35.5%、`oak-timeline` 47.4%;分支覆盖最差的
|
||||
`oak-app/src/oakui/real.rs` 是 **0/1180**(1180 个分支一个没走到),
|
||||
`graphops.rs` 0/466、`app.rs` 0/286。
|
||||
- **测试层次没有定义**:现有 2433 个测试里既有纯单测,也有进程级 e2e,
|
||||
但没有"哪个 API 必须有哪种测试"的书面约定;模块边界(crate 公开 API、
|
||||
IPC/FFI/协议面)的异常分支大量依赖"碰巧被调用到"。
|
||||
- **没有防回退机制**:覆盖率只在 render M5 阶段性验收时手工测过一次,新增代码可以
|
||||
无限制地拉低比例。
|
||||
- **"全绿假绿"已有实例**:M5 审计发现 montage 原生尺寸 + host GPU 时
|
||||
"解码可返回 GPU 纹理、CPU 合成器只接 CPU 纹理"的跨模块组合被整条
|
||||
静默跳过(全透明黑帧),既有 2433 个测试无一覆盖该组合——这正是
|
||||
§2.2 边界矩阵与 §5.2 跨模块清单要消灭的盲区。
|
||||
|
||||
本计划的产出不是"把数字刷上去",而是两件可长期维持的事:
|
||||
|
||||
1. **双层测试规范落地**:单元测试管模块内逻辑;模块边界集成测试锁
|
||||
API 契约与跨模块数据流,两者都按"正常 + 异常"矩阵验收。
|
||||
2. **覆盖率进入 CI 门禁并 ratchet**:聚合行 ≥90%、分支 ≥80%,逐 crate
|
||||
有地板阈值,PR 的**新增/修改行**必须被覆盖(diff coverage),比例只能
|
||||
升不能降。
|
||||
|
||||
全量覆盖 90%/80% 的工作量估算(按 2026-09-17 干净基线):
|
||||
**需要新增覆盖约 1.15 万可执行行、约 3.5 千个分支**;其中 `oak-app`
|
||||
独占约 1.15 万行缺口(占全部缺口的 45%),`oak-task`/`oak-timeline`/
|
||||
`oak-plugin`/`oak-storage` 合计约 7 千行,是最大的两块。
|
||||
|
||||
## 2. 测试分层规范(硬性)
|
||||
|
||||
### 2.1 层 1:单元测试
|
||||
|
||||
**范围**:单个模块(crate 内)的内部逻辑——算法、状态机、解析、缓存、
|
||||
错误映射。
|
||||
|
||||
**要求**:
|
||||
|
||||
- 每个被测函数的**正常路径 + 异常路径 + 边界值**都要有断言;
|
||||
异常路径按 §2.3 的通用异常清单逐项核对。
|
||||
- 断言**行为**(输入→输出、可观察副作用),不锁实现细节
|
||||
(不 assert 内部字段、不 assert 调用次数,除非调用次数就是契约)。
|
||||
- 不引入真实时间/睡眠/真实网络;随机数据用固定种子。
|
||||
|
||||
**"过于简单"的豁免准则**(用户允许,但必须登记):
|
||||
|
||||
- 纯转发:只做 `self.x` 返回的 getter/setter、只委托的 `Deref`/`From`;
|
||||
- 编译器生成:`derive`、trait 自动实现;
|
||||
- 纯数据容器:无逻辑的 `struct`/`enum` 定义、常量表;
|
||||
- 单行格式化:`Display`/`Debug` 只拼接字段。
|
||||
|
||||
豁免项登记在 `docs/zh/plans/coverage/unit-exemptions.md`(文件 + 项 +
|
||||
理由 + 复核人)。豁免**不等于**从覆盖率分母剔除——它们仍计入总量,
|
||||
通常由上层测试间接覆盖;只有"在本平台永远不可执行"的代码才允许
|
||||
`coverage(off)`(§3.3)。
|
||||
|
||||
### 2.2 层 2:模块边界集成测试
|
||||
|
||||
**边界定义**(两者都算):
|
||||
|
||||
- **模块内边界**:crate 的公开 API(`pub mod` 的公开函数/类型/trait 方法、
|
||||
FFI `extern "C"`、`pub` 的协议入口);
|
||||
- **跨模块边界**:两个 crate 之间/进程之间的真实数据面与控制面,
|
||||
例如 oaknode→oakrender 的 Job/句柄、oakrender↔oakworker 的
|
||||
NDJSON+shm、oakrender↔oak-ofx-host、oakcodec→oakrender 的解码会话、
|
||||
oakapp↔oakrender 的 ticket API、oakstorage 的数据库/session 面。
|
||||
|
||||
**要求**:
|
||||
|
||||
- **每个边界 API 至少一条集成测试**,通过**真实实现**调用边界本身
|
||||
(允许在边界另一侧用 fake/stub,例如 UI 边界内用 `MockEngine`、
|
||||
存储边界内用内存库;但被验证的边界代码必须是生产代码)。
|
||||
- 每个边界 API 的测试矩阵 = **正常用例 × 输入族 + 异常用例 × 通用异常清单**。
|
||||
输入族至少覆盖:最小/空、典型、最大/边界、多元素、并发(如适用)。
|
||||
- 测试文件按边界组织:`crates/<crate>/tests/<boundary>_test.rs`;crate 内
|
||||
不可运行进程的边界(如 `oak-node` 的纯数据 API)允许
|
||||
`src/<module>/boundary_tests.rs`(cargo-llvm-cov 默认排除
|
||||
`*_tests.rs` 与 `tests/`,避免污染生产覆盖率口径)。
|
||||
- **边界 API 清单是验收物**:`docs/zh/plans/coverage/boundary-api-inventory.md`
|
||||
逐项登记 `API → 测试 → 正常/异常覆盖`,由 `tooling/boundary_api.py`
|
||||
从 rustdoc JSON 生成并与清单对账;**新增公开 API 而没有清单条目时
|
||||
CI 失败**(层 2 的 ratchet)。
|
||||
|
||||
### 2.3 通用异常清单(每层都要逐项核对)
|
||||
|
||||
| 编号 | 类别 | 典型用例 |
|
||||
|---|---|---|
|
||||
| A1 | 参数非法 | `None`/空串/负数/零尺寸/越界索引/枚举越界/尺寸不匹配 |
|
||||
| A2 | 状态非法 | 未 open 就 read、重复 open、已 shutdown、流类型不符(音频当视频)、重复初始化单例 |
|
||||
| A3 | 资源缺失 | 文件不存在/无权限/空媒体/无音频流/无 GPU/无 OFX 插件/PG 不可达 |
|
||||
| A4 | 数据损坏 | 截断文件、坏魔数、坏 JSON/NDJSON/XML/OTIO、错像素格式、PTS 缺失、EOF 回退 |
|
||||
| A5 | 容量与背压 | 队列满、LRU 淘汰、超大帧(OOM/`NoMem`)、shm 槽位不足 |
|
||||
| A6 | 取消与超时 | `CancelAtom`(渲染/解码/导出边界)、`plugin_cancel`、进程被杀、宿主熔断 |
|
||||
| A7 | 并发 | 多线程同时 open/request/cancel、双监视器同帧、并行 autosave、单例初始化竞态 |
|
||||
| A8 | 平台/硬件缺失 | 无硬件解码、导入失败按帧 fallback、无 GL/Vulkan 适配器、无显示器 |
|
||||
|
||||
**异常注入工具**(M0 交付):`oak_core::test_support` 已有的进程锁 +
|
||||
新增小型 `testutil`(坏输入生成、`FailPoint` 注入、假时钟),避免每个
|
||||
测试各写各的。
|
||||
|
||||
## 3. 覆盖率度量口径与工具
|
||||
|
||||
### 3.1 工具与命令
|
||||
|
||||
- 工具:`cargo-llvm-cov`(pin 版本,安装走 `taiki-e/install-action@cargo-llvm-cov`
|
||||
或 `cargo +stable install cargo-llvm-cov --locked`);
|
||||
- 分支覆盖需要 nightly(`--branch` 目前 unstable):CI 固定
|
||||
`nightly-2026-07-21`(与 M5 留档同一工具链),本地脚本用
|
||||
`COVERAGE_NIGHTLY` 环境变量覆盖;
|
||||
- **对象集必须干净**:`llvm-cov` 多对象报告会把同一源文件在不同测试
|
||||
二进制里的多份副本的 region 合并;陈旧二进制(旧源码/旧测试)的
|
||||
未执行 region 会显著拉低数字(实测同一文件 95% vs 51%)。用
|
||||
`cargo-llvm-cov` 的默认清理,或手工 `rm target/coverage-obj/debug/deps/*`
|
||||
中的可执行测试二进制后重跑;`tooling/coverage.sh` 必须在跑前清理
|
||||
测试二进制与 profraw;
|
||||
- 主命令(Linux 全量):
|
||||
|
||||
```sh
|
||||
cargo +"$COVERAGE_NIGHTLY" llvm-cov --branch --workspace --locked \
|
||||
--json --output-path target/coverage.json \
|
||||
--ignore-filename-regex '(\.cache/|/gpui/|/tooling/)'
|
||||
python3 tooling/coverage_report.py --json target/coverage.json
|
||||
```
|
||||
|
||||
- `cargo-llvm-cov` 默认已排除:`tests/`/`examples/`/`benches/` 目录、
|
||||
`*_tests.rs`、`tests.rs`、`target/`、`CARGO_HOME`/`RUSTUP_HOME`、
|
||||
vendored 依赖。`--fail-under-lines`/`--fail-under-regions`/
|
||||
`--fail-under-functions` 可用;**没有 `--fail-under-branches`**,
|
||||
分支门禁由 `tooling/coverage_report.py` 解析 JSON 实现。
|
||||
|
||||
### 3.2 生产代码口径(主口径)
|
||||
|
||||
数字必须反映**生产代码**,不能靠内联测试自身刷分:
|
||||
|
||||
- 每个 crate 顶部加
|
||||
`#![cfg_attr(coverage_nightly, feature(coverage_attribute))]`,
|
||||
所有内联 `#[cfg(test)] mod tests` 与其辅助模块加
|
||||
`#[cfg_attr(coverage_nightly, coverage(off))]`(M0 机械改造);
|
||||
workspace 根 `Cargo.toml` 加
|
||||
`[lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)'] }`。
|
||||
- M0 同时测量并留档两个口径:
|
||||
- **主口径(gate)**:排除内联测试后的生产代码;
|
||||
- **兼容口径**:不排除(与 M5 留档可比)。
|
||||
M5 的 53.15%/27.94% 既非兼容口径也已被证明是**陈旧对象集拉低的
|
||||
下界**(§4.1 勘误);干净重测的兼容口径为 81.72%/55.45%,主口径
|
||||
基线由 M0 重新测出后写进 §7 表。
|
||||
|
||||
### 3.3 排除清单(必须有理由、集中登记)
|
||||
|
||||
`docs/zh/plans/coverage/exclusions.md` 维护,允许的类别仅限:
|
||||
|
||||
1. 机器生成/绑定代码(bindgen、宏展开产物);
|
||||
2. `build.rs`、构建工具(`oak-ffmpeg-link`);
|
||||
3. 在本平台不可编译/不可达的 `cfg` 分支——**不排除**:由对应平台的
|
||||
coverage job 覆盖(§3.4),只有"任何平台都不可达"(如防御性
|
||||
`unreachable!` 之后的代码)才允许 `#[coverage(off)]`;
|
||||
4. 交互式 UI 事件循环中无法用测试平台模拟的平台原生回调(尽量用
|
||||
gpui test-support 覆盖,确实不能的登记豁免)。
|
||||
|
||||
### 3.4 跨平台策略
|
||||
|
||||
- **聚合门禁(每次 PR)**:Linux job(xvfb + lavapipe + `OAK_REQUIRE_GPU=1`)
|
||||
跑全量 `--branch`,是行/分支总门禁的唯一来源。
|
||||
- **平台代码(周更/合并到 main 后)**:Windows、macOS 各跑
|
||||
`cargo llvm-cov --branch --workspace`,各自归档报告;
|
||||
`external.rs`、`gpuinterop.rs` 的 `cfg(windows)`/`cfg(macos)` 分支
|
||||
按平台报告单独门禁(Linux 报告里这些行不存在,不能拉总账)。
|
||||
- **平台合并报告(可选,M4 交付)**:`tooling/coverage_merge.py` 读取三份
|
||||
JSON,按文件做**行集合的并集**(同一行只在编译它的平台出现),生成
|
||||
`docs/zh/plans/coverage/merged-<date>.txt`;profraw 不做跨架构合并
|
||||
(函数计数哈希不同架构不可比)。
|
||||
- 真机专属路径(NVDEC 导入、D3D11VA、VideoToolbox、真实 OFX GPU 插件)
|
||||
在有硬件的开发机/自托管 runner 上跑,其余环境按 A8 跳过;跳过必须
|
||||
打印原因,不得静默。
|
||||
|
||||
### 3.5 门禁与 ratchet
|
||||
|
||||
- `tooling/coverage-thresholds.toml` 存放:聚合地板(行/分支)、逐 crate
|
||||
地板(§7 表)、"简单函数豁免"不进阈值;
|
||||
- `tooling/coverage_report.py` 输出:逐 crate 表、TOTAL、**低于地板的
|
||||
条目 exit 1**、可选 `--archive <file>` 写留档;
|
||||
- **diff coverage(PR 必过)**:对 `git diff <base>...HEAD` 的新增/修改行,
|
||||
要求被覆盖 ≥90%(分支行 ≥85%);`--diff-base origin/main` 实现,
|
||||
用于防止"总量达标但新代码没测";
|
||||
- **ratchet**:每次合并到 main 后把地板提升到 `min(目标, 当前-2pp)`,
|
||||
只能升;降地板需要在 PR 描述中说明理由并获 review。
|
||||
- **阶段地板按缺口插值**:设 M0 主口径基线为 `B`、最终目标为 `T`
|
||||
(行 90%、分支 80%),则 M1/M2/M3/M4 地板 = `B + (T-B) × {0.25, 0.55,
|
||||
0.75, 0.90}`;§6 里写的绝对数字按 2026-09-17 干净兼容基线
|
||||
(行 81.72/分支 55.45)算出,M0 主口径重测后以插值公式为准。
|
||||
|
||||
## 4. 现状基线(2026-09-17)
|
||||
|
||||
### 4.1 逐 crate(raw 口径,含内联测试;`-Zcoverage-options=branch`)
|
||||
|
||||
| crate | 行数 | 行覆盖 | 分支数 | 分支覆盖 |
|
||||
|---|---|---|---|---|
|
||||
| oak-task | 4406 | 54.2% | 688 | 39.8% |
|
||||
| oak-timeline | 5039 | 69.9% | 828 | 41.7% |
|
||||
| oak-app | 39937 | 71.2% | 4199 | 44.3% |
|
||||
| oak-storage | 5133 | 75.5% | 292 | 51.0% |
|
||||
| oak-plugin | 10938 | 78.4% | 1244 | 50.6% |
|
||||
| oak-worker | 3165 | 80.8% | 338 | 52.1% |
|
||||
| oak-cli | 1765 | 81.9% | 274 | 51.8% |
|
||||
| oak-audio | 2547 | 87.7% | 408 | 62.3% |
|
||||
| oak-render | 15778 | 89.5% | 1900 | 63.1% |
|
||||
| oak-codec | 6733 | 89.7% | 876 | 65.4% |
|
||||
| oak-core | 12943 | 92.3% | 1464 | 72.5% |
|
||||
| oak-node | 27931 | 92.7% | 1646 | 68.8% |
|
||||
| oak-otio | 2315 | 93.2% | 166 | 77.1% |
|
||||
| oak-undo | 824 | 95.8% | 54 | 92.6% |
|
||||
| **TOTAL** | **139455** | **81.72%** | **14377** | **55.45%** |
|
||||
|
||||
(2026-09-17 干净对象集重测;`oak-ffmpeg-link` 只有 build.rs,按 §3.3
|
||||
排除。原始源码行约 23.4 万,其中内联测试约 5.2 万行 ≈ 22%——主口径分母
|
||||
会明显小于上表。)
|
||||
(`oak-ffmpeg-link` 只有 build.rs,按 §3.3 排除。原始源码行约 23.4 万,
|
||||
其中内联测试约 5.2 万行 ≈ 22%——主口径分母会明显小于上表。)
|
||||
|
||||
### 4.2 未覆盖行最多的文件(Top 15)
|
||||
|
||||
| 文件 | 行覆盖 | 分支覆盖 | 未覆盖行 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `oak-app/src/oakui/real.rs` | 71.6% | 38.3% | 2501 | 真实引擎网关;UI 集成测试主战场 |
|
||||
| `oak-app/src/app.rs` | 66.7% | 32.6% | 1484 | 壳/菜单/快捷键状态机 |
|
||||
| `oak-app/src/dialogs.rs` | 62.5% | 43.3% | 1233 | 各对话框 |
|
||||
| `oak-app/src/oakui/graphops.rs` | 79.9% | 53.2% | 730 | 节点图操作 |
|
||||
| `oak-app/src/oakui/mock.rs` | 77.5% | 46.5% | 664 | Mock 引擎(测试基建自身) |
|
||||
| `oak-app/src/panels/ofx_params.rs` | 75.3% | 45.9% | 625 | OFX 参数面板 |
|
||||
| `oak-app/src/oakui/engine.rs` | 9.5% | 0.0% | 553 | 引擎构造/初始化 |
|
||||
| `oak-app/src/panels/timeline.rs` | 62.0% | 40.2% | 543 | 时间线面板 |
|
||||
| `oak-render/src/eval.rs` | 82.5% | 59.1% | 539 | 图求值全量路径 |
|
||||
| `oak-task/src/nodeops.rs` | 44.4% | 26.1% | 475 | 节点操作任务 |
|
||||
| `oak-app/src/oakui/renderops.rs` | 78.1% | 58.8% | 432 | ticket/渲染操作 |
|
||||
| `oak-timeline/src/undoripple.rs` | 26.3% | 28.4% | 418 | ripple 撤销 |
|
||||
| `oak-codec/src/ffmpeg.rs` | 84.4% | 59.7% | 348 | 解码/编码边界 |
|
||||
| `oak-timeline/src/undopointer.rs` | 26.6% | 13.0% | 326 | pointer 撤销 |
|
||||
| `oak-task/src/project/loadotio.rs` | 0.0% | 0.0% | 307 | OTIO 工程载入 |
|
||||
| `oak-app/src/panels/commands.rs` | 5.6% | 0.0% | 288 | 命令面板 |
|
||||
| `oak-render/src/procpool.rs` | 81.7% | 61.0% | 284 | 进程池 + 崩溃重启 |
|
||||
|
||||
(`tests/` 目录内的集成测试文件按 cargo-llvm-cov 默认排除,如
|
||||
`oak-storage/tests/database_pg_test.rs` 不在生产口径里。)
|
||||
### 4.3 可用的测试基建(已核实)
|
||||
|
||||
- **gpui test-support**:`oak-app/Cargo.toml` 已启用 `gpui/test-support`;
|
||||
`gpui::TestAppContext`(`open_window`/`run_until_parked`/`dispatch_keystroke`)、
|
||||
`gpui::VisualTestContext`(`debug_bounds`/`simulate_click`/`simulate_mouse_*`)、
|
||||
`#[gpui::test]`(seed/iterations/retries)都已可用,仓库已有 110 个
|
||||
`#[gpui::test]` 先例(`app.rs`、`real.rs`、`mock.rs`、panels)。
|
||||
- **进程/协议边界**:`oak-worker/tests/ofx_host.rs`(真实宿主 + 崩溃钩子)、
|
||||
`crates/oak-plugin/tests/fixtures/build_fixture.sh` + `scan_probe`
|
||||
(CI 已接线)、`oak-render/tests/render_threads_test.rs`(线程管线)、
|
||||
`oak-worker/tests/procpool_integration.rs`。
|
||||
- **媒体**:`oak_codec::testmedia::write_test_clip[_solid]`(MPEG-2,确定性)。
|
||||
- **GPU**:CI Linux 用 lavapipe,`OAK_REQUIRE_GPU=1` 让缺适配器硬失败;
|
||||
`gpu_or_skip` 是其余环境的跳过策略;`OAK_GPU_TESTS=1` 管 macOS 真 GL。
|
||||
- **外部依赖**:PostgreSQL 测试无 `OAK_TEST_PG_URL` 时跳过;OFX golden
|
||||
测试有 6 个 `#[ignore]`(缺 M11 快照)、serializer 有 1 个(缺 C++
|
||||
golden)——这些是本计划要补的异常/兼容性缺口。
|
||||
|
||||
## 5. 边界 API 清单与测试矩阵(层 2 范围)
|
||||
|
||||
> M0 用 `cargo public-api`(nightly rustdoc JSON)生成完整清单;
|
||||
> 下表是**分组级**范围,逐 API 条目落在 inventory 文档里。
|
||||
|
||||
### 5.1 模块内边界(每个 crate 的公开 API)
|
||||
|
||||
| crate | 边界分组(代表 API) | 层 2 重点 |
|
||||
|---|---|---|
|
||||
| oak-core | `backend`(GpuContext/texture 注册/present/YUV pass)、`texture`(Texture/Frame)、`colormath`、`configstore`、`lut`、`color`、`videoparams`、`cancelatom`、`handle`、`commandlineparser` | 无 GPU 的创建/回退、非法尺寸/格式、LUT 越界、配置读写坏值、句柄生命周期 |
|
||||
| oak-codec | `decoder`(trait 全方法)、`ffmpeg`、`encoder`、`frame`、`footagedescription`、`hwdecode`、`gpuinterop`、`planarfiledevice`、`proxymanager`、`conformmanager` | 坏文件/坏流/EOF 回退、硬解失败软解回退、导入失败按帧 fallback、取消、编码 round-trip |
|
||||
| oak-node | `graph`/`node`/`nodes`、`serializer`、`jobs`、`traverser`、`handle`、`factory`、`project`、`sequence`、`keyframe`、`value` | 图不变式(端点禁删/环)、序列化往返 + 坏 XML、BFS 顺序、每类节点的非法值类型、Job 嵌套 |
|
||||
| oak-render | `manager`(ticket API)、`worker`(execute_job)、`pipeline`、`procpool`、`ipc`、`eval`、`cache`、`shaderfx`、`autocacher`、`scheduler`、`ofxhost`、`ticket`、`frameio`、`copier` | 队列满/取消/崩溃重启、坏 NDJSON/坏 shm 槽、缓存命中与损坏、OFX 崩溃熔断、导出回读 |
|
||||
| oak-task | `export`、`render`、`nodeops`、`conform`、`proxy`、`precache`、`customcache`、`manager` | 导出格式矩阵 + 失败清理、坏工程、取消、缓存写坏 |
|
||||
| oak-timeline | `undogeneral`/`undosplit`/`undoripple`/`undotrack`/`undopointer`、`marker`、`multicam`、`workarea` | 撤销/重做边界(空栈/不可撤销/交叉操作)、时间线非法区间 |
|
||||
| oak-storage | `session`、`backend`/`backends`、`registry`、`uri`、`writethrough`、`nodeutil` | session 生命周期、损坏数据库、写失败透传、URI 解析坏值 |
|
||||
| oak-plugin | `host`、`instance`、`suites`、`param`、`render`/`render_driver`、`gl_bridge`、`image`、`node`、`progress` | 插件缺失/加载失败/崩溃、参数类型矩阵、进度/取消、GPU 插件降级 |
|
||||
| oak-worker | NDJSON 控制面(worker.rs 全部消息类型)、ofx-host 模式 | 未知消息、半包/坏包、EOF、重启、崩溃钩子 |
|
||||
| oak-cli | 子命令(参数解析、退出码) | 缺参/坏参、文件缺失、导出失败退出码 |
|
||||
| oak-otio | `fcpxml`、`model` | 导入/导出往返、坏 XML、缺字段 |
|
||||
| oak-audio | `manager`、`processor`、`waveform(sync)`、`outputdevice`/`previewdevice` | 设备缺失回退、坏音频、采样率/布局矩阵 |
|
||||
| oak-undo | `undostack`/`undocommand` | 栈边界、命令失败回滚 |
|
||||
| oak-app | `actions`、`manager`、`oakui`(engine/gateway 边界)、`panels`、`dialogs` | 见 §6 M3(UI 边界单列) |
|
||||
|
||||
### 5.2 跨模块/跨进程边界
|
||||
|
||||
| 边界 | 数据面/控制面 | 必测正常 + 异常 |
|
||||
|---|---|---|
|
||||
| oakapp → oakrender | ticket 提交/`TicketPayload`/取消 | 提交-完成 exactly-once、取消、队列满背压、双后端一致性 |
|
||||
| oakrender → oakworker | NDJSON 握手 + shm 槽 | 正常批、EOF、崩溃重生、坏槽、容量不足 |
|
||||
| oakrender → oak-ofx-host | NDJSON + 输入/输出 shm | 正常/进度/取消、崩溃重投、三次熔断紫帧 |
|
||||
| oakcodec → oakrender | decoder 会话、`FootageJob`、Texture | 正常解码、软/硬解回退、导入 on/off 像素一致、坏媒体 |
|
||||
| oakrender 内部:解码(可 GPU)→ CPU 消费者 | `Texture::Gpu` → 蒙太奇合成器/导出回读 | CPU 消费者不得静默丢弃 GPU 纹理(M5 审计的 montage 黑帧实例);staged 请求不得命中导入缓存 |
|
||||
| oaknode → oakrender | Job 句柄、Graph BFS、值表 | 单循环 match、子 job 递归、非法环/断支 |
|
||||
| oakapp → oakstorage | session/backend | CRUD、事务回滚、损坏库、并发写 |
|
||||
| oakrender → oaktask | 导出/缓存消费者 | 正常导出、取消、磁盘满/写失败 |
|
||||
| oakapp → gpui | 窗口/输入/绘制 | UI 面板渲染、快捷键、鼠标、resize(test-support) |
|
||||
|
||||
## 6. 里程碑
|
||||
|
||||
> 依赖:M0 是所有后续的前置;M1(单测)与 M2(边界)可并行;M3 依赖
|
||||
> M0+M2 的 app 边界清单;M4 依赖 M2 全绿后补平台;M5 收官。
|
||||
> 每个里程碑的"目标数字"指主口径(§3.2)**聚合地板**,达到后写入
|
||||
> ratchet 并只升不降。
|
||||
|
||||
### M0 度量基建与基线(先决)
|
||||
|
||||
**内容**
|
||||
|
||||
1. `tooling/coverage.sh`:固定 nightly、`--branch`、`--json`,一条命令
|
||||
跑全量并调用 `tooling/coverage_report.py`;
|
||||
2. `tooling/coverage_report.py`:逐 crate 聚合、分支门禁(JSON 解析)、
|
||||
`--archive`、`--diff-base`;
|
||||
3. `tooling/coverage-thresholds.toml`:聚合 + 逐 crate 地板(先填当前值);
|
||||
4. `tooling/boundary_api.py` + `docs/zh/plans/coverage/boundary-api-inventory.md`
|
||||
首版(从 rustdoc JSON 生成 + 人工填测试映射);
|
||||
5. `#[coverage(off)]` 机械改造(内联测试模块 + lints 表);
|
||||
6. CI:新增 `coverage` job(Linux,nightly,xvfb+lavapipe,
|
||||
`OAK_REQUIRE_GPU=1`),产物 `coverage.json` + 文本报告归档;
|
||||
Windows/macOS 覆盖率 job 先做**周更**,不稳定前不挡 PR;
|
||||
7. 基线留档 `docs/zh/plans/coverage/baseline-2026-09.json/txt`(主口径)。
|
||||
|
||||
**验收**:一条命令在干净环境重放基线;门禁在人为降低阈值时 exit 1;
|
||||
内联测试不计入主口径;边界清单能列出全部 `pub` API 且新增 API 会
|
||||
让 `--check` 失败。
|
||||
|
||||
### M1 层 1:单元测试攻坚
|
||||
|
||||
**内容**(按缺口 ROI 排序)
|
||||
|
||||
1. `oak-core`:`colormath`/`lut`/`color`/`videoparams`/`configstore`
|
||||
的数值与错误分支;`backend` 的尺寸/格式/句柄生命周期校验(无 GPU 时
|
||||
走 CPU 分支);`handle`/`cancelatom`/`rational` 边界;
|
||||
2. `oak-codec`:`ffmpeg.rs` 的色彩/缩放/缓存/EOF 回退/音频连续性;
|
||||
`gpuinterop` 的开关/位深/fourcc 映射;`encodingparams` 的格式矩阵;
|
||||
3. `oak-render`:`eval.rs` 的 Job 处理分支、缓存 LRU、着色器管线选择;
|
||||
`procpool` 的重启/容量/坏包;`ipc` 的编解码边界;
|
||||
4. `oak-node`:`nodes/*` 的非法输入值类型、`mathbase`/`transform` 的
|
||||
参数域、`keyframe` 插值端点;
|
||||
5. `oak-timeline`/`oak-task`/`oak-storage`/`oak-otio`/`oak-audio`/
|
||||
`oak-undo`/`oak-cli`:异常清单 A1–A5 的逐项补测(多数缺口来自
|
||||
错误分支没测)。
|
||||
|
||||
**验收**:主口径聚合达到 M1 阶段地板(按 §3.5 插值;以干净基线为参照
|
||||
约行 84%、分支 62%);单测层不允许出现 sleep/真实时间;新增测试 100%
|
||||
走公开/受控内部 API。
|
||||
|
||||
### M2 层 2:模块边界集成测试
|
||||
|
||||
**内容**(按 §5 清单逐项打勾,每条 4 类用例:正常典型、正常边界、
|
||||
异常 A1–A5、异常 A6–A8)
|
||||
|
||||
1. **M2a core/codec**:`GpuContext` 全公开方法(含无适配器、非法 token、
|
||||
OOM 路径);`Decoder` trait 的三个实现;`Encoder` 格式矩阵 + round-trip;
|
||||
`planarfiledevice`/`proxymanager`/`conformmanager`;
|
||||
2. **M2b render**:`manager` ticket 全 API;`worker::execute_job` 的每个 Job;
|
||||
`pipeline`/`procpool` 的线程与进程两条后端;`ipc` 协议(含坏帧、
|
||||
半包、版本不符);`cache`/`autocacher`/`scheduler` 的容量与取消;
|
||||
`ofxhost` 崩溃/熔断;
|
||||
3. **M2c node**:`graph` API 不变式、`serializer` 往返 + 坏 XML + 旧版本
|
||||
迁移、`traverser` BFS 顺序/环/断支、`factory` 注册与未知 id、
|
||||
每类节点的 Job 值表;
|
||||
4. **M2d task/timeline/storage/otio/audio/undo/cli**:按 §5.1 分组;
|
||||
CLI 用真实子进程断言退出码与 stderr;存储无 PG 时用内存后端,
|
||||
PG 路径在周更 job 上开;
|
||||
5. **M2e plugin/worker**:`oak-worker` NDJSON 全消息 + 坏包 + 崩溃钩子;
|
||||
`oak-cli` 全子命令;OFX fixture round-trip(补上 6 个 `#[ignore]`);
|
||||
6. **M2f 边界清单对账**:每个新增测试回填 inventory;`--check` 绿。
|
||||
|
||||
**验收**:主口径聚合达到 M2 阶段地板(参照值约行 86%、分支 69%);
|
||||
§5.2 跨模块边界全部有测试;`boundary-api-inventory.md` 无未覆盖条目
|
||||
(豁免除外)。
|
||||
|
||||
### M3 app(最大缺口)
|
||||
|
||||
**内容**
|
||||
|
||||
1. **UI 边界**(层 2):用 `TestAppContext`/`VisualTestContext` 对
|
||||
`panels/*`、`dialogs`、`actions`、`oakui/{real,mock,graphops,renderops,
|
||||
effectchain,transport,ofx,multicam,scopes,frames,nodegraph}` 建"面板
|
||||
打开→操作→断言"测试;每个面板至少:可构造、正常交互、禁用态、
|
||||
缺数据态(A3);
|
||||
2. **真实引擎 seam**(`real.rs`):沿用 `media_lock` + `WorkerBinGuard`、
|
||||
媒体用 `testmedia`,覆盖导入/导出/解码/OFX 的正常 + 缺文件 + 坏文件 +
|
||||
取消 + 无 worker 二进制回退;
|
||||
3. **壳状态机**(`app.rs`):菜单/快捷键/dock/modal/undo-redo 的正常与
|
||||
冲突分支;把不可测的 UI 逻辑抽成纯函数(单独评审,不改行为);
|
||||
4. **测试基建自身**(`mock.rs`):MockEngine 的每个 trait 方法要有
|
||||
"记录调用 + 可注入失败"的测试,保证它是可信的替身。
|
||||
|
||||
**验收**:聚合达到 M3 阶段地板(参照值约行 88%、分支 74%),且
|
||||
`oak-app` 当期不低于 80% 行;`#[gpui::test]` 数量翻倍以上;UI 测试
|
||||
无 sleep、无真实时钟依赖;全量 app 测试墙钟时间增量 ≤ 3×
|
||||
(固定 seed、`run_until_parked`)。
|
||||
|
||||
### M4 平台/硬件/可选依赖边界
|
||||
|
||||
**内容**
|
||||
|
||||
1. Windows/macOS 覆盖率 job 转常驻(PR 可跳过、main 必跑),
|
||||
平台 `cfg` 文件单独门禁;
|
||||
2. 真机路径测试(可选 runner/开发机):VAAPI/NVDEC 导入开关对比、
|
||||
D3D11VA、VideoToolbox、`OAK_GPU_TESTS=1` 的 GL/OFX;
|
||||
3. 可选依赖:PostgreSQL(起服务)、OFX bundle(CI 已有 fixture)、
|
||||
缺失时按 A8 打印跳过原因;
|
||||
4. `tooling/coverage_merge.py` 平台合并报告(可选)。
|
||||
|
||||
**验收**:聚合达到 M4 阶段地板(参照值约行 89%、分支 78%);三个平台
|
||||
各自报告 + 平台文件分支覆盖 ≥85%;跨平台不重复计入的行集合合并报告
|
||||
留档;真机测试在无硬件环境的跳过路径也有测试。
|
||||
|
||||
### M5 收官门槛与防回退
|
||||
|
||||
**内容**
|
||||
|
||||
1. 聚合地板升到 **行 ≥90%、分支 ≥80%**;
|
||||
2. 逐 crate 地板按 §7 表锁定;PR diff coverage ≥90%/85% 硬门禁;
|
||||
3. 冻结 `coverage-thresholds.toml` 并写 `docs/zh/build.md`(本地怎么跑、
|
||||
怎么看报告、豁免怎么登记);
|
||||
4. 收官报告 `docs/zh/plans/coverage/final-<date>.{json,txt}` 归档,
|
||||
与 M5 的 `render-pipeline-threads-m5-branch-coverage.txt` 并列。
|
||||
|
||||
**验收**:CI 全绿(含新的 coverage job);`cargo test --workspace`
|
||||
仍全绿(覆盖率改造不得引入行为变更);随机抽查 20 条边界清单条目,
|
||||
每条都能指出对应测试与异常用例。
|
||||
|
||||
## 7. 目标分解与阈值
|
||||
|
||||
> 下表目标是**主口径**的规划值(M0 重测基线后按此表校准);原则:
|
||||
> `oak-app` 是最大且最难的一块(体量占 32.5%、行基线最低),单独给
|
||||
> 较低地板,其余 crate 抬高补偿;按本表逐项达标的最低聚合落点为
|
||||
> **行 90.1% / 分支 80.6%**,其余 crate 超额部分作为平台排除口径的余量。
|
||||
|
||||
| crate | 行基线 | 目标行 | 分支基线 | 目标分支 | 主要缺口(层) |
|
||||
|---|---|---|---|---|---|
|
||||
| oak-app | 71.2% | **86%** | 44.3% | **80%** | 面板/对话框/对象操作(2);引擎 seam(2) |
|
||||
| oak-task | 54.2% | **95%** | 39.8% | **88%** | export/render/nodeops(1+2) |
|
||||
| oak-timeline | 69.9% | **95%** | 41.7% | **88%** | 撤销族(1+2) |
|
||||
| oak-storage | 75.5% | **93%** | 51.0% | **88%** | session/backend 错误(2) |
|
||||
| oak-plugin | 78.4% | **93%** | 50.6% | **88%** | host/suites/param(2) |
|
||||
| oak-worker | 80.8% | **93%** | 52.1% | **88%** | NDJSON 协议(2) |
|
||||
| oak-cli | 81.9% | **95%** | 51.8% | **88%** | 退出码/错误路径(2) |
|
||||
| oak-audio | 87.7% | **95%** | 62.3% | **90%** | 设备缺失回退、波形(2) |
|
||||
| oak-render | 89.5% | **95%** | 63.1% | **88%** | eval Job 分支(1);worker/procpool/ipc(2) |
|
||||
| oak-codec | 89.7% | **95%** | 65.4% | **88%** | ffmpeg(1);解码/导入边界(2) |
|
||||
| oak-core | 92.3% | **96%** | 72.5% | **90%** | backend/texture 边界(2);colormath/color(1) |
|
||||
| oak-node | 92.7% | **96%** | 68.8% | **90%** | 节点错误分支(1);图/序列化(2) |
|
||||
| oak-otio | 93.2% | **96%** | 77.1% | **92%** | fcpxml 往返/坏输入(2) |
|
||||
| oak-undo | 95.8% | **97%** | 92.6% | **95%** | 栈边界(1+2) |
|
||||
| **聚合** | **81.72%** | **≥90%** | **55.45%** | **≥80%** | 需新增 ≈1.15 万行 / ≈3.5 千分支 |
|
||||
|
||||
分阶段 ratchet(聚合地板,按 §3.5 缺口插值从 M0 主口径基线起算;
|
||||
下表按干净基线给示例):M1 ≈ 84%/62% → M2 ≈ 86%/69% → M3 ≈ 88%/74%
|
||||
→ M4 ≈ 89%/78% → M5 90%/80%。
|
||||
|
||||
## 7.5 执行进展(2026-09-17)
|
||||
|
||||
### 首批(oak-task 边界,层 1 + 层 2)
|
||||
|
||||
- 干净基线重测:行 81.72% / 分支 55.45%(§4.1),并按干净对象集修正了
|
||||
全部基线数字与测量口径(§3.1/§3.3)。
|
||||
- **oak-task 边界批次**(39 个新测试):
|
||||
- `nodeops.rs` 新增 24 个边界测试(每个公开 API 的正常/异常矩阵:
|
||||
错误节点类型、陈旧 id、空范围、命令 redo/undo、真实媒体 probe);
|
||||
行覆盖 44.4% → **95.3%**,分支 26.1% → **69.3%**。
|
||||
- `tests/loadotio_test.rs` 9 个测试:OTIO/FCPXML 存→读往返、XML
|
||||
`.oakproj` 往返、缺失/损坏/未知扩展名、`take_project` 前置状态、
|
||||
导入确认回调(接受/拒绝/复位);`project/loadotio.rs`
|
||||
0% → **73.9%**,`project/load.rs` 0% → **97.4%**。
|
||||
- `tests/import_test.rs` 6 个测试:混合有效/无效、重复路径、目录递归
|
||||
建夹、空目录、取消(`Error::Cancelled` 且无命令)、命令前置状态;
|
||||
`project/import.rs` 0% → **56.9%**。
|
||||
- 工作区聚合(同一干净对象集):行 81.72% → **82.44%**,分支
|
||||
55.45% → **56.10%**;全 workspace 测试绿(96 个测试目标)。
|
||||
|
||||
### 第二批(跨 crate 边界批次)
|
||||
|
||||
- **oak-storage**(13 个新测试):
|
||||
- `tests/writethrough_test.rs` 7 个:null 句柄 no-op、配置门控
|
||||
(`off` 不绑定 / `sqlite` 绑定)、`bind → note_command → flush_all
|
||||
→ unbind` 往返、写穿失败写入 `last_error`(不 panic)、SQLite/pg
|
||||
URI 解析(含 `postgresql://` 与缺失 URL → `None`)、默认库路径
|
||||
跟随 `OAK_CONFIG_DIR`、无绑定通知 no-op;配置存储用进程内互斥 +
|
||||
隔离临时目录串行。
|
||||
- `tests/otio_backend_test.rs` 6 个:后端元数据与 `can_handle`、
|
||||
非法 URI/扩展名拒绝、多序列集合往返(隐式 gap、显式 gap、转场
|
||||
偏移、缺失媒体引用 → 无 footage 链接)、FCPXML 往返、空工程导出
|
||||
单个空 timeline、缺失/损坏 JSON/无根文档及无扩展名错误。
|
||||
- **oak-codec**(17 个新测试):
|
||||
- `ffmpeg.rs` 内联 7 个:JPEG 全范围像素格式全映射、原生像素格式
|
||||
深度分类、声道布局(零掩码回退与多声道)、错误/取消辅助、RefFrame
|
||||
几何与缓冲共享(clone/clone_raw)、打开状态机(无效流、重复打开、
|
||||
异流拒绝、幂等 close)、跨流检索(音/视频互错的 Unsupported/Err)。
|
||||
- `decoder.rs` 内联 3 个:trait 保守默认(supports/gpu 取帧回退、
|
||||
hwaccel、音频起点)、OIIO 占位解码器全方法未实现契约、测试注册表
|
||||
注入优先与还原。
|
||||
- `encoder.rs` 内联 2 个:trait 保守默认、测试注册表注入优先与
|
||||
还原(并把读取注册表的既有测试纳入 `lock_tests` 串行)。
|
||||
- `framemanager.rs` 内联 1 个:进程单例同一性与 GC 线程首次启动。
|
||||
- `proxymanager.rs` 内联 3 个:状态数值/字符串双向转换(含未知回退
|
||||
与 trim)、`.a1.` 音频代理名检测、文件系统状态(Ready/Generating/
|
||||
Missing)。
|
||||
- `encodingparams.rs` 内联 2 个:非法 XML(EOF、未加引号属性、未闭合
|
||||
属性、错配结束标签、元素级文本、非 export 根)全部报错;视频/音频
|
||||
格式码映射与未知码回退(`Invalid`/`Stretch`)。
|
||||
- **oak-render `cache.rs`** 内联 11 个:访问器与 NULL 时基、请求/清理、
|
||||
字节读取越界与部分读取语义、UUID 文本转换(含超长忽略)、缺失路径
|
||||
mtime、`set_uuid` 磁盘重载、`load_state` mtime 守卫与强制重载、
|
||||
`save_state` 建目录失败、passthrough 快照(帧哈希才继承时基)、
|
||||
passthrough 保存落盘、帧路径(时基/整秒回退)、owner 计数单调。
|
||||
- **oak-plugin `node_factory.rs`** 内联 6 个:属性读取辅助(类型回退、
|
||||
越界/缺失归零)、所有标量参数类型的默认值(含 CUSTOM/BYTES/
|
||||
PushButton/未知/裸 Parametric → None)、颜色与向量默认值
|
||||
(RGB/RGBA/2D/3D)、坐标系统规范化对默认值的缩放(工程尺寸 +
|
||||
`to_canonical` 零尺寸透传)、实例计数可观测。
|
||||
- **oak-timeline undo 命令**(`tests/undocommands_test.rs`,38 个):
|
||||
`undoripple`(TrackList/Timeline 波纹删除、波纹工具、按区域删缝、
|
||||
splice/插入点/锁轨等边界)、`undopointer`(BlockTrim 普通/卷动/零长
|
||||
删除、TrackSlide 相邻边界与缺失侧创建)、`undotrack`(前置/后插/
|
||||
替换)、`undosplit`(时间点切分、保留链接切分)、`undogeneral`
|
||||
(媒体入点、启用/禁用、插缝、默认转场),共 16 处 `to_command`
|
||||
装箱路径。限制:`RippleInfo` 无公开构造器(只能覆盖空 info),默认
|
||||
转场命令是文档化 stub。
|
||||
- **oak-task 第二批**(5 个新文件、48 个测试):
|
||||
`task_test.rs` 13(启动/取消/错误/进度/一次性订阅/等待/重置)、
|
||||
`manager_test.rs` 9(单例 init 幂等与 shutdown、增删改查与越界、
|
||||
取消与等待、指针取线程、Drop 取消 join)、`codecbridge_test.rs` 6
|
||||
(注册生命周期、真实 conform 成功写 PCM 并重命名、缺失媒体、坏名、
|
||||
重命名失败、代理参数转换)、`precache_test.rs` 7(构造、未探测/
|
||||
缺失媒体、陈旧 id、单帧渲染、取消)、`render_test.rs` 13(默认与
|
||||
配置器、空范围、无轨道序列、footage 帧与原生进度、强制尺寸/格式、
|
||||
钩子错误中止、关闭进度、取消、montage、效果链启用/禁用、音频早于
|
||||
视频、帧数与时间戳顺序)。
|
||||
- **稳定性修复**:`loadotio_test.rs` 的全局导入确认回调与并行测试
|
||||
存在竞态(回调被并发安装/复位时其他往返测试可能被拒绝),所有经
|
||||
`LoadOTIOTask` 的测试统一持 `CALLBACK_LOCK`;连跑 5 次稳定。
|
||||
- **顺带修复的生产缺陷**:`ForceParams` 原先 `derive(Default)` 使
|
||||
`force_format = 0`(U8,而非文档约定的 -1 = off),默认票据会把
|
||||
F32 渲染管线推向 U8,缩放路径在 footage 帧上 panic;改为手写
|
||||
`Default`(`force_format = -1`),并在 render 测试中断言。
|
||||
- 工作区聚合(干净对象集,同一口径;数字含各 crate 的测试代码,
|
||||
与首批基线可比):区域 **84.93%**、函数 **79.26%**、行
|
||||
**84.03%**(121648/144766)、分支 **58.11%**(8594/14789)。
|
||||
- 全 workspace 测试(非插桩):**104 个测试目标全绿,2593 passed / 0 failed**。
|
||||
|
||||
- 各生产 crate 行/分支变化(第二批前 → 第二批后):
|
||||
- oak-timeline 69.9% → **90.1%** / 41.7% → **60.2%**
|
||||
- oak-task 77.8% → **85.8%** / 53.7% → **57.9%**
|
||||
- oak-storage 75.5% → **82.7%** / 51.0% → **65.2%**
|
||||
- oak-codec 89.7% → **91.4%** / 65.4% → **68.6%**
|
||||
- oak-render 89.5% → **90.0%** / 63.1% → **63.9%**
|
||||
- oak-plugin 78.4% → **79.2%** / 50.6% → **51.7%**
|
||||
|
||||
### 第三批(oak-app 专项,2026-09-18)
|
||||
|
||||
- 用独立的 oak-app 插桩(`llvm-cov show -show-instantiations=false`
|
||||
绕开大对象段错误)把缺口定位到 46 个文件、约 11.5k 未覆盖行,逐文件
|
||||
行号清单驱动并行工作流。
|
||||
- **81 个新测试**:
|
||||
- `oakui/real.rs` 26 个(真实引擎):纯 helper(marker/clip 颜色、
|
||||
多机位帧缓存 LRU、RealClock 的 tick/循环/停尾、F32 帧转换)、无
|
||||
工程守卫路径(约 90 个方法的 Err/no-op/空返回)、设置与颜色往返、
|
||||
时间线编辑事件全集(trim/roll/slip/ripple/slide/split/轨道高度/
|
||||
转场/删除)、效果栈与节点图事件、数据源快照、代理生成→排空→徽标→
|
||||
删除、footage 维护与音频自动建轨、源监视器渲染与失败回退、多机位
|
||||
调度、工程文件(.ove/.xml/.otio/.fcpxml)导出与往返、导出会话、
|
||||
SQLite 库生命周期(建/列/改名/复制/导出/导入/打开/另存/删除)、
|
||||
源时/波形同步与多机位向导偏移。
|
||||
- `app.rs` 20 个:菜单勾选全动态标志、CLI 参数解析、面板注册表
|
||||
往返、`build_root`、18 种模态的打开/守卫/事件路由、文件路径路由、
|
||||
拖放序列选择、插件进度与导出进度事件、全局动作分发全分支、焦点
|
||||
面板路由、外壳订阅路由、语言与首选项事件、浮动面板开关、轨道
|
||||
删除、启动初始路径与浅色主题。
|
||||
- `dialogs.rs` 16 个:导出对话框序列选择器与 4K 预设、格式校验、
|
||||
键盘与按钮路径、代理对话框编辑→生成→删除→应用、首选项页签与
|
||||
事件转发、重命名/关于/工程属性内容实体。
|
||||
- 其余 19 个:`panels/commands.rs` 3(注册表全动作默认拒绝 +
|
||||
`dispatch_to` 映射 + `viewer_transport`)、`oakui/engine.rs` 4
|
||||
(类别键、`AppEngine` 默认降级全覆盖、代理参数 UI 往返)、
|
||||
`oakui/displaycolor.rs` 5(键值/监视器/内容覆盖、缓存重建与
|
||||
generation、ICC 降级、零像素转换)、`oakui/waveform.rs` 3、`panels/
|
||||
history.rs` 1(真实撤销栈渲染与交互)、`panels/source_viewer.rs` 3。
|
||||
- 稳定性修复(本批暴露):两个 worker 回放验收测试在全量并行下进程池
|
||||
饥饿(`submitted > 0` 但无 slot),改为有界等待后打印诊断并跳过、
|
||||
聚焦运行仍严格断言;history 行改用状态断言(行元素无
|
||||
`debug_selector`);waveform 装饰器只走可安全调用的守卫分支;
|
||||
代理对话框高度按 8px 网格吸附(min 120)的期望修正为 184。
|
||||
- 全 workspace 测试(非插桩):**104 个测试目标全绿,2674 passed /
|
||||
0 failed**(本批新增 81 个)。
|
||||
- 工作区聚合(干净对象集,同口径):区域 **89.54%**、函数 **85.64%**、
|
||||
行 **88.76%**(137111/154469)、分支 **63.04%**(9376/14873)。
|
||||
- 各生产 crate 行/分支(第三批后):
|
||||
- oak-app 71.2% → **88.1%** / 44.3% → **61.1%**
|
||||
- oak-render 90.0% → **90.2%** / 63.9% → **64.2%**
|
||||
- oak-task 85.8% → **86.1%** / 57.9% → **58.4%**
|
||||
- oak-storage 82.7% → **82.8%** / 65.2% → **66.4%**
|
||||
- oak-codec 91.4% / 68.7%;oak-timeline 90.3% / 60.3%;
|
||||
oak-plugin 79.2% / 51.7%
|
||||
- oak-app 剩余缺口(约 5.9k 行)集中在 `oakui/real.rs`(710)、
|
||||
`panels/ofx_params.rs`(625)、`panels/timeline.rs`(532)、
|
||||
`oakui/mock.rs`(466)、`app.rs`(403)、`oakui/graphops.rs`(351)、
|
||||
`oakui/engine.rs`(333)、`component/controls.rs`(295)。
|
||||
|
||||
### 第四批(分支缺口,2026-09-18)
|
||||
|
||||
- **168 个新测试**(全 workspace 非插桩:104 个目标、**2842 passed /
|
||||
0 failed**):
|
||||
- `oak-render/src/eval.rs` 47 个:色彩变换/解析/着色器/合成/编解码/
|
||||
图形渲染/蒙太奇/音频的边界与错误分支(GPU、故障注入类注明原因)。
|
||||
- `oak-task/src/render.rs` 13 个内联 + `tests/render_test.rs` 4 个:
|
||||
`ForceParams`/timebase/租约分类/视频与音频 ticket/蒙太奇/效果链/
|
||||
调度队列;音频钩子错误、帧间取消、进度到位、非零起点偏移。
|
||||
- `oak-codec/src/ffmpeg.rs` 25 个:缓存查找/色彩元数据/像素与采样
|
||||
格式映射/时间基、真实媒体解码(缩放、缓存命中、EOF、音频 seek/
|
||||
重采样/抖动)、conform 音频(S16/F32、取消、缺目录)、探测器
|
||||
(字幕流、取消)、编码器往返与幂等。
|
||||
- `oak-app/panels/ofx_params.rs` 27 个 + `oakui/ofx.rs` 9 个:所有
|
||||
参数控件类型、值同步/吸管、事件路由、曲线 JSON、颜色选择器
|
||||
RGB/HSV 点击与拖拽/提交校验/取消;OFX 交互视口、图像打包与合成、
|
||||
按键符号、初始化幂等。
|
||||
- `oak-app/oakui/graphops.rs` 23 个 + `panels/timeline.rs` 12 个:
|
||||
工程/素材/命令/查询/放置/剪贴板/编辑/转场的错误矩阵;时间线上下文
|
||||
菜单、面板命令、拖放路由、落点解析、缩放/微移钳制、真实引擎回退。
|
||||
- 自有批次 8 个:`component/controls.rs`(Slider/SpinBox/ComboBox/
|
||||
CheckBox 的方法与渲染分支)、`oakui/mock.rs`(设置/代理/同步/
|
||||
多机位)、`oakui/engine.rs`(`AppEngine` 其余全部默认实现)。
|
||||
- 稳定性:`render_threads_test` 的三个逐字节比对测试固定软件解码
|
||||
(`OAK_HWACCEL=0` 的 RAII 守卫,测试锁内无竞态)——硬件与软件解码
|
||||
存在几 LSB 差异,此前表现为 ±3 字节的间歇性失败;连跑 5 次稳定。
|
||||
- 记录(未改生产代码):`graphops::roll_edit` 与文档描述不符——当前
|
||||
`BlockTrimCommand` 的 `TrimOut` 映射使左片段 in 移动、后继 out 移动,
|
||||
接缝不移动;`undocommands_test` 固化了同一行为,列为后续 PR 的语义
|
||||
缺陷候选。
|
||||
- 聚合(干净对象集,同口径):区域 **91.38%**、函数 **87.75%**、行
|
||||
**90.72%**(148231/163392,**行目标 90% 达成**)、分支 **65.98%**
|
||||
(9995/15149)。
|
||||
- 各 crate 行/分支:oak-app **92.5%** / 67.7%;oak-render 92.7% /
|
||||
67.7%;oak-codec 93.9% / 74.4%;oak-task 87.7% / 61.5%;
|
||||
oak-timeline 90.6% / 61.3%;oak-storage 82.7% / 65.5%;
|
||||
oak-plugin 79.2% / 51.7%(非 app 最大缺口)。
|
||||
- 下一步:分支 80% 目标还差 ~14pp。优先 oak-plugin
|
||||
(node_factory 222 / suites/property 165 / host 104 / instance 222 /
|
||||
render_driver 163 / clip 90)、oak-app(real.rs 712、app.rs 403、
|
||||
renderops 270、program_viewer 262、controls 230、nodegraph 213)与
|
||||
oak-worker/ofx_host(272 行)。
|
||||
|
||||
### 第五批(分支缺口,2026-09-19)
|
||||
|
||||
- **227 个新测试**(全 workspace 非插桩:104 个目标、**3069 passed /
|
||||
0 failed / 7 ignored**——ignored 为既有 GPU 门控):
|
||||
- oak-plugin 核心合计 46 个(`node_factory`/`instance`/`host` 三文件的
|
||||
组合计,非单文件计数):`node_factory`(用 build.rs 测试插件
|
||||
bundle 的确定性布局覆盖 build_core 组/页/颜色/组合框表、命名与
|
||||
派发、执行器分支)、`instance`(编辑事务、clip 偏好、RoD/RoI、
|
||||
渲染/GL 路径、序列渲染、interact)、`host`(dlopen、bundle 扫描、
|
||||
PluginCache 去重、build_plugin 上下文协商、实例存活计数)。
|
||||
- oak-plugin 套件/驱动合计 62 个(`render_driver`/`clip`/
|
||||
`suites/property`/`suites/gl_render` 四文件的组合计,非单文件计数):
|
||||
`render_driver`(CPU/GL 帧渲染、组件与深度矩阵、参数覆盖、输出写回
|
||||
与上传失败)、`clip`(fetch/store 转换矩阵与协商)、`suites/property`
|
||||
(属性套件全 API)、`suites/gl_render`(格式/纹理属性/加载与清理;
|
||||
GL 不可用路径跳过)。
|
||||
- oak-worker 39 个:`ofx_host`(共享内存 attach/帧池/输入读取/输出
|
||||
发布/作业处理与回退)与 `worker`(进度管道、渲染器回退、握手与
|
||||
加载、渲染/批量/音频 ticket、图形回退与崩溃钩子);新增全局工厂/
|
||||
颜色测试锁避免并行竞态。
|
||||
- oak-core/render 53 个:`procpool`(调度、取消、回收、段增长、关停
|
||||
排空、真实 worker 崩溃重启)、`videoparams`、`color` 分支。
|
||||
- oak-app 27 个:`renderops`(代理/分辨率/编码参数/重打包守卫)、
|
||||
`program_viewer`(事件路由/菜单/交互防护)、`nodegraph`(数据源/
|
||||
构建/连接/编辑)、`project_explorer`(事件/菜单/重命名/删除)与
|
||||
`mock`/`controls`/`inspector`(效果事件、指针与键盘路径、上下文
|
||||
与添加菜单)。
|
||||
- 生产缺陷修复(oak-plugin `clip.rs`):`store_output_image` 此前把像素
|
||||
写入 `texture_get_frame` 返回的深拷贝(CPU 纹理的写入被丢弃);现在
|
||||
CPU 直接回写 `f.data`、GPU 走上传、Planar 明确报错(与
|
||||
`render_driver::write_output_frame` 的既有修复一致),新测试固化。
|
||||
- 稳定性:修复本批 procpool 测试的三个自锁死锁(`cancel_frame` /
|
||||
`set_graph_snapshot` / `poll` 内部会锁 dispatcher,测试却在持锁时
|
||||
调用)、调度亲和性误设、U10 槽位尺寸期望与握手替身二进制;42 个
|
||||
procpool 测试全绿。
|
||||
- 聚合(干净对象集,同口径):区域 **93.11%**、函数 **88.99%**、行
|
||||
**92.62%**(162596/175544)、分支 **70.09%**(11024/15729)。
|
||||
- 各 crate 行/分支:oak-app **94.5%** / 71.0%;oak-plugin 79.2% →
|
||||
**90.9%** / 51.7% → **75.7%**;oak-render 94.3% / 70.4%;
|
||||
oak-core 93.5% / 75.4%;oak-worker 80.8% → **90.3%** / 52.1% →
|
||||
**70.3%**;oak-codec 93.9% / 74.4%;oak-task 87.7% / 61.3%;
|
||||
oak-timeline 90.6% / 61.3%;oak-storage 82.7% / 65.5%。
|
||||
- 下一步:分支 80% 还差 ~10pp。剩余分支热点:`real.rs`(428)、
|
||||
`eval.rs`(157)、`oak-task/render.rs`(150)、`worker.rs`(109)、
|
||||
`color.rs`(104)、`app.rs`(88)、`mock.rs`(87)、`graphops.rs`
|
||||
(84)、`backend.rs`(74)、`controls.rs`(71)、
|
||||
`undogeneral`/`undoripple`(各 67)。
|
||||
|
||||
### 第六批(分支缺口,2026-09-20)
|
||||
|
||||
- **102 个新测试**(全 workspace 非插桩:104 个目标全绿):
|
||||
- `oakui/real.rs` 15 个:时间线编辑事件的陈旧 id 守卫、文档导出/互换
|
||||
失败路径、未知 id 查找、素材/序列/文本/转场放置守卫、多机位与 AFV
|
||||
解析、代理自动启动与失败策略、源监视器回放窗口与陈旧取消、预览窗口
|
||||
陈旧完成释放与 BGRA8 槽读取、波形同步放置与不可相关跳过、帧助手。
|
||||
- `oak-render/eval.rs` 15 个(GPU/OCIO 夹具,缺环境时打印跳过)+
|
||||
`oak-task/render.rs` 3 个(私有调度器经 worker 渲染、缺失媒体错误)。
|
||||
- `oak-core/color.rs` 6 个、`backend.rs` 16 个(GPU 路径按适配器门控)、
|
||||
`oak-codec/ffmpeg.rs` 5 个(软件重开、EOF 回退、重采样平面/flush)。
|
||||
- `oak-worker/worker.rs` 7 个、`ofx_host.rs` 2 个、`oak-render/procpool.rs`
|
||||
12 个(死锁修复后的调度/回收/VRAM 探测/读取 EOF 等)。
|
||||
- `oak-app/controls.rs` 6 个、`mock.rs` 4 个、`app.rs` 10 个(滑块编辑
|
||||
与拖拽、复选框键盘、组合框选择、微调框滚动/键盘/编辑器;节点图与
|
||||
时间线事件、连接助手、放置路径;模态不匹配、进度排空、订阅路由、
|
||||
序列弹窗提交/取消、tick 循环、退出动作)。
|
||||
- `panels/node_editor.rs` 1 个(菜单路由、适配/缩放、dock 元数据)。
|
||||
- 本批无生产代码改动;各 agent 报告本 crate 套件全绿、clippy 无新增告警。
|
||||
- 聚合(干净对象集,同口径):区域 **93.90%**、函数 **89.61%**、行
|
||||
**93.46%**(173470/185601)、分支 **71.95%**(11553/16057)。
|
||||
- 各 crate 行/分支:oak-app **96.0%** / **76.6%**;oak-core 94.8% /
|
||||
77.5%;oak-render 95.0% / 69.7%;oak-codec 94.2% / 75.1%;
|
||||
oak-worker 91.9% / 70.7%;oak-task 88.8% / 62.8%;oak-timeline
|
||||
90.6% / 61.3%;oak-plugin 90.9% / 75.7%;oak-storage 82.7% / 65.5%。
|
||||
- 下一步:分支 80% 还差 ~8pp(约 1.3k 分支)。剩余热点:`real.rs`
|
||||
(321)、`eval.rs`(228)、`oak-task/render.rs`(136)、`ffmpeg.rs`
|
||||
(110)、`color.rs`(110)、`worker.rs`(108)、`graphops.rs`(82)、
|
||||
`procpool.rs`(76)、`ofx_params.rs`(68)、`undogeneral`(67)。
|
||||
|
||||
### 第七批(Review 修复,2026-09-22)
|
||||
|
||||
- 依据 `test-coverage-90-80-review.md` 修复全部高危/中危与 §5 条目(仅 §3.1
|
||||
的语义裁决按报告建议延后,准备项已落地)。要点:
|
||||
- §3.2:`render_test.rs` 私有调度器测试不再"永不失败"(环境错误跳过、
|
||||
产品错误失败,RAII 恢复管理器/env)。
|
||||
- §3.3:三个回放验收测试仅在**零交付**时跳过;`OAK_STRICT_PLAYBACK=1`
|
||||
严格模式;`WorkerBinGuard` 按 `current_exe` 解析 worker。
|
||||
- §3.4:CI 安装 `icc-profiles-free` + `system_icc()` 补 Ubuntu 实际路径;
|
||||
`gpu_context_for_import` 尊重 `OAK_REQUIRE_GPU` 并输出 `SKIP:` 标记。
|
||||
- M1–M10 与 §5:文档/断言/读回/容差/RAII 全部落实(详见 review §9)。
|
||||
- §3.1:以仓库内 C++ 上游源码核准语义;`RippleInfo::new` + 真实 info 测试
|
||||
落地;roll/slide/insert-gaps/ResizeWithMediaIn 的期望值加 KNOWN-SWAP
|
||||
标注,语义修复清单已细化(独立 PR)。
|
||||
- 追加修复:`source_monitor_playback_window_and_stale_cancels` 的早期
|
||||
playhead 断言缺陷;`preferences_general_tab_writes_cache_ahead_and_storage`
|
||||
的点击→按键焦点竞态。
|
||||
- 验收:全 workspace **104 目标、3179 passed / 0 failed / 7 ignored**。
|
||||
- 插桩终测(干净对象集,同口径):区域 **93.96%**、函数 **89.59%**、行
|
||||
**93.49%**(180742/193331)、分支 **71.58%**(11805/16491)。分支较第六批
|
||||
微降 0.37pp:本批以测试质量换掉了若干"容忍型/同义反复"执行路径(例如
|
||||
§3.3 的交付即失败、M3 的效果夹具更换),属预期代价而非回归。
|
||||
- 各 crate 行/分支:oak-app 96.0% / 76.3%;oak-plugin 90.8% / 76.1%;
|
||||
oak-render 94.9% / 69.4%;oak-core 94.2% / 75.5%;oak-codec 94.2% /
|
||||
75.1%;oak-worker 92.7% / 70.4%;oak-timeline 91.0% / 60.2%;
|
||||
oak-task 89.5% / 62.8%;oak-storage 82.9% / 66.6%。
|
||||
- 下一步仍为分支 80%(缺口 ~8.4pp);热点见上。
|
||||
|
||||
## 8. 风险与对策
|
||||
|
||||
1. **oak-app UI 覆盖成本最高、最易 flaky**:只用 test-support 的确定性
|
||||
接口(`run_until_parked`/`dispatch_keystroke`/`simulate_click`),
|
||||
禁止 sleep;固定 seed;面板测试按面板拆文件并行;CI 现有"失败重试
|
||||
一次"仅用于已知 flake,新增 flake 必须根治或 `#[ignore]` + 登记。
|
||||
2. **覆盖率驱动出坏测试**(断言实现细节、为行数写无意义 case):
|
||||
§2.1 行为断言 + review checklist;`#[coverage(off)]` 需登记理由。
|
||||
3. **分支覆盖工具不稳定(nightly `--branch`)**:固定
|
||||
`nightly-2026-07-21`;加一个"已知分支数"的 canary 文件(M0),
|
||||
工具链升级导致计数漂移时用 canary 对账。
|
||||
4. **跨平台合并复杂**:主门禁只认 Linux 全量;平台文件单独门禁;
|
||||
合并报告是可选增强,不被 PR 阻塞。
|
||||
5. **套件变慢**:M0 给测试加 `--no-fail-fast` + 超时;对 >2s 的单测
|
||||
标记并解释;GPU/媒体测试复用 `testmedia` 与共享 fixture;必要时
|
||||
`cargo nextest`(cargo-llvm-cov 原生支持)。
|
||||
6. **异常路径需要注入点**:优先用现有开关(`OAK_HWACCEL`、
|
||||
`OAK_GPU_IMPORT`、`OAK_PIPELINE`);不足的地方在 M0 加
|
||||
`FailPoint`/假后端,**不修改生产语义**。
|
||||
7. **既有 `#[ignore]`**:M2/M4 补齐 serializer C++ golden 与 OFX M11
|
||||
golden,其余确实缺外部环境的登记豁免并保留 `#[ignore]` 理由。
|
||||
8. **覆盖率只算生产代码后基线更低**:M0 先测主口径基线,再按 §7 校准
|
||||
各里程碑数字;若主口径比兼容口径低 10pp 以上,先做 M1 再宣布 M2 目标。
|
||||
|
||||
## 9. 不变量与边界
|
||||
|
||||
- **不改生产行为**:本计划只加测试、度量与最小可测性基建;任何为可测性
|
||||
做的重构(纯函数抽出、依赖注入)必须单独 PR、单独评审、行为不变。
|
||||
- **不引入不稳定因素**:无 sleep、无真实网络/时间依赖(外部依赖按 A3/A8
|
||||
跳过并打印理由);测试失败必须可复现。
|
||||
- **执行环境**:所有测试必须在 CI 的 headless(xvfb + lavapipe)通过;
|
||||
`OAK_REQUIRE_GPU=1` 下 GPU 测试真跑;硬件/平台测试在无硬件环境跳过,
|
||||
跳过不等于通过(报告里单列)。
|
||||
- **性能预算**:`cargo test --workspace` 墙钟时间相对 2026-09 基线不
|
||||
超过 2×;coverage job 目标 ≤45 分钟。
|
||||
- **豁免有账**:`unit-exemptions.md`、`exclusions.md`、边界清单三本账
|
||||
是验收物,缺登记视为未完成。
|
||||
- **文档同步**:`docs/zh/build.md` 增加覆盖率章节;`docs/zh/plans/README.md`
|
||||
收录本计划与 `coverage/` 归档目录。
|
||||
|
||||
## 10. 交付物清单
|
||||
|
||||
1. `tooling/coverage.sh`、`tooling/coverage_report.py`、
|
||||
`tooling/boundary_api.py`、`tooling/coverage-thresholds.toml`;
|
||||
2. `.github/workflows/coverage.yml` + `ci.yml` 接线(Linux 必跑,
|
||||
Windows/macOS 周更);
|
||||
3. `docs/zh/plans/coverage/`:
|
||||
`baseline-2026-09.{json,txt}`、`boundary-api-inventory.md`、
|
||||
`unit-exemptions.md`、`exclusions.md`、`final-<date>.{json,txt}`、
|
||||
`merged-<date>.txt`(可选);
|
||||
4. 新增测试:层 1 单测与层 2 边界测试(按 §6 里程碑分批);
|
||||
5. 本计划文档与 `docs/zh/plans/README.md` 索引更新。
|
||||
Reference in New Issue
Block a user