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