Initial implementation

This commit is contained in:
2026-04-13 14:22:37 +02:00
commit a0c1b6ed93
26 changed files with 4125 additions and 0 deletions
+173
View File
@@ -0,0 +1,173 @@
"""Tests for modules/containers.py."""
import pytest
from unittest.mock import AsyncMock
def make_mock_mcp():
tools: dict = {}
class MockMCP:
def tool(self):
def decorator(fn):
tools[fn.__name__] = fn
return fn
return decorator
return MockMCP(), tools
def make_config():
from mcp_synology_container.config import AppConfig, ConnectionConfig
return AppConfig(
schema_version=1,
connection=ConnectionConfig(host="nas.local", port=443, https=True, verify_ssl=True),
)
SAMPLE_CONTAINERS_DATA = {
"containers": [
{
"name": "myapp_web",
"status": "running",
"image": "nginx:alpine",
"project_name": "myapp",
},
{
"name": "myapp_db",
"status": "running",
"image": "postgres:15",
"project_name": "myapp",
},
{
"name": "other_svc",
"status": "stopped",
"image": "redis:7",
"project_name": "other",
},
]
}
SAMPLE_LOGS_DATA = {
"logs": [
{
"created": "2025-01-01T10:00:00Z",
"stream": "stdout",
"text": "Server started",
"docid": "1",
},
{
"created": "2025-01-01T10:00:01Z",
"stream": "stderr",
"text": "Warning: deprecated option",
"docid": "2",
},
],
"total": 2,
}
@pytest.mark.asyncio
async def test_list_containers_all():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = SAMPLE_CONTAINERS_DATA
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["list_containers"]()
assert "myapp_web" in result
assert "myapp_db" in result
assert "other_svc" in result
@pytest.mark.asyncio
async def test_list_containers_filtered_by_project():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = SAMPLE_CONTAINERS_DATA
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["list_containers"](project_name="myapp")
assert "myapp_web" in result
assert "myapp_db" in result
assert "other_svc" not in result
@pytest.mark.asyncio
async def test_list_containers_empty():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = {"containers": []}
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["list_containers"]()
assert "No containers found" in result
@pytest.mark.asyncio
async def test_get_container_logs():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = SAMPLE_LOGS_DATA
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["get_container_logs"]("myapp_web", tail=50)
assert "myapp_web" in result
assert "Server started" in result
assert "Warning: deprecated option" in result
@pytest.mark.asyncio
async def test_get_container_logs_with_keyword():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = SAMPLE_LOGS_DATA
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
await tools["get_container_logs"]("myapp_web", tail=100, keyword="error")
call_params = client.request.call_args[1]["params"]
assert call_params["keyword"] == "error"
@pytest.mark.asyncio
async def test_exec_in_container_requires_confirmation():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["exec_in_container"]("myapp_web", "ls /app", confirmed=False)
assert "confirmed=True" in result
client.request.assert_not_called()
@pytest.mark.asyncio
async def test_exec_in_container_confirmed():
from mcp_synology_container.modules.containers import register_containers
client = AsyncMock()
client.request.return_value = {"output": "file1.py\nfile2.py", "exit_code": 0}
mcp, tools = make_mock_mcp()
register_containers(mcp, make_config(), client)
result = await tools["exec_in_container"]("myapp_web", "ls /app", confirmed=True)
assert "file1.py" in result
assert "Exit code: 0" in result