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