import unittest from unittest.mock import patch from app.services.ops_service import execute_driver_action class OpsServiceDriverActionTests(unittest.TestCase): @patch("app.services.ops_service.execute_managed_node_onboarding_recovery") def test_bootstrap_run_executes_node_onboarding_recovery( self, mock_execute_managed_node_onboarding_recovery, ) -> None: mock_execute_managed_node_onboarding_recovery.return_value = ( True, "自动收口任务已创建", { "recovery_action": "bootstrap_run", "playbook_run": {"run_code": "run-001"}, }, ) ok, message, data = execute_driver_action( { "action_code": "bootstrap_run", "node_codes": ["mainland-worker-02"], "action_payload": { "control_plane_base_url": "http://control.example:8100", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("自动收口任务已创建", message) self.assertTrue(data["handled"]) self.assertEqual("node-onboarding-recovery", data["mode"]) self.assertEqual("mainland-worker-02", data["node_code"]) mock_execute_managed_node_onboarding_recovery.assert_called_once_with( node_code="mainland-worker-02", requested_by="test/bootstrap_run", control_plane_base_url="http://control.example:8100", root_dir="", ) @patch("app.services.ops_service.create_release_and_smart_rollout_from_latest_package") def test_publish_latest_worker_calls_backend_launchpad_flow( self, mock_create_release_and_smart_rollout_from_latest_package, ) -> None: mock_create_release_and_smart_rollout_from_latest_package.return_value = ( True, "Release rollout 已创建", { "release": {"id": 51, "release_version": "domaincheck_release_launchpad"}, "rollout_created": True, }, ) ok, message, data = execute_driver_action( { "action_code": "publish_latest_worker", "action_payload": { "channel": "stable", "control_plane_base_url": "http://control.example:8100", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("Release rollout 已创建", message) self.assertTrue(data["handled"]) self.assertEqual("smart-release-rollout", data["mode"]) mock_create_release_and_smart_rollout_from_latest_package.assert_called_once() called_payload = mock_create_release_and_smart_rollout_from_latest_package.call_args.args[0] called_kwargs = mock_create_release_and_smart_rollout_from_latest_package.call_args.kwargs self.assertEqual("worker", called_payload["mode"]) self.assertEqual("stable", called_payload["channel"]) self.assertEqual("test/publish_latest_worker", called_payload["created_by"]) self.assertEqual("test/publish_latest_worker/rollout", called_payload["rollout_created_by"]) self.assertEqual("http://control.example:8100", called_kwargs["control_plane_base_url"]) @patch("app.services.ops_service.prepare_latest_release_package") def test_release_prepare_executes_final_signoff_flow( self, mock_prepare_latest_release_package, ) -> None: mock_prepare_latest_release_package.return_value = ( True, "最新发布包最终签收已完成", { "package": { "available": True, "package_name": "domaincheck_release_20260418_220000", "final_release_ok": True, }, "final_release_gate": { "ready": True, "status": "ready", }, }, ) ok, message, data = execute_driver_action( { "action_code": "release_prepare", "action_payload": {}, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("最新发布包最终签收已完成", message) self.assertTrue(data["handled"]) self.assertEqual("release-prepare", data["mode"]) self.assertTrue(data["release_prepare_result"]["package"]["final_release_ok"]) mock_prepare_latest_release_package.assert_called_once_with( requested_by="test/release_prepare" ) @patch("app.services.ops_service.get_runtime_build_info") def test_api_restart_returns_runtime_refresh_preview( self, mock_get_runtime_build_info, ) -> None: mock_get_runtime_build_info.return_value = { "commit_sha": "246838ae4c07", "route_surface": { "surface_complete": False, "missing_keys": ["ops_node_handover_bootstrap_plan"], }, } ok, message, data = execute_driver_action( { "action_code": "api-restart", "action_payload": { "control_plane_base_url": "http://control.example:8100", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertIn("刷新控制面运行时", message) self.assertTrue(data["handled"]) self.assertEqual("runtime-refresh-preview", data["mode"]) self.assertEqual("open_stack_diagnosis", data["ui_intent"]["kind"]) self.assertIn("runtime-refresh-recover", data["recommended_command"]) self.assertEqual( ["ops_node_handover_bootstrap_plan"], data["runtime_build_info"]["route_surface"]["missing_keys"], ) @patch("app.services.ops_service.get_release_launchpad") def test_review_smart_rollout_preview_returns_launchpad_preview_payload(self, mock_get_release_launchpad) -> None: mock_get_release_launchpad.return_value = { "launchpad_status": { "status": "attention", "status_label": "待确认", }, "latest_release": { "id": 88, "release_version": "domaincheck_release_demo", }, "worker_rollout_preview": { "message": "Worker 智能预案待确认", "smart_rollout": { "available": True, "target_node_codes": ["mainland-worker-01"], }, }, } ok, message, data = execute_driver_action( { "action_code": "review_smart_rollout_preview", "action_payload": { "channel": "stable", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertTrue(data["handled"]) self.assertEqual("release-launchpad-preview", data["mode"]) self.assertEqual("worker", data["review_mode"]) self.assertEqual("worker", data["release_launchpad_review"]["mode"]) self.assertEqual(88, data["release_launchpad_review"]["latest_release"]["id"]) self.assertEqual( ["mainland-worker-01"], data["release_launchpad_review"]["target_node_codes"], ) self.assertEqual("release_launchpad_review", data["ui_intent"]["kind"]) self.assertEqual("worker", data["ui_intent"]["mode"]) self.assertEqual(88, data["ui_intent"]["release_id"]) mock_get_release_launchpad.assert_called_once() @patch("app.services.ops_service.get_managed_node_handover") @patch("app.services.ops_service.get_release_launchpad") def test_fix_managed_nodes_returns_handover_ui_intent_when_gap_exists( self, mock_get_release_launchpad, mock_get_managed_node_handover, ) -> None: mock_get_release_launchpad.return_value = { "worker_rollout_preview": { "policy_preview": { "release_gate": { "operational_readiness": { "rows": [ { "node_code": "mainland-worker-01", "is_managed": False, "is_enabled": False, "is_agent_online": False, "remote_agent_ready": False, "inspection_status": "missing", } ] } } } } } mock_get_managed_node_handover.return_value = { "node_code": "mainland-worker-01", "stage": {"code": "unmanaged"}, } ok, message, data = execute_driver_action( { "action_code": "fix_managed_nodes", "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertTrue(data["handled"]) self.assertEqual("ui-intent", data["mode"]) self.assertEqual("managed_node_handover", data["ui_intent"]["kind"]) self.assertEqual("mainland-worker-01", data["ui_intent"]["node_code"]) self.assertEqual("unmanaged", data["handover"]["stage"]["code"]) @patch("app.services.ops_service.sync_managed_nodes_from_cluster") @patch("app.services.ops_service.get_release_launchpad") def test_fix_managed_nodes_syncs_cluster_when_gap_not_found( self, mock_get_release_launchpad, mock_sync_managed_nodes_from_cluster, ) -> None: mock_get_release_launchpad.return_value = { "worker_rollout_preview": { "policy_preview": { "release_gate": { "operational_readiness": { "rows": [] } } } } } mock_sync_managed_nodes_from_cluster.return_value = { "synced_count": 2, } ok, message, data = execute_driver_action( { "action_code": "fix_managed_nodes", "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("已按集群快照同步托管节点,请继续检查接管状态。", message) self.assertTrue(data["handled"]) self.assertEqual("cluster-sync", data["mode"]) self.assertEqual(2, data["sync_result"]["synced_count"]) mock_sync_managed_nodes_from_cluster.assert_called_once_with(dry_run=False) @patch("app.services.ops_service.get_managed_node_handover") def test_handover_first_gap_includes_handover_payload(self, mock_get_managed_node_handover) -> None: mock_get_managed_node_handover.return_value = { "node_code": "mainland-worker-01", "stage": {"code": "pending_bootstrap"}, } ok, message, data = execute_driver_action( { "action_code": "handover_first_gap", "action_payload": { "node_code": "mainland-worker-01", "control_plane_base_url": "http://control.example:8100", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertEqual("handover-preview", data["mode"]) self.assertEqual("pending_bootstrap", data["handover_preview"]["stage"]["code"]) self.assertEqual("managed_node_handover", data["ui_intent"]["kind"]) self.assertEqual("pending_bootstrap", data["handover"]["stage"]["code"]) mock_get_managed_node_handover.assert_called_once_with( "mainland-worker-01", control_plane_base_url="http://control.example:8100", ) @patch("app.services.ops_service.get_managed_node_handover") def test_view_first_gap_returns_handover_preview_and_edit_ui_intent(self, mock_get_managed_node_handover) -> None: mock_get_managed_node_handover.return_value = { "node_code": "mainland-worker-02", "stage": {"code": "runtime_only"}, } ok, message, data = execute_driver_action( { "action_code": "view_first_gap", "action_payload": { "node_code": "mainland-worker-02", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertEqual("handover-preview", data["mode"]) self.assertEqual("runtime_only", data["handover_preview"]["stage"]["code"]) self.assertEqual("managed_node_edit", data["ui_intent"]["kind"]) self.assertEqual("runtime_only", data["handover"]["stage"]["code"]) @patch("app.services.ops_service.get_latest_release_package_metadata") def test_release_package_returns_package_preview_and_open_release_dialog_ui_intent( self, mock_get_latest_release_package_metadata, ) -> None: mock_get_latest_release_package_metadata.return_value = { "available": True, "package_name": "domaincheck_release_20260418_120000", "release_version_suggestion": "domaincheck_release_20260418_120000", } ok, message, data = execute_driver_action( { "action_code": "release_package", "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertTrue(data["handled"]) self.assertEqual("release-package-preview", data["mode"]) self.assertTrue(data["release_package_preview"]["available"]) self.assertEqual( "domaincheck_release_20260418_120000", data["release_package_preview"]["package_name"], ) self.assertEqual("open_release_dialog", data["ui_intent"]["kind"]) mock_get_latest_release_package_metadata.assert_called_once_with() @patch("app.services.ops_service.get_release_summary") @patch("app.services.ops_service.get_latest_release_package_metadata") def test_open_release_dialog_returns_release_dialog_preview_and_ui_intent( self, mock_get_latest_release_package_metadata, mock_get_release_summary, ) -> None: mock_get_latest_release_package_metadata.return_value = { "available": True, "package_name": "domaincheck_release_20260418_120000", } mock_get_release_summary.return_value = { "latest_release": { "id": 7, "release_version": "2026.04.18", } } ok, message, data = execute_driver_action( { "action_code": "open_release_dialog", "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertTrue(data["handled"]) self.assertEqual("release-dialog-preview", data["mode"]) self.assertEqual(7, data["release_dialog_preview"]["summary"]["latest_release"]["id"]) self.assertEqual( "domaincheck_release_20260418_120000", data["release_dialog_preview"]["release_package_preview"]["package_name"], ) self.assertEqual("open_release_dialog", data["ui_intent"]["kind"]) mock_get_latest_release_package_metadata.assert_called_once_with() mock_get_release_summary.assert_called_once_with() @patch("app.services.ops_service.get_release_launchpad") @patch("app.services.ops_service.get_release_summary") def test_focus_release_hub_returns_release_hub_preview_and_ui_intent( self, mock_get_release_summary, mock_get_release_launchpad, ) -> None: mock_get_release_summary.return_value = { "latest_release": { "id": 7, "release_version": "2026.04.18", } } mock_get_release_launchpad.return_value = { "channel": "stable", "launchpad_status": { "status": "attention", "recommended_action_code": "review_smart_rollout_preview", }, } ok, message, data = execute_driver_action( { "action_code": "focus_release_hub", "action_payload": { "release_id": 7, "channel": "stable", "control_plane_base_url": "http://control.example:8100", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("", message) self.assertTrue(data["handled"]) self.assertEqual("release-hub-preview", data["mode"]) self.assertEqual("focus_release_hub", data["ui_intent"]["kind"]) self.assertEqual(7, data["ui_intent"]["release_id"]) self.assertEqual( "review_smart_rollout_preview", data["release_hub_preview"]["launchpad"]["launchpad_status"]["recommended_action_code"], ) self.assertEqual(7, data["release_hub_preview"]["summary"]["latest_release"]["id"]) mock_get_release_summary.assert_called_once_with() mock_get_release_launchpad.assert_called_once_with( control_plane_base_url="http://control.example:8100", channel="stable", ) def test_open_playbook_dialog_returns_ui_intent(self) -> None: ok, message, data = execute_driver_action( { "action_code": "open_playbook_dialog", "node_codes": ["mainland-worker-01"], "action_payload": { "playbook_key": "scene.logs.key", "execution_mode": "remote-agent", "auto_approve": True, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertTrue(data["handled"]) self.assertEqual("playbook-preview", data["mode"]) self.assertEqual("scene.logs.key", data["playbook_preview"]["playbook"]["key"]) self.assertEqual(1, data["playbook_preview"]["target_nodes_total"]) self.assertEqual(["mainland-worker-01"], data["playbook_preview"]["target_node_codes"]) self.assertEqual("remote-agent", data["playbook_preview"]["execution_mode"]) self.assertTrue(data["playbook_preview"]["auto_approve"]) self.assertEqual("open_playbook_dialog", data["ui_intent"]["kind"]) self.assertEqual("scene.logs.key", data["ui_intent"]["playbook_key"]) self.assertEqual(["mainland-worker-01"], data["ui_intent"]["target_node_codes"]) self.assertEqual("remote-agent", data["ui_intent"]["execution_mode"]) self.assertTrue(data["ui_intent"]["auto_approve"]) @patch("app.services.ops_service.list_ops_playbook_run_events") @patch("app.services.ops_service.get_ops_playbook_run") def test_focus_playbook_run_returns_run_focus_preview_and_ui_intent( self, mock_get_ops_playbook_run, mock_list_ops_playbook_run_events, ) -> None: mock_get_ops_playbook_run.return_value = { "run_code": "pbr-demo", "playbook_key": "inspection.standard", "status": "running", } mock_list_ops_playbook_run_events.return_value = { "run_code": "pbr-demo", "events": [{"event_key": "evt-1"}], } ok, message, data = execute_driver_action( { "action_code": "focus_playbook_run", "action_payload": { "run_code": "pbr-demo", "focus_step_key": "logs.collect", "focus_step_title": "收集服务日志", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("playbook-run-focus", data["mode"]) self.assertEqual("pbr-demo", data["playbook_run_focus"]["run"]["run_code"]) self.assertEqual("evt-1", data["playbook_run_focus"]["events"]["events"][0]["event_key"]) self.assertEqual("playbook_run_detail", data["ui_intent"]["kind"]) mock_get_ops_playbook_run.assert_called_once_with("pbr-demo") mock_list_ops_playbook_run_events.assert_called_once_with( "pbr-demo", limit=40, step_key="logs.collect", node_code="", ) @patch("app.services.ops_service.get_ops_activity_stream") def test_focus_activity_item_returns_activity_focus_preview_and_ui_intent( self, mock_get_ops_activity_stream, ) -> None: mock_get_ops_activity_stream.return_value = { "items": [ { "activity_key": "ops-job:42", "kind": "ops_job", "status": "attention", "summary": "任务待关注", } ] } ok, message, data = execute_driver_action( { "action_code": "focus_activity_item", "action_payload": { "activity_key": "ops-job:42", "kind": "ops_job", "status": "attention", "ui_intent": { "kind": "job_events", "job_id": 42, }, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("activity-focus", data["mode"]) self.assertEqual("ops-job:42", data["activity_focus_preview"]["activity"]["activity_key"]) self.assertEqual("job_events", data["ui_intent"]["kind"]) @patch("app.services.ops_service.list_ops_job_events_for_jobs") def test_focus_latest_job_events_returns_job_events_preview_and_ui_intent( self, mock_list_ops_job_events_for_jobs, ) -> None: mock_list_ops_job_events_for_jobs.return_value = [ { "id": 1, "job_id": 42, "event_type": "job_started", "message": "started", } ] ok, message, data = execute_driver_action( { "action_code": "focus_latest_job_events", "action_payload": { "focus_ref": { "kind": "ops_job", "job_id": 42, "job_code": "job-42", } }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("job-events-focus", data["mode"]) self.assertEqual(42, data["job_events_preview"]["job_id"]) self.assertEqual("job-42", data["job_events_preview"]["job_code"]) self.assertEqual(1, data["job_events_preview"]["events"][0]["id"]) self.assertEqual("job_events", data["ui_intent"]["kind"]) mock_list_ops_job_events_for_jobs.assert_called_once_with([42], limit=60) @patch("app.services.ops_service.list_ops_playbook_run_events") def test_open_playbook_run_latest_events_returns_events_preview_and_ui_intent( self, mock_list_ops_playbook_run_events, ) -> None: mock_list_ops_playbook_run_events.return_value = { "run_code": "pbr-demo", "events": [{"event_key": "evt-2"}], } ok, message, data = execute_driver_action( { "action_code": "open_playbook_run_latest_events", "action_payload": { "run_code": "pbr-demo", "focus_step_key": "logs.collect", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("playbook-run-events", data["mode"]) self.assertEqual("evt-2", data["playbook_run_events_preview"]["events"][0]["event_key"]) self.assertEqual("playbook_run_latest_events", data["ui_intent"]["kind"]) mock_list_ops_playbook_run_events.assert_called_once_with( "pbr-demo", limit=60, step_key="logs.collect", node_code="", ) @patch("app.services.ops_service.list_managed_nodes_with_agent_state") def test_open_playbook_dialog_auto_switches_to_ssh_when_supported_and_target_is_ssh_ready( self, mock_list_managed_nodes_with_agent_state, ) -> None: mock_list_managed_nodes_with_agent_state.return_value = { "nodes": [ { "node_code": "mainland-worker-01", "is_managed": True, "is_enabled": True, "is_agent_online": False, "has_ssh_access": True, } ] } ok, message, data = execute_driver_action( { "action_code": "open_playbook_dialog", "node_codes": ["mainland-worker-01"], "action_payload": { "playbook_key": "scene.logs.key", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("ssh", data["ui_intent"]["execution_mode"]) def test_open_playbook_dialog_keeps_control_plane_when_playbook_only_supports_control_plane(self) -> None: ok, message, data = execute_driver_action( { "action_code": "open_playbook_dialog", "node_codes": ["mainland-worker-01"], "action_payload": { "playbook_key": "onboarding.bootstrap", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("control-plane", data["ui_intent"]["execution_mode"]) def test_open_action_template_dialog_returns_ui_intent(self) -> None: ok, message, data = execute_driver_action( { "action_code": "open_action_template_dialog", "node_codes": ["mainland-controller-01"], "action_payload": { "template_key": "logs.collect", "execution_mode": "remote-agent", "auto_approve": False, "payload": { "service_name": "domaincheck-worker", "lines": 120, }, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertTrue(data["handled"]) self.assertEqual("action-template-preview", data["mode"]) self.assertEqual("logs.collect", data["template_preview"]["template"]["key"]) self.assertEqual("remote-agent", data["template_preview"]["execution_mode"]) self.assertEqual(["mainland-controller-01"], data["template_preview"]["target_node_codes"]) self.assertEqual("domaincheck-worker", data["template_preview"]["payload"]["service_name"]) self.assertEqual("open_action_template_dialog", data["ui_intent"]["kind"]) self.assertEqual("logs.collect", data["ui_intent"]["template_key"]) self.assertEqual(["mainland-controller-01"], data["ui_intent"]["target_node_codes"]) self.assertEqual("remote-agent", data["ui_intent"]["execution_mode"]) self.assertFalse(data["ui_intent"]["auto_approve"]) self.assertEqual("domaincheck-worker", data["ui_intent"]["payload"]["service_name"]) self.assertEqual(120, data["ui_intent"]["payload"]["lines"]) @patch("app.services.ops_service.create_ops_job_batch") def test_replay_delivery_queue_creates_ops_job_batch(self, mock_create_ops_job_batch) -> None: mock_create_ops_job_batch.return_value = ( True, "已创建 2 个运维任务;待审批 0;阻断 0;失败 0", { "summary": {"created_count": 2}, "jobs": [{"id": 1}, {"id": 2}], }, ) ok, message, data = execute_driver_action( { "action_code": "replay_delivery_queue", "node_codes": ["mainland-worker-01", "mainland-worker-02"], "action_payload": { "payload": { "limit": 2, "flush_after_replay": True, }, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("已创建 2 个运维任务;待审批 0;阻断 0;失败 0", message) self.assertTrue(data["handled"]) self.assertEqual("ops-job-batch", data["mode"]) self.assertEqual("delivery.queue.replay", data["template_key"]) called_payload = mock_create_ops_job_batch.call_args.args[0] self.assertEqual("delivery.queue.replay", called_payload["template_key"]) self.assertEqual(["mainland-worker-01", "mainland-worker-02"], called_payload["target_node_codes"]) self.assertEqual("test/replay_delivery_queue", called_payload["requested_by"]) self.assertEqual("remote-agent", called_payload["execution_mode"]) self.assertFalse(called_payload["auto_approve"]) self.assertTrue(called_payload["payload"]["flush_after_replay"]) @patch("app.services.ops_service.create_ops_job_batch") def test_flush_delivery_queue_creates_ops_job_batch(self, mock_create_ops_job_batch) -> None: mock_create_ops_job_batch.return_value = ( True, "已创建 1 个运维任务;待审批 0;阻断 0;失败 0", { "summary": {"created_count": 1}, "jobs": [{"id": 9}], }, ) ok, message, data = execute_driver_action( { "action_code": "flush_delivery_queue", "action_payload": { "target_node_codes": ["mainland-controller-01"], "auto_approve": True, "payload": { "limit": 5, }, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("ops-job-batch", data["mode"]) self.assertEqual("delivery.queue.flush", data["template_key"]) called_payload = mock_create_ops_job_batch.call_args.args[0] self.assertEqual("delivery.queue.flush", called_payload["template_key"]) self.assertEqual(["mainland-controller-01"], called_payload["target_node_codes"]) self.assertEqual("test/flush_delivery_queue", called_payload["requested_by"]) self.assertTrue(called_payload["auto_approve"]) self.assertEqual(5, called_payload["payload"]["limit"]) @patch("app.services.ops_service.list_managed_nodes_with_agent_state") def test_open_action_template_dialog_auto_switches_to_ssh_when_supported_and_target_is_ssh_ready( self, mock_list_managed_nodes_with_agent_state, ) -> None: mock_list_managed_nodes_with_agent_state.return_value = { "nodes": [ { "node_code": "mainland-controller-01", "is_managed": True, "is_enabled": True, "is_agent_online": False, "has_ssh_access": True, } ] } ok, message, data = execute_driver_action( { "action_code": "open_action_template_dialog", "node_codes": ["mainland-controller-01"], "action_payload": { "template_key": "logs.collect", "payload": { "service_name": "domaincheck-api", "lines": 120, }, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("ssh", data["ui_intent"]["execution_mode"]) @patch("app.services.ops_service.execute_ops_playbook") def test_run_scene_logs_full_executes_ops_playbook( self, mock_execute_ops_playbook, ) -> None: mock_execute_ops_playbook.return_value = ( True, "现场取证已创建", { "run_code": "playbook-logs-full-001", }, ) ok, message, data = execute_driver_action( { "action_code": "run_scene_logs_full", "node_codes": ["mainland-worker-01"], "action_payload": { "execution_mode": "remote-agent", "auto_approve": True, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("现场取证已创建", message) self.assertTrue(data["handled"]) self.assertEqual("ops-playbook", data["mode"]) self.assertEqual("scene.logs.full", data["playbook_key"]) called_payload = mock_execute_ops_playbook.call_args.args[0] self.assertEqual("scene.logs.full", called_payload["playbook_key"]) self.assertEqual(["mainland-worker-01"], called_payload["node_codes"]) self.assertEqual("remote-agent", called_payload["execution_mode"]) self.assertTrue(called_payload["auto_approve"]) self.assertEqual("test/run_scene_logs_full", called_payload["requested_by"]) @patch("app.services.ops_service.get_release_launchpad") @patch("app.services.ops_service.get_release_summary") def test_open_release_deploy_worker_returns_preview_and_ui_intent( self, mock_get_release_summary, mock_get_release_launchpad, ) -> None: mock_get_release_summary.return_value = { "latest_release": { "id": 11, "release_version": "2026.04.18", } } mock_get_release_launchpad.return_value = { "launchpad_status": { "status": "attention", "recommended_action_code": "review_smart_rollout_preview", } } ok, message, data = execute_driver_action( { "action_code": "open_release_deploy_worker", "node_codes": ["mainland-worker-01"], "action_payload": { "release_id": 11, "execution_mode": "remote-agent", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertTrue(data["handled"]) self.assertEqual("release-deploy-preview", data["mode"]) self.assertEqual("deploy.release.worker", data["release_deploy_preview"]["template"]["key"]) self.assertEqual(11, data["release_deploy_preview"]["release_id"]) self.assertEqual(["mainland-worker-01"], data["release_deploy_preview"]["target_node_codes"]) self.assertEqual("remote-agent", data["release_deploy_preview"]["execution_mode"]) self.assertEqual( "review_smart_rollout_preview", data["release_deploy_preview"]["launchpad"]["launchpad_status"]["recommended_action_code"], ) self.assertEqual("open_release_deploy_template", data["ui_intent"]["kind"]) self.assertEqual("deploy.release.worker", data["ui_intent"]["template_key"]) self.assertEqual(11, data["ui_intent"]["release_id"]) self.assertEqual(["mainland-worker-01"], data["ui_intent"]["target_node_codes"]) self.assertEqual("remote-agent", data["ui_intent"]["execution_mode"]) mock_get_release_summary.assert_called_once_with() mock_get_release_launchpad.assert_called_once_with() @patch("app.services.ops_service.list_managed_nodes_with_agent_state") def test_open_release_deploy_worker_auto_switches_to_ssh_when_agent_not_ready( self, mock_list_managed_nodes_with_agent_state, ) -> None: mock_list_managed_nodes_with_agent_state.return_value = { "nodes": [ { "node_code": "mainland-worker-01", "is_managed": True, "is_enabled": True, "is_agent_online": False, "has_ssh_access": True, } ] } ok, message, data = execute_driver_action( { "action_code": "open_release_deploy_worker", "node_codes": ["mainland-worker-01"], "action_payload": { "release_id": 11, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("ssh", data["ui_intent"]["execution_mode"]) @patch("app.services.ops_service.get_release_launchpad") @patch("app.services.ops_service.get_release_summary") def test_open_rollout_dialog_carries_release_id_and_returns_preview( self, mock_get_release_summary, mock_get_release_launchpad, ) -> None: mock_get_release_summary.return_value = { "latest_release": { "id": 9, "release_version": "2026.04.18", } } mock_get_release_launchpad.return_value = { "launchpad_status": { "status": "ready", "recommended_action_code": "publish_latest_worker", } } ok, message, data = execute_driver_action( { "action_code": "open_rollout_dialog", "action_payload": { "release_id": 23, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertTrue(data["handled"]) self.assertEqual("rollout-dialog-preview", data["mode"]) self.assertEqual( "publish_latest_worker", data["rollout_dialog_preview"]["launchpad"]["launchpad_status"]["recommended_action_code"], ) self.assertEqual(9, data["rollout_dialog_preview"]["summary"]["latest_release"]["id"]) self.assertEqual("open_rollout_dialog", data["ui_intent"]["kind"]) self.assertEqual(23, data["ui_intent"]["release_id"]) mock_get_release_summary.assert_called_once_with() mock_get_release_launchpad.assert_called_once_with() @patch("app.services.ops_service.create_release_and_smart_rollout_from_latest_package") def test_create_smart_release_rollout_worker_calls_backend_flow( self, mock_create_release_and_smart_rollout_from_latest_package, ) -> None: mock_create_release_and_smart_rollout_from_latest_package.return_value = ( True, "Release rollout 已创建", { "release": {"id": 31, "release_version": "domaincheck_release_demo"}, "rollout_created": True, }, ) ok, message, data = execute_driver_action( { "action_code": "create_smart_release_rollout_worker", "action_payload": { "channel": "stable", }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("Release rollout 已创建", message) self.assertTrue(data["handled"]) self.assertEqual("smart-release-rollout", data["mode"]) self.assertTrue(data["smart_release_result"]["rollout_created"]) mock_create_release_and_smart_rollout_from_latest_package.assert_called_once() called_payload = mock_create_release_and_smart_rollout_from_latest_package.call_args.args[0] self.assertEqual("worker", called_payload["mode"]) self.assertEqual("stable", called_payload["channel"]) self.assertEqual("test/create_smart_release_rollout_worker", called_payload["created_by"]) @patch("app.services.ops_service.create_release_and_smart_rollout_from_latest_package") def test_create_smart_release_rollout_control_passes_confirm_risky( self, mock_create_release_and_smart_rollout_from_latest_package, ) -> None: mock_create_release_and_smart_rollout_from_latest_package.return_value = ( True, "Release 已创建,智能 Rollout 需要确认", { "release": {"id": 32, "release_version": "domaincheck_release_demo"}, "requires_confirmation": True, "rollout_created": False, }, ) ok, message, data = execute_driver_action( { "action_code": "create_smart_release_rollout_control", "action_payload": { "confirm_risky": True, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("Release 已创建,智能 Rollout 需要确认", message) self.assertTrue(data["handled"]) self.assertEqual("smart-release-rollout", data["mode"]) mock_create_release_and_smart_rollout_from_latest_package.assert_called_once() called_payload = mock_create_release_and_smart_rollout_from_latest_package.call_args.args[0] self.assertEqual("control", called_payload["mode"]) self.assertTrue(called_payload["confirm_risky"]) @patch("app.services.ops_service.create_smart_release_rollout") def test_create_release_rollout_worker_calls_existing_release_backend_flow( self, mock_create_smart_release_rollout, ) -> None: mock_create_smart_release_rollout.return_value = ( True, "Release rollout 已创建", { "release": {"id": 41, "release_version": "domaincheck_release_existing"}, "release_created": False, "rollout_created": True, }, ) ok, message, data = execute_driver_action( { "action_code": "create_release_rollout_worker", "action_payload": { "release_id": 41, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("Release rollout 已创建", message) self.assertTrue(data["handled"]) self.assertEqual("smart-release-rollout", data["mode"]) mock_create_smart_release_rollout.assert_called_once() called_release_id = mock_create_smart_release_rollout.call_args.args[0] called_payload = mock_create_smart_release_rollout.call_args.args[1] self.assertEqual(41, called_release_id) self.assertEqual("worker", called_payload["mode"]) self.assertEqual("test/create_release_rollout_worker", called_payload["created_by"]) @patch("app.services.ops_service.create_smart_release_rollout") def test_create_release_rollout_control_passes_confirm_risky( self, mock_create_smart_release_rollout, ) -> None: mock_create_smart_release_rollout.return_value = ( True, "智能 Rollout 需要确认", { "release": {"id": 42, "release_version": "domaincheck_release_existing"}, "release_created": False, "requires_confirmation": True, "rollout_created": False, }, ) ok, message, data = execute_driver_action( { "action_code": "create_release_rollout_control", "action_payload": { "release_id": 42, "confirm_risky": True, }, "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("智能 Rollout 需要确认", message) self.assertTrue(data["handled"]) self.assertEqual("smart-release-rollout", data["mode"]) mock_create_smart_release_rollout.assert_called_once() called_release_id = mock_create_smart_release_rollout.call_args.args[0] called_payload = mock_create_smart_release_rollout.call_args.args[1] self.assertEqual(42, called_release_id) self.assertEqual("control", called_payload["mode"]) self.assertTrue(called_payload["confirm_risky"]) @patch("app.services.ops_service.update_runtime_settings") @patch("app.services.ops_service.get_runtime_settings") def test_enable_log_sync_key_updates_runtime_settings( self, mock_get_runtime_settings, mock_update_runtime_settings, ) -> None: mock_get_runtime_settings.return_value = { "worker_log_sync_enabled": False, "worker_log_sync_mode": "key", } mock_update_runtime_settings.return_value = { "worker_log_sync_enabled": True, "worker_log_sync_mode": "key", } ok, message, data = execute_driver_action( { "action_code": "enable_log_sync_key", "requested_by": "test", } ) self.assertTrue(ok, message) mock_update_runtime_settings.assert_called_once_with( { "worker_log_sync_enabled": True, "worker_log_sync_mode": "key", } ) self.assertEqual("远端日志回传已切到关键模式", message) self.assertTrue(data["handled"]) self.assertEqual("settings", data["mode"]) self.assertTrue(data["runtime_settings"]["worker_log_sync_enabled"]) self.assertEqual("key", data["runtime_settings"]["worker_log_sync_mode"]) @patch("app.services.ops_service.update_runtime_settings") @patch("app.services.ops_service.get_runtime_settings") def test_enable_log_sync_full_updates_runtime_settings( self, mock_get_runtime_settings, mock_update_runtime_settings, ) -> None: mock_get_runtime_settings.return_value = { "worker_log_sync_enabled": False, "worker_log_sync_mode": "key", } mock_update_runtime_settings.return_value = { "worker_log_sync_enabled": True, "worker_log_sync_mode": "full", } ok, message, data = execute_driver_action( { "action_code": "enable_log_sync_full", "requested_by": "test", } ) self.assertTrue(ok, message) mock_update_runtime_settings.assert_called_once_with( { "worker_log_sync_enabled": True, "worker_log_sync_mode": "full", } ) self.assertEqual("远端日志回传已切到全量模式", message) self.assertTrue(data["handled"]) self.assertEqual("settings", data["mode"]) self.assertTrue(data["runtime_settings"]["worker_log_sync_enabled"]) self.assertEqual("full", data["runtime_settings"]["worker_log_sync_mode"]) @patch("app.services.ops_service.update_runtime_settings") @patch("app.services.ops_service.get_runtime_settings") def test_disable_log_sync_updates_runtime_settings( self, mock_get_runtime_settings, mock_update_runtime_settings, ) -> None: mock_get_runtime_settings.return_value = { "worker_log_sync_enabled": True, "worker_log_sync_mode": "full", } mock_update_runtime_settings.return_value = { "worker_log_sync_enabled": False, "worker_log_sync_mode": "key", } ok, message, data = execute_driver_action( { "action_code": "disable_log_sync", "requested_by": "test", } ) self.assertTrue(ok, message) mock_update_runtime_settings.assert_called_once_with( { "worker_log_sync_enabled": False, "worker_log_sync_mode": "key", } ) self.assertEqual("远端日志回传已关闭", message) self.assertTrue(data["handled"]) self.assertEqual("settings", data["mode"]) self.assertFalse(data["runtime_settings"]["worker_log_sync_enabled"]) self.assertEqual("key", data["runtime_settings"]["worker_log_sync_mode"]) @patch("app.services.ops_service.execute_ops_playbook") @patch("app.services.ops_service.list_managed_nodes_with_agent_state") def test_open_worker_logs_auto_switches_to_ssh_when_target_is_ssh_ready( self, mock_list_managed_nodes_with_agent_state, mock_execute_ops_playbook, ) -> None: mock_list_managed_nodes_with_agent_state.return_value = { "nodes": [ { "node_code": "mainland-worker-01", "is_managed": True, "is_enabled": True, "is_agent_online": False, "has_ssh_access": True, } ] } mock_execute_ops_playbook.return_value = (True, "ok", {"run_code": "playbook-001"}) ok, message, data = execute_driver_action( { "action_code": "open_worker_logs_participating", "node_codes": ["mainland-worker-01"], "requested_by": "test", } ) self.assertTrue(ok, message) self.assertEqual("ssh", data["execution_mode"]) called_payload = mock_execute_ops_playbook.call_args.args[0] self.assertEqual("ssh", called_payload["execution_mode"]) if __name__ == "__main__": unittest.main()