From 67a8a6470ddb8a603db02c5fab84aa225dc00f8d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 24 May 2024 13:42:11 +0200 Subject: solver3: Implement APT::Solver::RemoveManual to allow removing manual packages This is mostly going to be useful for the test suite for now, implement a function there to set it up so we can use it to improve test suite correctness. --- apt-pkg/solver3.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index d43bd5b33..ab66c9501 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -853,6 +853,7 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache) bool KeepAuto = not _config->FindB("APT::Get::AutomaticRemove"); bool AllowRemove = _config->FindB("APT::Solver::Remove", true); bool AllowInstall = _config->FindB("APT::Solver::Install", true); + bool AllowRemoveManual = _config->FindB("APT::Solver::RemoveManual", false); DefaultRootSetFunc2 rootSet(&cache); for (auto P = cache.PkgBegin(); not P.end(); P++) @@ -863,6 +864,8 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache) auto state = depcache[P]; auto maybeInstall = state.Install() || (state.Keep() && P->CurrentVer); auto reject = state.Delete() || (depcache[P].Keep() && not P->CurrentVer && depcache[P].Protect()); + auto isAuto = (depcache[P].Flags & pkgCache::Flag::Auto); + auto isOptional = isAuto || (AllowRemoveManual && not depcache[P].Protect()); if (P->SelectedState == pkgCache::State::Hold && not state.Protect()) { if (unlikely(debug >= 1)) @@ -884,14 +887,14 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache) if (depcache[P].Keep() ? not Install(P, {}) : not Install(depcache.GetCandidateVersion(P), {})) return false; } - else if (maybeInstall && not(depcache[P].Flags & pkgCache::Flag::Auto)) + else if (maybeInstall && not isOptional) { if (unlikely(debug >= 1)) std::cerr << "MANUAL " << P.FullName() << "\n"; if (depcache[P].Keep() ? not Install(P, {}) : not Install(depcache.GetCandidateVersion(P), {})) return false; } - else if (maybeInstall && (KeepAuto || rootSet.InRootSet(P)) && (depcache[P].Flags & pkgCache::Flag::Auto)) + else if (maybeInstall && isOptional && (KeepAuto || rootSet.InRootSet(P) || not isAuto)) { auto Upgrade = depcache.GetCandidateVersion(P) != P.CurrentVer(); if (unlikely(debug >= 1)) -- cgit v1.2.3-70-g09d2 From acb77872861834d3c5b98ca2e81e0336a388e9f0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 May 2024 17:42:34 +0200 Subject: solver3: Try candidate before installed version on upgrade This fixes --no-strict-pinning attempting to upgrade all the versions on the system. Adjust the upgrade test case accordingly: 1) no-strict-pinning pulls in systemd despite it being pinned down due to a dependenc (this was true before this fix) 2) no-strict-pinning does not pull in the upgrade-simple because nothing depends on it (this is what the test fixes) --- apt-pkg/solver3.cc | 11 ++++++-- test/integration/test-apt-get-upgrade | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index ab66c9501..58fb07c01 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -46,8 +46,15 @@ struct CompareProviders3 /*{{{*/ { if (AV == BV) return false; - if (not upgrade && A->CurrentVer != 0 && A.CurrentVer() == AV) - return true; + // The current version should win, unless we are upgrading and the other is the + // candidate. + // If AV is the current version, AV only wins on upgrades if BV is not the candidate. + if (A.CurrentVer() == AV) + return upgrade ? Policy.GetCandidateVer(A) != BV : true; + // If BV is the current version, AV only wins on upgrades if it is the candidate. + if (A.CurrentVer() == BV) + return upgrade ? Policy.GetCandidateVer(A) == AV : false; + // If neither are the current version, order them by priority. if (Policy.GetPriority(AV) < Policy.GetPriority(BV)) return false; diff --git a/test/integration/test-apt-get-upgrade b/test/integration/test-apt-get-upgrade index 9fb2b41d1..c9e56d97d 100755 --- a/test/integration/test-apt-get-upgrade +++ b/test/integration/test-apt-get-upgrade @@ -167,3 +167,54 @@ Conf upgrade-with-conflict (2.0 unstable [all]) Conf new-dep (1.0 stable [all]) Conf upgrade-simple (2.0 unstable [all]) Conf upgrade-with-new-dep (2.0 unstable [all])' aptget -s dist-upgrade + +# --no-strict-pinning pulls in systemd due to the dependency +testsuccessequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +The following packages will be REMOVED: + conflicting-dep +The following NEW packages will be installed: + new-dep systemd +The following packages will be upgraded: + init upgrade-simple upgrade-with-conflict upgrade-with-new-dep +4 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv conflicting-dep [1.0] +Inst systemd (2 unstable [all]) +Conf systemd (2 unstable [all]) +Inst init [1] (2 unstable [all]) +Inst upgrade-with-conflict [1.0] (2.0 unstable [all]) +Inst new-dep (1.0 stable [all]) +Inst upgrade-simple [1.0] (2.0 unstable [all]) +Inst upgrade-with-new-dep [1.0] (2.0 unstable [all]) +Conf init (2 unstable [all]) +Conf upgrade-with-conflict (2.0 unstable [all]) +Conf new-dep (1.0 stable [all]) +Conf upgrade-simple (2.0 unstable [all]) +Conf upgrade-with-new-dep (2.0 unstable [all])' aptget -s dist-upgrade --no-strict-pinning --solver 3.0 + +# --no-strict-pinning does not cause a package to be upgraded on its own, though. +echo 'Package: upgrade-simple +Pin: release unstable +Pin-Priority: -1' > rootdir/etc/apt/preferences.d/no-strict-pinning.pref +testsuccessequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +The following packages will be REMOVED: + conflicting-dep +The following NEW packages will be installed: + new-dep systemd +The following packages will be upgraded: + init upgrade-with-conflict upgrade-with-new-dep +3 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv conflicting-dep [1.0] +Inst systemd (2 unstable [all]) +Conf systemd (2 unstable [all]) +Inst init [1] (2 unstable [all]) +Inst upgrade-with-conflict [1.0] (2.0 unstable [all]) +Inst new-dep (1.0 stable [all]) +Inst upgrade-with-new-dep [1.0] (2.0 unstable [all]) +Conf init (2 unstable [all]) +Conf upgrade-with-conflict (2.0 unstable [all]) +Conf new-dep (1.0 stable [all]) +Conf upgrade-with-new-dep (2.0 unstable [all])' aptget -s dist-upgrade --no-strict-pinning --solver 3.0 -- cgit v1.2.3-70-g09d2 From 0fa3b176652ff10276569a478c910ca866a4da5d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 May 2024 21:24:08 +0200 Subject: solver3: Promote satisfied Suggests to Recommends As per the test-suggests-promoted-to-recommends test. This is still a bit messy as we ignore alternative choices and only check the last one, but um seems useful? --- apt-pkg/solver3.cc | 66 +++++++++++++++++++++---------- test/integration/solver3.broken | 2 - test/integration/test-bug-591882-conkeror | 3 +- 3 files changed, 48 insertions(+), 23 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 58fb07c01..3c4ca4eb7 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -348,8 +348,6 @@ bool APT::Solver::Install(pkgCache::VerIterator Ver, Reason reason) pkgCache::DepIterator end; dep.GlobOr(start, end); // advances dep - if (not policy.IsImportantDep(start)) - continue; if (not EnqueueOrGroup(start, end, Reason(Ver))) return false; } @@ -452,8 +450,6 @@ bool APT::Solver::EnqueueCommonDependencies(pkgCache::PkgIterator Pkg) } if (not allHaveDep) continue; - if (not policy.IsImportantDep(start)) - continue; if (not EnqueueOrGroup(start, end, Reason(Pkg))) return false; } @@ -467,6 +463,11 @@ bool APT::Solver::EnqueueOrGroup(pkgCache::DepIterator start, pkgCache::DepItera auto Ver = start.ParentVer(); auto fixPolicy = _config->FindB("APT::Get::Fix-Policy-Broken"); + // Non-important dependencies can only be installed if they are currently satisfied, see the check further + // below once we have calculated all possible solutions. + if (start.ParentPkg()->CurrentVer == 0 && not policy.IsImportantDep(start)) + return true; + if (unlikely(debug >= 3)) std::cerr << "Found dependency critical " << Ver.ParentPkg().FullName() << "=" << Ver.VerStr() << " -> " << start.TargetPkg().FullName() << "\n"; @@ -513,32 +514,57 @@ bool APT::Solver::EnqueueOrGroup(pkgCache::DepIterator start, pkgCache::DepItera if (not fixPolicy) std::sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, TgtPkg}); - // Figure out if the reason is installed - bool reasonInstalled = false; - if (auto p = workItem.reason.Pkg()) - reasonInstalled = pkgCache::PkgIterator(cache, cache.PkgP + p)->CurrentVer != 0; - else if (auto v = workItem.reason.Ver()) - reasonInstalled = pkgCache::VerIterator(cache, cache.VerP + v).ParentPkg()->CurrentVer != 0; - // Try to perserve satisfied Recommends. FIXME: We should check if the Recommends was there in the installed version? - if (workItem.optional && reasonInstalled && not fixPolicy && - not std::any_of(workItem.solutions.begin(), workItem.solutions.end(), [this](auto ver) - { return pkgCache::VerIterator(cache, ver).ParentPkg()->CurrentVer != 0; })) + if (workItem.optional && start.ParentPkg()->CurrentVer) { - if (unlikely(debug >= 3)) + bool important = policy.IsImportantDep(start); + bool newOptional = true; + bool wasImportant = false; + for (auto D = start.ParentPkg().CurrentVer().DependsList(); not D.end(); D++) + if (not D.IsCritical() && not D.IsNegative() && D.TargetPkg() == start.TargetPkg()) + newOptional = false, wasImportant = policy.IsImportantDep(D); + + bool satisfied = std::any_of(workItem.solutions.begin(), workItem.solutions.end(), [this](auto ver) + { return pkgCache::VerIterator(cache, ver).ParentPkg()->CurrentVer != 0; }); + + if (important && wasImportant && not newOptional && not satisfied) { - std::cerr << "Ignoring currently unsatisfied Recommends "; - workItem.Dump(cache); - std::cerr << "\n"; + if (unlikely(debug >= 3)) + { + std::cerr << "Ignoring unsatisfied Recommends "; + workItem.Dump(cache); + std::cerr << "\n"; + } + return true; + } + if (not important && not wasImportant && not newOptional && satisfied) + { + if (unlikely(debug >= 3)) + { + std::cerr << "Promoting satisfied Suggests to Recommends: "; + workItem.Dump(cache); + std::cerr << "\n"; + } + important = true; + } + if (not important) + { + if (unlikely(debug >= 3)) + { + std::cerr << "Ignoring Suggests "; + workItem.Dump(cache); + std::cerr << "\n"; + } + return true; } - return true; } + if (not workItem.solutions.empty()) { // std::sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, TgtPkg}); if (unlikely(debug >= 3 && workItem.optional)) { - std::cerr << "Enqueuing currently satisfied Recommends "; + std::cerr << "Enqueuing Recommends "; workItem.Dump(cache); std::cerr << "\n"; } diff --git a/test/integration/solver3.broken b/test/integration/solver3.broken index 65e18a7ff..9228e46c8 100644 --- a/test/integration/solver3.broken +++ b/test/integration/solver3.broken @@ -8,7 +8,6 @@ test-apt-move-and-forget-manual-sections test-apt-patterns test-apt-source-and-build-dep test-bug-470115-new-and-tighten-recommends -test-bug-591882-conkeror test-bug-602412-dequote-redirect test-bug-611729-mark-as-manual test-bug-675449-essential-are-protected @@ -29,7 +28,6 @@ test-prevent-markinstall-multiarch-same-versionscrew test-release-candidate-switching test-resolve-by-keep-new-recommends test-resolver-provider-exchange -test-suggests-promoted-to-recommends test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings test-ubuntu-bug-1304403-obsolete-priority-standard test-ubuntu-bug-1990586 diff --git a/test/integration/test-bug-591882-conkeror b/test/integration/test-bug-591882-conkeror index 6b903431a..21c569756 100755 --- a/test/integration/test-bug-591882-conkeror +++ b/test/integration/test-bug-591882-conkeror @@ -4,6 +4,7 @@ set -e TESTDIR="$(readlink -f "$(dirname "$0")")" . "$TESTDIR/framework" setupenvironment +allowremovemanual configarchitecture "i386" setupaptarchive @@ -73,5 +74,5 @@ After this operation, 36.0 MB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." # Test that the old behavior can be restored with the option -testfailureequal "$UPGRADEFAIL" aptget dist-upgrade --trivial-only -o pkgProblemResolver::FixByInstall=0 +testfailureequal "$UPGRADEFAIL" aptget dist-upgrade --trivial-only -o pkgProblemResolver::FixByInstall=0 --solver internal testfailureequal "$UPGRADESUCCESS" aptget dist-upgrade --trivial-only #-o pkgProblemResolver::FixByInstall=0 -- cgit v1.2.3-70-g09d2 From cd245a57f273d3c069543c19d6ac31c84879ce7b Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 20 May 2024 14:59:58 +0200 Subject: solver3: Solve optional dependencies before optional packages This somewhat improves reliability of not breaking Recommends, e.g. if the Recommends gets tightened. One test case enabled by this now is the test-resolver-provider-exchange, which with a simple change to allow removal of automatically installed packages works now. --- apt-pkg/solver3.cc | 2 ++ test/integration/solver3.broken | 1 - test/integration/test-resolver-provider-exchange | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 3c4ca4eb7..216651a97 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -189,6 +189,8 @@ bool APT::Solver::Work::operator<(APT::Solver::Work const &b) const return std::any_of(solutions.begin(), solutions.end(), [b](auto sol) -> bool { return std::find(b.solutions.begin(), b.solutions.end(), sol) != b.solutions.end(); }); } + if (optional && b.optional && reason.empty() != b.reason.empty()) + return reason.empty(); // An optional item is less important than a required one. if (optional != b.optional) return optional; diff --git a/test/integration/solver3.broken b/test/integration/solver3.broken index 9228e46c8..c098b7498 100644 --- a/test/integration/solver3.broken +++ b/test/integration/solver3.broken @@ -27,7 +27,6 @@ test-phased-updates-upgrade test-prevent-markinstall-multiarch-same-versionscrew test-release-candidate-switching test-resolve-by-keep-new-recommends -test-resolver-provider-exchange test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings test-ubuntu-bug-1304403-obsolete-priority-standard test-ubuntu-bug-1990586 diff --git a/test/integration/test-resolver-provider-exchange b/test/integration/test-resolver-provider-exchange index 0a85db34d..45d936978 100755 --- a/test/integration/test-resolver-provider-exchange +++ b/test/integration/test-resolver-provider-exchange @@ -4,6 +4,7 @@ set -e TESTDIR="$(readlink -f "$(dirname "$0")")" . "$TESTDIR/framework" setupenvironment +allowremovemanual configarchitecture 'amd64' insertinstalledpackage 'fuse' 'all' '2' -- cgit v1.2.3-70-g09d2 From 808f51e800a9d6a834723fe1d1fdff98ee14d7b5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 21 May 2024 13:19:41 +0200 Subject: solver3: Use stable sort While it seems that libstdc++ is using stable_sort for sort, we should make this explicit: We don't want items in our queues to move ahead of earlier items of the same priority. i.e. consider dependencies, they are grouped by package, we don't want the sort algorithm to move B=2 ahead if A|B (which expands to A=2|A=1|B=2|B=1). --- apt-pkg/solver3.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 216651a97..e16a02684 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -290,7 +290,7 @@ bool APT::Solver::Install(pkgCache::PkgIterator Pkg, Reason reason) for (auto ver = Pkg.VersionList(); not ver.end(); ver++) if (IsAllowedVersion(ver)) workItem.solutions.push_back(ver); - std::sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, Pkg}); + std::stable_sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, Pkg}); assert(workItem.solutions.size() > 0); if (workItem.solutions.size() > 1 || workItem.optional) @@ -506,7 +506,7 @@ bool APT::Solver::EnqueueOrGroup(pkgCache::DepIterator start, pkgCache::DepItera // FIXME: This is not really true, though, we should fix the CompareProviders to ignore the // installed state if (fixPolicy) - std::sort(workItem.solutions.begin() + begin, workItem.solutions.end(), CompareProviders3{cache, policy, TgtPkg}); + std::stable_sort(workItem.solutions.begin() + begin, workItem.solutions.end(), CompareProviders3{cache, policy, TgtPkg}); if (start == end) break; @@ -514,7 +514,7 @@ bool APT::Solver::EnqueueOrGroup(pkgCache::DepIterator start, pkgCache::DepItera } while (1); if (not fixPolicy) - std::sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, TgtPkg}); + std::stable_sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, TgtPkg}); // Try to perserve satisfied Recommends. FIXME: We should check if the Recommends was there in the installed version? if (workItem.optional && start.ParentPkg()->CurrentVer) @@ -563,7 +563,7 @@ bool APT::Solver::EnqueueOrGroup(pkgCache::DepIterator start, pkgCache::DepItera if (not workItem.solutions.empty()) { - // std::sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, TgtPkg}); + // std::stable_sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, TgtPkg}); if (unlikely(debug >= 3 && workItem.optional)) { std::cerr << "Enqueuing Recommends "; @@ -946,7 +946,7 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache) for (auto V = P.VersionList(); not V.end(); ++V) if (IsAllowedVersion(V)) w.solutions.push_back(V); - std::sort(w.solutions.begin(), w.solutions.end(), CompareProviders3{cache, policy, P}); + std::stable_sort(w.solutions.begin(), w.solutions.end(), CompareProviders3{cache, policy, P}); AddWork(std::move(w)); } } -- cgit v1.2.3-70-g09d2 From aaa9e415ce48964726401462767d6038da6d82e7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 21 May 2024 16:57:56 +0200 Subject: solver3: Actually restore unsolved items rather than solved ones When restoring previously solved items, we try to restore items that have become unsolved again by skipping items that have a solved solution. Well at least we thought we did, but we accidentally had a "not" in there that inverted the meaning, hence we lost work items on backtracking. This mostly did not seem to have caused any issues, I stumbled over it while trying to add `autoremove` listings to `upgrade`, but fixing it also fixes: test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings This used to say "E: Broken packages", meaning the solver lost a non-optional install request and the 2nd stage solver caught an incomplete solution. Also test-bug-735967-lib32-to-i386-unavailable restores the legacy solver behavior, so win win? --- apt-pkg/solver3.cc | 2 +- test/integration/solver3.broken | 1 - test/integration/test-bug-735967-lib32-to-i386-unavailable | 8 +------- 3 files changed, 2 insertions(+), 9 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index e16a02684..d5811423d 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -710,7 +710,7 @@ bool APT::Solver::Pop() if (w.depth > depth) // Deeper decision level is no longer valid. return true; // This item is still solved, keep it on the solved list. - if (not std::any_of(w.solutions.begin(), w.solutions.end(), [this](auto ver) + if (std::any_of(w.solutions.begin(), w.solutions.end(), [this](auto ver) { return (*this)[ver].decision == Decision::MUST; })) return false; // We are not longer solved, move it back to work. diff --git a/test/integration/solver3.broken b/test/integration/solver3.broken index c098b7498..6575b068d 100644 --- a/test/integration/solver3.broken +++ b/test/integration/solver3.broken @@ -27,7 +27,6 @@ test-phased-updates-upgrade test-prevent-markinstall-multiarch-same-versionscrew test-release-candidate-switching test-resolve-by-keep-new-recommends -test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings test-ubuntu-bug-1304403-obsolete-priority-standard test-ubuntu-bug-1990586 test-ubuntu-bug-2025462-phased-dist-upgrade diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable index a44e58570..cc925d161 100755 --- a/test/integration/test-bug-735967-lib32-to-i386-unavailable +++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable @@ -32,12 +32,6 @@ setupaptarchive --no-update configarchitecture 'amd64' testsuccess aptget update -testsuccessequal 'Reading package lists... -Building dependency tree... -Calculating upgrade... -The following packages have been kept back: - lib32nss-mdns libnss-mdns -0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.' aptget dist-upgrade -s --solver 3.0 testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... @@ -48,7 +42,7 @@ The following packages will be upgraded: 1 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. Remv lib32nss-mdns [0.9-1] Inst libnss-mdns [0.9-1] (0.10-6 unstable [amd64]) -Conf libnss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s --solver internal +Conf libnss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s testfailuremsg 'E: Unsatisfiable dependency group libfoo:amd64=1 -> libfoo-bin:amd64' aptget install foo -s --solver 3.0 testfailureequal 'Reading package lists... -- cgit v1.2.3-70-g09d2 From 4a2b89be6fa73b9c193d5b70e11a9305272efc3e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 23 May 2024 13:24:25 +0200 Subject: solver3: Fix translations of removals for marked install We also need to issue a MarkDelete() if the package is marked for installation currently but should not be, not only if it did not have a previous version. This fixes the final test in test-multiarch-barbarian, the others only needed adjustments to mark all packages as automatic. --- apt-pkg/solver3.cc | 2 +- test/integration/solver3.broken | 1 - test/integration/test-multiarch-barbarian | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index d5811423d..9831f7e14 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -987,7 +987,7 @@ bool APT::Solver::ToDepCache(pkgDepCache &depcache) depcache[P].Marked = 1; depcache[P].Garbage = 0; } - else if (P->CurrentVer) + else if (P->CurrentVer || depcache[P].Install()) { depcache.MarkDelete(P, false, 0, (*this)[P].reason.empty()); depcache[P].Marked = 0; diff --git a/test/integration/solver3.broken b/test/integration/solver3.broken index 6575b068d..75ddbe5df 100644 --- a/test/integration/solver3.broken +++ b/test/integration/solver3.broken @@ -20,7 +20,6 @@ test-dont-forget-conflicts-via-unknown-architectures test-explore-or-groups-in-markinstall test-external-dependency-solver-protocol test-method-mirror -test-multiarch-barbarian test-parse-all-archs-into-cache test-phased-updates-new-depends test-phased-updates-upgrade diff --git a/test/integration/test-multiarch-barbarian b/test/integration/test-multiarch-barbarian index 293f22735..b89783473 100755 --- a/test/integration/test-multiarch-barbarian +++ b/test/integration/test-multiarch-barbarian @@ -5,6 +5,7 @@ TESTDIR="$(readlink -f "$(dirname "$0")")" . "$TESTDIR/framework" setupenvironment +allowremovemanual configarchitecture 'amd64' 'i386' buildsimplenativepackage 'foreign-foo' 'amd64,i386' '1' 'stable' 'Multi-Arch: foreign -- cgit v1.2.3-70-g09d2