Test suite: richer diagnostics, headless accessibility audit, perf/leak sanity

Andre's three "bigger ideas" from RemSound-smoke-test-agent-brief.md:

- Richer diagnostics: --diagnostics now includes a live localhost audio self-check
  (PCM + Opus, with packet/underrun/drop/buffer/latency counters), the most recent
  session snapshot parsed from the log (codec, send/receive state, buffer, drops,
  heartbeat), and a recent-warnings/errors digest from the log. BuildDiagnosticsReport
  gained a runLiveAudioProbe flag so the self-test's privacy check stays fast.

- Headless accessibility audit: new --selftest step constructs the dialogs that can be
  built without hardware (Startup behaviour, Recording settings, Preferences) and checks
  every actionable control announces a name and that Alt-key mnemonics are unique within
  a container. MainForm is out of scope (its constructor opens audio/hotkeys/sockets).
  Dialogs that won't construct are skipped, not failed. Currently audits 3, no violations.

- Perf/leak sanity: new --perftest command runs several audio-loopback cycles and reports
  whether handle/memory/thread counts stay bounded (handles ratcheting up cycle-on-cycle is
  the leak fingerprint, given RemSound's handle-leak history). Lenient thresholds; logs the
  numbers for build-to-build comparison. Wired into run-tests.ps1.

- Shared AudioLoopback helper (used by the self-test, diagnostics and perf test) so all
  three exercise the identical real capture/encode/network/decode path on test port 47929.

- csproj: the four previously-unconditional cue Content items are now Exists-guarded like
  the rest, so a mid-edit sounds\ folder doesn't break the dev build; the gate still
  enforces the required cues before release.

Help + manual updated (--perftest, --smoke-test, --config-dir, richer --selftest).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-06-12 23:45:08 +01:00
co-authored by Claude Opus 4.8
parent 832ed40bf7
commit ad66fe5364
7 changed files with 329 additions and 43 deletions
+8 -4
View File
@@ -62,19 +62,23 @@
user-supplied custom cue paths set in Preferences override the defaults at runtime.
Filenames containing a space (e.g. "record start.wav") are preserved verbatim on
copy so the load-by-filename path in TryLoadCueSound finds them exactly as written. -->
<Content Include="..\..\sounds\connect.wav">
<!-- Exists-guarded like the newer cues below: a missing source WAV (e.g. while the project owner
is swapping in new cue sounds) must not break the dev build. The release gate (run-tests.ps1
and the self-test "Bundled resources present" step) enforces that the required cues are
actually present before a release ships, so guarding here loses no safety. -->
<Content Include="..\..\sounds\connect.wav" Condition="Exists('..\..\sounds\connect.wav')">
<Link>sounds\connect.wav</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\sounds\disconnect.wav">
<Content Include="..\..\sounds\disconnect.wav" Condition="Exists('..\..\sounds\disconnect.wav')">
<Link>sounds\disconnect.wav</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\sounds\record start.wav">
<Content Include="..\..\sounds\record start.wav" Condition="Exists('..\..\sounds\record start.wav')">
<Link>sounds\record start.wav</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\sounds\record stop.wav">
<Content Include="..\..\sounds\record stop.wav" Condition="Exists('..\..\sounds\record stop.wav')">
<Link>sounds\record stop.wav</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>