Files
chanora/tools/windows-smoke.md
T
EdisonJwa 21945979a3 test(audio,ptt): comprehensive Windows P0 unit-test suite (L0-L11)
Layered test coverage for the Windows PTT subsystem ahead of the
v1.0.0-rc.8 official release sign-off.

L0 (refactor)
- Extract three pure-logic dispatchers from the existing WndProc /
  LowLevelKeyboardProc / LowLevelMouseProc bodies in
  crates/chanora_audio/src/ptt_backends/windows.rs:
    dispatch_raw_input(ctx, &RAWINPUT)
    dispatch_hook_keyboard(ctx, wparam, &KBDLLHOOKSTRUCT)
    dispatch_hook_mouse(ctx, wparam, &MSLLHOOKSTRUCT)
  Each takes a small Context (AtomicBinding + AudioTransmitGate +
  flags) and is callable without spinning up any Win32 plumbing.
  The real Win32 procs unchanged structurally; they unpack lparam
  and forward to the dispatchers. AtomicBinding / RawInputContext
  / HookContext / resolve_binding are now pub(crate) so the
  in-file test module can drive them.

L1 — windows_keymap full-table sweep (+13 tests)
  Every key_label_to_vk arm, all A-Z + a-z, all 0-9, F1-F20,
  navigation, modifiers, OEM punctuation, numpad. Exhaustive
  mouse_label_to_button cases including the 0x08 / 0x10 /
  unknown-bitmask fallbacks.

L2 — AtomicBinding lock-free correctness
  store/read round-trip, clear(), Default = zeros, single-writer
  / single-reader concurrency, many-readers / single-writer.

L3 — resolve_binding dispatcher tests
  All PttInputClass variants, well-known labels, unknown-label
  fallback, mismatched class+label rejection, mouse bitmask
  resolution.

L4 — Backend state-machine
  Both WindowsRawInputBackend and WindowsHookBackend:
  descriptor() pre-arm vs post-arm (L0Focused -> L2/L3), start()
  with None binding rejection, rebind() in-place, stop()
  clears + idempotent, stop() after stop() no-op.

L5 — dispatch_raw_input table
  Keyboard match/non-match, key-down/key-up via Flags & 0x01,
  no-binding short-circuit, mouse XBUTTON1/XBUTTON2 down/up
  matching the bound button, unhandled HID type. RAWINPUT structs
  built via mem::zeroed plus field-fill, owning the unsafe in
  the test layer where it belongs.

L6 — dispatch_hook_keyboard + dispatch_hook_mouse
  WM_KEYDOWN / WM_KEYUP / WM_SYSKEYDOWN / WM_SYSKEYUP for the
  keyboard path, WM_XBUTTONDOWN / WM_XBUTTONUP for the mouse
  path. Same shape as L5.

L7 — Privacy invariant (crates/chanora_audio/tests/ptt_privacy.rs)
  New cross-platform integration test installs a custom
  tracing_subscriber Layer that records every emitted event's
  target + field names. Exercises the public PTT API plus (on
  Windows) the backend factory. Asserts no field name in the
  banned list (vk, scan_code, keysym, key_label, bound_key,
  binding, platform_key, VKey, wVk, wScan, kbflags, mouseflags)
  is ever emitted and every field belongs to the DEC-027
  allow-list. Adds tracing-subscriber as a dev-dependency on
  chanora_audio.

L8 — Full-chain integration in core/chanora_core/src/ptt.rs
  Windows-only mod windows_full_chain_tests:
    zero-tail full chain (synchronous)
    default-tail full chain (200 ms wait then off)
    mid-press rebind abandons in-flight press

L9/L10/L11 — tools/windows-smoke.cmd + tools/windows-smoke.md
  Batch smoke script + operator doc. cargo build, flutter build,
  artifact existence + size checks, headless launch with stderr
  capture, bridge-initialised log assertion. Distinct exit codes
  per failure step. Doc explains invocation + common failure
  modes.

Verification (Linux)
- cargo check --workspace: clean.
- cargo test --workspace: 78 passed / 0 failed / 3 ignored.
  76 cross-platform unit tests (unchanged) plus the new
  ptt_privacy integration test plus one new ignored portal smoke
  test.

The Windows-gated tests (~49 new) compile and run on the Korean
Windows 11 host where they belong; cross-compile from Linux is
not configured locally. The smoke script is the production
acceptance gate for rc.8 on Windows.

Deviations from the original plan are minor (single ignored
real-runtime test rather than per-platform attribute, L7 uses
public API rather than pub(crate) dispatchers, dispatchers live
inside windows.rs rather than a sibling module) and documented
in the subagent report.
2026-05-16 00:47:10 +08:00

3.8 KiB

tools/windows-smoke.cmd — Korean host smoke build + launch

End-to-end "does Chanora build and start on Windows" verification. Designed for the lead's Korean Windows 11 test host and the product/scaffold-v0 branch. Run from any directory inside the checked-out repo:

C:\Users\admin\chanora> tools\windows-smoke.cmd

The script pushd's to the repo root (resolved from its own location), so the working directory does not matter as long as the script lives in tools\ inside the checkout.

What it does

  1. Prepends Flutter + Cargo + MSVC to PATH and runs vcvars64.bat. Hard-coded paths assume the Korean host layout. If a path changes, edit the set "PATH=..." and call "...\vcvars64.bat" lines near the top.
  2. cargo build -p chanora_bridge --release and checks target\release\chanora_bridge.dll exists and is at least 5 MB.
  3. flutter build windows --release inside apps\chanora_flutter and checks the runner + data\app.so.
  4. Copies the bridge DLL into the Flutter release folder.
  5. Launches the runner for five seconds with stderr redirected to %TEMP%\chanora-smoke.log, then kills it.
  6. Greps the log for bridge initialised (must be present) and panicked (must be absent).
  7. Prints PASS and exits 0 on success.

Exit codes

Code Step
0 PASS
1 vcvars64.bat failed
2 cargo build -p chanora_bridge --release failed
3 bridge DLL missing or smaller than 5 MB
4 flutter build windows --release failed
5 chanora_flutter.exe missing
6 data\app.so missing or smaller than 1 MB
7 bridge DLL copy into the Release folder failed
9 log did not contain bridge initialised (bridge didn't load / panic at init)
10 log contained panicked (Rust panic during the 5 s smoke window)

Common failure modes

  • vcvars64 returns non-zero: MSVC not installed at the expected path. Update the call "...\vcvars64.bat" line or install the Build Tools workload from the VS2022 installer.
  • cargo build fails with link.exe not found: vcvars64 did not take effect. Re-run from a fresh cmd.exe (PowerShell has its own quirks here).
  • Bridge DLL exists but smaller than 5 MB: a debug build slipped in. Make sure the script's --release flag was honoured; check that no [profile.release] override is stripping symbols too aggressively.
  • data\app.so smaller than 1 MB: Flutter assets did not bundle. Run flutter clean then re-run the script.
  • bridge initialised absent: the bridge extern symbol is not being found by the Flutter side. Verify the DLL copy step ran (it did, or the script would have exited 7) and that the DLL name matches what lib/main.dart's ffi setup expects.
  • panicked present: open %TEMP%\chanora-smoke.log (the script dumps it on failure) and read the panic message. The most common cause during scaffold development is a missing flutter-rust-bridge code-gen file; re-run the codegen step per docs/release/desktop-build-runbook.md.

Manual rerun of just the launch step

The PASS path always tears the runner down. If you want to inspect the running application after a green smoke pass:

target\release\chanora_bridge.dll  (already copied into Release\)
apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe

Launching the EXE directly will reuse the copied DLL.