#![allow(clippy::float_arithmetic)]
use std::{
io::{self, Error, ErrorKind},
sync::atomic::{AtomicUsize, Ordering::Relaxed},
};
pub async fn inject_delay() {
use std::time::Duration;
static GLOBAL_DELAYS: AtomicUsize = AtomicUsize::new(0);
thread_local!(
static LOCAL_DELAYS: std::cell::RefCell<usize> = std::cell::RefCell::new(0)
);
let global_delays = GLOBAL_DELAYS.fetch_add(1, Relaxed);
let local_delays = LOCAL_DELAYS.with(|ld| {
let mut ld = ld.borrow_mut();
let old = *ld;
*ld = std::cmp::max(global_delays + 1, *ld + 1);
old
});
if global_delays == local_delays {
return;
}
if fastrand::i32(..10) == 0 {
let duration = fastrand::u64(..50);
tokio::time::sleep(Duration::from_millis(duration)).await;
}
if fastrand::i32(..2) == 0 {
std::thread::yield_now();
}
}
pub fn inject_io_failure() -> io::Result<()> {
if fastrand::i32(..100) == 0 {
Err(Error::new(ErrorKind::Other, "injected fault"))
} else {
Ok(())
}
}