Spaces:
Sleeping
Sleeping
| """ | |
| Agent Tests | |
| ============ | |
| Unit tests for the multi-agent system components. | |
| """ | |
| import pytest | |
| import sys | |
| import os | |
| # Add src to path for imports | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) | |
| from agents.research_agent import ResearchAgent | |
| from agents.summarizer_agent import SummarizerAgent | |
| from orchestrator import Orchestrator | |
| from ledger.merkle import compute_merkle_root, hash_leaf | |
| class TestResearchAgent: | |
| """Tests for ResearchAgent.""" | |
| async def test_research_agent_returns_results(self): | |
| """ | |
| Test that research agent returns results with expected structure. | |
| """ | |
| agent = ResearchAgent() | |
| result = await agent.run({"query": "diabetes AI"}) | |
| # Assert 'results' key exists and is a list | |
| assert "results" in result, "Result should contain 'results' key" | |
| assert isinstance(result["results"], list), "Results should be a list" | |
| assert len(result["results"]) > 0, "Results should not be empty" | |
| # Assert each result has expected structure | |
| for item in result["results"]: | |
| assert "title" in item, "Each result should have 'title'" | |
| assert "url" in item, "Each result should have 'url'" | |
| assert "snippet" in item, "Each result should have 'snippet'" | |
| async def test_research_agent_includes_query_in_response(self): | |
| """Test that response includes the original query.""" | |
| agent = ResearchAgent() | |
| query = "machine learning healthcare" | |
| result = await agent.run({"query": query}) | |
| assert result["query"] == query | |
| assert result["agent"] == "research" | |
| class TestSummarizerAgent: | |
| """Tests for SummarizerAgent.""" | |
| async def test_summarizer_agent_composes_summary(self): | |
| """ | |
| Test that summarizer agent creates a summary from documents. | |
| """ | |
| agent = SummarizerAgent() | |
| sample_docs = [ | |
| {"title": "Doc 1", "snippet": "This is the first document about AI."}, | |
| {"title": "Doc 2", "snippet": "This is the second document about healthcare."}, | |
| {"title": "Doc 3", "snippet": "This is the third document about research."} | |
| ] | |
| result = await agent.run({"documents": sample_docs}) | |
| # Assert 'summary' key exists and is a non-empty string | |
| assert "summary" in result, "Result should contain 'summary' key" | |
| assert isinstance(result["summary"], str), "Summary should be a string" | |
| assert len(result["summary"]) > 10, "Summary should be longer than 10 characters" | |
| async def test_summarizer_handles_empty_documents(self): | |
| """Test that summarizer handles empty document list gracefully.""" | |
| agent = SummarizerAgent() | |
| result = await agent.run({"documents": []}) | |
| assert "summary" in result | |
| assert result["document_count"] == 0 | |
| class TestOrchestrator: | |
| """Tests for Orchestrator.""" | |
| async def test_orchestrator_runs_pipeline(self): | |
| """ | |
| Test that orchestrator runs the full pipeline and returns expected structure. | |
| """ | |
| orchestrator = Orchestrator() | |
| task = {"query": "AI in medical diagnosis"} | |
| result = await orchestrator.run_task(task) | |
| # Assert steps list exists and has at least 2 steps | |
| assert "steps" in result, "Result should contain 'steps' key" | |
| assert isinstance(result["steps"], list), "Steps should be a list" | |
| assert len(result["steps"]) >= 2, "Pipeline should have at least 2 steps" | |
| # Assert each step has required fields | |
| for step in result["steps"]: | |
| assert "agent" in step, "Each step should have 'agent' field" | |
| assert "output" in step, "Each step should have 'output' field" | |
| assert "step" in step, "Each step should have 'step' number" | |
| assert "timestamp" in step, "Each step should have 'timestamp'" | |
| assert "hash" in step, "Each step should have 'hash'" | |
| async def test_orchestrator_produces_final_output(self): | |
| """Test that orchestrator produces a final output from summarizer.""" | |
| orchestrator = Orchestrator() | |
| result = await orchestrator.run_task({"query": "test query"}) | |
| assert "final_output" in result | |
| assert "summary" in result["final_output"] | |
| class TestMerkle: | |
| """Tests for Merkle tree functions.""" | |
| def test_merkle_root(self): | |
| """ | |
| Test that merkle root is computed correctly and has valid format. | |
| """ | |
| leaves = ["leaf1", "leaf2"] | |
| root = compute_merkle_root(leaves) | |
| # Assert root is 64 hex characters (SHA256) | |
| assert len(root) == 64, "Merkle root should be 64 hex characters" | |
| assert all(c in '0123456789abcdef' for c in root), "Root should be valid hex" | |
| def test_hash_leaf(self): | |
| """Test that hash_leaf produces valid SHA256 hash.""" | |
| result = hash_leaf("test data") | |
| assert len(result) == 64, "Hash should be 64 hex characters" | |
| assert all(c in '0123456789abcdef' for c in result), "Hash should be valid hex" | |
| def test_merkle_root_single_leaf(self): | |
| """Test merkle root with single leaf.""" | |
| root = compute_merkle_root(["single"]) | |
| assert len(root) == 64 | |
| def test_merkle_root_deterministic(self): | |
| """Test that merkle root is deterministic.""" | |
| leaves = ["a", "b", "c"] | |
| root1 = compute_merkle_root(leaves) | |
| root2 = compute_merkle_root(leaves) | |
| assert root1 == root2, "Merkle root should be deterministic" | |
| def test_merkle_root_empty_raises(self): | |
| """Test that empty leaves raises ValueError.""" | |
| with pytest.raises(ValueError): | |
| compute_merkle_root([]) | |
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v"]) | |