reifydb_testing/util/
wait.rs1use std::time::{Duration, Instant};
5
6use tokio::time::sleep;
7
8pub const DEFAULT_TIMEOSVT: Duration = Duration::from_secs(5);
10
11pub const DEFAULT_POLL_INTERVAL: Duration = Duration::from_millis(1);
13
14pub async fn wait_for_condition<F>(condition: F, timeout: Duration, poll_interval: Duration, timeout_message: &str)
25where
26 F: Fn() -> bool,
27{
28 #[allow(clippy::disallowed_methods)]
29 let start = Instant::now();
30 let mut poll_count = 0u64;
31
32 while !condition() {
33 if start.elapsed() > timeout {
34 println!(
35 "[DEBUG:await] TIMEOUT elapsed={:.1}s polls={poll_count} msg={timeout_message}",
36 start.elapsed().as_secs_f64()
37 );
38 panic!("Timeout after {:?}: {}", timeout, timeout_message);
39 }
40 poll_count += 1;
41 if poll_count.is_multiple_of(1000) {
42 println!(
43 "[DEBUG:await] poll #{poll_count} elapsed={:.1}s msg={timeout_message}",
44 start.elapsed().as_secs_f64()
45 );
46 }
47 sleep(poll_interval).await;
48 }
49 println!(
50 "[DEBUG:await] condition met after {poll_count} polls elapsed={:.3}s msg={timeout_message}",
51 start.elapsed().as_secs_f64()
52 );
53}
54
55pub async fn wait_for<F>(condition: F, message: &str)
59where
60 F: Fn() -> bool,
61{
62 wait_for_condition(condition, DEFAULT_TIMEOSVT, DEFAULT_POLL_INTERVAL, message).await;
63}
64
65#[cfg(test)]
66pub mod tests {
67 use std::{
68 sync::{Arc, Mutex},
69 thread,
70 };
71
72 use super::*;
73
74 #[tokio::test]
75 async fn test_wait_for_immediate() {
76 wait_for(|| true, "Should not timeout").await;
78 }
79
80 #[tokio::test]
81 async fn test_wait_for_becomes_true() {
82 let counter = Arc::new(Mutex::new(0));
83 let counter_clone = counter.clone();
84
85 thread::spawn(move || {
86 thread::sleep(Duration::from_millis(50));
87 *counter_clone.lock().unwrap() = 5;
88 });
89
90 wait_for(|| *counter.lock().unwrap() == 5, "Counter should reach 5").await;
91
92 assert_eq!(*counter.lock().unwrap(), 5);
93 }
94
95 #[tokio::test]
96 #[should_panic(expected = "Timeout after")]
97 async fn test_wait_for_timeout() {
98 wait_for_condition(
99 || false,
100 Duration::from_millis(10),
101 Duration::from_millis(1),
102 "Condition never becomes true",
103 )
104 .await;
105 }
106}