522 lines
19 KiB
Python
522 lines
19 KiB
Python
"""Step definitions for CleverClaude agent management features."""
|
|
|
|
from behave import given, then, when
|
|
from hypothesis import given as hypothesis_given
|
|
from hypothesis import strategies as st
|
|
|
|
from cleverclaude.agents.types import AgentType
|
|
|
|
|
|
@given("I have agent management capabilities")
|
|
def step_agent_management_available(context):
|
|
"""Ensure agent management is available."""
|
|
# This would initialize agent management in the test context
|
|
context.agent_management_available = True
|
|
|
|
|
|
@given("I have created an agent named {agent_name}")
|
|
def step_agent_created(context, agent_name):
|
|
"""Create an agent for testing."""
|
|
# Mock agent creation for testing
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
context.created_agents[agent_name] = {
|
|
"id": f"agent_{len(context.created_agents)}",
|
|
"name": agent_name,
|
|
"type": AgentType.RESEARCHER,
|
|
"status": "active",
|
|
"capabilities": {"research", "analysis"},
|
|
}
|
|
|
|
|
|
@given("I have a {agent_type} agent")
|
|
def step_have_agent_type(context, agent_type):
|
|
"""Ensure we have an agent of specific type."""
|
|
agent_name = f"test_{agent_type}_agent"
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
context.created_agents[agent_name] = {
|
|
"id": f"agent_{len(context.created_agents)}",
|
|
"name": agent_name,
|
|
"type": getattr(AgentType, agent_type.upper()),
|
|
"status": "active",
|
|
"capabilities": {agent_type, "general"},
|
|
}
|
|
|
|
|
|
@given("I have multiple active agents")
|
|
def step_multiple_active_agents(context):
|
|
"""Create multiple active agents."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
agent_types = ["researcher", "coder", "analyst"]
|
|
for i, agent_type in enumerate(agent_types):
|
|
agent_name = f"multi_agent_{i + 1}"
|
|
context.created_agents[agent_name] = {
|
|
"id": f"agent_{len(context.created_agents)}",
|
|
"name": agent_name,
|
|
"type": getattr(AgentType, agent_type.upper()),
|
|
"status": "active",
|
|
"capabilities": {agent_type, "general"},
|
|
"health": {"cpu_usage": 25.5, "memory_usage": 150.2, "task_count": 3},
|
|
}
|
|
|
|
|
|
@given("I have agents with different capabilities")
|
|
def step_agents_with_capabilities(context):
|
|
"""Create agents with different capabilities."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
agents_config = [
|
|
{"name": "research_agent", "capabilities": {"research", "analysis"}},
|
|
{"name": "data_agent", "capabilities": {"data_analysis", "visualization"}},
|
|
{"name": "coding_agent", "capabilities": {"coding", "testing"}},
|
|
]
|
|
|
|
for config in agents_config:
|
|
context.created_agents[config["name"]] = {
|
|
"id": f"agent_{len(context.created_agents)}",
|
|
"name": config["name"],
|
|
"type": AgentType.RESEARCHER,
|
|
"status": "active",
|
|
"capabilities": config["capabilities"],
|
|
}
|
|
|
|
|
|
@given("I have multiple agents of different types")
|
|
def step_multiple_different_types(context):
|
|
"""Create multiple agents of different types."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
agent_configs = [
|
|
{"name": "coord_researcher", "type": "RESEARCHER"},
|
|
{"name": "coord_coder", "type": "CODER"},
|
|
{"name": "coord_analyst", "type": "ANALYST"},
|
|
]
|
|
|
|
for config in agent_configs:
|
|
context.created_agents[config["name"]] = {
|
|
"id": f"agent_{len(context.created_agents)}",
|
|
"name": config["name"],
|
|
"type": getattr(AgentType, config["type"]),
|
|
"status": "active",
|
|
"capabilities": {"general", config["type"].lower()},
|
|
}
|
|
|
|
|
|
@when('I create a {agent_type} agent named "{agent_name}"')
|
|
def step_create_agent(context, agent_type, agent_name):
|
|
"""Create an agent with specified type and name."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
# Simulate agent creation
|
|
agent_id = f"agent_{len(context.created_agents)}"
|
|
context.created_agents[agent_name] = {
|
|
"id": agent_id,
|
|
"name": agent_name,
|
|
"type": getattr(AgentType, agent_type.upper()),
|
|
"status": "active",
|
|
"capabilities": {agent_type.lower(), "general"},
|
|
}
|
|
|
|
context.last_created_agent = agent_name
|
|
context.agent_creation_result = "success"
|
|
|
|
|
|
@when("I create the following agents")
|
|
def step_create_multiple_agents(context):
|
|
"""Create multiple agents from table data."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
context.bulk_creation_results = []
|
|
|
|
for row in context.table:
|
|
agent_type = row["type"]
|
|
agent_name = row["name"]
|
|
capabilities = {cap.strip() for cap in row["capabilities"].split(",")}
|
|
|
|
agent_id = f"agent_{len(context.created_agents)}"
|
|
context.created_agents[agent_name] = {
|
|
"id": agent_id,
|
|
"name": agent_name,
|
|
"type": getattr(AgentType, agent_type.upper()),
|
|
"status": "active",
|
|
"capabilities": capabilities,
|
|
}
|
|
|
|
context.bulk_creation_results.append({"name": agent_name, "status": "success"})
|
|
|
|
|
|
@when("I create a {agent_type} agent with {timeout:d} second timeout")
|
|
def step_create_agent_with_timeout(context, agent_type, timeout):
|
|
"""Create agent with specified timeout."""
|
|
agent_name = f"timeout_{agent_type}_agent"
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
agent_id = f"agent_{len(context.created_agents)}"
|
|
context.created_agents[agent_name] = {
|
|
"id": agent_id,
|
|
"name": agent_name,
|
|
"type": getattr(AgentType, agent_type.upper()),
|
|
"status": "active",
|
|
"capabilities": {agent_type.lower()},
|
|
"timeout": timeout,
|
|
}
|
|
|
|
context.timeout_agent = agent_name
|
|
|
|
|
|
@when("I pause the agent")
|
|
def step_pause_agent(context):
|
|
"""Pause an agent."""
|
|
# Get the last created agent or use a default
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if hasattr(context, "created_agents") and agent_name in context.created_agents:
|
|
context.created_agents[agent_name]["status"] = "paused"
|
|
context.agent_action_result = "paused"
|
|
|
|
|
|
@when("I resume the agent")
|
|
def step_resume_agent(context):
|
|
"""Resume an agent."""
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if hasattr(context, "created_agents") and agent_name in context.created_agents:
|
|
context.created_agents[agent_name]["status"] = "active"
|
|
context.agent_action_result = "resumed"
|
|
|
|
|
|
@when("I destroy the agent")
|
|
def step_destroy_agent(context):
|
|
"""Destroy an agent."""
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if hasattr(context, "created_agents") and agent_name in context.created_agents:
|
|
del context.created_agents[agent_name]
|
|
context.agent_action_result = "destroyed"
|
|
|
|
|
|
@when("I assign a research task to the agent")
|
|
def step_assign_research_task(context):
|
|
"""Assign a research task with multiline content."""
|
|
task_content = context.text
|
|
context.assigned_task = {"type": "research", "content": task_content, "status": "assigned"}
|
|
|
|
# Simulate task acceptance and execution
|
|
context.task_execution_result = {
|
|
"accepted": True,
|
|
"status": "completed",
|
|
"result": "Research task completed successfully with relevant findings",
|
|
}
|
|
|
|
|
|
@when("I check agent health status")
|
|
def step_check_health_status(context):
|
|
"""Check agent health status."""
|
|
if hasattr(context, "created_agents"):
|
|
context.health_check_results = {}
|
|
for name, agent in context.created_agents.items():
|
|
health = agent.get(
|
|
"health", {"cpu_usage": 15.0, "memory_usage": 100.5, "task_count": 2, "status": "healthy"}
|
|
)
|
|
context.health_check_results[name] = health
|
|
|
|
|
|
@when('I query for agents with "{capability}" capability')
|
|
def step_query_agents_by_capability(context, capability):
|
|
"""Query agents by capability."""
|
|
if hasattr(context, "created_agents"):
|
|
context.capability_query_results = []
|
|
for name, agent in context.created_agents.items():
|
|
if capability in agent.get("capabilities", set()):
|
|
context.capability_query_results.append(
|
|
{
|
|
"name": name,
|
|
"id": agent["id"],
|
|
"type": agent["type"],
|
|
"capabilities": list(agent["capabilities"]),
|
|
}
|
|
)
|
|
|
|
|
|
@when("I create a coordination task requiring multiple agent types")
|
|
def step_create_coordination_task(context):
|
|
"""Create a coordination task."""
|
|
context.coordination_task = {
|
|
"type": "coordination",
|
|
"required_types": ["researcher", "coder", "analyst"],
|
|
"task_data": {
|
|
"description": "Complex analysis requiring multiple perspectives",
|
|
"components": ["research", "coding", "analysis"],
|
|
},
|
|
}
|
|
|
|
# Simulate coordination
|
|
context.coordination_result = {"distributed": True, "agents_assigned": 3, "status": "in_progress"}
|
|
|
|
|
|
@when("I create many agents rapidly")
|
|
def step_create_many_agents_rapidly(context):
|
|
"""Stress test agent creation."""
|
|
if not hasattr(context, "created_agents"):
|
|
context.created_agents = {}
|
|
|
|
@hypothesis_given(
|
|
st.lists(
|
|
st.text(min_size=1, max_size=20, alphabet=st.characters(whitelist_categories=("Lu", "Ll", "Nd"))),
|
|
min_size=10,
|
|
max_size=50,
|
|
)
|
|
)
|
|
def test_rapid_agent_creation(agent_names):
|
|
stress_results = []
|
|
|
|
for i, name in enumerate(agent_names):
|
|
try:
|
|
agent_id = f"stress_agent_{i}"
|
|
context.created_agents[f"stress_{name}"] = {
|
|
"id": agent_id,
|
|
"name": f"stress_{name}",
|
|
"type": AgentType.RESEARCHER,
|
|
"status": "active",
|
|
"capabilities": {"stress_test"},
|
|
}
|
|
stress_results.append({"name": f"stress_{name}", "status": "success"})
|
|
except Exception as e:
|
|
stress_results.append({"name": f"stress_{name}", "status": "failed", "error": str(e)})
|
|
|
|
context.stress_test_results = stress_results
|
|
# Check for system stability
|
|
context.system_performance = {
|
|
"stable": True,
|
|
"resource_leaks": False,
|
|
"created_count": len([r for r in stress_results if r["status"] == "success"]),
|
|
}
|
|
|
|
# Run the hypothesis test
|
|
test_rapid_agent_creation()
|
|
|
|
|
|
@then("the agent should be created successfully")
|
|
def step_agent_created_successfully(context):
|
|
"""Verify agent creation success."""
|
|
assert getattr(context, "agent_creation_result", None) == "success"
|
|
assert hasattr(context, "last_created_agent")
|
|
agent_name = context.last_created_agent
|
|
assert hasattr(context, "created_agents")
|
|
assert agent_name in context.created_agents
|
|
|
|
|
|
@then('the agent should be in "{expected_status}" status')
|
|
def step_agent_status_check(context, expected_status):
|
|
"""Verify agent status."""
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if hasattr(context, "created_agents") and agent_name in context.created_agents:
|
|
actual_status = context.created_agents[agent_name]["status"]
|
|
assert actual_status == expected_status, f"Expected {expected_status}, got {actual_status}"
|
|
|
|
|
|
@then("the agent should have {agent_type} capabilities")
|
|
def step_agent_capabilities_check(context, agent_type):
|
|
"""Verify agent has expected capabilities."""
|
|
agent_name = context.last_created_agent
|
|
agent = context.created_agents[agent_name]
|
|
capabilities = agent["capabilities"]
|
|
expected_capability = agent_type.lower()
|
|
assert expected_capability in capabilities, f"{expected_capability} not in {capabilities}"
|
|
|
|
|
|
@then("all agents should be created successfully")
|
|
def step_all_agents_created(context):
|
|
"""Verify all agents in bulk creation succeeded."""
|
|
assert hasattr(context, "bulk_creation_results")
|
|
for result in context.bulk_creation_results:
|
|
assert result["status"] == "success", f"Agent {result['name']} failed to create"
|
|
|
|
|
|
@then("each agent should have the correct type and capabilities")
|
|
def step_verify_agent_types_capabilities(context):
|
|
"""Verify each agent has correct type and capabilities."""
|
|
for row in context.table:
|
|
agent_name = row["name"]
|
|
expected_type = row["type"]
|
|
expected_capabilities = {cap.strip() for cap in row["capabilities"].split(",")}
|
|
|
|
assert agent_name in context.created_agents
|
|
agent = context.created_agents[agent_name]
|
|
|
|
assert agent["type"] == getattr(AgentType, expected_type.upper())
|
|
assert expected_capabilities.issubset(agent["capabilities"])
|
|
|
|
|
|
@then('the agent status should be "{expected_status}"')
|
|
def step_verify_agent_status(context, expected_status):
|
|
"""Verify agent status after action."""
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if (
|
|
(expected_status == "paused" or expected_status == "active")
|
|
and hasattr(context, "created_agents")
|
|
and agent_name in context.created_agents
|
|
):
|
|
actual_status = context.created_agents[agent_name]["status"]
|
|
assert actual_status == expected_status
|
|
|
|
|
|
@then("the agent should no longer exist")
|
|
def step_agent_destroyed(context):
|
|
"""Verify agent destruction."""
|
|
agent_name = getattr(context, "last_created_agent", "test_agent")
|
|
if hasattr(context, "created_agents"):
|
|
assert agent_name not in context.created_agents
|
|
|
|
|
|
@then("the agent should accept the task")
|
|
def step_agent_accepts_task(context):
|
|
"""Verify task acceptance."""
|
|
assert hasattr(context, "task_execution_result")
|
|
assert context.task_execution_result["accepted"] is True
|
|
|
|
|
|
@then("the task should be executed within the timeout period")
|
|
def step_task_executed_in_timeout(context):
|
|
"""Verify task execution within timeout."""
|
|
assert hasattr(context, "task_execution_result")
|
|
assert context.task_execution_result["status"] in ["completed", "in_progress"]
|
|
|
|
|
|
@then("the result should contain relevant research findings")
|
|
def step_result_contains_findings(context):
|
|
"""Verify research results."""
|
|
assert hasattr(context, "task_execution_result")
|
|
result = context.task_execution_result["result"]
|
|
assert "research" in result.lower() or "findings" in result.lower()
|
|
|
|
|
|
@then("each agent should report health metrics")
|
|
def step_agents_report_health(context):
|
|
"""Verify health metrics reporting."""
|
|
assert hasattr(context, "health_check_results")
|
|
for _agent_name, health in context.health_check_results.items():
|
|
assert "cpu_usage" in health
|
|
assert "memory_usage" in health
|
|
assert "task_count" in health
|
|
|
|
|
|
@then("unhealthy agents should be identified")
|
|
def step_unhealthy_agents_identified(context):
|
|
"""Verify unhealthy agent identification."""
|
|
assert hasattr(context, "health_check_results")
|
|
# For testing, we'll assume all agents are healthy unless specifically set
|
|
for _agent_name, health in context.health_check_results.items():
|
|
status = health.get("status", "healthy")
|
|
if status != "healthy":
|
|
# This would trigger alerting in real system
|
|
pass
|
|
|
|
|
|
@then("health metrics should include CPU, memory, and task count")
|
|
def step_health_metrics_complete(context):
|
|
"""Verify complete health metrics."""
|
|
assert hasattr(context, "health_check_results")
|
|
for _agent_name, health in context.health_check_results.items():
|
|
assert "cpu_usage" in health
|
|
assert "memory_usage" in health
|
|
assert "task_count" in health
|
|
assert isinstance(health["cpu_usage"], int | float)
|
|
assert isinstance(health["memory_usage"], int | float)
|
|
assert isinstance(health["task_count"], int)
|
|
|
|
|
|
@then("only agents with that capability should be returned")
|
|
def step_capability_query_filtered(context):
|
|
"""Verify capability query filtering."""
|
|
assert hasattr(context, "capability_query_results")
|
|
capability = context.table.headings[0] if hasattr(context, "table") else "data_analysis"
|
|
|
|
for result in context.capability_query_results:
|
|
capabilities = result["capabilities"]
|
|
# This would be the capability we queried for
|
|
assert any(capability in cap for cap in capabilities)
|
|
|
|
|
|
@then("the results should include agent metadata")
|
|
def step_results_include_metadata(context):
|
|
"""Verify query results include metadata."""
|
|
assert hasattr(context, "capability_query_results")
|
|
for result in context.capability_query_results:
|
|
assert "name" in result
|
|
assert "id" in result
|
|
assert "type" in result
|
|
assert "capabilities" in result
|
|
|
|
|
|
@then("the agents should coordinate automatically")
|
|
def step_agents_coordinate(context):
|
|
"""Verify agent coordination."""
|
|
assert hasattr(context, "coordination_result")
|
|
assert context.coordination_result["distributed"] is True
|
|
|
|
|
|
@then("the task should be distributed appropriately")
|
|
def step_task_distributed(context):
|
|
"""Verify task distribution."""
|
|
assert hasattr(context, "coordination_result")
|
|
assert context.coordination_result["agents_assigned"] > 1
|
|
|
|
|
|
@then("the results should be aggregated correctly")
|
|
def step_results_aggregated(context):
|
|
"""Verify result aggregation."""
|
|
assert hasattr(context, "coordination_result")
|
|
assert context.coordination_result["status"] in ["in_progress", "completed"]
|
|
|
|
|
|
@then("the agent should be created with the specified timeout")
|
|
def step_agent_created_with_timeout(context):
|
|
"""Verify agent creation with timeout."""
|
|
agent_name = context.timeout_agent
|
|
assert agent_name in context.created_agents
|
|
agent = context.created_agents[agent_name]
|
|
assert "timeout" in agent
|
|
|
|
|
|
@then("the agent should respect timeout limits during task execution")
|
|
def step_agent_respects_timeout(context):
|
|
"""Verify timeout respect during execution."""
|
|
# This would be verified during actual task execution
|
|
# For testing, we assume the timeout configuration is respected
|
|
agent_name = context.timeout_agent
|
|
agent = context.created_agents[agent_name]
|
|
timeout = agent.get("timeout", 300)
|
|
assert timeout > 0
|
|
|
|
|
|
@then("all stress test agents should be created successfully")
|
|
def step_stress_test_success(context):
|
|
"""Verify stress test agent creation success."""
|
|
assert hasattr(context, "stress_test_results")
|
|
successful = [r for r in context.stress_test_results if r["status"] == "success"]
|
|
total = len(context.stress_test_results)
|
|
success_rate = len(successful) / total if total > 0 else 0
|
|
assert success_rate > 0.9, f"Success rate too low: {success_rate}"
|
|
|
|
|
|
@then("system performance should remain stable")
|
|
def step_system_stable(context):
|
|
"""Verify system stability during stress test."""
|
|
assert hasattr(context, "system_performance")
|
|
assert context.system_performance["stable"] is True
|
|
|
|
|
|
@then("no resource leaks should occur")
|
|
def step_no_resource_leaks(context):
|
|
"""Verify no resource leaks during stress test."""
|
|
assert hasattr(context, "system_performance")
|
|
assert context.system_performance["resource_leaks"] is False
|