From ce3ed53754394aee30821493f80d77c38c956d07 Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Mon, 4 Nov 2024 13:14:31 +0100 Subject: [PATCH] test: root constraint shouldnt crash (#916) This test is triggered by work in `conda-rattler-solver`. For some reason the constraints seem to run into a problem in resolvo where the unsat message runs in to a "unreachable" code path. --------- Co-authored-by: Bas Zalmstra --- Cargo.toml | 2 +- .../src/match_spec/parse.rs | 2 +- ...s__repo_data__test__base_url_packages.snap | 4 +- ...repo_data__test__serialize_packages-2.snap | 45 +++++++++++- ...__repo_data__test__serialize_packages.snap | 41 ++++++++++- .../rattler_networking/src/gcs_middleware.rs | 2 +- crates/rattler_solve/tests/backends.rs | 71 +++++++++++++------ ...ackends__resolvo__panic_on_constraint.snap | 10 +++ .../channels/dummy/linux-64/repodata.json | 44 ++++++++++++ 9 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 crates/rattler_solve/tests/snapshots/backends__resolvo__panic_on_constraint.snap diff --git a/Cargo.toml b/Cargo.toml index 4e7dab1cf..46605ced2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ regex = "1.11.1" reqwest = { version = "0.12.9", default-features = false } reqwest-middleware = "0.3.3" reqwest-retry = "0.6.1" -resolvo = { version = "0.8.2" } +resolvo = { version = "0.8.3" } retry-policies = { version = "0.4.0", default-features = false } rmp-serde = { version = "1.3.0" } rstest = { version = "0.23.0" } diff --git a/crates/rattler_conda_types/src/match_spec/parse.rs b/crates/rattler_conda_types/src/match_spec/parse.rs index 8c5feafbf..b4c39c706 100644 --- a/crates/rattler_conda_types/src/match_spec/parse.rs +++ b/crates/rattler_conda_types/src/match_spec/parse.rs @@ -236,7 +236,7 @@ fn parse_bracket_vec_into_components( let mut seen = HashSet::new(); for (key, _) in &bracket { if seen.contains(key) { - return Err(ParseMatchSpecError::MultipleValueForKey(key.to_string())); + return Err(ParseMatchSpecError::MultipleValueForKey((*key).to_string())); } seen.insert(key); } diff --git a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__base_url_packages.snap b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__base_url_packages.snap index d129494da..aa5c1e207 100644 --- a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__base_url_packages.snap +++ b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__base_url_packages.snap @@ -1,13 +1,14 @@ --- source: crates/rattler_conda_types/src/repo_data/mod.rs -assertion_line: 594 expression: file_urls --- +- channels/dummy/linux-64/xbar-1-xxx.tar.bz2 - channels/dummy/linux-64/issue_717-2.1-bla_1.tar.bz2 - channels/dummy/linux-64/bar-1.0-unix_py36h1af98f8_2.tar.bz2 - channels/dummy/linux-64/foobar-2.0-bla_1.tar.bz2 - channels/dummy/linux-64/foo-3.0.2-py36h1af98f8_1.conda - channels/dummy/linux-64/foo-3.0.2-py36h1af98f8_1.tar.bz2 +- channels/dummy/linux-64/xfoo-2-xxx.tar.bz2 - channels/dummy/linux-64/foo-4.0.2-py36h1af98f8_2.tar.bz2 - channels/dummy/linux-64/foo-3.0.2-py36h1af98f8_3.conda - channels/dummy/linux-64/bors-1.2.1-bla_1.tar.bz2 @@ -18,5 +19,6 @@ expression: file_urls - channels/dummy/linux-64/bors-1.1-bla_1.tar.bz2 - channels/dummy/linux-64/baz-2.0-unix_py36h1af98f8_2.tar.bz2 - channels/dummy/linux-64/foobar-2.1-bla_1.tar.bz2 +- channels/dummy/linux-64/xfoo-1-xxx.tar.bz2 - channels/dummy/linux-64/bors-2.0-bla_1.tar.bz2 - channels/dummy/linux-64/cuda-version-12.5-hd4f0392_3.conda diff --git a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages-2.snap b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages-2.snap index c832f9539..391ff587f 100644 --- a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages-2.snap +++ b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages-2.snap @@ -1,6 +1,5 @@ --- source: crates/rattler_conda_types/src/repo_data/mod.rs -assertion_line: 497 expression: json --- { @@ -263,6 +262,50 @@ expression: json "subdir": "linux-64", "timestamp": 1715610974, "version": "2.1" + }, + "xbar-1-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [ + "xfoo >=2" + ], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xbar", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974, + "version": "1" + }, + "xfoo-1-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xfoo", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974, + "version": "1" + }, + "xfoo-2-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xfoo", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974, + "version": "2" } }, "packages.conda": {}, diff --git a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages.snap b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages.snap index 570ea57e1..7da4158a3 100644 --- a/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages.snap +++ b/crates/rattler_conda_types/src/repo_data/snapshots/rattler_conda_types__repo_data__test__serialize_packages.snap @@ -1,6 +1,5 @@ --- source: crates/rattler_conda_types/src/repo_data/mod.rs -assertion_line: 493 expression: repodata --- info: @@ -238,5 +237,45 @@ packages: subdir: linux-64 timestamp: 1715610974 version: "2.1" + xbar-1-xxx.tar.bz2: + build: xxx + build_number: 0 + depends: + - xfoo >=2 + license: MIT + license_family: MIT + md5: bc13aa58e2092bcb0b97c561373d3905 + name: xbar + sha256: 97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a + size: 414494 + subdir: linux-64 + timestamp: 1715610974 + version: "1" + xfoo-1-xxx.tar.bz2: + build: xxx + build_number: 0 + depends: [] + license: MIT + license_family: MIT + md5: bc13aa58e2092bcb0b97c561373d3905 + name: xfoo + sha256: 97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a + size: 414494 + subdir: linux-64 + timestamp: 1715610974 + version: "1" + xfoo-2-xxx.tar.bz2: + build: xxx + build_number: 0 + depends: [] + license: MIT + license_family: MIT + md5: bc13aa58e2092bcb0b97c561373d3905 + name: xfoo + sha256: 97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a + size: 414494 + subdir: linux-64 + timestamp: 1715610974 + version: "2" packages.conda: {} repodata_version: 2 diff --git a/crates/rattler_networking/src/gcs_middleware.rs b/crates/rattler_networking/src/gcs_middleware.rs index 89b027ed0..9cb9649ac 100644 --- a/crates/rattler_networking/src/gcs_middleware.rs +++ b/crates/rattler_networking/src/gcs_middleware.rs @@ -48,7 +48,7 @@ async fn authenticate_with_google_cloud(mut req: Request) -> MiddlewareResult match provider.token_source().token().await { Ok(token) => { - let bearer_auth = format!("Bearer {}", token); + let bearer_auth = format!("Bearer {token}"); let header_value = reqwest::header::HeaderValue::from_str(&bearer_auth) .map_err(reqwest_middleware::Error::middleware)?; req.headers_mut() diff --git a/crates/rattler_solve/tests/backends.rs b/crates/rattler_solve/tests/backends.rs index fc588273f..6f7deacca 100644 --- a/crates/rattler_solve/tests/backends.rs +++ b/crates/rattler_solve/tests/backends.rs @@ -244,7 +244,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_favored() { let result = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["bors"], installed_packages: vec![installed_package( @@ -267,7 +267,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_with_error() { let result = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foobar >=2", "bors >= 2"], ..SimpleSolveTask::default() @@ -283,7 +283,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_dummy_repo_install_non_existent() { let result = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["asdfasdf", "foo<4"], ..SimpleSolveTask::default() @@ -299,7 +299,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_dummy_repo_missing_virtual_package() { let result = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["bar"], ..SimpleSolveTask::default() @@ -312,7 +312,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_dummy_repo_with_virtual_package() { let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["bar"], virtual_packages: vec![GenericVirtualPackage { @@ -335,7 +335,7 @@ macro_rules! solver_backend_tests { #[test] fn test_solve_dummy_repo_install_new() { let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo<4"], ..SimpleSolveTask::default() @@ -381,7 +381,7 @@ macro_rules! solver_backend_tests { let match_spec = "foo=3.0.2=py36h1af98f8_1"; let operations = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &[match_spec], ..SimpleSolveTask::default() @@ -406,7 +406,7 @@ macro_rules! solver_backend_tests { )]; let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo<4"], installed_packages: already_installed, @@ -435,7 +435,7 @@ macro_rules! solver_backend_tests { )]; let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo>=4"], installed_packages: already_installed, @@ -462,7 +462,7 @@ macro_rules! solver_backend_tests { )]; let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo<4"], installed_packages: already_installed, @@ -491,7 +491,7 @@ macro_rules! solver_backend_tests { )]; let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { installed_packages: already_installed, ..SimpleSolveTask::default() @@ -508,7 +508,7 @@ macro_rules! solver_backend_tests { let date = "2021-12-12T12:12:12Z".parse::>().unwrap(); let pkgs = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo"], exclude_newer: Some(date), @@ -546,7 +546,7 @@ macro_rules! solver_backend_tests { fn test_constraints() { // There following package is provided as .tar.bz and as .conda in repodata.json let mut operations = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foobar"], constraints: vec!["bors <=1", "nonexisting"], @@ -568,7 +568,7 @@ macro_rules! solver_backend_tests { // This tests that a package that has a constrains on a virtual package is // properly restricted. let result = solve::<$T>( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["cuda-version"], virtual_packages: vec![GenericVirtualPackage { @@ -713,7 +713,7 @@ mod resolvo { #[test] fn test_solve_locked() { let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["bors >=2"], pinned_packages: vec![installed_package( @@ -735,7 +735,7 @@ mod resolvo { #[test] fn test_issue_717() { let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["issue_717"], ..SimpleSolveTask::default() @@ -751,7 +751,7 @@ mod resolvo { let date = "2021-12-12T12:12:12Z".parse::>().unwrap(); let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo>=4"], exclude_newer: Some(date), @@ -766,7 +766,7 @@ mod resolvo { #[test] fn test_lowest_version_strategy_highest_build_number() { let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foo"], strategy: rattler_solve::SolveStrategy::LowestVersion, @@ -789,7 +789,7 @@ mod resolvo { #[test] fn test_lowest_version_strategy_all() { let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foobar"], strategy: rattler_solve::SolveStrategy::LowestVersion, @@ -817,7 +817,7 @@ mod resolvo { #[test] fn test_lowest_direct_version_strategy() { let result = solve::( - dummy_channel_json_path(), + &[dummy_channel_json_path()], SimpleSolveTask { specs: &["foobar"], strategy: rattler_solve::SolveStrategy::LowestVersionDirect, @@ -918,6 +918,28 @@ mod resolvo { assert!(matches!(solve_error, SolveError::Unsolvable(_))); } + + #[test] + fn test_panic_on_constraint() { + let result = solve::( + &[dummy_channel_json_path()], + SimpleSolveTask { + specs: &["xbar"], + constraints: vec!["xfoo==1"], + pinned_packages: vec![installed_package( + "conda-forge", + "linux-64", + "xfoo", + "1", + "xxx", + 1, + )], + ..SimpleSolveTask::default() + }, + ); + + insta::assert_snapshot!(result.unwrap_err()); + } } #[derive(Default)] @@ -932,10 +954,13 @@ struct SimpleSolveTask<'a> { } fn solve( - repo_path: String, + repo_path: &[String], task: SimpleSolveTask<'_>, ) -> Result, SolveError> { - let repo_data = read_repodata(&repo_path); + let repo_data = repo_path + .iter() + .map(|path| read_repodata(path)) + .collect::>(); let specs: Vec<_> = task .specs @@ -957,7 +982,7 @@ fn solve( pinned_packages: task.pinned_packages, exclude_newer: task.exclude_newer, strategy: task.strategy, - ..SolverTask::from_iter([&repo_data]) + ..SolverTask::from_iter(&repo_data) }; let pkgs = T::default().solve(task)?; diff --git a/crates/rattler_solve/tests/snapshots/backends__resolvo__panic_on_constraint.snap b/crates/rattler_solve/tests/snapshots/backends__resolvo__panic_on_constraint.snap new file mode 100644 index 000000000..e52ddaeb0 --- /dev/null +++ b/crates/rattler_solve/tests/snapshots/backends__resolvo__panic_on_constraint.snap @@ -0,0 +1,10 @@ +--- +source: crates/rattler_solve/tests/backends.rs +expression: result.unwrap_err() +--- +Cannot solve the request because of: The following packages are incompatible +└─ xbar * can be installed with any of the following options: + └─ xbar 1 would require + └─ xfoo >=2, which can be installed with any of the following options: + └─ xfoo 2 +├─ constraint '==1' cannot be fulfilled diff --git a/test-data/channels/dummy/linux-64/repodata.json b/test-data/channels/dummy/linux-64/repodata.json index edb62f8b3..999ae7286 100644 --- a/test-data/channels/dummy/linux-64/repodata.json +++ b/test-data/channels/dummy/linux-64/repodata.json @@ -261,6 +261,50 @@ "subdir": "linux-64", "timestamp": 1715610974000, "version": "2.1" + }, + "xfoo-1-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xfoo", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974000, + "version": "1" + }, + "xfoo-2-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xfoo", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974000, + "version": "2" + }, + "xbar-1-xxx.tar.bz2": { + "build": "xxx", + "build_number": 0, + "depends": [ + "xfoo >=2" + ], + "license": "MIT", + "license_family": "MIT", + "md5": "bc13aa58e2092bcb0b97c561373d3905", + "name": "xbar", + "sha256": "97ec377d2ad83dfef1194b7aa31b0c9076194e10d995a6e696c9d07dd782b14a", + "size": 414494, + "subdir": "linux-64", + "timestamp": 1715610974000, + "version": "1" } }, "packages.conda": {},