Стабилизация подключения K1 после сна и ожидания Bluetooth
This commit is contained in:
@@ -2222,6 +2222,90 @@ def test_start_outcome_unknown_blocks_reopen_even_when_transport_is_closed(
|
||||
session.retire_for_network_change()
|
||||
|
||||
|
||||
def test_post_start_read_only_timeout_preserves_durable_active_proof_without_stop_authority(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
class PostStartRefreshFailureExecutor(FakeExecutor):
|
||||
start_attempted = False
|
||||
start_active_confirmed = False
|
||||
|
||||
def execute_canonical_start(self, *_args: object, **kwargs: object) -> object:
|
||||
type(self).start_attempted = True
|
||||
self.records.append("start:11-12")
|
||||
self.transport.ready = False
|
||||
observer = kwargs.get("start_active_observer")
|
||||
assert callable(observer)
|
||||
observer()
|
||||
type(self).start_active_confirmed = True
|
||||
self.records.append("refresh:13-14-timeout")
|
||||
raise ApplicationMqttTransportError(
|
||||
"post-START read-only response timed out after host wake",
|
||||
reason_code="mqtt_response_timeout",
|
||||
)
|
||||
|
||||
def snapshot(self) -> dict[str, object]:
|
||||
return {
|
||||
"dialogue_stage": (
|
||||
"start-active-observed"
|
||||
if type(self).start_active_confirmed
|
||||
else "start-attempted"
|
||||
),
|
||||
"start_attempted": type(self).start_attempted,
|
||||
"start_active_confirmed": type(self).start_active_confirmed,
|
||||
"start_complete": False,
|
||||
"stop_attempted": False,
|
||||
"response_evidence": [],
|
||||
"automatic_retry": False,
|
||||
}
|
||||
|
||||
FakeExecutor.records = []
|
||||
PostStartRefreshFailureExecutor.start_attempted = False
|
||||
PostStartRefreshFailureExecutor.start_active_confirmed = False
|
||||
monkeypatch.setattr(
|
||||
session_module,
|
||||
"PhysicalAcceptanceDialogueExecutor",
|
||||
PostStartRefreshFailureExecutor,
|
||||
)
|
||||
coordinator = FakePhysicalCommandCoordinator()
|
||||
scanning_observed = threading.Event()
|
||||
session = InteractiveApplicationControlSession(
|
||||
FakeAuthorityLoader(),
|
||||
transport_factory=lambda host: FakeTransport(host), # type: ignore[arg-type]
|
||||
physical_command_coordinator=coordinator, # type: ignore[arg-type]
|
||||
scanning_observer=scanning_observed.set,
|
||||
)
|
||||
coordinator.phase_probe = lambda: str(session.snapshot()["state"])
|
||||
|
||||
session.open(
|
||||
host="192.168.1.20",
|
||||
timezone_name="Europe/Moscow",
|
||||
connection_binding=_connection_binding(),
|
||||
)
|
||||
_wait_phase(session, "connection-ready")
|
||||
session.enter_workspace()
|
||||
_wait_phase(session, "workspace-ready")
|
||||
session.open_project_prompt()
|
||||
_wait_phase(session, "project-ready")
|
||||
session.request_start(
|
||||
project_name="SLEEP_WAKE",
|
||||
confirmation=_confirmation(),
|
||||
command_context=_physical_context("start"),
|
||||
preparation_checkpoint_observer=_successful_start_checkpoint_observer, # type: ignore[arg-type]
|
||||
)
|
||||
failed = _wait_phase(session, "failed")
|
||||
|
||||
assert coordinator.resolutions == [("start", "initializing")]
|
||||
assert scanning_observed.is_set()
|
||||
assert failed["can_stop"] is False
|
||||
assert failed["outcome_unknown"] is True
|
||||
assert failed["failure"]["reason_code"] == "mqtt_response_timeout" # type: ignore[index]
|
||||
assert failed["dialogue"]["start_active_confirmed"] is True # type: ignore[index]
|
||||
assert FakeExecutor.records[-2:] == [
|
||||
"start:11-12",
|
||||
"refresh:13-14-timeout",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("disconnect_error", "expected_reason_code"),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user