amberjs 1.17.0

JavaScript/TypeScript runtime built with Rust and V8
Documentation
// 性能回归检测引擎
// Stage 31.3.2: 自动化性能测试套件
//
// 该模块提供完整的性能回归检测能力,包括:
// - 自动性能基准测试执行
// - 性能基线数据管理
// - 智能回归检测算法
// - 性能阈值动态调整
// - 详细性能报告生成

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
use thiserror::Error;

/// Stub type for MemoryStats (normally from benchmarks module)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryStats {
    pub allocated: usize,
    pub used: usize,
}

/// Stub type for BenchmarkResult (normally from benchmarks module)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchmarkResult {
    pub test_name: String,
    pub duration_ns: u64,
    pub operations_count: usize,
    pub memory_used: usize,
}

/// Stub type for PerformanceDelta (normally from benchmarks module)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceDelta {
    pub delta_ns: i64,
    pub delta_percent: f64,
}

/// 性能回归检测错误
#[derive(Error, Debug)]
pub enum RegressionError {
    #[error("Failed to load baseline data: {0}")]
    BaselineLoadError(String),
    #[error("Failed to save baseline data: {0}")]
    BaselineSaveError(String),
    #[error("Performance regression detected: {0}")]
    RegressionDetected(String),
    #[error("Configuration error: {0}")]
    ConfigError(String),
}
/// 性能阈值配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceThresholds {
    pub startup_time_regression_percent: f64, // 启动时间回归阈值 (%)
    pub execution_time_regression_percent: f64, // 执行时间回归阈值 (%)
    pub memory_regression_percent: f64,       // 内存使用回归阈值 (%)
    pub throughput_regression_percent: f64,   // 吞吐量回归阈值 (%)
    pub regression_count_threshold: usize,    // 回归次数阈值
}
impl Default for PerformanceThresholds {
    fn default() -> Self {
        Self {
            startup_time_regression_percent: 10.0,  // 10% 回归阈值
            execution_time_regression_percent: 5.0, // 5% 回归阈值
            memory_regression_percent: 15.0,        // 15% 回归阈值
            throughput_regression_percent: 8.0,     // 8% 回归阈值
            regression_count_threshold: 1,          // 单次回归即报警
        }
    }
}
/// 性能基线数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceBaseline {
    pub test_name: String,
    pub metric_type: String, // Simplified from MetricType
    pub avg_duration_ns: u64,
    pub std_deviation_ns: f64,
    pub operations_per_second: f64,
    pub memory_stats: Option<MemoryStats>,
    pub timestamp: u64,
    pub sample_count: usize,
    pub metadata: HashMap<String, String>,
}
/// 性能回归检测结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegressionDetectionResult {
    pub test_name: String,
    pub is_regression: bool,
    pub regression_severity: RegressionSeverity,
    pub current_result: BenchmarkResult,
    pub baseline_result: Option<PerformanceBaseline>,
    pub performance_delta: Option<PerformanceDelta>,
    pub threshold: f64,
    pub actual_delta_percent: f64,
    pub recommendations: Vec<String>,
}
/// 回归严重程度
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum RegressionSeverity {
    None,
    Minor,    // < 5% regression
    Moderate, // 5-15% regression
    Severe,   // > 15% regression
    Critical, // > 30% regression or system failure
}
impl RegressionSeverity {
    /// 根据回归百分比判断严重程度
    pub fn from_percentage(percent: f64) -> Self {
        if percent < 5.0 {
            RegressionSeverity::Minor
        } else if percent < 15.0 {
            RegressionSeverity::Moderate
        } else {
            RegressionSeverity::Severe
        }
    }
}
/// 性能回归检测器
pub struct PerformanceRegressionDetector {
    thresholds: PerformanceThresholds,
    baselines: HashMap<String, PerformanceBaseline>,
}

impl Default for PerformanceRegressionDetector {
    fn default() -> Self {
        Self::new(PerformanceThresholds::default())
    }
}

impl PerformanceRegressionDetector {
    /// 创建性能回归检测器
    pub fn new(thresholds: PerformanceThresholds) -> Self {
        Self {
            thresholds,
            baselines: HashMap::new(),
        }
    }

    /// 从结果创建基线数据
    pub fn create_baseline_from_result(&self, result: &BenchmarkResult) -> PerformanceBaseline {
        let timestamp = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap_or_default()
            .as_secs();

        PerformanceBaseline {
            test_name: result.test_name.clone(),
            metric_type: "execution_time".to_string(),
            avg_duration_ns: result.duration_ns,
            std_deviation_ns: 0.0,
            operations_per_second: if result.duration_ns > 0 {
                (result.operations_count as f64) / (result.duration_ns as f64 / 1_000_000_000.0)
            } else {
                0.0
            },
            memory_stats: Some(MemoryStats {
                allocated: result.memory_used,
                used: result.memory_used,
            }),
            timestamp,
            sample_count: 1,
            metadata: HashMap::new(),
        }
    }

    /// 检测性能回归
    pub fn detect_regression(&self, result: &BenchmarkResult) -> RegressionDetectionResult {
        let baseline = self.baselines.get(&result.test_name);
        let threshold = self.thresholds.execution_time_regression_percent;

        let (is_regression, actual_delta_percent, performance_delta) =
            if let Some(baseline) = baseline {
                let delta_ns = result.duration_ns as i64 - baseline.avg_duration_ns as i64;
                let delta_percent = if baseline.avg_duration_ns > 0 {
                    (delta_ns as f64 / baseline.avg_duration_ns as f64) * 100.0
                } else {
                    0.0
                };
                let is_regression = delta_percent > threshold;
                (
                    is_regression,
                    delta_percent,
                    Some(PerformanceDelta {
                        delta_ns,
                        delta_percent,
                    }),
                )
            } else {
                (false, 0.0, None)
            };

        let regression_severity = RegressionSeverity::from_percentage(actual_delta_percent.abs());

        RegressionDetectionResult {
            test_name: result.test_name.clone(),
            is_regression,
            regression_severity,
            current_result: result.clone(),
            baseline_result: baseline.cloned(),
            performance_delta,
            threshold,
            actual_delta_percent,
            recommendations: Vec::new(),
        }
    }
}

/// 回归检测统计信息
#[derive(Debug, Clone)]
pub struct RegressionStats {
    pub total_tests: usize,
    pub regressions_detected: usize,
    pub minor_regressions: usize,
    pub moderate_regressions: usize,
    pub severe_regressions: usize,
    pub critical_regressions: usize,
    pub false_positive_rate: f64,
}

/// 性能回归测试套件
pub struct RegressionTestSuite {
    detector: PerformanceRegressionDetector,
}

impl RegressionTestSuite {
    /// 创建新的回归测试套件
    pub fn new() -> Result<Self, RegressionError> {
        Ok(Self {
            detector: PerformanceRegressionDetector::default(),
        })
    }

    /// 运行回归检测
    pub fn run_regression_detection(&mut self, results: &[BenchmarkResult]) -> RegressionStats {
        let mut stats = RegressionStats {
            total_tests: results.len(),
            regressions_detected: 0,
            minor_regressions: 0,
            moderate_regressions: 0,
            severe_regressions: 0,
            critical_regressions: 0,
            false_positive_rate: 0.0,
        };

        for result in results {
            let detection_result = self.detector.detect_regression(result);

            if detection_result.is_regression {
                stats.regressions_detected += 1;
            }

            match detection_result.regression_severity {
                RegressionSeverity::Minor => stats.minor_regressions += 1,
                RegressionSeverity::Moderate => stats.moderate_regressions += 1,
                RegressionSeverity::Severe => stats.severe_regressions += 1,
                RegressionSeverity::Critical => stats.critical_regressions += 1,
                _ => {}
            }
        }

        stats
    }
}

/// 默认测试运行器
pub struct DefaultTestRunner;

impl DefaultTestRunner {
    /// 运行默认测试
    pub fn run_default_tests() -> Result<BenchmarkResult, RegressionError> {
        // 模拟测试执行
        let start = SystemTime::now();
        std::thread::sleep(std::time::Duration::from_millis(10));
        let duration = start.elapsed().unwrap_or_default();

        Ok(BenchmarkResult {
            test_name: "default_test".to_string(),
            duration_ns: duration.as_nanos() as u64,
            operations_count: 1000,
            memory_used: 1024 * 1024, // 1MB
        })
    }
}