Show More
@@ -0,0 +1,81 b'' | |||||
|
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 | } |
@@ -9,6 +9,21 b' import time' | |||||
9 | environ = getattr(os, 'environ') |
|
9 | environ = getattr(os, 'environ') | |
10 |
|
10 | |||
11 |
|
11 | |||
|
12 | def wait_on_cfg(ui, cfg, timeout=10): | |||
|
13 | """synchronize on the `cfg` config path | |||
|
14 | ||||
|
15 | Use this to synchronize commands during race tests. | |||
|
16 | """ | |||
|
17 | full_config = b'sync.' + cfg | |||
|
18 | wait_config = full_config + b'-timeout' | |||
|
19 | sync_path = ui.config(b'devel', full_config) | |||
|
20 | if sync_path is not None: | |||
|
21 | timeout = ui.config(b'devel', wait_config) | |||
|
22 | ready_path = sync_path + b'.waiting' | |||
|
23 | write_file(ready_path) | |||
|
24 | wait_file(sync_path, timeout=timeout) | |||
|
25 | ||||
|
26 | ||||
12 | def _timeout_factor(): |
|
27 | def _timeout_factor(): | |
13 | """return the current modification to timeout""" |
|
28 | """return the current modification to timeout""" | |
14 | default = int(environ.get('HGTEST_TIMEOUT_DEFAULT', 360)) |
|
29 | default = int(environ.get('HGTEST_TIMEOUT_DEFAULT', 360)) |
General Comments 0
You need to be logged in to leave comments.
Login now