Files
mcp-proxmox/tests/test_vm_console.py
defiQUG 68f824b17e fix(mcp): harden Proxmox MCP server tools and expand test coverage
Refine VM/cluster/storage tool handlers and auth utilities; add conftest
and extend server/console tests for more reliable operator automation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 21:51:35 -07:00

123 lines
3.7 KiB
Python

"""
Tests for VM console operations.
"""
from unittest.mock import Mock
import pytest
from proxmox_mcp.tools.console.manager import VMConsoleManager
def _agent_mock(*, exec_result: dict, status_result: dict) -> Mock:
exec_endpoint = Mock()
exec_endpoint.post.return_value = exec_result
status_endpoint = Mock()
status_endpoint.get.return_value = status_result
def _route(command: str) -> Mock:
if command == "exec":
return exec_endpoint
if command == "exec-status":
return status_endpoint
raise AssertionError(f"unexpected agent command: {command}")
return Mock(side_effect=_route)
@pytest.fixture
def mock_proxmox():
"""Fixture to create a mock ProxmoxAPI instance."""
mock = Mock()
mock.nodes.return_value.qemu.return_value.status.current.get.return_value = {
"status": "running"
}
mock.nodes.return_value.qemu.return_value.agent = _agent_mock(
exec_result={"pid": 123},
status_result={
"out-data": "command output",
"err-data": "",
"exitcode": 0,
"exited": 1,
},
)
return mock
@pytest.fixture
def vm_console(mock_proxmox):
"""Fixture to create a VMConsoleManager instance."""
return VMConsoleManager(mock_proxmox)
@pytest.mark.asyncio
async def test_execute_command_success(vm_console, mock_proxmox):
"""Test successful command execution."""
result = await vm_console.execute_command("node1", "100", "ls -l")
assert result["success"] is True
assert result["output"] == "command output"
assert result["error"] == ""
assert result["exit_code"] == 0
mock_proxmox.nodes.assert_called_with("node1")
mock_proxmox.nodes.return_value.qemu.assert_called_with("100")
@pytest.mark.asyncio
async def test_execute_command_vm_not_running(vm_console, mock_proxmox):
"""Test command execution on stopped VM."""
mock_proxmox.nodes.return_value.qemu.return_value.status.current.get.return_value = {
"status": "stopped"
}
with pytest.raises(ValueError, match="not running"):
await vm_console.execute_command("node1", "100", "ls -l")
@pytest.mark.asyncio
async def test_execute_command_vm_not_found(vm_console, mock_proxmox):
"""Test command execution on non-existent VM."""
mock_proxmox.nodes.return_value.qemu.return_value.status.current.get.side_effect = Exception(
"VM not found"
)
with pytest.raises(ValueError, match="not found"):
await vm_console.execute_command("node1", "100", "ls -l")
@pytest.mark.asyncio
async def test_execute_command_failure(vm_console, mock_proxmox):
"""Test command execution failure."""
mock_proxmox.nodes.return_value.qemu.return_value.agent = _agent_mock(
exec_result={"pid": 123},
status_result={},
)
mock_proxmox.nodes.return_value.qemu.return_value.agent.side_effect = Exception(
"Command failed"
)
with pytest.raises(RuntimeError, match="Failed to execute command"):
await vm_console.execute_command("node1", "100", "ls -l")
@pytest.mark.asyncio
async def test_execute_command_with_error_output(vm_console, mock_proxmox):
"""Test command execution with error output."""
mock_proxmox.nodes.return_value.qemu.return_value.agent = _agent_mock(
exec_result={"pid": 123},
status_result={
"out-data": "",
"err-data": "command error",
"exitcode": 1,
"exited": 1,
},
)
result = await vm_console.execute_command("node1", "100", "invalid-command")
assert result["success"] is True
assert result["output"] == ""
assert result["error"] == "command error"
assert result["exit_code"] == 1