#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod coverage_tests {
use super::*;
#[test]
fn test_rate_limiter_available_tokens() {
let limiter = RateLimiter::new(100, 10);
let available = limiter.available_tokens();
assert_eq!(available, 100);
limiter.try_acquire(30);
let available = limiter.available_tokens();
assert_eq!(available, 70);
}
#[actix_rt::test]
async fn test_rate_limiter_acquire_async() {
let limiter = RateLimiter::new(5, 100);
assert!(limiter.try_acquire(5));
assert!(!limiter.try_acquire(1));
let start = Instant::now();
limiter.acquire(1).await;
let elapsed = start.elapsed();
assert!(elapsed.as_millis() >= 5);
}
#[test]
fn test_rate_limiter_refill_partial() {
let limiter = RateLimiter::new(10, 1000);
assert!(limiter.try_acquire(10));
assert_eq!(limiter.available_tokens(), 0);
std::thread::sleep(Duration::from_millis(5));
let available = limiter.available_tokens();
assert!(available > 0);
assert!(available <= 10); }
#[test]
fn test_rate_limiter_concurrent_acquire() {
use std::sync::Arc;
use std::thread;
let limiter = Arc::new(RateLimiter::new(100, 50));
let mut handles = vec![];
for _ in 0..5 {
let limiter_clone = limiter.clone();
handles.push(thread::spawn(move || {
let mut acquired = 0;
for _ in 0..10 {
if limiter_clone.try_acquire(2) {
acquired += 2;
}
}
acquired
}));
}
let total_acquired: u32 = handles.into_iter().map(|h| h.join().unwrap()).sum();
assert!(total_acquired <= 100);
}
#[test]
fn test_backpressure_metrics_default() {
let metrics = BackpressureMetrics::default();
assert_eq!(metrics.rejected_count, 0);
assert_eq!(metrics.accepted_count, 0);
assert_eq!(metrics.queue_depth_sum, 0);
assert_eq!(metrics.max_queue_depth, 0);
assert_eq!(metrics.sample_count, 0);
}
#[test]
fn test_backpressure_metrics_clone() {
let metrics = BackpressureMetrics {
rejected_count: 10,
accepted_count: 100,
queue_depth_sum: 500,
max_queue_depth: 8,
sample_count: 100,
};
let cloned = metrics.clone();
assert_eq!(cloned.rejected_count, metrics.rejected_count);
assert_eq!(cloned.accepted_count, metrics.accepted_count);
assert_eq!(cloned.queue_depth_sum, metrics.queue_depth_sum);
assert_eq!(cloned.max_queue_depth, metrics.max_queue_depth);
assert_eq!(cloned.sample_count, metrics.sample_count);
}
#[test]
fn test_backpressure_metrics_debug() {
let metrics = BackpressureMetrics {
rejected_count: 5,
accepted_count: 50,
queue_depth_sum: 200,
max_queue_depth: 10,
sample_count: 50,
};
let debug_str = format!("{:?}", metrics);
assert!(debug_str.contains("BackpressureMetrics"));
assert!(debug_str.contains("rejected_count"));
assert!(debug_str.contains("accepted_count"));
}
#[actix_rt::test]
async fn test_backpressure_controller_acquire_permit() {
let controller = BackpressureController::new(5);
let permit = controller.acquire_permit().await;
assert!(permit.is_ok());
assert_eq!(controller.get_queue_depth(), 1);
}
#[actix_rt::test]
async fn test_backpressure_controller_get_metrics() {
let controller = BackpressureController::new(10);
let _p1 = controller.try_acquire_permit().unwrap();
let _p2 = controller.try_acquire_permit().unwrap();
let metrics = controller.get_metrics();
assert_eq!(metrics.accepted_count, 2);
assert_eq!(metrics.max_queue_depth, 2);
assert_eq!(metrics.sample_count, 2);
}
#[actix_rt::test]
async fn test_backpressure_controller_average_queue_depth() {
let controller = BackpressureController::new(10);
assert_eq!(controller.get_average_queue_depth(), 0.0);
let _p1 = controller.try_acquire_permit().unwrap();
let _p2 = controller.try_acquire_permit().unwrap();
let _p3 = controller.try_acquire_permit().unwrap();
let avg = controller.get_average_queue_depth();
assert!((avg - 2.0).abs() < f64::EPSILON);
}
#[actix_rt::test]
async fn test_backpressure_controller_rejected_metrics() {
let controller = BackpressureController::new(2);
let _p1 = controller.try_acquire_permit().unwrap();
let _p2 = controller.try_acquire_permit().unwrap();
let result = controller.try_acquire_permit();
assert!(matches!(result, Err(BackpressureError::QueueFull)));
let metrics = controller.get_metrics();
assert_eq!(metrics.rejected_count, 1);
}
#[actix_rt::test]
async fn test_backpressure_permit_drop_releases() {
let controller = BackpressureController::new(2);
let p1 = controller.try_acquire_permit().unwrap();
let _p2 = controller.try_acquire_permit().unwrap();
assert_eq!(controller.get_queue_depth(), 2);
drop(p1);
assert_eq!(controller.get_queue_depth(), 1);
}
#[test]
fn test_backpressure_error_queue_full() {
let err = BackpressureError::QueueFull;
let display_str = format!("{}", err);
assert!(display_str.contains("full"));
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("QueueFull"));
}
#[test]
fn test_backpressure_error_rate_limit() {
let err = BackpressureError::RateLimitExceeded;
let display_str = format!("{}", err);
assert!(display_str.contains("Rate limit"));
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("RateLimitExceeded"));
}
#[test]
fn test_load_monitor_creation() {
let monitor = LoadMonitor::new(0.8, 0.9);
assert_eq!(monitor.cpu_threshold, 0.8);
assert_eq!(monitor.memory_threshold, 0.9);
}
#[test]
fn test_load_monitor_get_load_factor() {
let monitor = LoadMonitor::new(0.8, 0.9);
let load_factor = monitor.get_load_factor();
assert!(load_factor >= 0.0);
assert!(load_factor <= 1.0);
}
#[actix_rt::test]
async fn test_adaptive_rate_controller_try_acquire() {
let controller = AdaptiveRateController::new(100, 10, 500);
assert!(controller.try_acquire());
}
#[actix_rt::test]
async fn test_adaptive_rate_controller_acquire_async() {
let controller = AdaptiveRateController::new(100, 10, 500);
controller.acquire().await;
let rate = controller.get_current_rate();
assert!(rate >= 10 && rate <= 500);
}
#[actix_rt::test]
async fn test_adaptive_rate_controller_rate_bounds() {
let controller = AdaptiveRateController::new(50, 10, 200);
for _ in 0..10 {
controller.adapt_rate().await;
}
let rate = controller.get_current_rate();
assert!(rate >= 10);
assert!(rate <= 200);
}
#[test]
fn test_bulkhead_creation() {
let bulkhead = Bulkhead::new("test-bulkhead".to_string(), 5);
let metrics = bulkhead.get_metrics();
assert_eq!(metrics.name, "test-bulkhead");
assert_eq!(metrics.max_concurrent, 5);
assert_eq!(metrics.active_count, 0);
assert_eq!(metrics.rejected_count, 0);
}
#[test]
fn test_bulkhead_clone() {
let bulkhead = Bulkhead::new("test".to_string(), 3);
let cloned = bulkhead.clone();
assert_eq!(bulkhead.name, cloned.name);
assert_eq!(bulkhead.max_concurrent, cloned.max_concurrent);
}
#[actix_rt::test]
async fn test_bulkhead_metrics_after_execution() {
let bulkhead = Bulkhead::new("metrics-test".to_string(), 5);
let result = bulkhead.execute(async { 42 }).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), 42);
let metrics = bulkhead.get_metrics();
assert_eq!(metrics.active_count, 0);
assert_eq!(metrics.rejected_count, 0);
}
#[actix_rt::test]
async fn test_bulkhead_rejection_metrics() {
let bulkhead = Bulkhead::new("rejection-test".to_string(), 1);
let bulkhead_clone = bulkhead.clone();
let handle = tokio::spawn(async move {
bulkhead_clone
.execute(async {
tokio::time::sleep(Duration::from_millis(100)).await;
1
})
.await
});
tokio::time::sleep(Duration::from_millis(10)).await;
let result = bulkhead.execute(async { 2 }).await;
assert!(matches!(result, Err(BackpressureError::QueueFull)));
let metrics = bulkhead.get_metrics();
assert_eq!(metrics.rejected_count, 1);
let _ = handle.await;
}
#[test]
fn test_bulkhead_metrics_debug() {
let metrics = BulkheadMetrics {
name: "test".to_string(),
max_concurrent: 5,
active_count: 2,
rejected_count: 1,
};
let debug_str = format!("{:?}", metrics);
assert!(debug_str.contains("BulkheadMetrics"));
assert!(debug_str.contains("test"));
assert!(debug_str.contains("5"));
}
#[test]
fn test_bulkhead_metrics_clone() {
let metrics = BulkheadMetrics {
name: "cloned".to_string(),
max_concurrent: 10,
active_count: 3,
rejected_count: 2,
};
let cloned = metrics.clone();
assert_eq!(cloned.name, metrics.name);
assert_eq!(cloned.max_concurrent, metrics.max_concurrent);
assert_eq!(cloned.active_count, metrics.active_count);
assert_eq!(cloned.rejected_count, metrics.rejected_count);
}
#[test]
fn test_rate_limiter_zero_tokens_acquire() {
let limiter = RateLimiter::new(10, 5);
assert!(limiter.try_acquire(0));
assert_eq!(limiter.available_tokens(), 10); }
#[test]
fn test_rate_limiter_exact_capacity_acquire() {
let limiter = RateLimiter::new(10, 5);
assert!(limiter.try_acquire(10));
assert_eq!(limiter.available_tokens(), 0);
assert!(!limiter.try_acquire(1));
}
#[actix_rt::test]
async fn test_backpressure_controller_queue_depth_zero_when_empty() {
let controller = BackpressureController::new(5);
assert_eq!(controller.get_queue_depth(), 0);
{
let _permit = controller.try_acquire_permit().unwrap();
assert_eq!(controller.get_queue_depth(), 1);
}
assert_eq!(controller.get_queue_depth(), 0);
}
#[actix_rt::test]
async fn test_adaptive_rate_low_load_increases_rate() {
let controller = AdaptiveRateController::new(100, 10, 1000);
let initial_rate = controller.get_current_rate();
controller.adapt_rate().await;
let new_rate = controller.get_current_rate();
assert!(new_rate >= initial_rate - 10); assert!(new_rate <= 1000); }
#[actix_rt::test]
async fn test_bulkhead_sequential_execution() {
let bulkhead = Bulkhead::new("sequential".to_string(), 2);
let r1 = bulkhead.execute(async { 1 }).await.unwrap();
let r2 = bulkhead.execute(async { 2 }).await.unwrap();
let r3 = bulkhead.execute(async { 3 }).await.unwrap();
assert_eq!(r1, 1);
assert_eq!(r2, 2);
assert_eq!(r3, 3);
}
}