from __future__ import annotations import threading import time from types import SimpleNamespace from unittest.mock import patch import pytest from cognitive_agent.server import SeatDemoHandler def _result(mode: str, *, status: str = "succeeded") -> dict[str, object]: return { "request_id": f"req-{mode}-{status}", "status": status, "success": status == "succeeded", "execution_mode": mode, "decision_summary": [], "function_configs": {}, "command_plans": {}, "trace_events": [], "operation_results": [], "execution_report": None, "control_transport": "test", } def _entries() -> list[dict[str, object]]: return [ { "index": 0, "clause": "打开闪烁灯", "capability": { "id": "ir-slot:flash:2", "device_id": "flash", "device_name": "闪烁灯", "action": "打开", "slot": 2, "parse_source": "local_rule", }, } ] def test_hardware_branches_preflight_then_start_together() -> None: handler = object.__new__(SeatDemoHandler) lock = threading.Lock() preflight_completed: set[str] = set() hardware_started: dict[str, float] = {} def mark_preflight(name: str) -> dict[str, object]: time.sleep(0.03) with lock: preflight_completed.add(name) return _result("dry_run") def execute_can() -> dict[str, object]: with lock: assert preflight_completed == {"can", "peripheral"} hardware_started["can"] = time.perf_counter() time.sleep(0.12) return _result("hardware") def execute_peripheral( _utterance: str, _entries_value: list[dict[str, object]], *, execution_mode: str, **_kwargs: object, ) -> dict[str, object]: if execution_mode == "dry_run": return mark_preflight("peripheral") with lock: assert preflight_completed == {"can", "peripheral"} hardware_started["peripheral"] = time.perf_counter() time.sleep(0.12) return _result("hardware") with patch.object( handler, "_execute_local_peripheral_actions", side_effect=execute_peripheral, ): result = handler._execute_can_and_peripheral_branches( utterance="打开空调和闪烁灯", entries=_entries(), execution_mode="hardware", provider="local", conversation_id="conv-parallel-unit", can_execute=execute_can, can_preflight=lambda: mark_preflight("can"), parallel_eligible=True, ) assert result["status"] == "succeeded" assert result["parallel_dispatch"]["enabled"] is True assert result["parallel_dispatch"]["preflight_status"] == "succeeded" assert abs(hardware_started["can"] - hardware_started["peripheral"]) < 0.05 dispatch = result["parallel_dispatch"]["dispatch"] branch_durations = [ item["duration_ms"] for item in dispatch["branches"].values() ] assert dispatch["total_ms"] < sum(branch_durations) def test_failed_preflight_starts_neither_hardware_branch() -> None: handler = object.__new__(SeatDemoHandler) hardware_calls: list[str] = [] def execute_peripheral( _utterance: str, _entries_value: list[dict[str, object]], *, execution_mode: str, **_kwargs: object, ) -> dict[str, object]: if execution_mode == "hardware": hardware_calls.append("peripheral") return _result(execution_mode) with patch.object( handler, "_execute_local_peripheral_actions", side_effect=execute_peripheral, ): result = handler._execute_can_and_peripheral_branches( utterance="打开空调和闪烁灯", entries=_entries(), execution_mode="hardware", provider="local", conversation_id="conv-parallel-preflight-failure", can_execute=lambda: hardware_calls.append("can") or _result("hardware"), can_preflight=lambda: _result( "dry_run", status="validation_failed", ), parallel_eligible=True, ) assert hardware_calls == [] assert result["status"] == "validation_failed" assert result["execution_mode"] == "dry_run" assert result["hardware_execution_allowed"] is False assert result["parallel_dispatch"]["enabled"] is False assert result["parallel_dispatch"]["preflight_status"] == "failed" def test_wireless_parallel_dispatch_does_not_require_local_bench_lease() -> None: handler = object.__new__(SeatDemoHandler) authorization_calls: list[str | None] = [] handler.service = SimpleNamespace( hardware_access=SimpleNamespace( ensure_authorized=lambda client_id: authorization_calls.append(client_id) ) ) handler._ensure_parallel_hardware_authorized( execution_mode="hardware", control_transport="wireless_mqtt", hardware_access_bypass=False, hardware_client_id=None, ) assert authorization_calls == [] def test_wired_parallel_dispatch_keeps_local_bench_lease_gate() -> None: handler = object.__new__(SeatDemoHandler) authorization_calls: list[str | None] = [] handler.service = SimpleNamespace( hardware_access=SimpleNamespace( ensure_authorized=lambda client_id: authorization_calls.append(client_id) ) ) handler._ensure_parallel_hardware_authorized( execution_mode="hardware", control_transport="wired_can", hardware_access_bypass=False, hardware_client_id="hwc-wired-parallel-test", ) assert authorization_calls == ["hwc-wired-parallel-test"] @pytest.mark.parametrize( "utterance", ( "先打开空调,再打开闪烁灯", "打开空调,然后打开闪烁灯", "打开空调,2秒后打开闪烁灯", ), ) def test_explicit_cross_transport_order_disables_parallelism( utterance: str, ) -> None: assert SeatDemoHandler._mixed_request_requires_transport_order(utterance) def test_ineligible_flow_keeps_existing_can_then_peripheral_order() -> None: handler = object.__new__(SeatDemoHandler) calls: list[str] = [] def execute_peripheral( _utterance: str, _entries_value: list[dict[str, object]], *, execution_mode: str, **_kwargs: object, ) -> dict[str, object]: calls.append(f"peripheral:{execution_mode}") return _result(execution_mode) def unexpected_preflight() -> dict[str, object]: raise AssertionError("ordered flow must not run a duplicate preflight") with patch.object( handler, "_execute_local_peripheral_actions", side_effect=execute_peripheral, ): result = handler._execute_can_and_peripheral_branches( utterance="先打开空调,再打开闪烁灯", entries=_entries(), execution_mode="hardware", provider="local", conversation_id="conv-ordered-unit", can_execute=lambda: calls.append("can:hardware") or _result("hardware"), can_preflight=unexpected_preflight, parallel_eligible=False, ) assert calls == ["can:hardware", "peripheral:hardware"] assert result["status"] == "succeeded" assert "parallel_dispatch" not in result def test_saved_static_mode_uses_parallel_can_and_peripheral_path() -> None: handler = object.__new__(SeatDemoHandler) can_modes: list[str] = [] peripheral_modes: list[str] = [] persisted: list[dict[str, object]] = [] profile = SimpleNamespace( id="mode-parallel", schedule=None, command_flow={"execution_steps": []}, public_dict=lambda: {"id": "mode-parallel", "name": "并行模式"}, ) def execute_mode_profile_card( _mode_id: str, **kwargs: object, ) -> dict[str, object]: mode = str(kwargs.get("execution_mode") or "") can_modes.append(mode) return _result(mode) handler.service = SimpleNamespace( execute_mode_profile_card=execute_mode_profile_card, persist_composed_result=lambda result: persisted.append(result), ) def execute_peripheral( _utterance: str, _entries_value: list[dict[str, object]], *, execution_mode: str, **_kwargs: object, ) -> dict[str, object]: peripheral_modes.append(execution_mode) return _result(execution_mode) with ( patch.object( handler, "_exact_local_peripheral_mode_invocation", return_value=profile, ), patch.object(handler, "_exact_n7_mode_invocation", return_value=None), patch.object(handler, "_saved_mode_infrared_entries", return_value=_entries()), patch.object( handler, "_execute_local_peripheral_actions", side_effect=execute_peripheral, ), ): result = handler._execute_n7_named_mode_request( "/api/requests", { "utterance": "进入并行模式", "execution_mode": "hardware", "provider": "local", "conversation_id": "conv-saved-parallel", "vehicle_id": "denza_n7", "control_transport": "wired_can", }, ) assert result is not None assert can_modes == ["dry_run", "hardware"] assert peripheral_modes == ["dry_run", "hardware"] assert result["parallel_dispatch"]["enabled"] is True assert result["provider_used"] == "saved_mode_command_flow" assert persisted == [result]