minions-ai-agents/tests/test_pipeline.py

216 lines
6.8 KiB
Python

"""
Tests for Ticket Pipeline.
Tests the complete orchestration flow.
"""
import pytest
from unittest.mock import Mock, patch, AsyncMock
from src.agents.pipeline import (
TicketPipeline,
PipelineResult,
get_ticket_pipeline
)
from src.agents.triage_agent import TriageResult, ExtractedEntities, Priority, Category
from src.agents.specialist_agent import SpecialistResponse, EnrichedContext
class TestTicketPipeline:
"""Tests for TicketPipeline class."""
@pytest.fixture
def pipeline(self):
"""Create pipeline with mocked agents."""
patcher1 = patch('src.agents.pipeline.get_triage_agent')
patcher2 = patch('src.agents.pipeline.get_specialist_agent')
mock_triage = patcher1.start()
mock_specialist = patcher2.start()
mock_triage.return_value = Mock()
mock_specialist.return_value = Mock()
pipeline = TicketPipeline()
yield pipeline
patcher1.stop()
patcher2.stop()
def test_generate_ticket_id(self, pipeline):
"""Test ticket ID generation."""
ticket_id = pipeline._generate_ticket_id()
assert ticket_id.startswith("TKT-")
assert len(ticket_id) == 21 # TKT-YYYYMMDD-XXXXXXXX
def test_build_email_response(self, pipeline):
"""Test email response formatting."""
tenant = Mock()
tenant.name = "OESTEPAN"
triage = TriageResult(
success=True,
ticket_id="TKT-001",
tenant=tenant,
entities=ExtractedEntities(priority=Priority.HIGH),
sanitized_content="",
recommended_tools=[],
reasoning=""
)
specialist = SpecialistResponse(
success=True,
ticket_id="TKT-001",
diagnosis="Problema de memória",
recommended_actions=["Reiniciar serviço", "Verificar logs"],
response_to_client="O problema foi identificado como falta de memória.",
context_used=EnrichedContext(),
model_reasoning="",
confidence_score=0.9
)
response = pipeline._build_email_response(
ticket_id="TKT-001",
triage=triage,
specialist=specialist,
original_subject="Problema servidor"
)
assert "TKT-001" in response
assert "OESTEPAN" in response
assert "HIGH" in response
assert "Reiniciar serviço" in response
assert "Arthur" in response
def test_build_email_with_escalation(self, pipeline):
"""Test email response with escalation notice."""
tenant = Mock()
tenant.name = "ENSEG"
triage = TriageResult(
success=True,
ticket_id="TKT-002",
tenant=tenant,
entities=ExtractedEntities(priority=Priority.CRITICAL),
sanitized_content="",
recommended_tools=[],
reasoning=""
)
specialist = SpecialistResponse(
success=True,
ticket_id="TKT-002",
diagnosis="Problema complexo",
recommended_actions=[],
response_to_client="Estamos analisando o problema.",
context_used=EnrichedContext(),
model_reasoning="",
confidence_score=0.3,
requires_escalation=True,
escalation_reason="Requer acesso ao datacenter"
)
response = pipeline._build_email_response(
ticket_id="TKT-002",
triage=triage,
specialist=specialist,
original_subject="Emergência"
)
assert "escalado" in response.lower()
assert "datacenter" in response
@pytest.mark.asyncio
async def test_process_email_success(self, pipeline):
"""Test successful email processing."""
# Mock tenant
tenant = Mock()
tenant.id = "tenant-001"
tenant.name = "OESTEPAN"
# Mock triage result
triage_result = TriageResult(
success=True,
ticket_id="TKT-001",
tenant=tenant,
entities=ExtractedEntities(
hostname="srv-app01",
priority=Priority.HIGH,
category=Category.INFRASTRUCTURE
),
sanitized_content="Conteúdo sanitizado",
recommended_tools=["zabbix_get_status"],
reasoning="Ticket urgente"
)
pipeline._triage.process_ticket = AsyncMock(return_value=triage_result)
# Mock specialist result
specialist_result = SpecialistResponse(
success=True,
ticket_id="TKT-001",
diagnosis="Servidor sobrecarregado",
recommended_actions=["Reiniciar"],
response_to_client="Identificamos sobrecarga no servidor.",
context_used=EnrichedContext(),
model_reasoning="Análise completa",
confidence_score=0.85
)
pipeline._specialist.process = AsyncMock(return_value=specialist_result)
# Mock audit log creation to avoid dependency issues
pipeline._create_audit_log = Mock(return_value=Mock())
result = await pipeline.process_email(
sender_email="joao@oestepan.com.br",
subject="Servidor lento",
body="O servidor srv-app01 está muito lento"
)
assert result.success is True
assert result.triage is not None
assert result.specialist is not None
assert result.email_response is not None
@pytest.mark.asyncio
async def test_process_email_triage_failure(self, pipeline):
"""Test email processing with triage failure."""
triage_result = TriageResult(
success=False,
ticket_id="TKT-001",
tenant=None,
entities=ExtractedEntities(),
sanitized_content="",
recommended_tools=[],
reasoning="",
error="Tenant não encontrado"
)
pipeline._triage.process_ticket = AsyncMock(return_value=triage_result)
result = await pipeline.process_email(
sender_email="unknown@test.com",
subject="Teste",
body="Teste"
)
assert result.success is False
assert "Tenant" in result.error
class TestPipelineSingleton:
"""Tests for singleton."""
def test_singleton(self):
"""Test singleton pattern."""
import src.agents.pipeline as module
module._pipeline = None
with patch('src.agents.pipeline.get_triage_agent'), \
patch('src.agents.pipeline.get_specialist_agent'):
p1 = get_ticket_pipeline()
p2 = get_ticket_pipeline()
assert p1 is p2