mcqemu/tests/test_integration.py

73 lines
2.4 KiB
Python

"""Integration: boots a real (diskless) QEMU VM through the MCP tools.
Run with: uv run pytest -m integration
"""
import base64
import shutil
import pytest
from fastmcp import Client
from conftest import result_data
from mcqemu.registry import pid_alive
from mcqemu.server import mcp
pytestmark = [
pytest.mark.integration,
pytest.mark.skipif(
shutil.which("qemu-system-x86_64") is None, reason="qemu-system-x86_64 not installed"
),
]
async def test_real_vm_lifecycle(dirs):
async with Client(mcp) as client:
data = result_data(
await client.call_tool(
"launch_vm",
{"name": "itest", "memory_mb": 128, "cpus": 1, "no_net": True},
)
)
pid = data["pid"]
try:
assert data["status"] == "running"
assert pid_alive(pid)
vms = result_data(await client.call_tool("list_vms", {}))
assert [(v["name"], v["status"]) for v in vms] == [("itest", "running")]
info = result_data(await client.call_tool("vm_info", {"name": "itest"}))
assert info["vcpus"] == 1
data = result_data(await client.call_tool("pause_vm", {"name": "itest"}))
assert data["status"] == "paused"
vms = result_data(await client.call_tool("list_vms", {}))
assert vms[0]["status"] == "paused"
await client.call_tool("resume_vm", {"name": "itest"})
# See & drive against the live SeaBIOS display.
result = await client.call_tool("vm_screenshot", {"name": "itest"})
block = result.content[0]
assert block.type == "image"
png = base64.b64decode(block.data)
assert png[:8] == b"\x89PNG\r\n\x1a\n"
await client.call_tool(
"vm_send_keys", {"name": "itest", "keys": ["f2", "enter"], "delay_ms": 0}
)
await client.call_tool("vm_click", {"name": "itest", "x": 10, "y": 10})
data = result_data(await client.call_tool("vm_serial_read", {"name": "itest"}))
assert "tail" in data
data = result_data(await client.call_tool("stop_vm", {"name": "itest", "force": True}))
assert data["status"] == "stopped"
assert not pid_alive(pid)
finally:
if pid_alive(pid):
import os
import signal
os.kill(pid, signal.SIGKILL)