Files
Jake 2491c7a7dd
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia-rebrand — fix Codex cross-model review blockers
Codex independent review found 11 blockers post-cascade. All addressed.

CRITICAL (data-loss / crash):

10. crates/core/src/paths.rs — migrate_legacy_data_dir_inner used
    fs::rename which fails with EXDEV when source + target are on
    different filesystems (encrypted-home, bind mounts, separate
    $XDG_DATA_HOME partition). Combined with the Phase 5 QC fix that
    made migration errors fatal, this would crash on first launch
    for any user whose data dir spans filesystems. Added
    rename_or_copy_tree() that falls back to copy_dir_recursive +
    remove_dir_all on CrossesDevices / errno 18 (EXDEV). Symlinks
    preserved verbatim. Same fallback applied to magnotia.db ->
    lumotia.db inside the dir.

11. Added 4 unit tests: copy_dir_recursive preserves nested
    structure, rename_or_copy_tree same-filesystem happy path,
    is_cross_device classifies CrossesDevices kind + raw errno 18.

Doc residuals (blockers 1-9):

1. crates/cloud-providers/Cargo.toml — "Wyrdnote pending rebrand"
   description.
2. crates/cloud-providers/src/provider.rs — module docs + test
   fixture Wyrdnote refs.
3. crates/transcription/src/orchestrator.rs — module docs + test
   fixture Wyrdnote refs.
4. docs/roadmap/2026-05-10-pkm-phase-tooling-shortlist.md — phase
   name + outputs/wyrdnote path refs.
5. docs/architecture-map/04-llm-formatting-mcp/llm-tests.md —
   MAGNOTIA_LLM_TEST_MODEL env var.
6. .../cloud-providers-stubs.md — MAGNOTIA_API_KEY_*.
7. docs/architecture-map/03-audio-transcription/tests-and-fixtures.md
   — MAGNOTIA_WHISPER_*.
8. docs/gpu-tuning/plan.md — MAGNOTIA_BENCH_RUN.
9. docs/superpowers/specs/2026-05-09-battery-gpu-aware-thread-tuning-
   design.md + corresponding plan — MAGNOTIA_POWER_STATE_OVERRIDE,
   MAGNOTIA_INFERENCE_THREADS.

cargo test --workspace: 343 pass / 0 fail (up from 339; +4 EXDEV
fallback tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:39:21 +01:00

7.8 KiB
Raw Permalink Blame History

name, type, slice, last_verified
name type slice last_verified
Tests and fixtures architecture-map-page 03-audio-transcription 2026/05/09

Tests and fixtures

Where you are: Architecture mapAudio + Transcription → Tests and fixtures

Plain English summary. This slice has three categories of test. Inline unit tests under #[cfg(test)] mod tests exercise every public type (capture monitor detection, resampler duration preservation, RmsVadChunker state machine, LocalAgreement invariants, buffer trim bounds, model-manager hash and resume paths). Integration tests under crates/transcription/tests/ exercise whisper-rs end-to-end with env-var-gated fixtures so CI without a model checkpoint exits quietly. Test-only fixtures include in-tree tokio::net::TcpListener HTTP servers that simulate Range / 5xx / no-Range-honour servers for the download stack.

At a glance

  • Crate: lumotia-transcription (mostly) and lumotia-audio (inline only).
  • Paths:
    • crates/audio/src/{capture,decode,wav,resample,streaming_resample}.rs — inline #[cfg(test)] modules.
    • crates/transcription/src/{model_manager,local_engine,transcriber,streaming/*}.rs — inline #[cfg(test)] modules.
    • crates/transcription/tests/whisper_rs_smoke.rs — env-gated load + transcribe.
    • crates/transcription/tests/jfk_bench.rs — env-gated benchmark with cold/warm RTF.
    • crates/transcription/tests/thread_sweep.rs — env-gated thread-count scaling sweep.
  • External deps (dev): tempfile 3, tokio (rt, sync, net, io-util, macros), num_cpus 1 (label-only).

Inline unit tests (selected highlights)

lumotia-audio

  • capture.rs:570monitor_pattern_detection for the PulseAudio / PipeWire heuristics.
  • decode.rs:262mid_stream_io_error_propagates_instead_of_returning_partial_audio. RB-09 regression: a flaky MediaSource (FlakyCursor, decode.rs:203) injects an I/O error after the probe header and asserts the function errors instead of returning Ok(partial).
  • wav.rs:170wav_writer_survives_crash. Uses std::mem::forget to skip the hound finaliser, simulating a process kill, then asserts the flushed prefix is recoverable via read_wav.
  • wav.rs:235read_wav_surfaces_truncated_sample_stream_errors. 2026-04-22 regression: the previous filter_map(|s| s.ok()) swallowed errors silently.
  • streaming_resample.rs:182streaming_48k_to_16k_preserves_duration. Pushes 1 s of 48 kHz audio in 700-sample chunks (forcing the residual-buffer path) and asserts the output is within 50 ms of 1 s at 16 kHz.
  • resample.rs:84resample_preserves_approximate_duration.

lumotia-transcription

  • streaming/rms_vad.rs:371:734 — comprehensive state-machine coverage: silence, hysteresis, onset gating, max-chunk continuity (max_chunk_split_preserves_audio_contiguity), padded-final-frame regression (flush_preserves_hit_max_chunk_from_padded_final_frame, flush_preserves_end_of_utterance_chunk_from_padded_final_frame — both 2026-04-22 CRITICAL C2 fixes), idempotent flush.
  • streaming/commit_policy.rs:212:402 — LocalAgreement-n correctness: text-only equality, non-shrinkage invariant, defensive shorter-pass handling (shorter_pass_after_commit_does_not_panic, regression for the latest[committed_count..] panic), n=3 behaviour.
  • streaming/buffer_trim.rs:56:206 — defensive non-finite handling, integration test against LocalAgreement::last_committed_end_secs, the long-session bound proof (trim_bounds_buffer_over_long_session).
  • model_manager.rs:339:615 — three TcpListener-backed fixtures (spawn_range_server, spawn_no_range_server, spawn_500_server) drive download_file through the resume path, the ResumeUnsupported path (server returns 200 to a Range request), the 5xx rejection path, and the SHA-mismatch cleanup path.
  • local_engine.rs:218engine_reports_not_available_before_loading.
  • transcriber.rs:54transcriber_trait_is_object_safe (compile-time witness).

Env-gated integration tests (crates/transcription/tests/)

All three skip silently if the env vars are unset, so cargo test on a fresh machine is a no-op for them.

whisper_rs_smoke.rs

  • Env vars: LUMOTIA_WHISPER_TEST_MODEL (path to a ggml/gguf Whisper model).
  • Loads the context, builds a state, calls set_initial_prompt("Wren, CORBEL, ADHD") (proves the API still exists), runs inference on 1 s of silence, exercises full_n_segments and get_segment(i).to_str(). Smoke test only; assertion is "did this run without panicking".

jfk_bench.rs

  • Env vars: LUMOTIA_WHISPER_TEST_MODEL, LUMOTIA_WHISPER_TEST_AUDIO (path to a 16 kHz mono 16-bit PCM WAV — assertions in the test enforce this format on the fixture, not the runtime).
  • Reports cold-load time, cold-transcribe RTF, warm-transcribe RTF, peak RSS read from /proc/{pid}/status. Hardcodes set_n_threads(6) for both runs (so a sweep across thread counts is a separate test, not this one).

thread_sweep.rs

  • Same env vars as jfk_bench.rs. Adds LUMOTIA_POWER_STATE_OVERRIDE (set internally per panel to ac or battery) so inference_thread_count returns its predicted pick for each combination of (power state × GPU offload) and the empirical RTF table can be compared against the helper's choice.
  • Runs the JFK clip at n_threads = 1, 2, 4, physical, logical (plus 8 if logical ≥ 8), takes the min of two runs per setting, prints a four-panel table:
    1. AC, CPU.
    2. AC, GPU (Vulkan).
    3. battery, CPU.
    4. battery, GPU (Vulkan).
  • Uses num_cpus::get() and num_cpus::get_physical() purely for the printed labels (thread_sweep.rs:35). The runtime helper inference_thread_count(Workload::Whisper, gpu_offloaded) does the actual prediction.
  • vulkan_runtime_ok snapshot taken once via cfg!(feature = "whisper-vulkan") && vulkan_loader_available().

Watch-outs

  • All three integration tests are quiet on missing env vars. A green cargo test does NOT mean the Whisper path works; it means "either the path works or you didn't set the env vars". CI configurations must explicitly set LUMOTIA_WHISPER_TEST_MODEL to exercise these.
  • jfk_bench.rs hardcodes n_threads = 6. Production code uses inference_thread_count(Workload::Whisper, gpu_offloaded) which is power-aware. Bench numbers are not directly comparable to runtime numbers without rerunning with the helper-picked thread count.
  • thread_sweep.rs mutates LUMOTIA_POWER_STATE_OVERRIDE via env::set_var. Globally process-wide. Concurrent tests in the same cargo test invocation that read LUMOTIA_POWER_STATE_OVERRIDE will race. The test removes the var at the end (thread_sweep.rs:94).
  • tempfile 3 is a dev-dep, not a runtime dep. Production code never creates temp files.
  • num_cpus = "1" (the version, not "one CPU"). Test-only labelling; production uses the slice 5 helper.
  • In-tree HTTP fixtures use ephemeral ports (bind 127.0.0.1:0) and run on a tokio task. No port-collision risk, but a paranoid sandbox that blocks raw TCP loopback would break these tests.
  • ModelFile's &'static str fields force the test helper leak() (model_manager.rs:462). Each test leaks a few small strings. Acceptable for one-shot tests; do not copy this pattern into production code.

See also

  • Transcription model manager — the production code these download tests guard.
  • Transcription whisper — the production code these integration tests guard.
  • Transcription streaming — exhaustive unit-test coverage lives alongside this code.
  • docs/whisper-ecosystem/brief.md — the source of the items (#6, #8, #19, #21, #24, #25) repeatedly referenced in test docstrings.
  • docs/code-review-2026-04-22.md — the audit pass that produced the C2, RB-09, and read_wav regressions captured here.