rust/hg-core/src/utils/debug.rs
changeset 50252 a6b8b1ab9116
parent 50228 fc8e37c380d3
equal deleted inserted replaced
50248:2fbc109fd58a 50252:a6b8b1ab9116
       
     1 //! Utils for debugging hg-core
       
     2 
       
     3 use crate::config::Config;
       
     4 
       
     5 /// Write the file path given by the config option `devel.<config_option>` with
       
     6 /// the suffix `.waiting`, then wait for the file path given by the
       
     7 /// config option `devel.<config_option>` to appear on disk
       
     8 /// up to `devel.<config_option>-timeout` seconds.
       
     9 /// Note that the timeout may be higher because we scale it if global
       
    10 /// `run-tests` timeouts are raised to prevent flakiness on slower hardware.
       
    11 ///
       
    12 /// Useful for testing race conditions.
       
    13 pub fn debug_wait_for_file(
       
    14     config: &Config,
       
    15     config_option: &str,
       
    16 ) -> Result<(), String> {
       
    17     let path_opt = format!("sync.{config_option}");
       
    18     let file_path = match config.get_str(b"devel", path_opt.as_bytes()).ok() {
       
    19         Some(Some(file_path)) => file_path,
       
    20         _ => return Ok(()),
       
    21     };
       
    22 
       
    23     // TODO make it so `configitems` is shared between Rust and Python so that
       
    24     // defaults work out of the box, etc.
       
    25     let default_timeout = 2;
       
    26     let timeout_opt = format!("sync.{config_option}-timeout");
       
    27     let timeout_seconds =
       
    28         match config.get_u32(b"devel", timeout_opt.as_bytes()) {
       
    29             Ok(Some(timeout)) => timeout,
       
    30             Err(e) => {
       
    31                 log::debug!("{e}");
       
    32                 default_timeout
       
    33             }
       
    34             _ => default_timeout,
       
    35         };
       
    36     let timeout_seconds = timeout_seconds as u64;
       
    37 
       
    38     log::debug!(
       
    39         "Config option `{config_option}` found, \
       
    40              waiting for file `{file_path}` to be created"
       
    41     );
       
    42     std::fs::File::create(format!("{file_path}.waiting")).ok();
       
    43     // If the test timeout have been extended, scale the timer relative
       
    44     // to the normal timing.
       
    45     let global_default_timeout: u64 = std::env::var("HGTEST_TIMEOUT_DEFAULT")
       
    46         .map(|t| t.parse())
       
    47         .unwrap_or(Ok(0))
       
    48         .unwrap();
       
    49     let global_timeout_override: u64 = std::env::var("HGTEST_TIMEOUT")
       
    50         .map(|t| t.parse())
       
    51         .unwrap_or(Ok(0))
       
    52         .unwrap();
       
    53     let timeout_seconds = if global_default_timeout < global_timeout_override {
       
    54         timeout_seconds * global_timeout_override / global_default_timeout
       
    55     } else {
       
    56         timeout_seconds
       
    57     };
       
    58     let timeout = std::time::Duration::from_secs(timeout_seconds);
       
    59 
       
    60     let start = std::time::Instant::now();
       
    61     let path = std::path::Path::new(file_path);
       
    62     let mut found = false;
       
    63     while start.elapsed() < timeout {
       
    64         if path.exists() {
       
    65             log::debug!("File `{file_path}` was created");
       
    66             found = true;
       
    67             break;
       
    68         } else {
       
    69             std::thread::sleep(std::time::Duration::from_millis(10));
       
    70         }
       
    71     }
       
    72     if !found {
       
    73         let msg = format!(
       
    74             "File `{file_path}` set by `{config_option}` was not found \
       
    75             within the allocated {timeout_seconds} seconds timeout"
       
    76         );
       
    77         Err(msg)
       
    78     } else {
       
    79         Ok(())
       
    80     }
       
    81 }
       
    82 
       
    83 pub fn debug_wait_for_file_or_print(config: &Config, config_option: &str) {
       
    84     if let Err(e) = debug_wait_for_file(config, config_option) {
       
    85         eprintln!("{e}");
       
    86     };
       
    87 }