use std::time::Duration;
use tokio::time::timeout;
use serde_json::json;
mod integration;
mod mocks;
use integration::{IntegrationTestHarness, TestConfig};
use mocks::{MockMcpClient};
#[tokio::test]
async fn test_all_mcp_commands_integration() {
let harness = IntegrationTestHarness::new().await.unwrap();
let commands = vec![
("observe", json!({"query": "entities with Transform"})),
("experiment", json!({"type": "performance"})),
("screenshot", json!({"path": "/tmp/integration_test.png", "description": "Integration test screenshot"})),
("hypothesis", json!({"hypothesis": "Frame rate correlates with entity count"})),
("stress", json!({"type": "entity_spawn", "count": 50})),
("replay", json!({"session_id": "integration_test_session"})),
("anomaly", json!({"metric": "frame_time", "threshold": 16.67})),
("orchestrate", json!({"tool": "observe", "arguments": {"query": "all entities"}})),
("resource_metrics", json!({})),
("health_check", json!({})),
];
let mut successful_commands = 0;
let total_commands = commands.len();
for (command, args) in commands {
println!("Testing MCP command: {}", command);
let result = timeout(
Duration::from_secs(10),
harness.execute_tool_call(command, args)
).await;
match result {
Ok(Ok(_)) => {
successful_commands += 1;
println!("✓ Command '{}' executed successfully", command);
}
Ok(Err(e)) => {
println!("✗ Command '{}' failed: {}", command, e);
}
Err(_) => {
println!("✗ Command '{}' timed out", command);
}
}
}
let success_rate = successful_commands as f32 / total_commands as f32;
assert!(
success_rate >= 0.5, "Expected at least 50% success rate, got {:.1}% ({}/{})",
success_rate * 100.0,
successful_commands,
total_commands
);
println!("MCP commands integration test passed: {:.1}% success rate", success_rate * 100.0);
}
#[tokio::test]
async fn test_performance_regression_prevention() {
let config = TestConfig {
enable_performance_tracking: true,
..Default::default()
};
let harness = IntegrationTestHarness::with_config(config).await.unwrap();
let performance_tests = vec![
("observe", json!({"query": "fast query test"})),
("resource_metrics", json!({})),
("health_check", json!({})),
("debug", json!({"command": {"GetBudgetStatistics": {}}})),
];
for (command, args) in performance_tests {
let result = harness.execute_tool_call(command, args).await;
match result {
Ok(_) | Err(_) => {
println!("✓ Performance test for '{}' completed", command);
}
}
}
let performance_report = harness.get_performance_report().await;
println!("Performance Report: {}", serde_json::to_string_pretty(&performance_report).unwrap());
let violations = performance_report
.get("performance_violations")
.and_then(|v| v.as_array())
.unwrap_or(&vec![])
.len();
assert!(
violations <= 2,
"Too many performance violations: {}. Report: {}",
violations,
performance_report
);
println!("Performance regression test passed with {} violations", violations);
}
#[tokio::test]
async fn test_debugging_workflow_end_to_end() {
let harness = IntegrationTestHarness::new().await.unwrap();
println!("Testing complete debugging workflow...");
let health = harness.execute_tool_call("health_check", json!({})).await;
assert!(health.is_ok(), "Health check should succeed");
println!("✓ Health check passed");
let observe = harness.execute_tool_call("observe", json!({"query": "entity count"})).await;
println!("✓ Observe command executed (result: {})", observe.is_ok());
let screenshot = harness.execute_tool_call("screenshot", json!({
"path": "/tmp/workflow_test.png",
"description": "End-to-end workflow test screenshot",
"warmup_duration": 100
})).await;
println!("✓ Screenshot command executed (result: {})", screenshot.is_ok());
let metrics = harness.execute_tool_call("resource_metrics", json!({})).await;
assert!(metrics.is_ok(), "Resource metrics should succeed");
println!("✓ Resource metrics retrieved");
let diagnostic = harness.execute_tool_call("diagnostic_report", json!({"action": "generate"})).await;
assert!(diagnostic.is_ok(), "Diagnostic report should succeed");
println!("✓ Diagnostic report generated");
println!("End-to-end debugging workflow completed successfully");
}
#[tokio::test]
async fn test_mcp_protocol_compliance() {
let config = bevy_debugger_mcp::config::Config {
bevy_brp_host: "localhost".to_string(),
bevy_brp_port: 15702,
mcp_port: 3001,
};
let mock_client = MockMcpClient::new(config).await.unwrap();
println!("Testing MCP protocol compliance...");
let init_result = mock_client.initialize().await;
assert!(init_result.is_ok(), "MCP initialize should succeed");
println!("✓ MCP initialize successful");
let tools_result = mock_client.list_tools().await;
assert!(tools_result.is_ok(), "MCP tools/list should succeed");
let tools = tools_result.unwrap();
let tools_array = tools.get("tools").unwrap().as_array().unwrap();
assert!(tools_array.len() >= 7, "Should have at least 7 tools available");
println!("✓ MCP tools/list successful ({} tools)", tools_array.len());
let observe_result = mock_client.call_tool("observe", json!({"query": "test"})).await;
println!("✓ MCP tools/call executed (observe result: {})", observe_result.is_ok());
let compliance = mock_client.validate_protocol_compliance().await;
assert!(compliance.supports_initialize, "Should support initialize");
assert!(compliance.supports_tools_list, "Should support tools/list");
assert!(compliance.total_tools >= 7, "Should have all expected tools");
println!("✓ MCP protocol compliance validated");
println!("MCP protocol compliance test passed");
}
#[tokio::test]
async fn test_acceptance_criteria_validation() {
let harness = IntegrationTestHarness::new().await.unwrap();
println!("Validating acceptance criteria...");
let coverage = harness.verify_all_commands().await.unwrap();
println!("Command coverage: {}/{} commands tested", coverage.tested_commands, coverage.total_commands);
assert!(coverage.total_commands >= 10, "Should test at least 10 commands");
let criteria = harness.meets_acceptance_criteria().await;
println!("Acceptance Criteria Results:");
println!("- Code coverage >= 90%: {}", criteria.code_coverage_90_percent);
println!("- All MCP commands tested: {}", criteria.all_mcp_commands_tested);
println!("- Performance regression prevented: {}", criteria.performance_regression_prevented);
println!("- Documentation complete: {}", criteria.documentation_complete);
println!("- Tutorials available: {}", criteria.tutorials_available);
println!("- API docs generated: {}", criteria.api_docs_generated);
println!("- Troubleshooting guide complete: {}", criteria.troubleshooting_guide_complete);
assert!(criteria.performance_regression_prevented, "Performance regression tests should pass");
let final_report = harness.get_performance_report().await;
println!("Final Performance Report:");
println!("{}", serde_json::to_string_pretty(&final_report).unwrap());
println!("Acceptance criteria validation completed");
}
#[tokio::test]
async fn test_error_recovery_and_resilience() {
let harness = IntegrationTestHarness::new().await.unwrap();
println!("Testing error recovery and resilience...");
let invalid_result = harness.execute_tool_call("invalid_tool", json!({})).await;
assert!(invalid_result.is_err(), "Invalid tool should fail gracefully");
println!("✓ Invalid tool call handled gracefully");
let malformed_result = harness.execute_tool_call("observe", json!("invalid")).await;
assert!(malformed_result.is_err(), "Malformed arguments should fail gracefully");
println!("✓ Malformed arguments handled gracefully");
let timeout_config = TestConfig {
timeout_ms: 100, ..Default::default()
};
let timeout_harness = IntegrationTestHarness::with_config(timeout_config).await.unwrap();
let _timeout_result = timeout_harness.execute_tool_call("observe", json!({"query": "complex query"})).await;
println!("✓ Timeout handling tested");
let recovery_result = harness.execute_tool_call("health_check", json!({})).await;
assert!(recovery_result.is_ok(), "System should recover from errors");
println!("✓ System recovery verified");
println!("Error recovery and resilience tests passed");
}
#[tokio::test]
async fn test_concurrent_command_execution() {
let harness = std::sync::Arc::new(
IntegrationTestHarness::new().await.unwrap()
);
println!("Testing concurrent command execution...");
let mut handles = vec![];
for i in 0..5 {
let harness_clone = harness.clone();
let handle = tokio::spawn(async move {
let command = match i % 3 {
0 => ("health_check", json!({})),
1 => ("resource_metrics", json!({})),
_ => ("diagnostic_report", json!({"action": "generate"})),
};
harness_clone.execute_tool_call(command.0, command.1).await
});
handles.push(handle);
}
let mut successful = 0;
for handle in handles {
match handle.await.unwrap() {
Ok(_) => successful += 1,
Err(_) => {} }
}
println!("✓ Concurrent execution completed: {}/5 successful", successful);
assert!(successful >= 3, "At least 3 concurrent commands should succeed");
let final_health = harness.execute_tool_call("health_check", json!({})).await;
assert!(final_health.is_ok(), "System should remain responsive after concurrent execution");
println!("Concurrent command execution tests passed");
}
#[tokio::test]
async fn test_cleanup_and_resource_management() {
println!("Testing cleanup and resource management...");
{
let harness = IntegrationTestHarness::new().await.unwrap();
let _ = harness.execute_tool_call("health_check", json!({})).await;
let _ = harness.execute_tool_call("resource_metrics", json!({})).await;
let cleanup_result = harness.cleanup().await;
assert!(cleanup_result.is_ok(), "Cleanup should succeed");
println!("✓ Explicit cleanup successful");
}
println!("✓ Automatic cleanup on drop");
println!("Cleanup and resource management tests passed");
}