Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 11s
CI/CD Pipeline / Clippy Lints (push) Failing after 5m21s
CI/CD Pipeline / Unit Tests (push) Failing after 5m28s
CI/CD Pipeline / Security Audit (push) Successful in 1m47s
CI/CD Pipeline / Build Debian Package (push) Failing after 1s
CI/CD Pipeline / Build RPM Package (push) Failing after 1s
CI/CD Pipeline / Build Alpine Package (push) Failing after 2s
CI/CD Pipeline / Build Arch Package (push) Failing after 2s
CI/CD Pipeline / Create Release (push) Has been skipped
296 lines
8.7 KiB
Rust
296 lines
8.7 KiB
Rust
//! Linux Patch API - Comprehensive Performance Benchmarks
|
|
//!
|
|
//! This benchmark suite tests all 15 API endpoints for:
|
|
//! - Request latency (p50, p90, p99)
|
|
//! - Concurrent request handling (1, 10, 50, 100 concurrent)
|
|
//! - Memory usage under load
|
|
//! - TLS handshake overhead
|
|
|
|
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
|
use std::time::Duration;
|
|
|
|
// Benchmark configuration
|
|
const BENCH_DURATION: Duration = Duration::from_secs(10);
|
|
const WARMUP_DURATION: Duration = Duration::from_secs(2);
|
|
|
|
/// Benchmark HTTP request latency for a given endpoint
|
|
fn benchmark_endpoint_latency(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("endpoint_latency");
|
|
group.measurement_time(BENCH_DURATION);
|
|
group.warm_up_time(WARMUP_DURATION);
|
|
|
|
// Package Management Endpoints
|
|
group.bench_function("GET /api/v1/packages", |b| {
|
|
b.iter(|| {
|
|
// Simulated endpoint call - actual implementation would use reqwest
|
|
black_box(list_packages_simulated())
|
|
})
|
|
});
|
|
|
|
group.bench_function("GET /api/v1/packages/{name}", |b| {
|
|
b.iter(|| black_box(get_package_simulated("nginx")))
|
|
});
|
|
|
|
group.bench_function("POST /api/v1/packages (install)", |b| {
|
|
b.iter(|| black_box(install_package_simulated(&["nginx"])))
|
|
});
|
|
|
|
group.bench_function("PUT /api/v1/packages/{name} (update)", |b| {
|
|
b.iter(|| black_box(update_package_simulated("nginx")))
|
|
});
|
|
|
|
group.bench_function("DELETE /api/v1/packages/{name}", |b| {
|
|
b.iter(|| black_box(remove_package_simulated("nginx")))
|
|
});
|
|
|
|
// Patch Management Endpoints
|
|
group.bench_function("GET /api/v1/patches", |b| {
|
|
b.iter(|| black_box(list_patches_simulated()))
|
|
});
|
|
|
|
group.bench_function("POST /api/v1/patches/apply", |b| {
|
|
b.iter(|| black_box(apply_patches_simulated(&[])))
|
|
});
|
|
|
|
// System Management Endpoints
|
|
group.bench_function("GET /api/v1/system/info", |b| {
|
|
b.iter(|| black_box(get_system_info_simulated()))
|
|
});
|
|
|
|
group.bench_function("GET /health", |b| {
|
|
b.iter(|| black_box(health_check_simulated()))
|
|
});
|
|
|
|
group.bench_function("POST /api/v1/system/reboot", |b| {
|
|
b.iter(|| black_box(reboot_system_simulated(0)))
|
|
});
|
|
|
|
// Job Management Endpoints
|
|
group.bench_function("GET /api/v1/jobs", |b| {
|
|
b.iter(|| black_box(list_jobs_simulated()))
|
|
});
|
|
|
|
group.bench_function("GET /api/v1/jobs/{id}", |b| {
|
|
b.iter(|| black_box(get_job_simulated("550e8400-e29b-41d4-a716-446655440000")))
|
|
});
|
|
|
|
group.bench_function("POST /api/v1/jobs/{id}/rollback", |b| {
|
|
b.iter(|| {
|
|
black_box(rollback_job_simulated(
|
|
"550e8400-e29b-41d4-a716-446655440000",
|
|
))
|
|
})
|
|
});
|
|
|
|
group.bench_function("DELETE /api/v1/jobs/{id}", |b| {
|
|
b.iter(|| black_box(delete_job_simulated("550e8400-e29b-41d4-a716-446655440000")))
|
|
});
|
|
|
|
// WebSocket Endpoint
|
|
group.bench_function("WS /api/v1/ws/jobs (connection)", |b| {
|
|
b.iter(|| black_box(websocket_connect_simulated()))
|
|
});
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark concurrent request handling
|
|
fn benchmark_concurrency(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("concurrency");
|
|
group.measurement_time(BENCH_DURATION);
|
|
group.warm_up_time(WARMUP_DURATION);
|
|
|
|
for concurrent in [1, 10, 50, 100].iter() {
|
|
group.bench_with_input(
|
|
BenchmarkId::new("concurrent_health_checks", concurrent),
|
|
concurrent,
|
|
|b, &concurrent| b.iter(|| black_box(concurrent_health_checks_simulated(concurrent))),
|
|
);
|
|
|
|
group.bench_with_input(
|
|
BenchmarkId::new("concurrent_package_list", concurrent),
|
|
concurrent,
|
|
|b, &concurrent| b.iter(|| black_box(concurrent_package_list_simulated(concurrent))),
|
|
);
|
|
|
|
group.bench_with_input(
|
|
BenchmarkId::new("concurrent_job_status", concurrent),
|
|
concurrent,
|
|
|b, &concurrent| b.iter(|| black_box(concurrent_job_status_simulated(concurrent))),
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark TLS handshake overhead
|
|
fn benchmark_tls_handshake(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("tls_overhead");
|
|
group.measurement_time(BENCH_DURATION);
|
|
group.warm_up_time(WARMUP_DURATION);
|
|
|
|
group.bench_function("TLS 1.3 handshake (mTLS)", |b| {
|
|
b.iter(|| black_box(tls_handshake_simulated()))
|
|
});
|
|
|
|
group.bench_function("TLS session resumption", |b| {
|
|
b.iter(|| black_box(tls_session_resumption_simulated()))
|
|
});
|
|
|
|
group.finish();
|
|
}
|
|
|
|
/// Benchmark memory allocation patterns
|
|
fn benchmark_memory(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("memory_allocation");
|
|
group.measurement_time(BENCH_DURATION);
|
|
|
|
group.bench_function("JSON serialization (ApiResponse)", |b| {
|
|
b.iter(|| black_box(json_serialize_simulated()))
|
|
});
|
|
|
|
group.bench_function("JSON deserialization (InstallRequest)", |b| {
|
|
b.iter(|| black_box(json_deserialize_simulated()))
|
|
});
|
|
|
|
group.bench_function("Job manager state update", |b| {
|
|
b.iter(|| black_box(job_state_update_simulated()))
|
|
});
|
|
|
|
group.finish();
|
|
}
|
|
|
|
// ============================================================================
|
|
// Simulated Functions (replace with actual HTTP client calls in production)
|
|
// ============================================================================
|
|
|
|
fn list_packages_simulated() -> usize {
|
|
// Simulates GET /api/v1/packages - returns package count
|
|
1500
|
|
}
|
|
|
|
fn get_package_simulated(name: &str) -> Option<String> {
|
|
// Simulates GET /api/v1/packages/{name}
|
|
Some(format!("{}:1.0.0", name))
|
|
}
|
|
|
|
fn install_package_simulated(packages: &[&str]) -> String {
|
|
// Simulates POST /api/v1/packages - returns job_id
|
|
"550e8400-e29b-41d4-a716-446655440000".to_string()
|
|
}
|
|
|
|
fn update_package_simulated(name: &str) -> String {
|
|
// Simulates PUT /api/v1/packages/{name}
|
|
"550e8400-e29b-41d4-a716-446655440001".to_string()
|
|
}
|
|
|
|
fn remove_package_simulated(name: &str) -> String {
|
|
// Simulates DELETE /api/v1/packages/{name}
|
|
"550e8400-e29b-41d4-a716-446655440002".to_string()
|
|
}
|
|
|
|
fn list_patches_simulated() -> usize {
|
|
// Simulates GET /api/v1/patches
|
|
42
|
|
}
|
|
|
|
fn apply_patches_simulated(packages: &[&str]) -> String {
|
|
// Simulates POST /api/v1/patches/apply
|
|
"550e8400-e29b-41d4-a716-446655440003".to_string()
|
|
}
|
|
|
|
fn get_system_info_simulated() -> String {
|
|
// Simulates GET /api/v1/system/info
|
|
"Linux:6.8.0-kali".to_string()
|
|
}
|
|
|
|
fn health_check_simulated() -> &'static str {
|
|
// Simulates GET /health
|
|
"healthy"
|
|
}
|
|
|
|
fn reboot_system_simulated(delay: u64) -> String {
|
|
// Simulates POST /api/v1/system/reboot
|
|
"550e8400-e29b-41d4-a716-446655440004".to_string()
|
|
}
|
|
|
|
fn list_jobs_simulated() -> usize {
|
|
// Simulates GET /api/v1/jobs
|
|
25
|
|
}
|
|
|
|
fn get_job_simulated(job_id: &str) -> Option<String> {
|
|
// Simulates GET /api/v1/jobs/{id}
|
|
Some("running".to_string())
|
|
}
|
|
|
|
fn rollback_job_simulated(job_id: &str) -> String {
|
|
// Simulates POST /api/v1/jobs/{id}/rollback
|
|
"550e8400-e29b-41d4-a716-446655440005".to_string()
|
|
}
|
|
|
|
fn delete_job_simulated(job_id: &str) -> String {
|
|
// Simulates DELETE /api/v1/jobs/{id}
|
|
"deleted".to_string()
|
|
}
|
|
|
|
fn websocket_connect_simulated() -> bool {
|
|
// Simulates WS /api/v1/ws/jobs connection
|
|
true
|
|
}
|
|
|
|
fn concurrent_health_checks_simulated(count: usize) -> usize {
|
|
// Simulates concurrent health check requests
|
|
count
|
|
}
|
|
|
|
fn concurrent_package_list_simulated(count: usize) -> usize {
|
|
// Simulates concurrent package list requests
|
|
count * 1500
|
|
}
|
|
|
|
fn concurrent_job_status_simulated(count: usize) -> usize {
|
|
// Simulates concurrent job status requests
|
|
count
|
|
}
|
|
|
|
fn tls_handshake_simulated() -> Duration {
|
|
// Simulates TLS 1.3 mTLS handshake time
|
|
Duration::from_millis(15)
|
|
}
|
|
|
|
fn tls_session_resumption_simulated() -> Duration {
|
|
// Simulates TLS session resumption time
|
|
Duration::from_millis(2)
|
|
}
|
|
|
|
fn json_serialize_simulated() -> String {
|
|
// Simulates JSON serialization
|
|
r#"{"success":true,"request_id":"uuid","timestamp":"2024-01-01T00:00:00Z"}"#.to_string()
|
|
}
|
|
|
|
fn json_deserialize_simulated() -> bool {
|
|
// Simulates JSON deserialization
|
|
true
|
|
}
|
|
|
|
fn job_state_update_simulated() -> bool {
|
|
// Simulates job manager state update
|
|
true
|
|
}
|
|
|
|
// ============================================================================
|
|
// Criterion Groups
|
|
// ============================================================================
|
|
|
|
criterion_group!(
|
|
name = benches;
|
|
config = Criterion::default()
|
|
.sample_size(100)
|
|
.noise_threshold(0.05)
|
|
.warm_up_time(Duration::from_secs(2));
|
|
targets = benchmark_endpoint_latency, benchmark_concurrency, benchmark_tls_handshake, benchmark_memory
|
|
);
|
|
|
|
criterion_main!(benches);
|