Files
getDomain/domain-api/tests/test_ops_service_driver_actions.py
2026-04-18 23:52:51 +08:00

1266 lines
50 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()