diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0385d8cc..94fef458 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,19 @@ jobs: - run: cargo build --workspace - run: cargo test --all-features --workspace + test-i686: + name: Tests (32-bit) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: dtolnay/rust-toolchain@stable + - run: | + sudo apt-get update + sudo apt-get install -y gcc-multilib + - run: rustup target add i686-unknown-linux-gnu + - run: cargo build --workspace --target i686-unknown-linux-gnu + - run: cargo test --all-features --workspace --target i686-unknown-linux-gnu + clippy: name: Clippy runs-on: ubuntu-latest diff --git a/tests/tests.rs b/tests/tests.rs index e8390f86..7d342067 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,6 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 -use pubgrub::{OfflineDependencyProvider, PubGrubError, Ranges, resolve}; +use pubgrub::{ + Dependencies, DependencyProvider, OfflineDependencyProvider, Package, + PackageResolutionStatistics, PubGrubError, Ranges, VersionSet, resolve, +}; +use std::convert::Infallible; type NumVS = Ranges; @@ -50,3 +54,85 @@ fn depend_on_self() { dependency_provider.add_dependencies("a", 66u32, [("a", Ranges::singleton(111u32))]); assert!(resolve(&dependency_provider, "a", 66u32).is_err()); } + +/// Test the prioritization is stable across platforms. +/// +/// https://github.com/pubgrub-rs/pubgrub/issues/373#issuecomment-3384608891 +#[test] +fn same_result_across_platforms() { + struct UnprioritizingDependencyProvider { + dependency_provider: OfflineDependencyProvider, + } + + impl UnprioritizingDependencyProvider { + fn new() -> Self { + Self { + dependency_provider: OfflineDependencyProvider::new(), + } + } + + pub fn add_dependencies>( + &mut self, + package: P, + version: impl Into, + dependencies: I, + ) { + self.dependency_provider + .add_dependencies(package, version, dependencies); + } + } + + impl DependencyProvider for UnprioritizingDependencyProvider { + type P = P; + type V = VS::V; + type VS = VS; + type M = String; + type Priority = u32; + type Err = Infallible; + + fn choose_version(&self, package: &P, range: &VS) -> Result, Infallible> { + self.dependency_provider.choose_version(package, range) + } + + fn prioritize( + &self, + _package: &Self::P, + _range: &Self::VS, + _package_statistics: &PackageResolutionStatistics, + ) -> Self::Priority { + 0 + } + + fn get_dependencies( + &self, + package: &P, + version: &VS::V, + ) -> Result, Infallible> { + self.dependency_provider.get_dependencies(package, version) + } + } + + let mut dependency_provider = UnprioritizingDependencyProvider::<_, NumVS>::new(); + + let x = (0..1000) + .into_iter() + .map(|i| (i.to_string(), Ranges::full())) + .collect::>(); + dependency_provider.add_dependencies("root".to_string(), 1u32, x); + + for i in 0..1000 { + let x = (0..1000) + .into_iter() + .filter(|j| *j != i) + .map(|i| (i.to_string(), Ranges::::singleton(1u32))) + .collect::>(); + dependency_provider.add_dependencies(i.to_string(), 2u32, x); + dependency_provider.add_dependencies(i.to_string(), 1u32, []); + } + + let name = "root".to_string(); + let ver: u32 = 1; + let resolution = resolve(&dependency_provider, name, ver).unwrap(); + let (p, _v) = resolution.into_iter().find(|(_p, v)| *v == 2).unwrap(); + assert_eq!(p, "712".to_string()); +}