multi-agent-system / tests /test_consistency_validator.py
firepenguindisopanda
Refactor test documentation and improve consistency in comments
e382248
Raw
History Blame Contribute Delete
5.78 kB
"""
Tests for ConsistencyValidator - cross-agent contradiction detection.
"""
import pytest
from app.core.consistency_validator import ConsistencyValidator
from app.core.kg_schemas import (
Component,
Requirement,
)
from app.core.kg_service import KGService, reset_kg_service
@pytest.fixture(autouse=True)
def reset_service():
"""Reset KGService singleton between tests."""
reset_kg_service()
yield
@pytest.fixture
def empty_graph_dict() -> dict:
return {"nodes": [], "edges": [], "kg_schema_version": 2}
@pytest.fixture
def validator() -> ConsistencyValidator:
return ConsistencyValidator()
def test_no_contradictions_empty_graph(validator):
"""Empty knowledge graph returns no contradictions."""
state = {"knowledge_graph": {}}
assert validator.validate_all(state) == []
def test_no_contradictions_single_entity(validator, empty_graph_dict):
"""Single entity produces no contradictions."""
svc = KGService()
state: dict = {"knowledge_graph": {}}
g = empty_graph_dict
g = svc.add_entity(
g, Requirement(id="req-1", role="product_owner", content="Test requirement")
)
state["knowledge_graph"] = svc.set_role_graph(state, "product_owner", g)
result = validator.validate_all(state)
assert result == []
def test_detects_property_conflict(validator, empty_graph_dict):
"""SA and DA write Component with same name but different technology."""
svc = KGService()
state: dict = {"knowledge_graph": {}}
# SA writes Component(name="AuthService", technology="FastAPI")
g_sa = empty_graph_dict
g_sa = svc.add_entity(
g_sa,
Component(
id="comp-1",
role="solution_architect",
name="AuthService",
technology="FastAPI",
content="Auth service component",
),
)
state["knowledge_graph"] = svc.set_role_graph(state, "solution_architect", g_sa)
# DA writes Component(name="AuthService", technology="Express.js")
g_da = empty_graph_dict
g_da = svc.add_entity(
g_da,
Component(
id="comp-2",
role="data_architect",
name="AuthService",
technology="Express.js",
content="Auth service data layer",
),
)
state["knowledge_graph"] = svc.set_role_graph(state, "data_architect", g_da)
result = validator.validate_all(state)
assert len(result) >= 1
assert any(c["type"] == "property_conflict" for c in result)
found = [c for c in result if c["type"] == "property_conflict"]
conflict_detail = found[0].get("detail", "")
assert "AuthService" in conflict_detail
def test_detects_missing_dependency(validator, empty_graph_dict):
"""SA writes Component referencing PaymentService with no entity for it."""
svc = KGService()
state: dict = {"knowledge_graph": {}}
g_sa = empty_graph_dict
g_sa = svc.add_entity(
g_sa,
Component(
id="comp-1",
role="solution_architect",
name="OrderService",
technology="FastAPI",
content="Order service depends on PaymentService for processing",
),
)
state["knowledge_graph"] = svc.set_role_graph(state, "solution_architect", g_sa)
result = validator.validate_all(state)
assert len(result) >= 1
assert any(c["type"] == "missing_dependency" for c in result)
found = [c for c in result if c["type"] == "missing_dependency"]
assert "PaymentService" in found[0].get("detail", "")
def test_no_false_positive_for_same_role(validator, empty_graph_dict):
"""Two Requirements from same role are NOT contradictions."""
svc = KGService()
state: dict = {"knowledge_graph": {}}
g_po = empty_graph_dict
g_po = svc.add_entity(
g_po,
Requirement(id="req-1", role="product_owner", content="Requirement one"),
)
g_po = svc.add_entity(
g_po,
Requirement(id="req-2", role="product_owner", content="Requirement two"),
)
state["knowledge_graph"] = svc.set_role_graph(state, "product_owner", g_po)
result = validator.validate_all(state)
# Same-role entities should not produce contradictions
for c in result:
roles = c.get("roles", [])
if len(roles) == 1 and "product_owner" in roles:
pytest.fail(f"Same-role contradiction detected: {c}")
# This is fine - at minimum no property_conflicts should appear
property_conflicts = [c for c in result if c["type"] == "property_conflict"]
assert property_conflicts == []
def test_format_warnings_section(validator):
"""Verify formatted output contains expected content."""
contradictions = [
{
"type": "property_conflict",
"entity_ids": ["comp-1", "comp-2"],
"roles": ["solution_architect", "data_architect"],
"detail": "Conflicting properties for Component:AuthService",
"severity": "high",
"conflicts": [
{
"property": "Technology stack",
"values": {
"solution_architect": "FastAPI",
"data_architect": "Express.js",
},
}
],
}
]
output = validator.format_warnings_section(contradictions)
assert "Consistency Warnings" in output
assert "AuthService" in output
assert "FastAPI" in output
assert "Express.js" in output
assert "solution_architect" in output
assert "data_architect" in output
assert "high" in output
def test_format_warnings_section_empty(validator):
"""Empty contradictions produce empty string."""
assert validator.format_warnings_section([]) == ""