Skip to content

test: full test-suite overhaul (post-#784) — master tracking #797

@SlyWombat

Description

@SlyWombat

Status

Master tracking issue for the post-#784 test-suite overhaul. Files #789-#796 are the per-tier child issues spec'd by #787.

This is a planning deliverable — every test file in the repo is accounted for in some child issue's inventory (KEEP / REWRITE / DELETE / ADD). No code changes have been made; the children describe the work the implementer executes.

Architectural context (load before any execution)

The moving-head aim/cal subsystem has been entirely rewritten under #784. Key invariants the test suite must obey post-#784:

  • mountedInverted is NEVER consulted at runtime. Inversion lives in fixture.rotation = [0, 180, 0]. Any test that asserts mountedInverted changes runtime DMX is wrong → REWRITE to drive rotation, or DELETE.
  • homeSecondary is FIRST-CLASS — the per-fixture sign source for AimSphere. Construction without Secondary HARD-FAILS with "fixture <id> has no homeSecondary direction calls + offsets". Tests that omit Secondary while expecting aim to work need it added; tests that previously asserted "Secondary deprecated" need rewrite. (Operator's 2026-05-03 reversal on feat: rewrite moving-head aim/cal from scratch — new aim/ package, no legacy imports (supersedes #780, #783) #784.)
  • Canonical aim endpoint: POST /api/mover/<fid>/aim {x,y,z} or {azDeg,elDeg}. Old /aim-angles is alias-only, deletes in PR-7.
  • aim/park.go_home(fid) is the canonical "park to home" helper. Tests for park / blackout / abort / cancel / release should drive through it.
  • Stage convention (Z-up, +X = stage-LEFT, tilt+ = above horizon, pan+ = beam toward +X) is asserted at aim/ module boundaries. Tests reinforce.

Deletion-track summary (PR-7 / PR-η)

Confirmed deletion list per #784 PR-7 + #782 PR-η:

  • desktop/shared/coverage_math.py IK functions: solve_dmx_per_degree, angles_to_dmx, dmx_to_angles, world_to_fixture_pt, fixture_aim_to_world. (_mount_rotation/_matvec/_transpose may stay if camera-coverage code consumes them.)
  • desktop/shared/sphere_model.py (the pre-feat: rewrite moving-head aim/cal from scratch — new aim/ package, no legacy imports (supersedes #780, #783) #784 pseudo-sphere class).
  • desktop/shared/mover_calibrator.py (entire file — SMART probe loop, _set_mover_dmx, _beam_detect_flash, _confirm, _dark_reference, _depth_at_pixel, pan_tilt_to_ray, aim_to_pan_tilt, all legacy battleship/BFS/v2 cal threads).
  • parent_server.py cal routes (/api/calibration/mover/*), _smart_* helpers, _write_dmx_pose, the cal-mode pulldown.
  • The aim-angles legacy alias (after one release).
  • Tests targeting the above: tests/test_coverage_math.py, tests/test_mover_calibration.py, tests/test_mover_inverted.py, tests/test_sphere_model.py, tests/test_sphere_model-DAVEBOOK-5.py, plus ~20 cal-related test files.
  • tools/emulate_smart_pipeline.py and tests/fixtures/cal/corpus.json (replaced by sphere-model corpus + runner).

The home/secondary/* POST routes STAY — Secondary is first-class per the 2026-05-03 reversal.

Bugs the test gap should have caught

Per #785 round-2 QA (2026-05-03), three concrete bugs in the running aim/sphere.py:

  • Bug 1pan_sign not derived from homeSecondary.panMovedDirection ("right" + offset > 0 should yield pan_sign = -1, but is using +1). All ArUco-marker pans land inverted.
  • Bug 2 — Below-horizon hemisphere not populated when home is at a tilt extreme. Floor targets snap to equator (tilt_dmx16 ≈ 0).
  • Bug 3current_pose plumbing makes one-off HTTP /aim calls non-deterministic (engine-last-write leaks into multi-valued branch picking).
  • Bug 4 — Degenerate target (target == fixture_xyz) returns valid DMX instead of None.
  • Bug 5aim_xyz(target) and aim_direction(stage_az_from_target, stage_el_from_target) return different DMX (XYZ→angle reduction in routes layer not byte-equivalent to direct angular path).

The Tier 1 + Tier 7 ADD rows lock these down.

Child issue list

Tier # Title Scope
1 #789 Python unit tests overhaul (post-#784) Top-level pytest scripts. ~25 DELETE files, surgical REWRITE in test_parent.py, ADD rows for aim/park, sphere round-trip, current_pose determinism, blackout.
2 #790 Camera-node tests overhaul Mostly orthogonal — KEEP test_camera.py, test_beam_detector.py, etc. Single REWRITE row for any cal-integration subsection.
3 #791 Child-node firmware tests Clean KEEP set — UDP protocol v4 unchanged. No deletes, no rewrites.
4 #792 Regression suite overhaul mountedInverted rewrites in 4 files, test_smart_pipeline_emulator.py DELETE, test_post_cal_confirm.py AUDIT, NEW test_save_home_wizard.py + test_park.py.
5 #793 Visual / Playwright suite overhaul Calibration tab DELETE, Save-Home wizard NEW Playwright test, screenshot baselines + Word manual cal-section regen, mountedInverted migration UI test.
6 #794 Android tests overhaul Operator-only app audit. KEEP all 5 JVM unit tests. REWRITE rows for any mountedInverted or aim-angles references.
7 #795 Tools / corpus overhaul Replace tools/emulate_smart_pipeline.py + corpus with tools/sphere_corpus_runner.py + tests/fixtures/aim/sphere_corpus.json. 15 required case categories spec'd.
8 #796 Dev GUI infrastructure tools/devgui/test_registry.py rewrite to drop deleted-test entries; one-click runner shortcuts for new tests.

PR sequencing (overall merge order)

Per #782 status update + this overhaul:

  1. PR-α / PR-β / PR-γ / PR-δ — already landed (lamp helpers, go_home, sphere endpoint, park-path migrations).
  2. PR-3 / fix(#784 PR-3): aim/sphere.py — 2°-cell precomputed lookup, bilinear bracketing-cell blend, clipped-target nearest-row fallback #785 fixes — sphere sign derivation, current_pose defaulting, degenerate-target guard, aim_xyz round-trip. Land WITH the corresponding ADD-row tests in tests/aim/test_sphere.py and tests/aim/test_routes.py (Tier 1).
  3. PR-6 — Save-Home wizard backend + aimSphere persistence. Land WITH NEW tests/aim/test_save_home_persistence.py (Tier 1) + NEW tests/test_save_home_wizard.py Playwright (Tier 5) + NEW regression wrapper (Tier 4).
  4. PR-εmover_control rewire onto aim/sphere.py. Land WITH REWRITE rows in test_dmx_moving_heads.py, test_remote_math.py, test_mover_control.py (Tier 1) + mountedInverted rewrite in 4 regression files (Tier 4).
  5. PR-7 / PR-η — mass deletion. Every DELETE row in every tier lands in this PR. Includes: 25 cal-test files (Tier 1), test_advanced_scan_recommend.py Playwright (Tier 5), test_smart_pipeline_emulator.py regression shell (Tier 4), tools/emulate_smart_pipeline.py + corpus (Tier 7), tools/devgui/test_registry.py registry update (Tier 8). NEW sphere-corpus + runner + regression wrapper (Tier 7) replace the deleted SMART corpus + emulator in the SAME PR. CLAUDE.md ## Cal-pipeline change checklist (#733) updates with the new runner path.
  6. PR-ζbake_engine Option-A migration (angle-pair bake). Re-validate test_dmx_actions.py, test_dmx_bake.py, test_show_generator.py, test_show_playback.py, test_smart_bake.py, test_capability_bake_e2e.py, test_timeline_bake.py, test_mover_tracking.py.

Done definition

Cross-references to existing test issues

Architecture predecessors / drivers

Open questions surfaced in child issues (collated for human review)

Tier 1:

  1. Is parametric_mover.py on PR-7 deletion list, or retained for a non-cal consumer?
  2. Is fixture_pose_solver.py (feat: Verify fixture pose wizard — operator-driven X/Z calibration before mover-cal #699) on the deletion list?
  3. Where do pixel_to_stage / stage_to_pixel / pick_calibration_targets relocate when mover_calibrator.py deletes?
  4. Where do pan_tilt_to_ray / aim_to_pan_tilt (consumed by test_remote_math.py) relocate?
  5. Does the Save-Home wizard reuse _set_calibrating / _fixture_is_calibrating, or need a fresh lock primitive?
  6. Does _apply_marker_z_alignment + /api/space/shift survive PR-7?
  7. Does cal_trace recorder get repurposed for wizard diagnostics or delete?
  8. Does the Save-Home wizard ever consume pick_calibration_targets?
  9. Does DMX-test continue to 423 during a wizard step?

Tier 2:

  1. Does tests/test_camera.py have a SMART-driven subsection?
  2. Does tests/test_cv_engine.py import from mover_calibrator?

Tier 4:

  1. Does tools/post_cal_confirm.py survive PR-7?
  2. Does mover_calibrations.json survive PR-7?
  3. Does test_beam_detect_canary.py driver use a deletion-track route?

Tier 5:

  1. Does test_spa.py have a Calibration-tab subsection?
  2. Does the Save-Home wizard live under a new SPA tab, modal, or fixture-edit dialog?
  3. Is the 3D Coverage overlay shipping in feat: rewrite moving-head aim/cal from scratch — new aim/ package, no legacy imports (supersedes #780, #783) #784 or deferred?
  4. Are screenshot_capture.py baselines pre-feat: replace 2-pair affine cal with profile-derived sphere model — Home-only calibration, Secondary deprecated (supersedes #780 P1+P2) #783 or post-feat: replace 2-pair affine cal with profile-derived sphere model — Home-only calibration, Secondary deprecated (supersedes #780 P1+P2) #783?
  5. Is test_red_chair.py Playwright or unit?

Tier 6:

  1. Does ApiIntegrationTest.kt call /api/calibration/mover/*?
  2. Is mountedInverted carried in the Android-deserialized JSON?
  3. Does Android Mover Control drive /api/mover/<fid>/aim directly or via /api/remotes/<id>/orient?

Tier 7:

  1. Fate of tools/post_cal_confirm.py and tools/cal_trace/?
  2. Does the corpus runner exercise HTTP /aim or in-process AimSphere only?
  3. Is step=128 the right default for the corpus?

Tier 8:

  1. Does test_registry.py use auto-discovery or a hardcoded list?
  2. Is the Dev GUI used in CI?

These are aggregated from #789-#796. Most resolve via a 5-minute audit during execution; a few need operator decisions (parametric_mover fate, post_cal_confirm fate, cal_trace fate, wizard lock primitive, coverage overlay timing).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions