//! Utils for debugging hg-core use crate::config::Config; /// Write the file path given by the config option `devel.` with /// the suffix `.waiting`, then wait for the file path given by the /// config option `devel.` to appear on disk /// up to `devel.-timeout` seconds. /// Note that the timeout may be higher because we scale it if global /// `run-tests` timeouts are raised to prevent flakiness on slower hardware. /// /// Useful for testing race conditions. pub fn debug_wait_for_file( config: &Config, config_option: &str, ) -> Result<(), String> { let path_opt = format!("sync.{config_option}"); let file_path = match config.get_str(b"devel", path_opt.as_bytes()).ok() { Some(Some(file_path)) => file_path, _ => return Ok(()), }; // TODO make it so `configitems` is shared between Rust and Python so that // defaults work out of the box, etc. let default_timeout = 2; let timeout_opt = format!("sync.{config_option}-timeout"); let timeout_seconds = match config.get_u32(b"devel", timeout_opt.as_bytes()) { Ok(Some(timeout)) => timeout, Err(e) => { log::debug!("{e}"); default_timeout } _ => default_timeout, }; let timeout_seconds = timeout_seconds as u64; log::debug!( "Config option `{config_option}` found, \ waiting for file `{file_path}` to be created" ); std::fs::File::create(format!("{file_path}.waiting")).ok(); // If the test timeout have been extended, scale the timer relative // to the normal timing. let global_default_timeout: u64 = std::env::var("HGTEST_TIMEOUT_DEFAULT") .map(|t| t.parse()) .unwrap_or(Ok(0)) .unwrap(); let global_timeout_override: u64 = std::env::var("HGTEST_TIMEOUT") .map(|t| t.parse()) .unwrap_or(Ok(0)) .unwrap(); let timeout_seconds = if global_default_timeout < global_timeout_override { timeout_seconds * global_timeout_override / global_default_timeout } else { timeout_seconds }; let timeout = std::time::Duration::from_secs(timeout_seconds); let start = std::time::Instant::now(); let path = std::path::Path::new(file_path); let mut found = false; while start.elapsed() < timeout { if path.exists() { log::debug!("File `{file_path}` was created"); found = true; break; } else { std::thread::sleep(std::time::Duration::from_millis(10)); } } if !found { let msg = format!( "File `{file_path}` set by `{config_option}` was not found \ within the allocated {timeout_seconds} seconds timeout" ); Err(msg) } else { Ok(()) } } pub fn debug_wait_for_file_or_print(config: &Config, config_option: &str) { if let Err(e) = debug_wait_for_file(config, config_option) { eprintln!("{e}"); }; }