diff options
| -rw-r--r-- | mullvad-tests/src/lib.rs | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/mullvad-tests/src/lib.rs b/mullvad-tests/src/lib.rs index 523d74eede..978eae1816 100644 --- a/mullvad-tests/src/lib.rs +++ b/mullvad-tests/src/lib.rs @@ -17,8 +17,8 @@ use std::fs::{self, File}; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use std::sync::{mpsc, Arc, Mutex}; -use std::thread; use std::time::{Duration, Instant}; +use std::{cmp, thread}; use mullvad_ipc_client::DaemonRpcClient; use mullvad_paths::resources::API_CA_FILENAME; @@ -122,6 +122,37 @@ impl PathWatcher { } } } + + /// Waits for a burst of file events. + /// + /// Here, a burst of events is defined as a series of events that are emitted with less than one + /// second between each of them. + /// + /// The `max_wait_time` defines the maximum time to wait for all of the events. If a burst of + /// events is emitted that is longer than the specified time, the function will return before + /// all events have been received. + pub fn wait_for_burst_of_events(&mut self, max_wait_time: Duration) { + const EVENT_INTERVAL: Duration = Duration::from_secs(1); + + let start = Instant::now(); + let original_timeout = self.timeout; + + // We wait at most for the maximum waiting time for the first event to arrive + self.timeout = max_wait_time; + + if self.next().is_some() { + while let Some(remaining_time) = max_wait_time.checked_sub(start.elapsed()) { + // Avoid exceeding the maximum wait time + self.timeout = cmp::min(EVENT_INTERVAL, remaining_time); + + if self.next().is_none() { + break; + } + } + } + + self.timeout = original_timeout; + } } impl Iterator for PathWatcher { @@ -296,13 +327,16 @@ impl DaemonRunner { } pub fn rpc_client(&mut self) -> Result<DaemonRpcClient> { - if !self.rpc_address_file.exists() { - let _ = PathWatcher::watch(&self.rpc_address_file).map(|mut events| { - events - .set_timeout(Duration::from_secs(10)) - .find(|&event| event == watch_event::CLOSE_WRITE) - }); - } + let _wait_for_rpc_file = PathWatcher::watch(&self.rpc_address_file).map(|mut watcher| { + if !self.rpc_address_file.exists() { + // No event has been emitted yet. Wait for a longer amount of time. + watcher.wait_for_burst_of_events(Duration::from_secs(10)); + } else { + // The file was created, so at least one event was emitted. Assume the burst has + // started and wait for a shorter amount of time. + watcher.wait_for_burst_of_events(Duration::from_secs(1)); + } + }); DaemonRpcClient::with_insecure_rpc_address_file(&self.rpc_address_file) .map_err(|error| format!("Failed to create RPC client: {}", error)) |
