network-monitor/tests/integration_test.rs
Ivan Li e2bd5e9be5 Clean up Chinese comments and add comprehensive English README
- Replace all Chinese comments with English equivalents in:
  - src/health_monitor.rs
  - src/lib.rs
  - tests/integration_test.rs
- Add comprehensive README.md with:
  - Project overview and features
  - Architecture diagram
  - Installation and configuration guide
  - Data format specifications
  - Health monitoring documentation
  - Troubleshooting guide
2025-06-30 17:40:37 +08:00

149 lines
4.5 KiB
Rust

use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::time::sleep;
use network_monitor::retry::{RetryConfig, retry_with_config};
/// Test simulating network failure recovery
#[tokio::test]
async fn test_network_failure_recovery() {
// Simulate an operation that fails a few times then succeeds
let attempt_count = Arc::new(AtomicU32::new(0));
let max_failures = 3;
let config = RetryConfig {
max_attempts: 10,
initial_delay: Duration::from_millis(10),
max_delay: Duration::from_millis(100),
backoff_multiplier: 1.5,
jitter: false, // Disable jitter for more predictable testing
};
let attempt_count_clone = attempt_count.clone();
let result = retry_with_config(config, move || {
let attempt_count = attempt_count_clone.clone();
async move {
let current_attempt = attempt_count.fetch_add(1, Ordering::SeqCst) + 1;
if current_attempt <= max_failures {
// Simulate network error
Err(format!("Network error on attempt {}", current_attempt))
} else {
// Simulate successful recovery
Ok(format!("Success on attempt {}", current_attempt))
}
}
}).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Success on attempt 4");
assert_eq!(attempt_count.load(Ordering::SeqCst), 4);
}
/// Test connection timeout scenario
#[tokio::test]
async fn test_connection_timeout_scenario() {
let config = RetryConfig {
max_attempts: 3,
initial_delay: Duration::from_millis(5),
max_delay: Duration::from_millis(20),
backoff_multiplier: 2.0,
jitter: false,
};
let attempt_count = Arc::new(AtomicU32::new(0));
let attempt_count_clone = attempt_count.clone();
let result: Result<String, &str> = retry_with_config(config, move || {
let attempt_count = attempt_count_clone.clone();
async move {
attempt_count.fetch_add(1, Ordering::SeqCst);
// Simulate connection timeout
sleep(Duration::from_millis(1)).await;
Err("Connection timeout")
}
}).await;
assert!(result.is_err());
assert_eq!(attempt_count.load(Ordering::SeqCst), 3); // Should have attempted 3 times
}
/// Test fast recovery scenario
#[tokio::test]
async fn test_fast_recovery() {
let config = RetryConfig::fast();
let attempt_count = Arc::new(AtomicU32::new(0));
let attempt_count_clone = attempt_count.clone();
let result = retry_with_config(config, move || {
let attempt_count = attempt_count_clone.clone();
async move {
let current_attempt = attempt_count.fetch_add(1, Ordering::SeqCst) + 1;
if current_attempt == 1 {
Err("Temporary failure")
} else {
Ok("Quick recovery")
}
}
}).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Quick recovery");
assert_eq!(attempt_count.load(Ordering::SeqCst), 2);
}
/// Test slow retry scenario
#[tokio::test]
async fn test_slow_retry_scenario() {
let config = RetryConfig::slow();
let attempt_count = Arc::new(AtomicU32::new(0));
let attempt_count_clone = attempt_count.clone();
let result = retry_with_config(config, move || {
let attempt_count = attempt_count_clone.clone();
async move {
let current_attempt = attempt_count.fetch_add(1, Ordering::SeqCst) + 1;
if current_attempt <= 2 {
Err("Service unavailable")
} else {
Ok("Service restored")
}
}
}).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Service restored");
assert_eq!(attempt_count.load(Ordering::SeqCst), 3);
}
/// Test maximum retry limit
#[tokio::test]
async fn test_max_retry_limit() {
let config = RetryConfig {
max_attempts: 2,
initial_delay: Duration::from_millis(1),
max_delay: Duration::from_millis(5),
backoff_multiplier: 2.0,
jitter: false,
};
let attempt_count = Arc::new(AtomicU32::new(0));
let attempt_count_clone = attempt_count.clone();
let result = retry_with_config(config, move || {
let attempt_count = attempt_count_clone.clone();
async move {
attempt_count.fetch_add(1, Ordering::SeqCst);
Err::<String, &str>("Persistent failure")
}
}).await;
assert!(result.is_err());
assert_eq!(attempt_count.load(Ordering::SeqCst), 2);
}