diff --git a/Cargo.lock b/Cargo.lock index a0f54606ae0..6fdc84aeb21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1903,6 +1903,7 @@ dependencies = [ "fastrand", "gix-features 0.40.0", "gix-utils 0.1.14", + "is_ci", "serde", "tempfile", ] diff --git a/gix-fs/Cargo.toml b/gix-fs/Cargo.toml index ba396c5f25a..a11252b2c52 100644 --- a/gix-fs/Cargo.toml +++ b/gix-fs/Cargo.toml @@ -27,5 +27,6 @@ serde = { version = "1.0.114", optional = true, default-features = false, featur fastrand = { version = "2.1.0", default-features = false, features = ["std"] } [dev-dependencies] -tempfile = "3.5.0" crossbeam-channel = "0.5.0" +is_ci = "1.1.1" +tempfile = "3.5.0" diff --git a/gix-fs/tests/fs/snapshot.rs b/gix-fs/tests/fs/snapshot.rs index d7f4ae91c58..00e0ad2d76e 100644 --- a/gix-fs/tests/fs/snapshot.rs +++ b/gix-fs/tests/fs/snapshot.rs @@ -4,7 +4,7 @@ use std::path::Path; #[test] fn journey() -> Result<(), Box> { let tmp = tempfile::tempdir().unwrap(); - if !has_nanosecond_times(tmp.path())? { + if !has_granular_times(tmp.path())? { return Ok(()); } @@ -41,17 +41,28 @@ fn journey() -> Result<(), Box> { Ok(()) } -fn has_nanosecond_times(root: &Path) -> std::io::Result { - let test_file = root.join("nanosecond-test"); +fn has_granular_times(root: &Path) -> std::io::Result { + let n = 50; - std::fs::write(&test_file, "a")?; - let first_time = test_file.metadata()?.modified()?; - - std::fs::write(&test_file, "b")?; - let second_time = test_file.metadata()?.modified()?; + let paths = (0..n).map(|i| root.join(format!("{i:03}"))); + for (index, path) in paths.clone().enumerate() { + std::fs::write(&path, index.to_string().as_bytes())?; + } + let mut times = Vec::new(); + for path in paths { + times.push(path.symlink_metadata()?.modified()?); + } + times.sort(); + times.dedup(); - Ok(second_time.duration_since(first_time).is_ok_and(|d| - // This can be falsely false if a filesystem would be ridiculously fast, - // which means a test won't run even though it could. But that's OK, and unlikely. - d.subsec_nanos() != 0)) + // This could be wrongly false if a filesystem has very precise timings yet is ridiculously + // fast. Then the `journey` test wouldn't run, though it could. But that's OK, and unlikely. + if cfg!(target_os = "macos") && is_ci::cached() { + assert_eq!( + times.len(), + n, + "should have very granular timestamps at least on macOS on CI" + ); + } + Ok(times.len() == n) }