Lint the commits being pushed and scope overlay failures per sensor

The pre-push gate linted only the dirty tree, so the commits about to be pushed went
unchecked; and every failed overlay projection was sticky, which cost a finger result its
overlay over one bad frame while box results were retried nowhere. gate.ps1 now takes
-LintBase (default origin/main, exit 2 on an unknown ref), the projector declares whether
its own failures are permanent, and serve_stored_view decides before it sets the view.
Verified with gate.ps1 (PASS: 569 studio + 485 shared tests, 632 ui_check checks) and the
two round-2 red samples kept in scratch.
This commit is contained in:
ykcheungab
2026-10-18 21:17:03 +08:00
parent 0998009ec3
commit c37efd7a44
9 changed files with 648 additions and 260 deletions
@@ -0,0 +1,147 @@
"""How long an overlay-base failure lasts: one frame, or the whole session.
R2 of ``docs/test-repair-rework.zh.md``. The second round made every failed projection
sticky, so one bad finger frame cost that result its overlay view for the session — a
behaviour change beyond the box case it was written for. The scope is now the
projector's own declaration (``overlay_base.OverlayBaseProjector``), never a guess made
from a ``None`` or from an exception's text:
* a **finger** unroll that loses a frame is transient — the next frame is tried and the
session is *not* marked unavailable;
* a **box** stitch that cannot rebuild the lenslet grid on this footage is permanent —
the session records it and stops asking, so scrubbing does not rebuild the same
failure on every cursor move;
* a projector that cannot be **opened** at all is permanent, because no frame can work.
No SDK and no recording are involved: the projector is given a stand-in ``project``, and
the session is handed that projector directly, so these run on any machine.
"""
from __future__ import annotations
from pathlib import Path
from types import SimpleNamespace
import numpy as np
import pytest
from orisys_app_shared.analysis.model import Provenance
from orisys_app_shared.analysis.overlay_base import (
OverlayBaseProjector,
projection_failures_are_permanent,
)
from orisys_studio.replay_analysis import AnalysisSession
FRAME = np.zeros((6, 6, 3), dtype=np.uint8)
BASE = np.full((6, 6, 3), 7, dtype=np.uint8)
class _Reader:
"""The smallest reader ``AnalysisSession`` accepts, with no result behind it."""
complete = True
key = "overlay-scope"
directory = Path(".")
frame_ids = np.array([1, 2], dtype=np.int64)
times = np.array([0.0, 0.1])
keyframes: dict = {}
provenance = Provenance()
def mask(self):
return None
def frame(self, frame_id):
return SimpleNamespace(depth=np.zeros((6, 6), dtype=np.float32))
def grid(self, grid_id):
raise AssertionError("no grid in this stub")
def _session(projector) -> AnalysisSession:
"""A session whose projector is supplied directly (its provenance is not used)."""
session = AnalysisSession(_Reader())
session._overlay = projector
return session
def test_one_bad_finger_frame_does_not_cost_the_session_its_overlay():
"""A finger unroll that fails on one frame is retried on the next."""
answers = [None, BASE]
projector = OverlayBaseProjector(
sensor_type="finger",
project=lambda image: answers.pop(0),
projection_failures_are_permanent=False,
)
session = _session(projector)
assert session.overlay_base(FRAME, frame_id=1) is None
assert session.overlay_unavailable is False, "one frame made the whole result unavailable"
base = session.overlay_base(FRAME, frame_id=2)
assert base is not None, "the second frame was never projected"
assert np.array_equal(base, BASE)
assert session.overlay_unavailable is False
def test_a_finger_projection_that_raises_is_also_only_that_frame():
"""The exception text is not consulted: a raising finger projection is transient."""
answers = [RuntimeError("unroll miss"), BASE]
def project(image):
answer = answers.pop(0)
if isinstance(answer, Exception):
raise answer
return answer
session = _session(
OverlayBaseProjector(
sensor_type="finger",
project=project,
projection_failures_are_permanent=False,
)
)
assert session.overlay_base(FRAME, frame_id=1) is None
assert session.overlay_unavailable is False
assert session.overlay_base(FRAME, frame_id=2) is not None
def test_a_box_projection_that_fails_is_permanent_and_is_not_retried():
"""A box stitch that fails will fail again; the session stops asking."""
calls: list[int] = []
def project(image):
calls.append(1)
return None
session = _session(OverlayBaseProjector(sensor_type="box", project=project))
assert session.overlay_base(FRAME, frame_id=1) is None
assert session.overlay_unavailable is True
assert session.overlay_base(FRAME, frame_id=2) is None
assert len(calls) == 1, "a permanent failure was retried on the next frame"
def test_a_projector_that_cannot_open_is_permanent(monkeypatch):
"""No projector at all is the other permanent case: no frame could ever work."""
calls: list[int] = []
@classmethod
def _cannot_open(cls, provenance):
calls.append(1)
return None
monkeypatch.setattr(OverlayBaseProjector, "open_from_provenance", _cannot_open)
session = AnalysisSession(_Reader())
assert session.overlay_base(FRAME, frame_id=1) is None
assert session.overlay_unavailable is True
assert session.overlay_base(FRAME, frame_id=2) is None
assert len(calls) == 1, "opening was retried after it had already failed"
@pytest.mark.parametrize(
("sensor_type", "permanent"),
(("finger", False), ("box", True)),
)
def test_the_sensor_decides_which_kind_of_failure_it_has(sensor_type, permanent):
"""The policy lives with the sensor's opener, not in each caller's judgement."""
assert projection_failures_are_permanent(sensor_type) is permanent