Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/utils/debug.rs @ 50252:a6b8b1ab9116
branching: merge stable into default
The clippy god had to be appeased on some aspect.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 02 Mar 2023 19:02:52 +0100 |
parents | fc8e37c380d3 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hg-core/src/utils/debug.rs Thu Mar 02 19:02:52 2023 +0100 @@ -0,0 +1,87 @@ +//! Utils for debugging hg-core + +use crate::config::Config; + +/// Write the file path given by the config option `devel.<config_option>` with +/// the suffix `.waiting`, then wait for the file path given by the +/// config option `devel.<config_option>` to appear on disk +/// up to `devel.<config_option>-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}"); + }; +}