Files
oak-editor/crates/oaktask/COVERAGE.md
T
Mike-Solar 013a175707 refactor: workspace layout — crates/, app at root, legacy C++ removed
Single mechanical restructure commit:
- root Cargo.toml = oakapp bin + workspace; one cargo build produces
  oakapp, oak-cli, oak-worker, liboakengine.dylib
- app/rust/src -> src/ (app at repo root, no rust/ nesting)
- src/<mod>/rust -> crates/oak<mod>; src/oakcore-rs -> crates/oakcore;
  src/bindings/oakotio -> crates/oakotio; src/engine/rust ->
  crates/oakengine (keeps cdylib+staticlib+rlib)
- public C headers include/<mod>/ -> crates/oakengine/include/<mod>/
- OFX SDK headers vendored into crates/oakplugin/ofx/ (HostSupport gone)
- legacy deleted: old src/ C++ modules, engine/, core/, ffmpeg_bridge/,
  app/ (Qt), cli/worker C++, root CMakeLists, third_party/KDDockWidgets
  submodule, otio-install, all build-* output (~40GB)
- oakstorage kept but excluded from the workspace (skeleton w/ todos);
  gpui excluded (own workspace)
- verified: cargo build green, cargo test --workspace 1845/0
  (with the documented OCIO_RS_* env override for the homebrew OCIO)
2026-08-10 20:24:25 +08:00

7.7 KiB

oaktask coverage map

Maps every C++ task class/method in src/task/src to its Rust home in this crate. The C++ code remains the parity source of truth; // CPP-PARITY: markers in the Rust files point at the exact C++ file. Review this map before touching a task class so you rewrite the right module.

C++ class / file (src/task/src/...) Rust home
task.holive::Task base src/task.rs
taskmanager.hTaskManager src/manager.rs
codecbridge.h — submitter registration src/codecbridge.rs + src/bridge/codec.rs
conform/conform.hConformTask src/conform.rs
customcache/customcachetask.h src/customcache.rs
export/export.hExportTask src/export.rs
precache/precachetask.hPreCacheTask src/precache.rs
proxy/proxy.hProxyTask src/proxy.rs
render/render.hRenderTask base src/render.rs
project/import/import.h src/project/import.rs
project/load/load.h src/project/load.rs
interchange-format dispatch (task-side) src/project/format.rs
project/loadotio/loadotio.h src/project/loadotio.rs
project/save/save.h src/project/save.rs
project/saveotio/saveotio.h src/project/saveotio.rs

Parity / golden tests

Golden source Rust test
ConformTask::derive_filenames (conform.h) tests/parity_test.rs::conform_derive_filenames
ProxyTask::build_arguments (proxy.h) tests/parity_test.rs::proxy_build_arguments
ProxyTask::parse_progress (proxy.h) tests/parity_test.rs::proxy_parse_progress
src/task/tests/task_test.cpp (manager/task) tests/manager_test.rs, tests/ffi_contract_test.rs
include/task/*.h (C ABI contract) tests/ffi_contract_test.rs
loadotio.cpp (OTIO -> project) tests/otio_test.rs::otio_load_*, fcpxml_load_* (synthetic documents built with oakotio)
saveotio.cpp (project -> OTIO) tests/otio_test.rs::otio_save_*, fcpxml_save_* (exports re-parsed with oakotio)
extension dispatch (.otio/.fcpxml) tests/otio_test.rs::otio_load_extension_dispatch_matrix (+ unknown-extension failures on both tasks)

Couplings handled through other modules' C ABIs

The task module never reimplements another oak module. Every cross-module call is a declared extern "C" import in src/bridge/, mirroring the frozen headers verbatim:

  • oakrender: bridge/render.rs — cancelatom (OakCancelAtom), tickets (OakRenderTicket, oakrender_ticket_*), project copier (OakRenderProjectCopier), color processor (OakColorProcessor), frame cache (OakRenderCache).
  • oakcodec: bridge/codec.rs — encoder/decoder (OakEncoder/OakDecoder), frames (OakFrame), task submitter (oakcodec_set_task_submit_cb, OakCodecTaskRequest), proxy params (oakcodec_proxy_params).
  • oaknode: bridge/node.rs — project/footage/folder/sequence/colormanager/ node handles for the project tasks.
  • oakundo: bridge/undo.rsOakUndoCommand.
  • oakcommon / oakcore: bridge/common.rsOakVideoParams, OakColorTransform, OakAudioParams.

Deliberately out of scope

  • Export/precache render details — the C++ render loop is a concurrent ticket pool; the Rust render.rs is a simplified synchronous loop (one ticket at a time, wait()ed). The per-frame observable contract (ordered frame_downloaded/audio_downloaded, progress, cancellation) is preserved. The export task additionally skips the temporary-file rename dance and the sidecar subtitle encoder.

export.cpp.pending / export.h.pending in src/task/src/export/ are in-progress variants; src/export.rs is mapped to the canonical export.h.

OpenTimelineIO was previously out of scope (OTIO parsing stayed in the C++ impl); since oakotio landed it is covered: LoadOTIOTask/SaveOTIOTask parse/serialize through oakotio (see README decision #6) and the project graph still moves across the oaknode/oaktimeline C ABIs only. The tasks are format-aware: src/project/format.rs dispatches .otio (OpenTimelineIO JSON) vs .fcpxml (FCPXML) from the filename extension (case-insensitive) at the parse/serialize call; the track/clip/footage code is shared, and the C ABI is unchanged (the format parameter is the filename itself).

Test strategy

  • tests/common/mod.rs provides #[no_mangle] stubs for every extern C symbol the crate imports (test binaries link the rlib without the real module DLLs). Each stub family exposes set_* controls so tests drive both the success and the failure path. The oakrender ticket stubs are compiled out when the real-oakrender feature is on.
  • tests/manager_test.rs drives the codec submitter end-to-end: a real shell script stands in for ffmpeg (proxy success + 3 failure modes), and conform success/failure/cancellation are exercised through real file renames.
  • tests/render_real_integration_test.rs (feature real-oakrender + --test filter; links the real oakrender crate) drives RenderTask::render against the actual ticket arena — frames arrive in timestamp order through the CPU path, no GPU.
  • Every exported oaktask_* symbol has at least one success and one failure-path test (tests/ffi_contract_test.rs, tests/project_task_test.rs).

Coverage (cargo tarpaulin, 2026-08)

86.53% line coverage (1850/2138). Per-file (lines covered/total):

File Covered
src/bridge/node.rs 4/4
src/bridge/render.rs 29/36
src/codecbridge.rs 49/49
src/conform.rs 72/79
src/customcache.rs 43/45
src/error.rs 4/8
src/export.rs 104/113
src/ffi/manager.rs 25/27
src/ffi/project.rs 173/180
src/ffi/task.rs 94/98
src/ffi/taskhandle.rs 44/46
src/handle.rs 29/56
src/manager.rs 67/89
src/precache.rs 33/43
src/project/format.rs 8/8
src/project/import.rs 184/235
src/project/load.rs 36/51
src/project/loadotio.rs 201/224
src/project/save.rs 28/41
src/project/saveotio.rs 196/220
src/proxy.rs 114/141
src/render.rs 215/242
src/task.rs 98/103

The remaining gaps are the panic-guard helpers (handle.rs, exercised only through #[no_mangle] exports that return codes directly), the load/save serializer code-map alternatives, and a few import/manager edge branches — all reachable but not individually asserted.

The concurrent render loop (src/render.rs) is exercised both through the export run-path tests and the dedicated concurrency suite (tests/render_loop_test.rs: scrambled completion order, audio-first ordering, cancel drain, progress monotonicity, error stop, windowing).