From 380030bb5c5de02cadda07d78ddcbfd3dc04dcb5 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 19 Nov 2023 07:10:57 -0800 Subject: [PATCH] Pin all resolver tests using `--exclude-newer` (#456) Uses yesterday's date, which should make it much less likely that our tests become stale over time. Closes https://github.com/astral-sh/puffin/issues/449. --- crates/puffin-cli/tests/pip_compile.rs | 79 ++++++++++++ crates/puffin-resolver/tests/resolver.rs | 157 +++++++++++++---------- 2 files changed, 171 insertions(+), 65 deletions(-) diff --git a/crates/puffin-cli/tests/pip_compile.rs b/crates/puffin-cli/tests/pip_compile.rs index deea938ab..fd32339cb 100644 --- a/crates/puffin-cli/tests/pip_compile.rs +++ b/crates/puffin-cli/tests/pip_compile.rs @@ -14,6 +14,9 @@ use common::{BIN_NAME, INSTA_FILTERS}; mod common; +// Exclude any packages uploaded after this date. +static EXCLUDE_NEWER: &str = "2023-11-18T12:00:00Z"; + fn make_venv_py312(temp_dir: &TempDir, cache_dir: &TempDir) -> PathBuf { let venv = temp_dir.child(".venv"); @@ -49,6 +52,8 @@ fn compile_requirements_in() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -121,6 +126,8 @@ dependencies = [ .arg("pyproject.toml") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -151,6 +158,8 @@ fn compile_constraints_txt() -> Result<()> { .arg("constraints.txt") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -180,6 +189,8 @@ fn compile_constraints_inline() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -214,6 +225,8 @@ fn compile_constraints_markers() -> Result<()> { .arg("constraints.txt") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -252,6 +265,8 @@ optional-dependencies.foo = [ .arg("foo") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -290,6 +305,8 @@ optional-dependencies."FrIeNdLy-._.-bArD" = [ .arg("FRiENDlY-...-_-BARd") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -328,6 +345,8 @@ optional-dependencies.foo = [ .arg("bar") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -370,6 +389,8 @@ optional-dependencies.foo = [ .arg("foobar") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -395,6 +416,8 @@ fn compile_requirements_file_extra() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .arg("--all-extras") .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir), @@ -442,6 +465,8 @@ optional-dependencies.foo = [ .arg("invalid name!") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -469,6 +494,8 @@ fn compile_python_312() -> Result<()> { .arg("py312") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -496,6 +523,8 @@ fn compile_python_37() -> Result<()> { .arg("py37") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -535,6 +564,8 @@ fn compile_numpy_py38() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .arg("--no-build") .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir), @r###" @@ -571,6 +602,8 @@ fn compile_wheel_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -596,6 +629,8 @@ fn compile_sdist_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -626,6 +661,8 @@ fn compile_git_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -652,6 +689,8 @@ fn compile_git_branch_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -678,6 +717,8 @@ fn compile_git_tag_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -706,6 +747,8 @@ fn compile_git_long_commit_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -732,6 +775,8 @@ fn compile_git_short_commit_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -759,6 +804,8 @@ fn compile_git_refs_https_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -785,6 +832,8 @@ fn compile_git_subdirectory_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -812,6 +861,8 @@ fn compile_git_concurrent_access() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -839,6 +890,8 @@ fn compile_git_mismatched_name() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -865,6 +918,8 @@ fn mixed_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -891,6 +946,8 @@ fn conflicting_direct_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -917,6 +974,8 @@ fn compatible_direct_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -942,6 +1001,8 @@ fn conflicting_repeated_url_dependency_version_mismatch() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -969,6 +1030,8 @@ fn conflicting_repeated_url_dependency_version_match() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -994,6 +1057,8 @@ fn conflicting_transitive_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1021,6 +1086,8 @@ fn disallowed_transitive_url_dependency() -> Result<()> { .arg("requirements.in") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1053,6 +1120,8 @@ fn allowed_transitive_url_dependency() -> Result<()> { .arg("constraints.txt") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1086,6 +1155,8 @@ fn allowed_transitive_canonical_url_dependency() -> Result<()> { .arg("constraints.txt") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1126,6 +1197,8 @@ optional-dependencies.bar = [ .arg("--all-extras") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1168,6 +1241,8 @@ optional-dependencies.bar = [ .arg("foo") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir), @r###" @@ -1213,6 +1288,8 @@ dependencies = ["django==5.0b1", "django==5.0a1"] .arg("pyproject.toml") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); @@ -1247,6 +1324,8 @@ dependencies = ["django==300.1.4"] .arg("pyproject.toml") .arg("--cache-dir") .arg(cache_dir.path()) + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) .env("VIRTUAL_ENV", venv.as_os_str()) .current_dir(&temp_dir)); }); diff --git a/crates/puffin-resolver/tests/resolver.rs b/crates/puffin-resolver/tests/resolver.rs index 61d36766e..f20a4701d 100644 --- a/crates/puffin-resolver/tests/resolver.rs +++ b/crates/puffin-resolver/tests/resolver.rs @@ -9,6 +9,7 @@ use std::pin::Pin; use std::str::FromStr; use anyhow::Result; +use chrono::{DateTime, Utc}; use once_cell::sync::Lazy; use tempfile::tempdir; @@ -22,6 +23,13 @@ use puffin_resolver::{ }; use puffin_traits::BuildContext; +// Exclude any packages uploaded after this date. +static EXCLUDE_NEWER: Lazy> = Lazy::new(|| { + DateTime::parse_from_rfc3339("2023-11-18T12:00:00Z") + .unwrap() + .with_timezone(&Utc) +}); + struct DummyContext { interpreter_info: InterpreterInfo, } @@ -96,14 +104,13 @@ async fn black() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -120,14 +127,13 @@ async fn black_colorama() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -144,14 +150,13 @@ async fn black_python_310() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_310, - &TAGS_310, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_310, &TAGS_310).await?; insta::assert_display_snapshot!(resolution); @@ -170,14 +175,13 @@ async fn black_mypy_extensions() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -196,14 +200,13 @@ async fn black_mypy_extensions_extra() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -222,14 +225,13 @@ async fn black_flake8() -> Result<()> { vec![], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -246,7 +248,11 @@ async fn black_lowest() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::Lowest, PreReleaseMode::default(), None); + let options = ResolutionOptions::new( + ResolutionMode::Lowest, + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -268,7 +274,7 @@ async fn black_lowest_direct() -> Result<()> { let options = ResolutionOptions::new( ResolutionMode::LowestDirect, PreReleaseMode::default(), - None, + Some(*EXCLUDE_NEWER), ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -288,14 +294,13 @@ async fn black_respect_preference() -> Result<()> { vec![Requirement::from_str("black==23.9.0").unwrap()], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -312,14 +317,13 @@ async fn black_ignore_preference() -> Result<()> { vec![Requirement::from_str("black==23.9.2").unwrap()], None, ); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::default(), + Some(*EXCLUDE_NEWER), + ); - let resolution = resolve( - manifest, - ResolutionOptions::default(), - &MARKERS_311, - &TAGS_311, - ) - .await?; + let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; insta::assert_display_snapshot!(resolution); @@ -336,7 +340,11 @@ async fn black_disallow_prerelease() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::Disallow, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::Disallow, + Some(*EXCLUDE_NEWER), + ); let err = resolve(manifest, options, &MARKERS_311, &TAGS_311) .await @@ -357,8 +365,11 @@ async fn black_allow_prerelease_if_necessary() -> Result<()> { vec![], None, ); - let options = - ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::IfNecessary, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::IfNecessary, + Some(*EXCLUDE_NEWER), + ); let err = resolve(manifest, options, &MARKERS_311, &TAGS_311) .await @@ -379,7 +390,11 @@ async fn pylint_disallow_prerelease() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::Disallow, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::Disallow, + Some(*EXCLUDE_NEWER), + ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -398,7 +413,11 @@ async fn pylint_allow_prerelease() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::Allow, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::Allow, + Some(*EXCLUDE_NEWER), + ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -420,7 +439,11 @@ async fn pylint_allow_explicit_prerelease_without_marker() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::Explicit, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::Explicit, + Some(*EXCLUDE_NEWER), + ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -442,7 +465,11 @@ async fn pylint_allow_explicit_prerelease_with_marker() -> Result<()> { vec![], None, ); - let options = ResolutionOptions::new(ResolutionMode::default(), PreReleaseMode::Explicit, None); + let options = ResolutionOptions::new( + ResolutionMode::default(), + PreReleaseMode::Explicit, + Some(*EXCLUDE_NEWER), + ); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?;