ClaudeFlow ported, needs cleanup

This commit is contained in:
Your Name
2025-08-10 12:00:13 -04:00
parent 08df0d26aa
commit 475b483850
61 changed files with 14025 additions and 3000 deletions
+506
View File
@@ -0,0 +1,506 @@
"""Integration tests for MCP (Model Context Protocol) system."""
import asyncio
from unittest.mock import AsyncMock, patch
import pytest
from cleverclaude.agents.manager import AgentManager
from cleverclaude.config.settings import Settings
from cleverclaude.coordination.swarm import SwarmCoordinator
from cleverclaude.core.app import CleverClaudeApp
from cleverclaude.mcp.client import MCPClient
from cleverclaude.mcp.types import MCPToolExecutionResult
@pytest.mark.integration
@pytest.mark.async_test
class TestMCPIntegration:
"""Integration tests for MCP system with other components."""
async def test_mcp_with_agent_manager(self, test_settings: Settings, async_session, mock_redis):
"""Test MCP integration with AgentManager."""
# Initialize MCP client and agent manager
mcp_client = MCPClient(test_settings)
agent_manager = AgentManager(test_settings.agents, async_session, mock_redis)
await mcp_client.initialize()
await agent_manager.initialize()
# Mock MCP tool for agent creation
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.return_value = MCPToolExecutionResult(
success=True, result={"agent_id": "mcp_agent_123", "type": "researcher", "status": "created"}
)
# Execute MCP tool to create agent
result = await mcp_client.execute_tool(
"agent_spawn",
{"type": "researcher", "name": "MCP Test Agent", "capabilities": ["research", "analysis"]},
)
assert result.success is True
assert result.result["agent_id"] == "mcp_agent_123"
await mcp_client.disconnect()
await agent_manager.shutdown()
async def test_mcp_with_swarm_coordinator(self, test_settings: Settings, async_session, mock_redis):
"""Test MCP integration with SwarmCoordinator."""
mcp_client = MCPClient(test_settings)
agent_manager = AgentManager(test_settings.agents, async_session, mock_redis)
swarm_coordinator = SwarmCoordinator(test_settings.swarm, async_session, agent_manager, mock_redis)
await mcp_client.initialize()
await agent_manager.initialize()
await swarm_coordinator.initialize()
# Test swarm creation via MCP
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.return_value = MCPToolExecutionResult(
success=True, result={"swarm_id": "mcp_swarm_456", "topology": "mesh", "status": "created"}
)
result = await mcp_client.execute_tool(
"swarm_init", {"topology": "mesh", "maxAgents": 10, "strategy": "balanced"}
)
assert result.success is True
assert result.result["swarm_id"] == "mcp_swarm_456"
await swarm_coordinator.shutdown()
await agent_manager.shutdown()
await mcp_client.disconnect()
async def test_mcp_end_to_end_workflow(self, test_settings: Settings, async_session, mock_redis):
"""Test complete end-to-end workflow using MCP tools."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Mock a complete workflow: swarm -> agents -> tasks -> results
workflow_steps = [
("swarm_init", {"topology": "hierarchical"}, {"swarm_id": "workflow_swarm"}),
("agent_spawn", {"type": "researcher"}, {"agent_id": "workflow_agent_1"}),
("agent_spawn", {"type": "coder"}, {"agent_id": "workflow_agent_2"}),
("task_orchestrate", {"task": "Complex analysis task"}, {"task_id": "workflow_task_1"}),
("task_status", {"taskId": "workflow_task_1"}, {"status": "completed"}),
("performance_report", {"format": "detailed"}, {"metrics": {"efficiency": 92.5}}),
]
results = []
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.side_effect = [
MCPToolExecutionResult(success=True, result=expected_result) for _, _, expected_result in workflow_steps
]
for tool_name, params, expected_result in workflow_steps:
result = await mcp_client.execute_tool(tool_name, params)
results.append(result)
assert result.success is True
assert result.result == expected_result
# Verify workflow completion
assert len(results) == 6
assert all(r.success for r in results)
await mcp_client.disconnect()
async def test_mcp_error_recovery(self, test_settings: Settings):
"""Test MCP error recovery and resilience."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test recovery from tool execution errors
with patch.object(mcp_client, "execute_tool") as mock_execute:
# First call fails, second succeeds
mock_execute.side_effect = [
MCPToolExecutionResult(success=False, result=None, error="Temporary network error"),
MCPToolExecutionResult(success=True, result={"swarm_id": "recovered_swarm"}),
]
# First attempt should fail
result1 = await mcp_client.execute_tool("swarm_init", {"topology": "mesh"})
assert result1.success is False
assert "network error" in result1.error.lower()
# Second attempt should succeed (simulating retry)
result2 = await mcp_client.execute_tool("swarm_init", {"topology": "mesh"})
assert result2.success is True
assert result2.result["swarm_id"] == "recovered_swarm"
await mcp_client.disconnect()
async def test_mcp_concurrent_operations(self, test_settings: Settings):
"""Test concurrent MCP operations."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Define concurrent operations
concurrent_ops = [
("swarm_status", {}, {"active_swarms": 2}),
("agent_metrics", {"agentId": "agent_1"}, {"performance": 85.5}),
("memory_usage", {"action": "list"}, {"total_keys": 42}),
("neural_status", {"modelId": "model_1"}, {"status": "trained"}),
("performance_report", {"format": "summary"}, {"uptime": "24h"}),
]
async def execute_operation(tool_name, params, expected_result):
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.return_value = MCPToolExecutionResult(success=True, result=expected_result)
return await mcp_client.execute_tool(tool_name, params)
# Execute operations concurrently
tasks = [execute_operation(tool_name, params, expected) for tool_name, params, expected in concurrent_ops]
results = await asyncio.gather(*tasks)
# Verify all operations completed successfully
assert len(results) == 5
assert all(r.success for r in results)
await mcp_client.disconnect()
async def test_mcp_with_full_application(self, test_settings: Settings, temp_dir):
"""Test MCP integration with full CleverClaude application."""
# Create config directory
config_dir = temp_dir / ".cleverclaude"
config_dir.mkdir(exist_ok=True)
with patch("cleverclaude.core.app.CleverClaudeApp._initialize_mcp") as mock_init_mcp:
mock_mcp_client = AsyncMock()
mock_mcp_client.get_available_tools.return_value = {
"swarm_init": {"description": "Initialize swarm"},
"agent_spawn": {"description": "Spawn agent"},
"task_orchestrate": {"description": "Orchestrate task"},
}
mock_init_mcp.return_value = mock_mcp_client
# Initialize application
app = CleverClaudeApp(config_dir)
with (
patch.object(app, "_initialize_database"),
patch.object(app, "_initialize_redis"),
patch.object(app, "_initialize_agents"),
patch.object(app, "_initialize_swarm"),
):
await app.initialize()
# Verify MCP client was initialized
assert app.mcp_client is not None
mock_init_mcp.assert_called_once()
await app.shutdown()
@pytest.mark.integration
@pytest.mark.async_test
class TestMCPTools:
"""Integration tests for specific MCP tools."""
async def test_neural_tools_integration(self, test_settings: Settings):
"""Test neural network tools integration."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test neural training workflow
training_workflow = [
(
"neural_train",
{"pattern_type": "coordination", "training_data": "sample_coordination_data", "epochs": 10},
),
("neural_status", {"modelId": "coordination_model"}),
("neural_predict", {"modelId": "coordination_model", "input": "test_coordination_scenario"}),
]
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.side_effect = [
MCPToolExecutionResult(success=True, result={"training_id": "train_123", "status": "started"}),
MCPToolExecutionResult(success=True, result={"status": "trained", "accuracy": 0.92}),
MCPToolExecutionResult(success=True, result={"prediction": "optimal_coordination", "confidence": 0.88}),
]
results = []
for tool_name, params in training_workflow:
result = await mcp_client.execute_tool(tool_name, params)
results.append(result)
assert len(results) == 3
assert all(r.success for r in results)
assert results[0].result["status"] == "started"
assert results[1].result["accuracy"] == 0.92
assert results[2].result["confidence"] == 0.88
await mcp_client.disconnect()
async def test_memory_tools_integration(self, test_settings: Settings):
"""Test memory management tools integration."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test memory operations workflow
memory_ops = [
(
"memory_usage",
{"action": "store", "key": "test_key", "value": "test_value", "namespace": "integration_test"},
),
("memory_usage", {"action": "retrieve", "key": "test_key", "namespace": "integration_test"}),
("memory_search", {"pattern": "test_*", "namespace": "integration_test"}),
("memory_usage", {"action": "delete", "key": "test_key", "namespace": "integration_test"}),
]
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.side_effect = [
MCPToolExecutionResult(success=True, result={"action": "store", "status": "success"}),
MCPToolExecutionResult(success=True, result={"value": "test_value", "found": True}),
MCPToolExecutionResult(success=True, result={"matches": ["test_key"], "count": 1}),
MCPToolExecutionResult(success=True, result={"action": "delete", "status": "success"}),
]
results = []
for tool_name, params in memory_ops:
result = await mcp_client.execute_tool(tool_name, params)
results.append(result)
assert len(results) == 4
assert all(r.success for r in results)
assert results[1].result["value"] == "test_value"
assert results[2].result["count"] == 1
await mcp_client.disconnect()
async def test_workflow_tools_integration(self, test_settings: Settings):
"""Test workflow automation tools integration."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test workflow creation and execution
workflow_definition = {
"name": "Integration Test Workflow",
"steps": [
{"action": "create_agents", "count": 3},
{"action": "create_swarm", "topology": "mesh"},
{"action": "assign_tasks", "task_count": 5},
{"action": "monitor_execution"},
{"action": "collect_results"},
],
"triggers": ["on_demand"],
}
workflow_ops = [
("workflow_create", workflow_definition),
("workflow_execute", {"workflowId": "workflow_123"}),
("workflow_status", {"workflowId": "workflow_123"}),
("workflow_results", {"workflowId": "workflow_123"}),
]
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.side_effect = [
MCPToolExecutionResult(success=True, result={"workflow_id": "workflow_123", "status": "created"}),
MCPToolExecutionResult(success=True, result={"execution_id": "exec_456", "status": "running"}),
MCPToolExecutionResult(success=True, result={"status": "completed", "progress": 100}),
MCPToolExecutionResult(success=True, result={"results": {"tasks_completed": 5, "success_rate": 100}}),
]
results = []
for tool_name, params in workflow_ops:
result = await mcp_client.execute_tool(tool_name, params)
results.append(result)
assert len(results) == 4
assert all(r.success for r in results)
assert results[0].result["workflow_id"] == "workflow_123"
assert results[2].result["progress"] == 100
assert results[3].result["results"]["success_rate"] == 100
await mcp_client.disconnect()
@pytest.mark.integration
@pytest.mark.slow
class TestMCPPerformance:
"""Performance and stress tests for MCP system."""
@pytest.mark.async_test
async def test_mcp_high_throughput(self, test_settings: Settings):
"""Test MCP system under high throughput."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Execute many operations rapidly
num_operations = 100
operations = []
for _i in range(num_operations):
operations.append(("swarm_status", {"detailed": False}))
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.return_value = MCPToolExecutionResult(success=True, result={"status": "running", "swarms": 2})
start_time = asyncio.get_event_loop().time()
# Execute operations in batches to avoid overwhelming
batch_size = 20
results = []
for i in range(0, num_operations, batch_size):
batch = operations[i : i + batch_size]
batch_tasks = [mcp_client.execute_tool(tool_name, params) for tool_name, params in batch]
batch_results = await asyncio.gather(*batch_tasks)
results.extend(batch_results)
end_time = asyncio.get_event_loop().time()
execution_time = end_time - start_time
# Verify performance
assert len(results) == num_operations
assert all(r.success for r in results)
assert execution_time < 10.0 # Should complete within 10 seconds
throughput = num_operations / execution_time
assert throughput > 10 # Should handle more than 10 ops/second
await mcp_client.disconnect()
@pytest.mark.async_test
async def test_mcp_connection_resilience(self, test_settings: Settings):
"""Test MCP connection resilience under stress."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Simulate connection failures and recoveries
failure_count = 0
success_count = 0
def mock_execute_with_failures(tool_name, params):
nonlocal failure_count, success_count
# Simulate intermittent failures (20% failure rate)
if (success_count + failure_count) % 5 == 0:
failure_count += 1
return MCPToolExecutionResult(success=False, result=None, error="Connection temporarily unavailable")
else:
success_count += 1
return MCPToolExecutionResult(success=True, result={"status": "success", "operation": tool_name})
with patch.object(mcp_client, "execute_tool", side_effect=mock_execute_with_failures):
# Execute operations with expected failures
num_operations = 50
results = []
for _i in range(num_operations):
result = await mcp_client.execute_tool("health_check", {})
results.append(result)
# Verify resilience
total_results = len(results)
successful_results = len([r for r in results if r.success])
failed_results = len([r for r in results if not r.success])
assert total_results == num_operations
assert successful_results > 0 # Should have some successes
assert failed_results > 0 # Should have some expected failures
assert successful_results >= failed_results # More successes than failures
await mcp_client.disconnect()
@pytest.mark.async_test
async def test_mcp_memory_efficiency(self, test_settings: Settings):
"""Test MCP memory efficiency during extended operations."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Execute long-running sequence of operations
import gc
initial_objects = len(gc.get_objects())
with patch.object(mcp_client, "execute_tool") as mock_execute:
mock_execute.return_value = MCPToolExecutionResult(
success=True,
result={"data": "test" * 100}, # Some data payload
)
# Execute many operations
for i in range(200):
result = await mcp_client.execute_tool("memory_usage", {"action": "list"})
assert result.success
# Force garbage collection periodically
if i % 50 == 0:
gc.collect()
# Final garbage collection
gc.collect()
final_objects = len(gc.get_objects())
# Verify no significant memory growth
object_growth = final_objects - initial_objects
assert object_growth < 1000 # Should not have excessive object growth
await mcp_client.disconnect()
@pytest.mark.integration
class TestMCPToolValidation:
"""Test MCP tool parameter validation and error handling."""
@pytest.mark.async_test
async def test_tool_parameter_validation(self, test_settings: Settings):
"""Test comprehensive tool parameter validation."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test various invalid parameter scenarios
invalid_scenarios = [
("swarm_init", {"topology": "invalid_topology"}, "Invalid topology"),
("agent_spawn", {"type": "invalid_type"}, "Invalid agent type"),
("task_orchestrate", {"priority": "invalid_priority"}, "Invalid priority"),
("memory_usage", {"action": "invalid_action"}, "Invalid action"),
("neural_train", {"epochs": -1}, "Invalid epochs"),
]
with patch.object(mcp_client, "execute_tool") as mock_execute:
for tool_name, invalid_params, expected_error in invalid_scenarios:
mock_execute.return_value = MCPToolExecutionResult(success=False, result=None, error=expected_error)
result = await mcp_client.execute_tool(tool_name, invalid_params)
assert result.success is False
assert expected_error.lower() in result.error.lower()
await mcp_client.disconnect()
@pytest.mark.async_test
async def test_tool_response_validation(self, test_settings: Settings):
"""Test MCP tool response validation."""
mcp_client = MCPClient(test_settings)
await mcp_client.initialize()
# Test various response formats
response_scenarios = [
("swarm_init", {"swarm_id": "test", "topology": "mesh", "status": "created"}),
("agent_spawn", {"agent_id": "test", "type": "researcher", "status": "active"}),
("task_status", {"task_id": "test", "status": "completed", "progress": 100}),
("performance_report", {"metrics": {"cpu": 50, "memory": 200}, "timestamp": "2024-01-01T12:00:00Z"}),
]
with patch.object(mcp_client, "execute_tool") as mock_execute:
for tool_name, expected_response in response_scenarios:
mock_execute.return_value = MCPToolExecutionResult(success=True, result=expected_response)
result = await mcp_client.execute_tool(tool_name, {})
assert result.success is True
assert result.result == expected_response
# Verify required fields are present
if tool_name == "swarm_init":
assert "swarm_id" in result.result
assert "topology" in result.result
elif tool_name == "agent_spawn":
assert "agent_id" in result.result
assert "type" in result.result
await mcp_client.disconnect()