"""Pytest configuration and shared fixtures for ContextEngine tests.
This module provides fixtures for testing with AGFS server.
"""
import os
import sys
import tempfile
import shutil
from pathlib import Path
import pytest
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
from core.models import RequestContext, ContextNode
from core.interfaces import ContextFS, VectorIndex, Embedder
from pyagfs import AGFSClient
from fs.agfs_adapter import AGFSContextFS
from providers.vector_index.in_memory_index import InMemoryVectorIndex
from providers.embedder.mock_embedder import MockEmbedder
AGFS_BASE_URL = os.environ.get("AGFS_BASE_URL", "http://localhost:1833")
AGFS_DATA_DIR = os.environ.get("AGFS_DATA_DIR", str(Path(__file__).parent.parent / ".agfs_test_data"))
@pytest.fixture(scope="session")
def agfs_server_info():
"""Check if AGFS server is available."""
import requests
try:
response = requests.get(f"{AGFS_BASE_URL}/api/v1/health", timeout=2)
if response.status_code == 200:
return {"available": True, "url": AGFS_BASE_URL}
except Exception:
pass
pytest.skip(f"AGFS server not available at {AGFS_BASE_URL}. Start it with:\n"
" cd agfs/agfs-server && ./build/agfs-server -c config.yaml")
@pytest.fixture(scope="function")
def agfs_client(agfs_server_info):
"""Create AGFS client for testing."""
return AGFSClient(api_base_url=agfs_server_info["url"])
@pytest.fixture(scope="function")
def agfs(agfs_client, tmp_path):
"""Create AGFS ContextFS for testing.
Each test gets an isolated mount point under /local/test_{test_name}/
"""
test_name = tmp_path.name[:16]
mount_prefix = f"/local/test_{test_name}"
fs = AGFSContextFS(client=agfs_client, mount_prefix=mount_prefix)
try:
agfs_client.mkdir(mount_prefix)
except Exception:
pass
yield fs
try:
pass
except Exception:
pass
@pytest.fixture(scope="function")
def sample_context():
"""Create a sample RequestContext for testing."""
import uuid
return RequestContext(
account_id="test-account",
user_id="test-user",
agent_id="test-agent",
session_id=str(uuid.uuid4()),
trace_id=str(uuid.uuid4()),
)
@pytest.fixture(scope="function")
def sample_context_a():
"""Context for user A in multi-tenant tests."""
import uuid
return RequestContext(
account_id="account-a",
user_id="alice",
agent_id="agent",
session_id=str(uuid.uuid4()),
trace_id=str(uuid.uuid4()),
)
@pytest.fixture(scope="function")
def sample_context_b():
"""Context for user B in multi-tenant tests."""
import uuid
return RequestContext(
account_id="account-b",
user_id="bob",
agent_id="agent",
session_id=str(uuid.uuid4()),
trace_id=str(uuid.uuid4()),
)
@pytest.fixture(scope="function")
def vector_index():
"""Create InMemoryVectorIndex for testing."""
return InMemoryVectorIndex(dimension=1536)
@pytest.fixture(scope="function")
def mock_embedder():
"""Create mock embedder for testing."""
return MockEmbedder(dimension=1536)
@pytest.fixture(scope="function")
def mock_agfs(agfs):
"""Alias for agfs (legacy name)."""
return agfs
@pytest.fixture(scope="function")
def mock_vector_index(vector_index):
"""Alias for vector_index (legacy name)."""
return vector_index
@pytest.fixture(scope="function")
def sample_profile_node():
"""Create a sample profile ContextNode."""
import uuid
return ContextNode(
uri="ctx://test-account/users/test-user/memories/profile",
context_type="MEMORY",
category="profile",
level=0,
owner_space="user:test-user",
abstract="Test user is a software engineer",
overview="## Profile\n\nName: Test User\nRole: Software Engineer",
content="Full profile content here...",
metadata={"status": "ACTIVE"},
)
@pytest.fixture(scope="function")
def sample_preference_node():
"""Create a sample preference ContextNode."""
import uuid
return ContextNode(
uri="ctx://test-account/users/test-user/memories/preferences/coding",
context_type="MEMORY",
category="preferences",
level=0,
owner_space="user:test-user",
abstract="Prefers PEP8 coding style",
overview="## Coding Preferences\n\n- PEP8 compliant\n- Type hints",
content="Detailed coding preferences...",
metadata={"status": "ACTIVE"},
)
@pytest.fixture(scope="function")
def mock_llm():
"""Create a mock LLM for testing."""
from providers.llm import MockLLM
return MockLLM()