d
This commit is contained in:
@@ -2,14 +2,17 @@ import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from app.services import ops_runtime_executor_service
|
||||
from app.services.ops_runtime_executor_service import execute_local_support_action, execute_ssh_action
|
||||
|
||||
|
||||
class OpsRuntimeExecutorServiceTests(unittest.TestCase):
|
||||
@patch("app.services.ops_runtime_executor_service.subprocess.run")
|
||||
def test_execute_ssh_action_parses_structured_json_result(self, mock_run) -> None:
|
||||
@patch("app.services.ops_runtime_executor_service._load_ssh_secret")
|
||||
def test_execute_ssh_action_parses_structured_json_result(self, mock_load_secret, mock_run) -> None:
|
||||
mock_load_secret.return_value = {"ssh_password": "", "ssh_private_key": ""}
|
||||
mock_run.return_value = subprocess.CompletedProcess(
|
||||
args=["ssh"],
|
||||
returncode=0,
|
||||
@@ -113,6 +116,105 @@ class OpsRuntimeExecutorServiceTests(unittest.TestCase):
|
||||
issued_command = mock_run.call_args.args[0]
|
||||
self.assertEqual(["systemctl", "restart", "domaincheck-worker"], issued_command)
|
||||
|
||||
@patch("app.services.ops_runtime_executor_service.subprocess.run")
|
||||
@patch("app.services.ops_runtime_executor_service._load_ssh_secret")
|
||||
@patch("app.services.ops_runtime_executor_service.paramiko.SSHClient")
|
||||
def test_execute_ssh_action_uses_paramiko_for_password_auth(self, mock_ssh_client_cls, mock_load_secret, mock_run) -> None:
|
||||
mock_load_secret.return_value = {"ssh_password": "demo-pass", "ssh_private_key": ""}
|
||||
mock_client = MagicMock()
|
||||
stdout = MagicMock()
|
||||
stderr = MagicMock()
|
||||
stdout.channel.recv_exit_status.return_value = 0
|
||||
stdout.read.return_value = (
|
||||
b'{"ok": true, "message": "health snapshot collected", "result": {"checks": {"api": {"state": "active"}}}}\n'
|
||||
)
|
||||
stderr.read.return_value = b""
|
||||
mock_client.exec_command.return_value = (None, stdout, stderr)
|
||||
mock_ssh_client_cls.return_value = mock_client
|
||||
|
||||
ok, message, data = execute_ssh_action(
|
||||
{
|
||||
"node_code": "mainland-worker-01",
|
||||
"ssh_host": "121.204.244.248",
|
||||
"ssh_port": 22,
|
||||
"ssh_user": "root",
|
||||
"auth_mode": "password",
|
||||
},
|
||||
"health.snapshot",
|
||||
{},
|
||||
)
|
||||
|
||||
self.assertTrue(ok)
|
||||
self.assertEqual("health snapshot collected", message)
|
||||
self.assertEqual("active", data["checks"]["api"]["state"])
|
||||
self.assertEqual("password", data["transport"]["auth_mode"])
|
||||
mock_client.connect.assert_called_once()
|
||||
self.assertFalse(mock_run.called)
|
||||
|
||||
@patch("app.services.ops_runtime_executor_service.subprocess.run")
|
||||
@patch("app.services.ops_runtime_executor_service._load_ssh_secret")
|
||||
@patch("app.services.ops_runtime_executor_service.paramiko.SSHClient")
|
||||
def test_execute_ssh_action_falls_back_to_password_when_node_auth_mode_is_key_but_only_password_exists(
|
||||
self,
|
||||
mock_ssh_client_cls,
|
||||
mock_load_secret,
|
||||
mock_run,
|
||||
) -> None:
|
||||
mock_load_secret.return_value = {"ssh_password": "demo-pass", "ssh_private_key": ""}
|
||||
mock_client = MagicMock()
|
||||
stdout = MagicMock()
|
||||
stderr = MagicMock()
|
||||
stdout.channel.recv_exit_status.return_value = 0
|
||||
stdout.read.return_value = (
|
||||
b'{"ok": true, "message": "health snapshot collected", "result": {"checks": {"api": {"state": "active"}}}}\n'
|
||||
)
|
||||
stderr.read.return_value = b""
|
||||
mock_client.exec_command.return_value = (None, stdout, stderr)
|
||||
mock_ssh_client_cls.return_value = mock_client
|
||||
|
||||
ok, message, data = execute_ssh_action(
|
||||
{
|
||||
"node_code": "mainland-controller-01",
|
||||
"ssh_host": "121.204.244.188",
|
||||
"ssh_port": 22,
|
||||
"ssh_user": "root",
|
||||
"auth_mode": "key",
|
||||
},
|
||||
"health.snapshot",
|
||||
{},
|
||||
)
|
||||
|
||||
self.assertTrue(ok)
|
||||
self.assertEqual("health snapshot collected", message)
|
||||
self.assertEqual("password", data["transport"]["auth_mode"])
|
||||
mock_client.connect.assert_called_once()
|
||||
self.assertFalse(mock_run.called)
|
||||
|
||||
@patch("app.services.ops_runtime_executor_service._load_ssh_secret")
|
||||
def test_execute_ssh_action_returns_graceful_error_when_paramiko_missing_for_password_auth(
|
||||
self,
|
||||
mock_load_secret,
|
||||
) -> None:
|
||||
mock_load_secret.return_value = {"ssh_password": "demo-pass", "ssh_private_key": ""}
|
||||
|
||||
with patch.object(ops_runtime_executor_service, "paramiko", None):
|
||||
ok, message, data = execute_ssh_action(
|
||||
{
|
||||
"node_code": "mainland-controller-01",
|
||||
"ssh_host": "121.204.244.188",
|
||||
"ssh_port": 22,
|
||||
"ssh_user": "root",
|
||||
"auth_mode": "password",
|
||||
},
|
||||
"health.snapshot",
|
||||
{},
|
||||
)
|
||||
|
||||
self.assertFalse(ok)
|
||||
self.assertIn("paramiko", message)
|
||||
self.assertEqual("password", data["transport"]["auth_mode"])
|
||||
self.assertEqual("121.204.244.188", data["transport"]["ssh_host"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user