From 2a1e115ebd86ecd99928c1003b59a6546a386f51 Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Thu, 5 Dec 2024 11:34:54 +0100 Subject: [PATCH] fix: attempt to fix flaky pypi CI for linux (#2651) --- src/install_pypi/plan/test/harness.rs | 6 ++++ src/install_pypi/plan/test/mod.rs | 44 +++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/install_pypi/plan/test/harness.rs b/src/install_pypi/plan/test/harness.rs index e44180a61..b64ee84d5 100644 --- a/src/install_pypi/plan/test/harness.rs +++ b/src/install_pypi/plan/test/harness.rs @@ -190,6 +190,11 @@ impl MockedSitePackages { } } + #[allow(dead_code)] + pub fn base_dir(&self) -> &Path { + self.fake_site_packages.path() + } + /// Create INSTALLER and METADATA files for the installed dist /// these are checked for the installer and requires python fn create_file_backing( @@ -516,6 +521,7 @@ pub fn fake_pyproject_toml( // Set the modification time if it is provided if let Some(modification_time) = modification_time { pyproject_toml.set_modified(modification_time).unwrap(); + pyproject_toml.sync_all().unwrap(); } (temp_dir, pyproject_toml) } diff --git a/src/install_pypi/plan/test/mod.rs b/src/install_pypi/plan/test/mod.rs index a6b48d43e..9c022ffd4 100644 --- a/src/install_pypi/plan/test/mod.rs +++ b/src/install_pypi/plan/test/mod.rs @@ -320,8 +320,7 @@ fn test_local_source_newer_than_local_metadata() { .unwrap(); pyproject.sync_all().unwrap(); - // pyproject.toml file is older than the cache, all else is the same - // so we do not expect a re-installation + // We expect a reinstall, because the pyproject.toml file is newer than the cache let plan = harness::install_planner(); let install_plan = plan .plan(&site_packages, NoCache, &required.to_borrowed()) @@ -332,6 +331,47 @@ fn test_local_source_newer_than_local_metadata() { ); } +#[test] +fn test_local_source_older_than_local_metadata() { + let (fake, pyproject) = harness::fake_pyproject_toml(Some( + std::time::SystemTime::now() - std::time::Duration::from_secs(60 * 60 * 24), + )); + let site_packages = MockedSitePackages::new().add_directory( + "aiofiles", + "0.6.0", + fake.path().to_path_buf(), + false, + // Set the metadata mtime to now explicitly + InstalledDistOptions::default().with_metadata_mtime(std::time::SystemTime::now()), + ); + // Requires following package + let required = RequiredPackages::new().add_directory( + "aiofiles", + "0.6.0", + fake.path().to_path_buf(), + false, + ); + + let dist_info = site_packages + .base_dir() + .join(format!("{}-{}.dist-info", "aiofiles", "0.6.0")) + .join("METADATA"); + // Sanity check that these timestamps are different + assert_ne!( + pyproject.metadata().unwrap().modified().unwrap(), + dist_info.metadata().unwrap().modified().unwrap() + ); + + // Install plan should not reinstall anything + let plan = harness::install_planner(); + let install_plan = plan + .plan(&site_packages, NoCache, &required.to_borrowed()) + .expect("should install"); + assert_eq!(install_plan.reinstalls.len(), 0); + assert_eq!(install_plan.local.len(), 0); + assert_eq!(install_plan.remote.len(), 0); +} + /// When we have an editable package installed and we require a non-editable package /// we should reinstall the non-editable package #[test]