use blvm_node::utils::circuit_breaker::{CircuitBreaker, CircuitState};
use std::thread;
use std::time::Duration;
#[test]
fn test_circuit_breaker_creation() {
let breaker = CircuitBreaker::new(5, Duration::from_secs(10));
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_with_success_threshold() {
let breaker = CircuitBreaker::with_success_threshold(5, 3, Duration::from_secs(10));
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_closed_state() {
let breaker = CircuitBreaker::new(5, Duration::from_secs(10));
assert_eq!(breaker.state(), CircuitState::Closed);
assert!(breaker.allow_request());
}
#[test]
fn test_circuit_breaker_record_success() {
let breaker = CircuitBreaker::new(5, Duration::from_secs(10));
assert_eq!(breaker.state(), CircuitState::Closed);
breaker.record_success();
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_record_failure() {
let breaker = CircuitBreaker::new(5, Duration::from_secs(10));
for _ in 0..4 {
breaker.record_failure();
assert_eq!(breaker.state(), CircuitState::Closed);
}
breaker.record_failure();
assert_eq!(breaker.state(), CircuitState::Open);
}
#[test]
fn test_circuit_breaker_open_state_blocks_requests() {
let breaker = CircuitBreaker::new(3, Duration::from_secs(1));
for _ in 0..3 {
breaker.record_failure();
}
assert_eq!(breaker.state(), CircuitState::Open);
assert!(!breaker.allow_request());
}
#[test]
fn test_circuit_breaker_timeout_transition_to_half_open() {
let breaker = CircuitBreaker::new(3, Duration::from_secs(1));
for _ in 0..3 {
breaker.record_failure();
}
assert_eq!(breaker.state(), CircuitState::Open);
thread::sleep(Duration::from_secs(2));
assert!(breaker.allow_request());
assert_eq!(breaker.state(), CircuitState::HalfOpen);
}
#[test]
fn test_circuit_breaker_half_open_to_closed() {
let breaker = CircuitBreaker::new(3, Duration::from_secs(1));
for _ in 0..3 {
breaker.record_failure();
}
thread::sleep(Duration::from_secs(2));
breaker.allow_request();
breaker.record_success();
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_half_open_to_open() {
let breaker = CircuitBreaker::new(3, Duration::from_secs(1));
for _ in 0..3 {
breaker.record_failure();
}
thread::sleep(Duration::from_secs(2));
breaker.allow_request();
breaker.record_failure();
assert_eq!(breaker.state(), CircuitState::Open);
}
#[test]
fn test_circuit_breaker_success_threshold() {
let breaker = CircuitBreaker::with_success_threshold(
3,
2, Duration::from_secs(1),
);
for _ in 0..3 {
breaker.record_failure();
}
thread::sleep(Duration::from_secs(2));
breaker.allow_request();
breaker.record_success();
assert_eq!(breaker.state(), CircuitState::HalfOpen);
breaker.record_success();
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_reset() {
let breaker = CircuitBreaker::new(3, Duration::from_secs(10));
for _ in 0..3 {
breaker.record_failure();
}
assert_eq!(breaker.state(), CircuitState::Open);
breaker.reset();
assert_eq!(breaker.state(), CircuitState::Closed);
}
#[test]
fn test_circuit_breaker_state_variants() {
let states = vec![
CircuitState::Closed,
CircuitState::Open,
CircuitState::HalfOpen,
];
for state in states {
match state {
CircuitState::Closed => assert!(true),
CircuitState::Open => assert!(true),
CircuitState::HalfOpen => assert!(true),
}
}
}