summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2025-06-10 11:47:41 +0200
committerJulian Andres Klode <jak@debian.org>2025-06-10 16:27:36 +0200
commit15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2 (patch)
treeb5bd06dd82dc44e64f16eeb3c98d53d1cfaa0546
parente3d854ebfa62662752cdf68136208f907d0a7cd7 (diff)
solver3: Ignore Architecture: all for obsoleted-by
In case a new version of the source package is published, we check that if there's a newer binary for the same architecture and then consider the binary obsoleted. This logic did not properly account for Architecture: all packages which are considered as native architecture package with an "All" multi-arch flag set, and hence a native architecture package may inadvertently be considered obsoleted by a package that only built on Architecture: all.
-rw-r--r--apt-pkg/solver3.cc4
-rwxr-xr-xtest/integration/test-solver3-obsoleted-by23
2 files changed, 24 insertions, 3 deletions
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc
index a458acb0b..c53911a80 100644
--- a/apt-pkg/solver3.cc
+++ b/apt-pkg/solver3.cc
@@ -499,7 +499,9 @@ bool APT::Solver::ObsoletedByNewerSourceVersion(pkgCache::VerIterator cand) cons
for (auto ver = cand.Cache()->FindGrp(cand.SourcePkgName()).VersionsInSource(); not ver.end(); ver = ver.NextInSource())
{
// We are only interested in other packages in the same source package; built for the same architecture.
- if (ver->ParentPkg == cand->ParentPkg || ver.ParentPkg()->Arch != cand.ParentPkg()->Arch || cache.VS->CmpVersion(ver.SourceVerStr(), cand.SourceVerStr()) <= 0)
+ if (ver->ParentPkg == cand->ParentPkg || ver.ParentPkg()->Arch != cand.ParentPkg()->Arch ||
+ (ver->MultiArch & pkgCache::Version::All) != (cand->MultiArch & pkgCache::Version::All) ||
+ cache.VS->CmpVersion(ver.SourceVerStr(), cand.SourceVerStr()) <= 0)
continue;
// We also take equal priority here, given that we have a higher version
diff --git a/test/integration/test-solver3-obsoleted-by b/test/integration/test-solver3-obsoleted-by
index e5135340c..dda6b61f0 100755
--- a/test/integration/test-solver3-obsoleted-by
+++ b/test/integration/test-solver3-obsoleted-by
@@ -8,7 +8,7 @@ configarchitecture 'amd64'
allowremovemanual
# We need a canary to make it trigger obsolete detection
-insertpackage 'installed' 'canary' 'amd64' '1' 'Depends: good | not-yet-built | obsolete | obsolete-in-experimental | obsolete-reason | obsolete-in-experimental-reason | local-only | current-version | obsolete-in-downgrade | obsolete-in-downgrade-reason'
+insertpackage 'installed' 'canary' 'amd64' '1' 'Depends: good | not-yet-built | not-yet-built-all | obsolete | obsolete-all | obsolete-in-experimental | obsolete-reason | obsolete-all-reason | obsolete-in-experimental-reason | local-only | current-version | obsolete-in-downgrade | obsolete-in-downgrade-reason'
# This package is good, it still exists in the candidate
insertpackage 'installed' 'good' 'amd64' '1' 'Source: good (= 1)'
@@ -18,10 +18,18 @@ insertpackage 'unstable' 'good' 'amd64' '2' 'Source: good (= 2)'
insertpackage 'installed,unstable' 'not-yet-built' 'amd64' '1' 'Source: not-yet-built (= 1)'
insertpackage 'unstable' 'not-yet-built' 'i386' '2' 'Source: not-yet-built (= 2)'
+# not-yet-built is not yet obsolete, because it has only been built on i386
+insertpackage 'installed,unstable' 'not-yet-built-all' 'amd64' '1' 'Source: not-yet-built-all (= 1)'
+insertpackage 'unstable' 'not-yet-built-all' 'all' '2' 'Source: not-yet-built-all (= 2)'
+
# obsolete is obsolete because obsolete-reason has been built on the same arch and is the source candidate
insertpackage 'installed,unstable' 'obsolete' 'amd64' '1' 'Source: obsolete (= 1)'
insertpackage 'unstable' 'obsolete-reason' 'amd64' '2' 'Source: obsolete (= 2)'
+# obsolete is obsolete because obsolete-reason has been built on the same arch and is the source candidate
+insertpackage 'installed,unstable' 'obsolete-all' 'amd64' '1' 'Source: obsolete-all (= 1)'
+insertpackage 'unstable' 'obsolete-all-reason' 'amd64' '2' 'Source: obsolete-all (= 2)'
+
# obsolete-in-experimental is only obsoleted in experimental, so it is not yet considered obsolete
insertpackage 'installed,unstable' 'obsolete-in-experimental' 'amd64' '1' 'Source: obsolete-in-experimental (= 1)'
insertpackage 'experimental' 'obsolete-in-experimental-reason' 'amd64' '2' 'Source: obsolete-in-experimental (= 2)'
@@ -47,20 +55,25 @@ testobsolete() {
}
# Test with manually installed local-only first, it cannot be obsolete
+# We get one obsolete message from the std::any_of check that ignores manual state
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2" aptget dist-upgrade
testsuccess aptmark auto '*'
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade --no-strict-pinning
msgmsg "Pinning the installed version down to experimental level means experimental wins"
printf 'Package: obsolete-in-experimental\nPin: release *\nPin-Priority: 1\n' > rootdir/etc/apt/preferences
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: obsolete-in-experimental:amd64=1 due to obsolete-in-experimental-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: obsolete-in-experimental:amd64=1 due to obsolete-in-experimental-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade --no-strict-pinning
@@ -68,16 +81,20 @@ msgmsg "Testing no-strict-pinning with negative pins on all packages"
printf 'Package: *\nPin: release *\nPin-Priority: -1\n' > rootdir/etc/apt/preferences
testobsolete "Obsolete: not-yet-built:amd64 - not installable
Obsolete: good:amd64 - not installable
+Obsolete: not-yet-built-all:amd64 - not installable
Obsolete: obsolete:amd64 - not installable
+Obsolete: obsolete-all:amd64 - not installable
Obsolete: obsolete-in-experimental:amd64 - not installable
Obsolete: obsolete-reason:amd64 - not installable
-Obsolete: local-only:amd64 - not installable
Obsolete: obsolete-in-experimental-reason:amd64 - not installable
+Obsolete: obsolete-all-reason:amd64 - not installable
+Obsolete: local-only:amd64 - not installable
Obsolete: current-version:amd64 - not installable
Obsolete: obsolete-in-downgrade:amd64 - not installable
Obsolete: obsolete-in-downgrade-reason:amd64 - not installable" aptget dist-upgrade
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: obsolete-in-experimental:amd64=1 due to obsolete-in-experimental-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable
Obsolete: obsolete-in-downgrade-reason:amd64=1 due to obsolete-in-downgrade:amd64=2" aptget dist-upgrade --no-strict-pinning
@@ -87,8 +104,10 @@ msgmsg "Testing that pinning a downgrade does not trigger obsoletes handling"
printf 'Package: downgrade-reason\nPin: release *\nPin-Priority: 1000\n' > rootdir/etc/apt/preferences
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade
testobsolete "Obsolete: obsolete:amd64=1 due to obsolete-reason:amd64=2
+Obsolete: obsolete-all:amd64=1 due to obsolete-all-reason:amd64=2
Obsolete: local-only:amd64=1 - not installable" aptget dist-upgrade --no-strict-pinning