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 let start = Instant::now();
34
35 while !condition() {
36 if start.elapsed() > timeout {
37 panic!("Timeout after {:?}: {}", timeout, timeout_message);
38 }
39 sleep(poll_interval).await;
40 }
41}
42
43pub async fn wait_for<F>(condition: F, message: &str)
47where
48 F: Fn() -> bool,
49{
50 wait_for_condition(condition, DEFAULT_TIMEOSVT, DEFAULT_POLL_INTERVAL, message).await;
51}
52
53#[cfg(test)]
54mod tests {
55 use std::{
56 sync::{Arc, Mutex},
57 thread,
58 };
59
60 use super::*;
61
62 #[tokio::test]
63 async fn test_wait_for_immediate() {
64 wait_for(|| true, "Should not timeout").await;
66 }
67
68 #[tokio::test]
69 async fn test_wait_for_becomes_true() {
70 let counter = Arc::new(Mutex::new(0));
71 let counter_clone = counter.clone();
72
73 thread::spawn(move || {
74 std::thread::sleep(Duration::from_millis(50));
75 *counter_clone.lock().unwrap() = 5;
76 });
77
78 wait_for(|| *counter.lock().unwrap() == 5, "Counter should reach 5").await;
79
80 assert_eq!(*counter.lock().unwrap(), 5);
81 }
82
83 #[tokio::test]
84 #[should_panic(expected = "Timeout after")]
85 async fn test_wait_for_timeout() {
86 wait_for_condition(
87 || false,
88 Duration::from_millis(10),
89 Duration::from_millis(1),
90 "Condition never becomes true",
91 )
92 .await;
93 }
94}