You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
swarms/tests/structs/test_spreadsheet_swarm_v2.py

296 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import os
import json
import asyncio
from typing import List, Dict, Any, Optional, Tuple
from datetime import datetime
from loguru import logger
import aiofiles
from swarms.structs.agent import Agent
from swarms.structs.spreadsheet_swarm import (
SpreadSheetSwarm,
AgentOutput,
SwarmRunMetadata
)
# Configure Loguru logger
logger.remove() # Remove default handler
logger.add(
"spreadsheet_swarm_{time}.log",
rotation="1 MB",
retention="7 days",
level="DEBUG",
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
backtrace=True,
diagnose=True
)
class SpreadSheetSwarmTestSuite:
"""
Enhanced test suite for SpreadSheetSwarm functionality.
Provides comprehensive testing of swarm initialization, CSV operations,
task execution, and data persistence with detailed logging and error tracking.
"""
def __init__(self, test_data_path: str = "./test_data"):
"""
Initialize test suite with configuration.
Args:
test_data_path (str): Directory for test data and outputs
"""
self.test_data_path = test_data_path
self._setup_test_environment()
def _setup_test_environment(self) -> None:
"""Setup required test directories and resources."""
try:
os.makedirs(self.test_data_path, exist_ok=True)
logger.info(f"Test environment initialized at {self.test_data_path}")
except Exception as e:
logger.error(f"Failed to setup test environment: {e}")
raise
async def create_test_csv(self) -> str:
"""
Create a test CSV file with agent configurations.
Returns:
str: Path to created CSV file
"""
try:
csv_content = """agent_name,description,system_prompt,task
test_agent_1,Test Agent 1,System prompt 1,Task 1
test_agent_2,Test Agent 2,System prompt 2,Task 2
test_agent_3,Test Agent 3,System prompt 3,Task 3"""
file_path = os.path.join(self.test_data_path, "test_agents.csv")
async with aiofiles.open(file_path, 'w') as f:
await f.write(csv_content)
logger.debug(f"Created test CSV at {file_path} with content:\n{csv_content}")
return file_path
except Exception as e:
logger.error(f"Failed to create test CSV: {e}")
raise
def create_test_agent(self, name: str, **kwargs) -> Agent:
"""
Create a test agent with specified configuration.
Args:
name (str): Agent name
**kwargs: Additional agent configuration
Returns:
Agent: Configured test agent
"""
try:
config = {
"agent_name": name,
"system_prompt": f"Test prompt for {name}",
"model_name": "gpt-4o-mini",
"max_loops": 1,
"autosave": True,
"verbose": True,
**kwargs
}
agent = Agent(**config)
logger.debug(f"Created test agent: {name}")
return agent
except Exception as e:
logger.error(f"Failed to create agent {name}: {e}")
raise
async def test_swarm_initialization(self) -> Tuple[bool, str]:
"""
Test swarm initialization with various configurations.
Returns:
Tuple[bool, str]: Success status and message
"""
try:
logger.info("Starting swarm initialization test")
# Test basic initialization
agents = [
self.create_test_agent("agent1"),
self.create_test_agent("agent2", max_loops=2)
]
swarm = SpreadSheetSwarm(
name="Test Swarm",
description="Test Description",
agents=agents,
max_loops=2
)
# Verify configuration
assert swarm.name == "Test Swarm"
assert swarm.description == "Test Description"
assert len(swarm.agents) == 2
assert swarm.max_loops == 2
# Test empty initialization
empty_swarm = SpreadSheetSwarm()
assert len(empty_swarm.agents) == 0
logger.info("Swarm initialization test passed")
return True, "Initialization successful"
except Exception as e:
logger.error(f"Swarm initialization test failed: {e}")
return False, str(e)
async def test_csv_operations(self) -> Tuple[bool, str]:
"""
Test CSV loading and saving operations.
Returns:
Tuple[bool, str]: Success status and message
"""
try:
logger.info("Starting CSV operations test")
# Test CSV loading
csv_path = await self.create_test_csv()
swarm = SpreadSheetSwarm(load_path=csv_path)
await swarm._load_from_csv()
assert len(swarm.agents) == 3
assert len(swarm.agent_configs) == 3
# Test CSV saving
output_path = os.path.join(self.test_data_path, "test_output.csv")
swarm.save_file_path = output_path
swarm._track_output("test_agent_1", "Test task", "Test result")
await swarm._save_to_csv()
assert os.path.exists(output_path)
# Cleanup
os.remove(csv_path)
os.remove(output_path)
logger.info("CSV operations test passed")
return True, "CSV operations successful"
except Exception as e:
logger.error(f"CSV operations test failed: {e}")
return False, str(e)
async def test_task_execution(self) -> Tuple[bool, str]:
"""
Test task execution and output tracking.
Returns:
Tuple[bool, str]: Success status and message
"""
try:
logger.info("Starting task execution test")
agents = [
self.create_test_agent("agent1"),
self.create_test_agent("agent2")
]
swarm = SpreadSheetSwarm(agents=agents, max_loops=1)
# Run test tasks
test_tasks = ["Task 1", "Task 2"]
for task in test_tasks:
await swarm._run_tasks(task)
# Verify execution
assert swarm.metadata.tasks_completed == 4 # 2 agents × 2 tasks
assert len(swarm.metadata.outputs) == 4
# Test output tracking
assert all(output.agent_name in ["agent1", "agent2"]
for output in swarm.metadata.outputs)
logger.info("Task execution test passed")
return True, "Task execution successful"
except Exception as e:
logger.error(f"Task execution test failed: {e}")
return False, str(e)
async def run_all_tests(self) -> Dict[str, Any]:
"""
Execute all test cases and generate report.
Returns:
Dict[str, Any]: Comprehensive test results and metrics
"""
start_time = datetime.now()
results = []
test_cases = [
("Swarm Initialization", self.test_swarm_initialization),
("CSV Operations", self.test_csv_operations),
("Task Execution", self.test_task_execution)
]
for test_name, test_func in test_cases:
try:
success, message = await test_func()
results.append({
"test_name": test_name,
"success": success,
"message": message,
"timestamp": datetime.now().isoformat()
})
except Exception as e:
logger.error(f"Unexpected error in {test_name}: {e}")
results.append({
"test_name": test_name,
"success": False,
"message": f"Unexpected error: {e}",
"timestamp": datetime.now().isoformat()
})
# Generate report
duration = (datetime.now() - start_time).total_seconds()
total_tests = len(results)
passed_tests = sum(1 for r in results if r["success"])
report = {
"summary": {
"total_tests": total_tests,
"passed_tests": passed_tests,
"failed_tests": total_tests - passed_tests,
"success_rate": f"{(passed_tests/total_tests)*100:.2f}%",
"duration_seconds": duration
},
"test_results": results,
"timestamp": datetime.now().isoformat()
}
# Save report
report_path = os.path.join(
self.test_data_path,
f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
)
async with aiofiles.open(report_path, 'w') as f:
await f.write(json.dumps(report, indent=2))
logger.info(f"Test suite completed. Report saved to {report_path}")
return report
async def main():
"""Entry point for test execution."""
logger.info("Starting SpreadSheetSwarm Test Suite")
test_suite = SpreadSheetSwarmTestSuite()
report = await test_suite.run_all_tests()
# Print summary
print("\n" + "="*50)
print("SpreadSheetSwarm Test Results")
print("="*50)
print(f"Total Tests: {report['summary']['total_tests']}")
print(f"Passed Tests: {report['summary']['passed_tests']}")
print(f"Failed Tests: {report['summary']['failed_tests']}")
print(f"Success Rate: {report['summary']['success_rate']}")
print(f"Duration: {report['summary']['duration_seconds']:.2f} seconds")
print("="*50)
if __name__ == "__main__":
asyncio.run(main())