| """ |
| Agent CRUD operations database integration tests (Phase 3, Plan 1, Task 2.2). |
| |
| Tests cover: |
| - Agent CRUD operations with database |
| - Agent filtering and sorting |
| - Agent pagination |
| - Agent relationship queries (executions, feedback) |
| |
| Coverage target: All query patterns tested with actual database |
| """ |
|
|
| import pytest |
| from datetime import datetime, timedelta |
| from sqlalchemy.orm import Session |
| from sqlalchemy import and_, or_, desc |
|
|
| from core.models import ( |
| AgentRegistry, AgentExecution, AgentFeedback, AgentStatus, |
| User |
| ) |
|
|
|
|
| class TestAgentCRUDOperations: |
| """Integration tests for agent CRUD operations.""" |
|
|
| def test_create_agent(self, db_session: Session): |
| """Test creating an agent in database.""" |
| agent = AgentRegistry( |
| name="CRUDAgent", |
| category="test", |
| module_path="test.module", |
| class_name="CRUDAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6, |
| description="A CRUD test agent" |
| ) |
| db_session.add(agent) |
| db_session.commit() |
| db_session.refresh(agent) |
|
|
| assert agent.id is not None |
| assert agent.name == "CRUDAgent" |
| assert agent.category == "test" |
| assert agent.status == AgentStatus.INTERN.value |
|
|
| def test_read_agent_by_id(self, db_session: Session): |
| """Test reading an agent by ID.""" |
| agent = AgentRegistry( |
| name="ReadAgent", |
| category="test", |
| module_path="test.module", |
| class_name="ReadAgent", |
| status=AgentStatus.SUPERVISED.value, |
| confidence_score=0.8 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
| db_session.refresh(agent) |
|
|
| retrieved = db_session.query(AgentRegistry).filter_by(id=agent.id).first() |
| assert retrieved is not None |
| assert retrieved.id == agent.id |
| assert retrieved.name == "ReadAgent" |
|
|
| def test_update_agent(self, db_session: Session): |
| """Test updating an agent.""" |
| agent = AgentRegistry( |
| name="UpdateAgent", |
| category="test", |
| module_path="test.module", |
| class_name="UpdateAgent", |
| status=AgentStatus.STUDENT.value, |
| confidence_score=0.3 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
| db_session.refresh(agent) |
|
|
| |
| agent.name = "UpdatedAgent" |
| agent.confidence_score = 0.75 |
| agent.status = AgentStatus.SUPERVISED.value |
| db_session.commit() |
| db_session.refresh(agent) |
|
|
| assert agent.name == "UpdatedAgent" |
| assert agent.confidence_score == 0.75 |
| assert agent.status == AgentStatus.SUPERVISED.value |
|
|
| def test_delete_agent(self, db_session: Session): |
| """Test deleting an agent.""" |
| agent = AgentRegistry( |
| name="DeleteAgent", |
| category="test", |
| module_path="test.module", |
| class_name="DeleteAgent", |
| status=AgentStatus.STUDENT.value, |
| confidence_score=0.3 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
| db_session.refresh(agent) |
|
|
| agent_id = agent.id |
|
|
| db_session.delete(agent) |
| db_session.commit() |
|
|
| deleted = db_session.query(AgentRegistry).filter_by(id=agent_id).first() |
| assert deleted is None |
|
|
| def test_bulk_agent_creation(self, db_session: Session): |
| """Test creating multiple agents.""" |
| agents = [] |
| for i in range(5): |
| agent = AgentRegistry( |
| name=f"BulkAgent{i}", |
| category="test", |
| module_path="test.module", |
| class_name=f"BulkAgent{i}", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.5 + (i * 0.1) |
| ) |
| agents.append(agent) |
| db_session.add(agent) |
|
|
| db_session.commit() |
|
|
| count = db_session.query(AgentRegistry).filter( |
| AgentRegistry.name.like("BulkAgent%") |
| ).count() |
| assert count == 5 |
|
|
|
|
| class TestAgentFiltering: |
| """Integration tests for agent filtering.""" |
|
|
| def test_filter_by_status(self, db_session: Session): |
| """Test filtering agents by status.""" |
| |
| for status in [AgentStatus.STUDENT, AgentStatus.INTERN, AgentStatus.SUPERVISED]: |
| agent = AgentRegistry( |
| name=f"FilterAgent{status.value}", |
| category="test", |
| module_path="test.module", |
| class_name="FilterAgent", |
| status=status.value, |
| confidence_score=0.5 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| interns = db_session.query(AgentRegistry).filter_by( |
| status=AgentStatus.INTERN.value |
| ).all() |
|
|
| assert len(interns) == 1 |
| assert interns[0].status == AgentStatus.INTERN.value |
|
|
| def test_filter_by_category(self, db_session: Session): |
| """Test filtering agents by category.""" |
| categories = ["sales", "support", "finance"] |
| for cat in categories: |
| agent = AgentRegistry( |
| name=f"{cat.capitalize()}Agent", |
| category=cat, |
| module_path="test.module", |
| class_name="CategoryAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| sales_agents = db_session.query(AgentRegistry).filter_by( |
| category="sales" |
| ).all() |
|
|
| assert len(sales_agents) == 1 |
| assert sales_agents[0].category == "sales" |
|
|
| def test_filter_by_confidence_range(self, db_session: Session): |
| """Test filtering agents by confidence score range.""" |
| |
| for score in [0.3, 0.5, 0.7, 0.9]: |
| agent = AgentRegistry( |
| name=f"ConfidenceAgent{int(score*10)}", |
| category="test", |
| module_path="test.module", |
| class_name="ConfidenceAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=score |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| high_confidence = db_session.query(AgentRegistry).filter( |
| AgentRegistry.confidence_score >= 0.7 |
| ).all() |
|
|
| assert len(high_confidence) == 2 |
|
|
| def test_filter_by_multiple_conditions(self, db_session: Session): |
| """Test filtering agents with multiple conditions.""" |
| agent1 = AgentRegistry( |
| name="MultiFilter1", |
| category="sales", |
| module_path="test.module", |
| class_name="MultiAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| agent2 = AgentRegistry( |
| name="MultiFilter2", |
| category="sales", |
| module_path="test.module", |
| class_name="MultiAgent", |
| status=AgentStatus.SUPERVISED.value, |
| confidence_score=0.8 |
| ) |
| db_session.add(agent1) |
| db_session.add(agent2) |
| db_session.commit() |
|
|
| results = db_session.query(AgentRegistry).filter( |
| and_( |
| AgentRegistry.category == "sales", |
| AgentRegistry.confidence_score >= 0.7 |
| ) |
| ).all() |
|
|
| assert len(results) == 1 |
| assert results[0].name == "MultiFilter2" |
|
|
| def test_filter_with_or_condition(self, db_session: Session): |
| """Test filtering agents with OR condition.""" |
| agent1 = AgentRegistry( |
| name="OrFilter1", |
| category="sales", |
| module_path="test.module", |
| class_name="OrAgent", |
| status=AgentStatus.STUDENT.value, |
| confidence_score=0.3 |
| ) |
| agent2 = AgentRegistry( |
| name="OrFilter2", |
| category="support", |
| module_path="test.module", |
| class_name="OrAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| agent3 = AgentRegistry( |
| name="OrFilter3", |
| category="finance", |
| module_path="test.module", |
| class_name="OrAgent", |
| status=AgentStatus.AUTONOMOUS.value, |
| confidence_score=0.95 |
| ) |
| db_session.add(agent1) |
| db_session.add(agent2) |
| db_session.add(agent3) |
| db_session.commit() |
|
|
| results = db_session.query(AgentRegistry).filter( |
| or_( |
| AgentRegistry.category == "sales", |
| AgentRegistry.category == "support" |
| ) |
| ).all() |
|
|
| assert len(results) == 2 |
|
|
|
|
| class TestAgentSorting: |
| """Integration tests for agent sorting.""" |
|
|
| def test_sort_by_name(self, db_session: Session): |
| """Test sorting agents by name.""" |
| names = ["Zebra", "Alpha", "Charlie"] |
| for name in names: |
| agent = AgentRegistry( |
| name=name, |
| category="test", |
| module_path="test.module", |
| class_name="SortAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| agents = db_session.query(AgentRegistry).order_by( |
| AgentRegistry.name |
| ).all() |
|
|
| assert agents[0].name == "Alpha" |
| assert agents[1].name == "Charlie" |
| assert agents[2].name == "Zebra" |
|
|
| def test_sort_by_confidence_desc(self, db_session: Session): |
| """Test sorting agents by confidence descending.""" |
| for score in [0.3, 0.9, 0.6]: |
| agent = AgentRegistry( |
| name=f"SortScore{int(score*10)}", |
| category="test", |
| module_path="test.module", |
| class_name="SortScoreAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=score |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| agents = db_session.query(AgentRegistry).order_by( |
| desc(AgentRegistry.confidence_score) |
| ).all() |
|
|
| assert agents[0].confidence_score == 0.9 |
| assert agents[1].confidence_score == 0.6 |
| assert agents[2].confidence_score == 0.3 |
|
|
| def test_sort_by_created_at(self, db_session: Session): |
| """Test sorting agents by creation time.""" |
| agent1 = AgentRegistry( |
| name="FirstAgent", |
| category="test", |
| module_path="test.module", |
| class_name="TimeAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6, |
| created_at=datetime.utcnow() - timedelta(hours=2) |
| ) |
| agent2 = AgentRegistry( |
| name="SecondAgent", |
| category="test", |
| module_path="test.module", |
| class_name="TimeAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6, |
| created_at=datetime.utcnow() - timedelta(hours=1) |
| ) |
| db_session.add(agent1) |
| db_session.add(agent2) |
| db_session.commit() |
|
|
| agents = db_session.query(AgentRegistry).order_by( |
| AgentRegistry.created_at |
| ).all() |
|
|
| assert agents[0].name == "FirstAgent" |
| assert agents[1].name == "SecondAgent" |
|
|
|
|
| class TestAgentPagination: |
| """Integration tests for agent pagination.""" |
|
|
| def test_paginate_agents(self, db_session: Session): |
| """Test paginating agent list.""" |
| |
| for i in range(15): |
| agent = AgentRegistry( |
| name=f"PageAgent{i}", |
| category="test", |
| module_path="test.module", |
| class_name="PageAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| |
| page1 = db_session.query(AgentRegistry).filter( |
| AgentRegistry.name.like("PageAgent%") |
| ).limit(5).all() |
|
|
| assert len(page1) == 5 |
|
|
| |
| page2 = db_session.query(AgentRegistry).filter( |
| AgentRegistry.name.like("PageAgent%") |
| ).offset(5).limit(5).all() |
|
|
| assert len(page2) == 5 |
| |
| assert page1[0].name != page2[0].name |
|
|
| def test_paginate_with_ordering(self, db_session: Session): |
| """Test paginating with ordering.""" |
| |
| names = ["AgentZ", "AgentA", "AgentM", "AgentB", "AgentY"] |
| for name in names: |
| agent = AgentRegistry( |
| name=name, |
| category="test", |
| module_path="test.module", |
| class_name="OrderedAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| |
| page1 = db_session.query(AgentRegistry).filter( |
| AgentRegistry.name.like("Agent%") |
| ).order_by(AgentRegistry.name).limit(2).all() |
|
|
| assert len(page1) == 2 |
| assert page1[0].name == "AgentA" |
| assert page1[1].name == "AgentB" |
|
|
| |
| page2 = db_session.query(AgentRegistry).filter( |
| AgentRegistry.name.like("Agent%") |
| ).order_by(AgentRegistry.name).offset(2).limit(2).all() |
|
|
| assert len(page2) == 2 |
| assert page2[0].name == "AgentM" |
| assert page2[1].name == "AgentY" |
|
|
|
|
| class TestAgentRelationshipQueries: |
| """Integration tests for agent relationship queries.""" |
|
|
| def test_agent_with_executions(self, db_session: Session): |
| """Test querying agent executions relationship.""" |
| agent = AgentRegistry( |
| name="RelAgent", |
| category="test", |
| module_path="test.module", |
| class_name="RelAgent", |
| status=AgentStatus.AUTONOMOUS.value, |
| confidence_score=0.95 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| |
| for i in range(3): |
| execution = AgentExecution( |
| agent_id=agent.id, |
| workspace_id="default", |
| status="completed", |
| input_data={"execution": i} |
| ) |
| db_session.add(execution) |
| db_session.commit() |
|
|
| |
| executions = db_session.query(AgentExecution).filter_by( |
| agent_id=agent.id |
| ).all() |
|
|
| assert len(executions) == 3 |
| for exec in executions: |
| assert exec.agent_id == agent.id |
|
|
| def test_agent_with_feedback(self, db_session: Session): |
| """Test querying agent feedback relationship.""" |
| agent = AgentRegistry( |
| name="FeedbackAgent", |
| category="test", |
| module_path="test.module", |
| class_name="FeedbackAgent", |
| status=AgentStatus.SUPERVISED.value, |
| confidence_score=0.8 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| |
| execution = AgentExecution( |
| agent_id=agent.id, |
| workspace_id="default", |
| status="completed", |
| input_data={} |
| ) |
| db_session.add(execution) |
| db_session.commit() |
|
|
| |
| feedback = AgentFeedback( |
| agent_id=agent.id, |
| execution_id=execution.id, |
| rating=5, |
| feedback="Excellent work!" |
| ) |
| db_session.add(feedback) |
| db_session.commit() |
|
|
| |
| feedbacks = db_session.query(AgentFeedback).filter_by( |
| agent_id=agent.id |
| ).all() |
|
|
| assert len(feedbacks) == 1 |
| assert feedbacks[0].rating == 5 |
|
|
| def test_join_agent_with_executions(self, db_session: Session): |
| """Test joining agents with executions.""" |
| agent1 = AgentRegistry( |
| name="JoinAgent1", |
| category="test", |
| module_path="test.module", |
| class_name="JoinAgent", |
| status=AgentStatus.AUTONOMOUS.value, |
| confidence_score=0.95 |
| ) |
| agent2 = AgentRegistry( |
| name="JoinAgent2", |
| category="test", |
| module_path="test.module", |
| class_name="JoinAgent", |
| status=AgentStatus.INTERN.value, |
| confidence_score=0.6 |
| ) |
| db_session.add(agent1) |
| db_session.add(agent2) |
| db_session.commit() |
|
|
| |
| execution = AgentExecution( |
| agent_id=agent1.id, |
| workspace_id="default", |
| status="completed", |
| input_data={} |
| ) |
| db_session.add(execution) |
| db_session.commit() |
|
|
| |
| results = db_session.query(AgentRegistry).join( |
| AgentExecution, |
| AgentRegistry.id == AgentExecution.agent_id |
| ).all() |
|
|
| |
| assert len(results) == 1 |
| assert results[0].name == "JoinAgent1" |
|
|
| def test_count_executions_per_agent(self, db_session: Session): |
| """Test counting executions per agent.""" |
| agent1 = AgentRegistry( |
| name="CountAgent1", |
| category="test", |
| module_path="test.module", |
| class_name="CountAgent", |
| status=AgentStatus.AUTONOMOUS.value, |
| confidence_score=0.95 |
| ) |
| agent2 = AgentRegistry( |
| name="CountAgent2", |
| category="test", |
| module_path="test.module", |
| class_name="CountAgent", |
| status=AgentStatus.AUTONOMOUS.value, |
| confidence_score=0.95 |
| ) |
| db_session.add(agent1) |
| db_session.add(agent2) |
| db_session.commit() |
|
|
| |
| for i in range(5): |
| execution = AgentExecution( |
| agent_id=agent1.id, |
| workspace_id="default", |
| status="completed", |
| input_data={} |
| ) |
| db_session.add(execution) |
|
|
| for i in range(2): |
| execution = AgentExecution( |
| agent_id=agent2.id, |
| workspace_id="default", |
| status="completed", |
| input_data={} |
| ) |
| db_session.add(execution) |
| db_session.commit() |
|
|
| |
| agent1_count = db_session.query(AgentExecution).filter_by( |
| agent_id=agent1.id |
| ).count() |
| agent2_count = db_session.query(AgentExecution).filter_by( |
| agent_id=agent2.id |
| ).count() |
|
|
| assert agent1_count == 5 |
| assert agent2_count == 2 |
|
|
| def test_average_feedback_per_agent(self, db_session: Session): |
| """Test calculating average feedback rating per agent.""" |
| agent = AgentRegistry( |
| name="AvgAgent", |
| category="test", |
| module_path="test.module", |
| class_name="AvgAgent", |
| status=AgentStatus.SUPERVISED.value, |
| confidence_score=0.8 |
| ) |
| db_session.add(agent) |
| db_session.commit() |
|
|
| |
| execution = AgentExecution( |
| agent_id=agent.id, |
| workspace_id="default", |
| status="completed", |
| input_data={} |
| ) |
| db_session.add(execution) |
| db_session.commit() |
|
|
| |
| ratings = [5, 4, 5, 3, 4] |
| for rating in ratings: |
| feedback = AgentFeedback( |
| agent_id=agent.id, |
| execution_id=execution.id, |
| rating=rating, |
| feedback=f"Rating {rating}" |
| ) |
| db_session.add(feedback) |
| db_session.commit() |
|
|
| |
| from sqlalchemy import func |
| avg_rating = db_session.query(func.avg(AgentFeedback.rating)).filter_by( |
| agent_id=agent.id |
| ).scalar() |
|
|
| expected_avg = sum(ratings) / len(ratings) |
| assert avg_rating == expected_avg |
|
|