techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 7)
cc036ff verified
Raw
History Blame Contribute Delete
5.82 kB
"""
Agent service test fixtures.
Provides fixtures for agent graduation service testing.
"""
import os
import tempfile
from datetime import datetime, timedelta
from pathlib import Path
import pytest
from sqlalchemy import create_engine, exc
from sqlalchemy.orm import Session, sessionmaker
# Set TESTING environment variable BEFORE any imports
os.environ["TESTING"] = "1"
# Add parent directory to path for imports
import sys
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
from core.database import Base
from core.models import (
AgentRegistry,
AgentStatus,
Episode,
EpisodeSegment,
SupervisionSession,
SkillExecution,
)
@pytest.fixture(scope="function")
def db_session():
"""
Create a fresh in-memory database for each test.
This ensures complete isolation between test runs by using a
temporary SQLite database file that is deleted after each test.
Each test gets its own database, preventing UNIQUE constraint violations
and state leakage between tests.
"""
# Use file-based temp SQLite for tests to ensure all connections see the same database
# In-memory SQLite (:memory:) creates a separate database for each connection
fd, db_path = tempfile.mkstemp(suffix='.db')
os.close(fd) # Close the file descriptor, we just need the path
engine = create_engine(
f"sqlite:///{db_path}",
connect_args={"check_same_thread": False},
echo=False
)
# Store path for cleanup
engine._test_db_path = db_path
# Create all tables, handling missing foreign key references from optional modules
# Same approach as property_tests conftest.py
tables_created = 0
tables_skipped = 0
for table in Base.metadata.sorted_tables:
try:
table.create(engine, checkfirst=True)
tables_created += 1
except exc.NoReferencedTableError:
# Skip tables with missing FK references (from optional modules)
tables_skipped += 1
continue
except (exc.CompileError, exc.UnsupportedCompilationError):
# Skip tables with unsupported types (JSONB in SQLite)
tables_skipped += 1
continue
except Exception as e:
# Ignore duplicate table/index errors
if "already exists" in str(e).lower() or "duplicate" in str(e).lower():
continue
else:
raise
# Create session
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
session = TestingSessionLocal()
yield session
# Cleanup
session.close()
engine.dispose()
# Delete temp database file
if hasattr(engine, '_test_db_path'):
try:
os.unlink(engine._test_db_path)
except Exception:
pass # File might already be deleted
@pytest.fixture
def test_agent_student(db_session):
"""Create a test STUDENT agent."""
agent = AgentRegistry(
id="test-agent-student",
name="Test Student Agent",
category="Testing",
module_path="test.agents.student",
class_name="StudentAgent",
status=AgentStatus.STUDENT,
tenant_id="default",
created_at=datetime.now()
)
db_session.add(agent)
db_session.commit()
return agent
@pytest.fixture
def test_agent_intern(db_session):
"""Create a test INTERN agent."""
agent = AgentRegistry(
id="test-agent-intern",
name="Test Intern Agent",
category="Testing",
module_path="test.agents.intern",
class_name="InternAgent",
status=AgentStatus.INTERN,
tenant_id="default",
created_at=datetime.now()
)
db_session.add(agent)
db_session.commit()
return agent
@pytest.fixture
def test_agent_supervised(db_session):
"""Create a test SUPERVISED agent."""
agent = AgentRegistry(
id="test-agent-supervised",
name="Test Supervised Agent",
category="Testing",
module_path="test.agents.supervised",
class_name="SupervisedAgent",
status=AgentStatus.SUPERVISED,
tenant_id="default",
created_at=datetime.now()
)
db_session.add(agent)
db_session.commit()
return agent
@pytest.fixture
def test_episodes_for_intern(db_session, test_agent_intern):
"""Create test episodes for INTERN promotion."""
agent_id = test_agent_intern.id
episodes = []
for i in range(15): # More than minimum 10 for INTERN
episode = Episode(
id=f"episode-{i}",
agent_id=agent_id,
title=f"Episode {i}",
maturity_at_time="INTERN",
status="completed",
human_intervention_count=1, # Low interventions (10% rate)
constitutional_score=0.85, # Above 0.70 threshold
started_at=datetime.now() - timedelta(days=i+1)
)
db_session.add(episode)
episodes.append(episode)
db_session.commit()
return episodes
@pytest.fixture
def test_supervision_sessions(db_session, test_agent_supervised):
"""Create test supervision sessions."""
agent_id = test_agent_supervised.id
sessions = []
for i in range(5):
session = SupervisionSession(
id=f"session-{i}",
agent_id=agent_id,
agent_name="Test Supervised Agent",
supervisor_id="supervisor-123",
workspace_id="default",
status="completed",
started_at=datetime.now() - timedelta(hours=i+1),
duration_seconds=3600, # 1 hour each
intervention_count=1,
supervisor_rating=4.5
)
db_session.add(session)
sessions.append(session)
db_session.commit()
return sessions