Files
mcp-proxmox/tests/test_server.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

125 lines
4.2 KiB
Python

"""
Tests for the Proxmox MCP server.
"""
import pytest
from mcp.server.mcpserver.exceptions import ToolError
def test_server_initialization(server, mock_proxmox):
"""Test server initialization with mocked configuration."""
assert server.config.proxmox.host == "test.proxmox.com"
assert server.config.auth.user == "test@pve"
assert server.config.auth.token_name == "test_token"
assert server.config.auth.token_value == "test_value"
assert server.config.logging.level == "DEBUG"
mock_proxmox.assert_called_once()
@pytest.mark.asyncio
async def test_list_tools(server):
"""Test listing available tools."""
tools = await server.mcp.list_tools()
tool_names = {tool.name for tool in tools}
assert {"get_nodes", "get_vms", "get_storage", "get_cluster_status", "execute_vm_command"} <= tool_names
@pytest.mark.asyncio
async def test_get_nodes(server, mock_proxmox):
"""Test get_nodes tool returns formatted node output."""
mock_proxmox.return_value.nodes.get.return_value = [
{"node": "node1", "status": "online"},
{"node": "node2", "status": "online"},
]
mock_proxmox.return_value.nodes.return_value.status.get.return_value = {
"uptime": 0,
"cpuinfo": {"cpus": 4},
"memory": {"used": 0, "total": 1},
}
response = await server.mcp.call_tool("get_nodes", {})
text = response[0].text
assert "node1" in text
assert "node2" in text
@pytest.mark.asyncio
async def test_get_node_status_missing_parameter(server):
"""Test get_node_status tool with missing parameter."""
with pytest.raises(ToolError, match="Field required"):
await server.mcp.call_tool("get_node_status", {})
@pytest.mark.asyncio
async def test_get_node_status(server, mock_proxmox):
"""Test get_node_status tool with valid parameter."""
mock_proxmox.return_value.nodes.return_value.status.get.return_value = {
"status": "running",
"uptime": 123456,
"cpu": 0.1,
"cpuinfo": {"cpus": 4},
"memory": {"used": 1, "total": 2, "free": 1},
}
response = await server.mcp.call_tool("get_node_status", {"node": "node1"})
assert "node1" in response[0].text
assert "123456" in response[0].text or "running" in response[0].text.lower()
@pytest.mark.asyncio
async def test_get_vms(server, mock_proxmox):
"""Test get_vms tool."""
mock_proxmox.return_value.nodes.get.return_value = [{"node": "node1", "status": "online"}]
mock_proxmox.return_value.nodes.return_value.qemu.get.return_value = [
{"vmid": "100", "name": "vm1", "status": "running", "mem": 0, "maxmem": 1},
{"vmid": "101", "name": "vm2", "status": "stopped", "mem": 0, "maxmem": 1},
]
mock_proxmox.return_value.nodes.return_value.qemu.return_value.config.get.return_value = {
"cores": 2
}
response = await server.mcp.call_tool("get_vms", {})
text = response[0].text
assert "vm1" in text
assert "vm2" in text
@pytest.mark.asyncio
async def test_get_storage(server, mock_proxmox):
"""Test get_storage tool."""
mock_proxmox.return_value.storage.get.return_value = [
{"storage": "local", "type": "dir", "enabled": True},
{"storage": "ceph", "type": "rbd", "enabled": True},
]
mock_proxmox.return_value.nodes.return_value.storage.return_value.status.get.return_value = {
"used": 1,
"total": 2,
"avail": 1,
}
response = await server.mcp.call_tool("get_storage", {})
text = response[0].text
assert "local" in text
assert "ceph" in text
@pytest.mark.asyncio
async def test_get_cluster_status(server, mock_proxmox):
"""Test get_cluster_status tool."""
mock_proxmox.return_value.cluster.status.get.return_value = [
{"name": "cluster", "quorate": True, "type": "cluster"},
{"node": "node1", "type": "node"},
{"node": "node2", "type": "node"},
]
response = await server.mcp.call_tool("get_cluster_status", {})
text = response[0].text.lower()
assert "cluster" in text or "quorum" in text
@pytest.mark.asyncio
async def test_execute_vm_command_missing_parameters(server):
"""Test VM command execution with missing parameters."""
with pytest.raises(ToolError):
await server.mcp.call_tool("execute_vm_command", {})