feat(perception): integrate calibrated operator pipeline
Add calibrated K1 projection, recorded and near-live perception qualification, unified Rerun operator layers, bounded replay admission, audited viewer controls, worker experiments, and lab evidence.
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import threading
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -64,7 +67,7 @@ class FakeVisualizationRuntime:
|
||||
self.source_mode = "idle"
|
||||
self.source_ready = False
|
||||
self.pcl_frames = 0
|
||||
self.start_calls: list[tuple[str, Path, float, str]] = []
|
||||
self.start_calls: list[tuple[str, Path, float | None, str]] = []
|
||||
self.stop_calls = 0
|
||||
self.stop_error: Exception | None = None
|
||||
|
||||
@@ -102,7 +105,7 @@ class FakeVisualizationRuntime:
|
||||
host: str,
|
||||
out_dir: Path,
|
||||
*,
|
||||
duration_seconds: float,
|
||||
duration_seconds: float | None,
|
||||
project_name: str,
|
||||
) -> None:
|
||||
self.start_calls.append((host, out_dir, duration_seconds, project_name))
|
||||
@@ -195,6 +198,132 @@ def service_with_fake_runtime(
|
||||
return service, runtime
|
||||
|
||||
|
||||
def _wifi_status_read(ipv4: str) -> dict[str, Any]:
|
||||
return {
|
||||
"schema_version": 1,
|
||||
"profile_id": "xgrids-k1-fw3-wifi-v1",
|
||||
"observed_at_utc": "2026-07-20T12:00:00Z",
|
||||
"adapter": "CoreBluetooth",
|
||||
"bleak_version": "test",
|
||||
"device_macos_uuid": "test-ble-transport",
|
||||
"device_name": "XGR-K1",
|
||||
"service_uuid": "00007f00-0000-1000-8000-00805f9b34fb",
|
||||
"status_characteristic_uuid": "00007f02-0000-1000-8000-00805f9b34fb",
|
||||
"operation": "single_reviewed_wifi_status_read",
|
||||
"write_performed": False,
|
||||
"status": {
|
||||
"value_length": 54,
|
||||
"mode": "WIFI_CLIENT",
|
||||
"ipv4": ipv4,
|
||||
"status_code": 1,
|
||||
"reserved": 0,
|
||||
"trailer_hex": "",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_verify_connection_refreshes_dynamic_dhcp_address_and_rotates_session(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._selected_device_id = "test-ble-transport" # noqa: SLF001
|
||||
service._connection_mode = "bridge" # noqa: SLF001
|
||||
service._k1_ip = "10.255.254.54" # noqa: SLF001
|
||||
service._device_id = "known-k1" # noqa: SLF001
|
||||
service._device_session_id = "old-device-session" # noqa: SLF001
|
||||
service._device_session_opened_at = "2026-07-20T10:00:00Z" # noqa: SLF001
|
||||
service._device_calibration = {"status": "available"} # noqa: SLF001
|
||||
|
||||
async def fake_status_read(*_: object, **__: object) -> dict[str, Any]:
|
||||
return _wifi_status_read("10.255.254.77")
|
||||
|
||||
monkeypatch.setattr(facade_module, "read_wifi_status_once", fake_status_read)
|
||||
monkeypatch.setattr(facade_module, "_target_is_local_ipv4", lambda _target: False)
|
||||
|
||||
state = service.verify_connection()
|
||||
|
||||
assert state["k1_ip"] == "10.255.254.77"
|
||||
assert state["device_session"]["device_session_id"] != "old-device-session"
|
||||
assert state["connection_verification"] == {
|
||||
"status": "live-address-observed",
|
||||
"endpoint_validation": "ble-wifi-status-read",
|
||||
"network_reachability": "not-probed",
|
||||
"address_changed": True,
|
||||
"previous_address_present": True,
|
||||
"write_performed": False,
|
||||
"observed_at": "2026-07-20T12:00:00Z",
|
||||
}
|
||||
assert state["device_calibration"]["status"] == "unavailable"
|
||||
|
||||
|
||||
def test_implicit_acquisition_target_uses_current_ble_dhcp_address(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._selected_device_id = "test-ble-transport" # noqa: SLF001
|
||||
service._connection_mode = "bridge" # noqa: SLF001
|
||||
service._k1_ip = "10.255.254.54" # noqa: SLF001
|
||||
|
||||
async def fake_status_read(*_: object, **__: object) -> dict[str, Any]:
|
||||
return _wifi_status_read("10.255.254.77")
|
||||
|
||||
monkeypatch.setattr(facade_module, "read_wifi_status_once", fake_status_read)
|
||||
monkeypatch.setattr(facade_module, "_target_is_local_ipv4", lambda _target: False)
|
||||
|
||||
state = service.prepare_acquisition(
|
||||
PrepareAcquisitionRequest(
|
||||
project_name=PROJECT_NAME,
|
||||
compatibility_attestation=ATTESTATION,
|
||||
)
|
||||
)
|
||||
|
||||
assert state["k1_ip"] == "10.255.254.77"
|
||||
assert state["acquisition"]["target_host"] == "10.255.254.77"
|
||||
|
||||
|
||||
def test_control_session_opens_against_current_ble_dhcp_address(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._selected_device_id = "test-ble-transport" # noqa: SLF001
|
||||
service._connection_mode = "bridge" # noqa: SLF001
|
||||
service._k1_ip = "10.255.254.54" # noqa: SLF001
|
||||
service._compatibility_attestation = {"profile": "exact"} # noqa: SLF001
|
||||
opened_hosts: list[str] = []
|
||||
|
||||
class FakeOpenControlSession:
|
||||
def snapshot(self) -> dict[str, object]:
|
||||
return {"state": "idle", "can_confirm_standby": False}
|
||||
|
||||
def open(self, *, host: str, **_: object) -> dict[str, object]:
|
||||
opened_hosts.append(host)
|
||||
return self.snapshot()
|
||||
|
||||
async def fake_status_read(*_: object, **__: object) -> dict[str, Any]:
|
||||
return _wifi_status_read("10.255.254.77")
|
||||
|
||||
service._application_control_session = FakeOpenControlSession() # type: ignore[assignment] # noqa: SLF001
|
||||
monkeypatch.setattr(facade_module, "read_wifi_status_once", fake_status_read)
|
||||
monkeypatch.setattr(facade_module, "_target_is_local_ipv4", lambda _target: False)
|
||||
|
||||
state = service.open_application_control_session(
|
||||
OpenApplicationControlSessionRequest(
|
||||
operator_present=True,
|
||||
owner_controlled_device=True,
|
||||
lixelgo_closed=True,
|
||||
battery_storage_confirmed=True,
|
||||
expected_physical_state_confirmed=True,
|
||||
timezone_name="Europe/Moscow",
|
||||
)
|
||||
)
|
||||
|
||||
assert opened_hosts == ["10.255.254.77"]
|
||||
assert state["k1_ip"] == "10.255.254.77"
|
||||
|
||||
|
||||
def test_prepare_creates_provisional_device_session_and_profiled_acquisition(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
@@ -237,11 +366,26 @@ def test_project_name_is_normalized_and_control_characters_are_rejected() -> Non
|
||||
)
|
||||
|
||||
|
||||
def test_acquisition_is_unbounded_by_default_and_accepts_ten_hour_hint() -> None:
|
||||
unbounded = PrepareAcquisitionRequest(
|
||||
project_name=PROJECT_NAME,
|
||||
host="192.168.1.20",
|
||||
compatibility_attestation=ATTESTATION,
|
||||
)
|
||||
ten_hours = PrepareAcquisitionRequest(
|
||||
project_name=PROJECT_NAME,
|
||||
host="192.168.1.20",
|
||||
duration_seconds=10 * 60 * 60,
|
||||
compatibility_attestation=ATTESTATION,
|
||||
)
|
||||
|
||||
assert unbounded.duration_seconds is None
|
||||
assert ten_hours.duration_seconds == 36_000
|
||||
|
||||
|
||||
def test_connection_modes_require_their_exact_topology_attestation() -> None:
|
||||
assert ConnectRequest(
|
||||
device_id="synthetic-device",
|
||||
ssid="synthetic-network",
|
||||
password=SecretStr(PRIMARY_TEST_CREDENTIAL),
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
).connection_mode == "quick-connect"
|
||||
@@ -253,12 +397,18 @@ def test_connection_modes_require_their_exact_topology_attestation() -> None:
|
||||
compatibility_attestation=DIRECT_CONNECT_ATTESTATION,
|
||||
).connection_mode == "direct-connect"
|
||||
with pytest.raises(ValidationError):
|
||||
ConnectRequest(
|
||||
device_id="synthetic-device",
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=ATTESTATION,
|
||||
)
|
||||
with pytest.raises(ValidationError, match="host Wi-Fi profile"):
|
||||
ConnectRequest(
|
||||
device_id="synthetic-device",
|
||||
ssid="synthetic-network",
|
||||
password=SecretStr(PRIMARY_TEST_CREDENTIAL),
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=ATTESTATION,
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
)
|
||||
with pytest.raises(ValidationError, match="32 UTF-8 bytes"):
|
||||
ConnectRequest(
|
||||
@@ -790,10 +940,10 @@ def test_camera_arm_failure_seals_stopped_session_before_releasing_lease(
|
||||
_host: str,
|
||||
out_dir: Path,
|
||||
*,
|
||||
duration_seconds: float,
|
||||
duration_seconds: float | None,
|
||||
project_name: str,
|
||||
) -> None:
|
||||
assert duration_seconds > 0
|
||||
assert duration_seconds is None
|
||||
assert project_name == PROJECT_NAME
|
||||
events.append("start")
|
||||
out_dir.mkdir(parents=True)
|
||||
@@ -1855,50 +2005,97 @@ def test_network_provisioning_is_single_flight_and_secret_is_unwrapped_only_at_b
|
||||
assert {item["status"] for item in provision_operations} == {"succeeded", "failed"}
|
||||
|
||||
|
||||
def test_quick_connect_associates_the_host_without_a_ble_write(
|
||||
def test_quick_connect_activates_the_device_ap_then_associates_the_host(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._devices = [{"device_id": "k1-a"}] # noqa: SLF001
|
||||
service._devices = [{"device_id": "k1-a", "name": "XGR-TEST-A"}] # noqa: SLF001
|
||||
activation_calls: list[str] = []
|
||||
association_calls: list[tuple[Path, str, str]] = []
|
||||
ble_session_open = False
|
||||
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"ensure_wifi_profile_from_credential_source",
|
||||
lambda *_args, **_kwargs: {
|
||||
"schema_version": 1,
|
||||
"adapter": "macOS Keychain",
|
||||
"available": True,
|
||||
"profile_enrolled": True,
|
||||
"credential_source": "exact-firmware-profile",
|
||||
},
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def fake_activation_session(
|
||||
device_id: str, **_: object
|
||||
) -> AsyncIterator[dict[str, Any]]:
|
||||
nonlocal ble_session_open
|
||||
activation_calls.append(device_id)
|
||||
ble_session_open = True
|
||||
try:
|
||||
yield {
|
||||
"profile_id": "xgrids-k1-fw3-quick-connect-ap-v1",
|
||||
"started_at_utc": "2026-07-19T15:00:00Z",
|
||||
"completed_at_utc": "2026-07-19T15:00:01Z",
|
||||
"outcome": "ap_ready_observed",
|
||||
"ready_observed": True,
|
||||
"write_performed": True,
|
||||
"write_mode": "with_response",
|
||||
}
|
||||
finally:
|
||||
ble_session_open = False
|
||||
|
||||
def fake_associate(
|
||||
helper_path: Path,
|
||||
ssid: str,
|
||||
password: str,
|
||||
profile_id: str,
|
||||
expected_ssid: str,
|
||||
**_: object,
|
||||
) -> dict[str, Any]:
|
||||
association_calls.append((helper_path, ssid, password))
|
||||
assert ble_session_open
|
||||
association_calls.append((helper_path, profile_id, expected_ssid))
|
||||
return {
|
||||
"schema_version": 1,
|
||||
"adapter": "CoreWLAN",
|
||||
"outcome": "associated",
|
||||
"already_associated": False,
|
||||
"profile_enrolled": True,
|
||||
"scan_attempt_count": 2,
|
||||
"scan_elapsed_ms": 900,
|
||||
"credential_source": "system-wifi-keychain",
|
||||
}
|
||||
|
||||
async def forbidden_ble_write(*_: object, **__: object) -> dict[str, Any]:
|
||||
raise AssertionError("Quick Connect must not provision the K1 over BLE")
|
||||
async def forbidden_provisioning_write(*_: object, **__: object) -> dict[str, Any]:
|
||||
raise AssertionError("Quick Connect must not send router credentials to the K1")
|
||||
|
||||
monkeypatch.setattr(facade_module, "associate_with_wifi_once", fake_associate)
|
||||
monkeypatch.setattr(facade_module, "provision_wifi_once", forbidden_ble_write)
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"device_ap_activation_session",
|
||||
fake_activation_session,
|
||||
)
|
||||
monkeypatch.setattr(facade_module, "associate_with_wifi_profile_once", fake_associate)
|
||||
monkeypatch.setattr(facade_module, "provision_wifi_once", forbidden_provisioning_write)
|
||||
monkeypatch.setattr(facade_module, "_target_is_local_ipv4", lambda _target: False)
|
||||
|
||||
state = asyncio.run(
|
||||
service.connect(
|
||||
ConnectRequest(
|
||||
device_id="k1-a",
|
||||
ssid="XGR-TEST",
|
||||
password=SecretStr(PRIMARY_TEST_CREDENTIAL),
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assert activation_calls == ["k1-a"]
|
||||
assert not ble_session_open
|
||||
assert len(association_calls) == 1
|
||||
assert association_calls[0][0].name == "associate_wifi.swift"
|
||||
assert association_calls[0][1:] == ("XGR-TEST", PRIMARY_TEST_CREDENTIAL)
|
||||
assert association_calls[0][1] == facade_module.quick_connect_host_profile_id(
|
||||
"XGR-TEST-A"
|
||||
)
|
||||
assert association_calls[0][2] == "XGR-TEST-A"
|
||||
assert state["connection_mode"] == "quick-connect"
|
||||
assert state["k1_ip"] == "192.168.56.1"
|
||||
assert state["compatibility"]["attestation"]["topology"] == "device-ap"
|
||||
@@ -1909,7 +2106,12 @@ def test_quick_connect_associates_the_host_without_a_ble_write(
|
||||
encoding="utf-8"
|
||||
)
|
||||
assert PRIMARY_TEST_CREDENTIAL not in redacted_manifest
|
||||
assert "XGR-TEST" not in redacted_manifest
|
||||
assert "host_wifi_profile_id" in redacted_manifest
|
||||
assert '"host_wifi_profile_ready_before_device_write": true' in redacted_manifest
|
||||
assert '"credentials_resolved_by_plugin": true' in redacted_manifest
|
||||
assert "credential_provider_id" in redacted_manifest
|
||||
assert "device_ap_activation_profile_id" in redacted_manifest
|
||||
assert (quick_sessions[0] / "ap-activation.redacted.json").exists()
|
||||
assert service._camera_target_for_session( # noqa: SLF001
|
||||
state["device_session"]["device_session_id"]
|
||||
) == "192.168.56.1"
|
||||
@@ -1928,7 +2130,7 @@ def test_direct_connect_reuses_the_reviewed_ble_provisioning_frame(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._devices = [{"device_id": "k1-a"}] # noqa: SLF001
|
||||
service._devices = [{"device_id": "k1-a", "name": "XGR-TEST-A"}] # noqa: SLF001
|
||||
provisioning_calls: list[tuple[str, str, str]] = []
|
||||
|
||||
async def fake_provision(
|
||||
@@ -1952,7 +2154,7 @@ def test_direct_connect_reuses_the_reviewed_ble_provisioning_frame(
|
||||
monkeypatch.setattr(facade_module, "provision_wifi_once", fake_provision)
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"associate_with_wifi_once",
|
||||
"associate_with_wifi_profile_once",
|
||||
forbidden_host_association,
|
||||
)
|
||||
monkeypatch.setattr(facade_module, "_target_is_local_ipv4", lambda _target: False)
|
||||
@@ -1979,28 +2181,182 @@ def test_direct_connect_reuses_the_reviewed_ble_provisioning_frame(
|
||||
)
|
||||
|
||||
|
||||
def test_quick_connect_missing_credential_provider_stops_before_ap_write(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._devices = [{"device_id": "k1-a", "name": "XGR-TEST-A"}] # noqa: SLF001
|
||||
service._selected_device_id = "previous-k1" # noqa: SLF001
|
||||
service._k1_ip = "192.168.1.20" # noqa: SLF001
|
||||
service._connection_mode = "bridge" # noqa: SLF001
|
||||
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"ensure_wifi_profile_from_credential_source",
|
||||
lambda *_args, **_kwargs: {
|
||||
"schema_version": 1,
|
||||
"adapter": "macOS Keychain",
|
||||
"available": False,
|
||||
"profile_enrolled": False,
|
||||
"credential_source": None,
|
||||
},
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def forbidden_activation(
|
||||
*_args: object, **_kwargs: object
|
||||
) -> AsyncIterator[dict[str, Any]]:
|
||||
raise AssertionError("missing host credential must stop before the K1 AP write")
|
||||
yield {}
|
||||
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"device_ap_activation_session",
|
||||
forbidden_activation,
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match="credential-source-unavailable"):
|
||||
asyncio.run(
|
||||
service.connect(
|
||||
ConnectRequest(
|
||||
device_id="k1-a",
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
state = service.state()
|
||||
assert state["selected_device_id"] == "previous-k1"
|
||||
assert state["k1_ip"] == "192.168.1.20"
|
||||
assert state["connection_mode"] == "bridge"
|
||||
assert not list(service.evidence_root.glob("*viewer_k1_ap_association*"))
|
||||
operation = next(
|
||||
item for item in state["operations"] if item["action"] == "network.provision"
|
||||
)
|
||||
assert operation["status"] == "failed"
|
||||
assert operation["error"]["side_effect_status"] == "none"
|
||||
assert operation["error"]["safe_to_retry"] is True
|
||||
|
||||
|
||||
def test_quick_connect_does_not_start_host_wifi_without_ap_ready_flag(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._devices = [{"device_id": "k1-a", "name": "XGR-TEST-A"}] # noqa: SLF001
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"ensure_wifi_profile_from_credential_source",
|
||||
lambda *_args, **_kwargs: {
|
||||
"schema_version": 1,
|
||||
"adapter": "macOS Keychain",
|
||||
"available": True,
|
||||
"profile_enrolled": False,
|
||||
"credential_source": "exact-firmware-profile",
|
||||
},
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def not_ready_session(
|
||||
*_: object, **__: object
|
||||
) -> AsyncIterator[dict[str, Any]]:
|
||||
yield {
|
||||
"profile_id": "xgrids-k1-fw3-quick-connect-ap-v1",
|
||||
"started_at_utc": "2026-07-19T15:00:00Z",
|
||||
"completed_at_utc": "2026-07-19T15:00:15Z",
|
||||
"outcome": "no_status_change_before_timeout",
|
||||
"ready_observed": False,
|
||||
"write_performed": True,
|
||||
"write_mode": "with_response",
|
||||
}
|
||||
|
||||
def forbidden_association(*_: object, **__: object) -> dict[str, Any]:
|
||||
raise AssertionError("host Wi-Fi must wait for the canonical AP-ready flag")
|
||||
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"device_ap_activation_session",
|
||||
not_ready_session,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"associate_with_wifi_profile_once",
|
||||
forbidden_association,
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match="не подтвердил готовность"):
|
||||
asyncio.run(
|
||||
service.connect(
|
||||
ConnectRequest(
|
||||
device_id="k1-a",
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
quick_sessions = sorted(service.evidence_root.glob("*viewer_k1_ap_association*"))
|
||||
assert len(quick_sessions) == 1
|
||||
assert (quick_sessions[0] / "ap-activation.redacted.json").exists()
|
||||
assert not (quick_sessions[0] / "manifest.redacted.json").exists()
|
||||
|
||||
|
||||
def test_failed_connection_change_revokes_the_previous_route(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service, _ = service_with_fake_runtime(tmp_path)
|
||||
service._devices = [{"device_id": "k1-a"}] # noqa: SLF001
|
||||
service._devices = [{"device_id": "k1-a", "name": "XGR-TEST-A"}] # noqa: SLF001
|
||||
service._selected_device_id = "previous-k1" # noqa: SLF001
|
||||
service._k1_ip = "192.168.1.20" # noqa: SLF001
|
||||
service._connection_mode = "bridge" # noqa: SLF001
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"ensure_wifi_profile_from_credential_source",
|
||||
lambda *_args, **_kwargs: {
|
||||
"schema_version": 1,
|
||||
"adapter": "macOS Keychain",
|
||||
"available": True,
|
||||
"profile_enrolled": False,
|
||||
"credential_source": "exact-firmware-profile",
|
||||
},
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def fake_activation_session(
|
||||
*_: object, **__: object
|
||||
) -> AsyncIterator[dict[str, Any]]:
|
||||
yield {
|
||||
"profile_id": "xgrids-k1-fw3-quick-connect-ap-v1",
|
||||
"started_at_utc": "2026-07-19T15:00:00Z",
|
||||
"completed_at_utc": "2026-07-19T15:00:01Z",
|
||||
"outcome": "ap_ready_observed",
|
||||
"ready_observed": True,
|
||||
"write_performed": True,
|
||||
"write_mode": "with_response",
|
||||
}
|
||||
|
||||
def failed_association(*_: object, **__: object) -> dict[str, Any]:
|
||||
raise RuntimeError("offline association fixture failed")
|
||||
raise facade_module.HostWifiProfileError(
|
||||
"network-not-found",
|
||||
scan_attempt_count=4,
|
||||
scan_elapsed_ms=15014,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(facade_module, "associate_with_wifi_once", failed_association)
|
||||
monkeypatch.setattr(
|
||||
facade_module,
|
||||
"device_ap_activation_session",
|
||||
fake_activation_session,
|
||||
)
|
||||
monkeypatch.setattr(facade_module, "associate_with_wifi_profile_once", failed_association)
|
||||
|
||||
with pytest.raises(RuntimeError, match="offline association fixture failed"):
|
||||
with pytest.raises(RuntimeError, match="network-not-found"):
|
||||
asyncio.run(
|
||||
service.connect(
|
||||
ConnectRequest(
|
||||
device_id="k1-a",
|
||||
ssid="XGR-OFFLINE",
|
||||
password=SecretStr(PRIMARY_TEST_CREDENTIAL),
|
||||
connection_mode="quick-connect",
|
||||
compatibility_attestation=QUICK_CONNECT_ATTESTATION,
|
||||
)
|
||||
@@ -2012,6 +2368,15 @@ def test_failed_connection_change_revokes_the_previous_route(
|
||||
assert state["k1_ip"] is None
|
||||
assert state["connection_mode"] is None
|
||||
assert state["compatibility"]["attestation"] is None
|
||||
quick_sessions = sorted(service.evidence_root.glob("*viewer_k1_ap_association*"))
|
||||
failure_evidence = json.loads(
|
||||
(quick_sessions[0] / "host-wifi-association.redacted.json").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
)
|
||||
assert failure_evidence["reason_code"] == "network-not-found"
|
||||
assert failure_evidence["scan_attempt_count"] == 4
|
||||
assert failure_evidence["scan_elapsed_ms"] == 15014
|
||||
|
||||
|
||||
def test_network_provisioning_rejects_an_ipv4_owned_by_the_local_host(
|
||||
@@ -2027,7 +2392,7 @@ def test_network_provisioning_rejects_an_ipv4_owned_by_the_local_host(
|
||||
"completed_at_utc": "2026-07-18T15:19:26Z",
|
||||
"profile_id": "xgrids-k1-fw3-wifi-v1",
|
||||
"outcome": "lan_address_observed",
|
||||
"observations": [{"status": {"ipv4": "192.168.68.51"}}],
|
||||
"observations": [{"status": {"ipv4": "10.255.254.51"}}],
|
||||
}
|
||||
|
||||
monkeypatch.setattr(facade_module, "provision_wifi_once", fake_provision)
|
||||
|
||||
Reference in New Issue
Block a user