We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/doobidoo/mcp-memory-service'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Tests for database integrity health monitoring."""
import asyncio
import json
import os
import sqlite3
import tempfile
import pytest
# Skip entire module if health subpackage can't be imported
# (happens in uvx/coverage environments where package namespace is shadowed)
pytest.importorskip("mcp_memory_service.health")
@pytest.fixture
def temp_db():
"""Create a temporary SQLite database with a memories table."""
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
db_path = f.name
conn = sqlite3.connect(db_path)
conn.execute("PRAGMA journal_mode=WAL")
conn.execute(
"""CREATE TABLE memories (
content_hash TEXT PRIMARY KEY,
content TEXT,
created_at REAL,
updated_at REAL,
metadata TEXT,
tags TEXT,
type TEXT
)"""
)
conn.execute(
"INSERT INTO memories VALUES (?, ?, ?, ?, ?, ?, ?)",
("hash1", "test memory", 1.0, 1.0, "{}", "test", "note"),
)
conn.commit()
conn.close()
yield db_path
os.unlink(db_path)
for suffix in ("-wal", "-shm"):
path = db_path + suffix
if os.path.exists(path):
os.unlink(path)
@pytest.fixture
def monitor(temp_db, monkeypatch):
"""Create an IntegrityMonitor with test config."""
from mcp_memory_service import config
from mcp_memory_service.health import integrity as integrity_mod
# Patch config values without importlib.reload (which breaks in uvx)
monkeypatch.setattr(config, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(config, "INTEGRITY_CHECK_INTERVAL", 60)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_INTERVAL", 60)
from mcp_memory_service.health.integrity import IntegrityMonitor
return IntegrityMonitor(temp_db)
class TestIntegrityCheck:
"""Tests for PRAGMA integrity_check."""
@pytest.mark.asyncio
async def test_healthy_database(self, monitor):
is_healthy, detail = await monitor.check_integrity()
assert is_healthy is True
assert detail == "ok"
@pytest.mark.asyncio
async def test_missing_database(self, tmp_path, monkeypatch):
from mcp_memory_service import config
from mcp_memory_service.health import integrity as integrity_mod
monkeypatch.setattr(config, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(config, "INTEGRITY_CHECK_INTERVAL", 60)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_INTERVAL", 60)
from mcp_memory_service.health.integrity import IntegrityMonitor
m = IntegrityMonitor(str(tmp_path / "nonexistent.db"))
# SQLite creates the file on connect, so it will be "healthy" but empty
is_healthy, detail = await m.check_integrity()
assert is_healthy is True
@pytest.mark.asyncio
async def test_check_increments_counters(self, monitor):
assert monitor.total_checks == 0
await monitor.run_check()
assert monitor.total_checks == 1
assert monitor.last_check_healthy is True
class TestWalRepair:
"""Tests for WAL checkpoint repair."""
@pytest.mark.asyncio
async def test_repair_on_healthy_db(self, monitor):
success, detail = await monitor.attempt_wal_repair()
assert success is True
assert "successful" in detail
class TestMemoryExport:
"""Tests for emergency memory export."""
@pytest.mark.asyncio
async def test_export_memories(self, monitor, tmp_path):
export_path = str(tmp_path / "export.json")
success, count = await monitor.export_memories(export_path)
assert success is True
assert count == 1
with open(export_path) as f:
data = json.load(f)
assert len(data) == 1
assert data[0]["hash"] == "hash1"
assert data[0]["content"] == "test memory"
@pytest.mark.asyncio
async def test_export_empty_database(self, tmp_path, monkeypatch):
from mcp_memory_service import config
from mcp_memory_service.health import integrity as integrity_mod
monkeypatch.setattr(config, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(config, "INTEGRITY_CHECK_INTERVAL", 60)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_ENABLED", True)
monkeypatch.setattr(integrity_mod, "INTEGRITY_CHECK_INTERVAL", 60)
from mcp_memory_service.health.integrity import IntegrityMonitor
db_path = str(tmp_path / "empty.db")
conn = sqlite3.connect(db_path)
conn.execute(
"""CREATE TABLE memories (
content_hash TEXT PRIMARY KEY, content TEXT,
created_at REAL, updated_at REAL,
metadata TEXT, tags TEXT, type TEXT
)"""
)
conn.close()
m = IntegrityMonitor(db_path)
export_path = str(tmp_path / "export.json")
success, count = await m.export_memories(export_path)
assert success is True
assert count == 0
class TestRunCheck:
"""Tests for the full check + repair flow."""
@pytest.mark.asyncio
async def test_healthy_check_result(self, monitor):
result = await monitor.run_check()
assert result["healthy"] is True
assert result["repaired"] is False
assert result["exported"] is False
assert result["check_ms"] < 1000 # Should be fast
class TestGetStatus:
"""Tests for status reporting."""
def test_initial_status(self, monitor):
status = monitor.get_status()
assert status["running"] is False
assert status["total_checks"] == 0
assert status["total_auto_repairs"] == 0
assert status["total_unrecoverable"] == 0
@pytest.mark.asyncio
async def test_status_after_check(self, monitor):
await monitor.run_check()
status = monitor.get_status()
assert status["total_checks"] == 1
assert status["last_check_healthy"] is True