Files
silver_pose/v1/tests/test_fall_state.py
ilaandClaude Opus 4.8 04422d9ca0 fix(v1): wire model confidence, explicit source mode, unique event ids
A: PoseAdapter.set_confidence_threshold is applied on start, so the
   settings model-confidence field actually affects inference.
B: config source.mode ('stream'|'replay') is explicit; app no longer
   guesses the source type from the URL prefix.
C: FallStateMachine takes a session_id and from_config generates a
   unique one per run, so event ids never collide across restarts
   (no screenshot overwrite or duplicate JSONL identity in a day).

51 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:54:34 +08:00

136 lines
4.7 KiB
Python

import pytest
from v1.fall_state import Evidence, FallState, FallStateMachine
CONFIG_VERSION = "cfg-test-20260721"
def test_confirmed_event_is_emitted_once_after_persistent_evidence():
machine = FallStateMachine(
confirm_window_seconds=1.8,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
assert machine.update("P-0007", Evidence(True, True), now=0.0) == []
events = machine.update("P-0007", Evidence(True, True), now=1.8)
assert len(events) == 1
assert events[0].track_id == "P-0007"
assert events[0].latency_seconds == 1.8
assert events[0].config_version == CONFIG_VERSION
assert machine.update("P-0007", Evidence(True, True), now=2.0) == []
assert machine.state_of("P-0007") is FallState.CONFIRMED
def test_brief_low_posture_returns_to_normal_without_event():
machine = FallStateMachine(
confirm_window_seconds=1.0,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
machine.update("P-0007", Evidence(True, True), now=0.0)
events = machine.update("P-0007", Evidence(True, False), now=0.3)
assert events == []
assert machine.state_of("P-0007") is FallState.NORMAL
def test_rejected_pose_resets_suspect_and_cannot_shorten_confirmation_window():
machine = FallStateMachine(
confirm_window_seconds=1.0,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
machine.update("P-0007", Evidence(True, True), now=0.0)
machine.update("P-0007", Evidence(False, False), now=0.9)
events = machine.update("P-0007", Evidence(True, True), now=1.1)
assert events == []
assert machine.state_of("P-0007") is FallState.SUSPECT
def test_recovery_must_persist_before_new_event_is_allowed():
machine = FallStateMachine(
confirm_window_seconds=1.0,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
machine.update("P-0007", Evidence(True, True), now=0.0)
first_event = machine.update("P-0007", Evidence(True, True), now=1.0)
assert len(first_event) == 1
machine.update("P-0007", Evidence(True, False, True), now=1.1)
machine.update("P-0007", Evidence(True, False, True), now=3.1)
assert machine.state_of("P-0007") is FallState.NORMAL
machine.update("P-0007", Evidence(True, True), now=4.0)
second_event = machine.update("P-0007", Evidence(True, True), now=5.0)
assert len(second_event) == 1
assert first_event[0].event_id != second_event[0].event_id
def test_confirmation_window_must_remain_within_customer_target():
with pytest.raises(ValueError, match="between 1 and 3"):
FallStateMachine(
confirm_window_seconds=0.9,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
def test_session_id_makes_event_ids_unique_across_runs():
run_a = FallStateMachine(
confirm_window_seconds=1.0, recovery_window_seconds=2.0,
config_version="cfg", session_id="run-a",
)
run_b = FallStateMachine(
confirm_window_seconds=1.0, recovery_window_seconds=2.0,
config_version="cfg", session_id="run-b",
)
run_a.update("P-0001", Evidence(True, True), now=0.0)
event_a = run_a.update("P-0001", Evidence(True, True), now=1.0)
run_b.update("P-0001", Evidence(True, True), now=0.0)
event_b = run_b.update("P-0001", Evidence(True, True), now=1.0)
assert event_a[0].event_id != event_b[0].event_id
assert "run-a" in event_a[0].event_id
assert "run-b" in event_b[0].event_id
def test_each_track_has_an_independent_confirmation_window():
machine = FallStateMachine(
confirm_window_seconds=1.0,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
)
machine.update("P-0001", Evidence(True, True), now=0.0)
machine.update("P-0002", Evidence(True, True), now=0.6)
first_events = machine.update("P-0001", Evidence(True, True), now=1.0)
second_events = machine.update("P-0002", Evidence(True, True), now=1.6)
assert first_events[0].track_id == "P-0001"
assert second_events[0].track_id == "P-0002"
assert first_events[0].event_id != second_events[0].event_id
def test_cooldown_delays_recovery_after_confirmation():
machine = FallStateMachine(
confirm_window_seconds=1.0,
recovery_window_seconds=2.0,
config_version=CONFIG_VERSION,
cooldown_seconds=3.0,
)
machine.update("P-0007", Evidence(True, True), now=0.0)
machine.update("P-0007", Evidence(True, True), now=1.0)
machine.update("P-0007", Evidence(True, False, True), now=1.1)
assert machine.state_of("P-0007") is FallState.CONFIRMED
machine.update("P-0007", Evidence(True, False, True), now=4.0)
assert machine.state_of("P-0007") is FallState.RECOVERING