pub mod attacks;
pub mod report;
pub mod runner;
pub mod scoring;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub struct BenchmarkConfig {
pub gateway: GatewayConfig,
pub format: OutputFormat,
pub timeout_secs: u64,
pub concurrency: usize,
}
#[derive(Debug, Clone)]
pub struct GatewayConfig {
pub base_url: String,
pub evaluate_path: String,
pub auth_header: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutputFormat {
Json,
Markdown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AttackResult {
pub attack_id: String,
pub name: String,
pub class: String,
pub passed: bool,
pub latency_ns: u64,
pub details: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PropertyScore {
pub property_id: String,
pub name: String,
pub score: f64,
pub tests_passed: usize,
pub tests_total: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchmarkResult {
pub framework: String,
pub version: String,
pub timestamp: String,
pub gateway: String,
pub gateway_version: String,
pub overall_score: f64,
pub tier: u8,
pub tier_name: String,
pub properties: Vec<PropertyScore>,
pub attacks: Vec<AttackResult>,
pub summary: BenchmarkSummary,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchmarkSummary {
pub total_tests: usize,
pub passed: usize,
pub failed: usize,
pub skipped: usize,
}
pub async fn run_benchmark(config: &BenchmarkConfig) -> BenchmarkResult {
let attack_results = runner::run_all(&config.gateway, config.timeout_secs).await;
let properties = scoring::calculate_property_scores(&attack_results);
let overall_score = scoring::calculate_overall_score(&properties);
let tier = scoring::score_to_tier(overall_score);
let tier_name = scoring::tier_name(tier);
let passed = attack_results.iter().filter(|r| r.passed).count();
let total = attack_results.len();
BenchmarkResult {
framework: "MCPSEC".to_string(),
version: "1.0.0".to_string(),
timestamp: chrono::Utc::now().to_rfc3339(),
gateway: config.gateway.base_url.clone(),
gateway_version: String::new(),
overall_score,
tier,
tier_name: tier_name.to_string(),
properties,
attacks: attack_results,
summary: BenchmarkSummary {
total_tests: total,
passed,
failed: total - passed,
skipped: 0,
},
}
}