diff options
-rw-r--r-- | apt-pkg/algorithms.cc | 49 | ||||
-rwxr-xr-x | test/integration/test-resolver-provider-exchange | 107 |
2 files changed, 147 insertions, 9 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index cba772d41..cd09a6944 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -517,18 +517,37 @@ void pkgProblemResolver::MakeScores() Score += PrioInstalledAndNotObsolete; // propagate score points along dependencies - for (pkgCache::DepIterator D = InstVer.DependsList(); D.end() == false; ++D) + for (pkgCache::DepIterator D = InstVer.DependsList(); not D.end(); ++D) { if (DepMap[D->Type] == 0) continue; pkgCache::PkgIterator const T = D.TargetPkg(); - if (D->Version != 0) + if (not D.IsIgnorable(T)) { - pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); - if (IV.end() == true || D.IsSatisfied(IV) == false) + if (D->Version != 0) + { + pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); + if (IV.end() || not D.IsSatisfied(IV)) + continue; + } + Scores[T->ID] += DepMap[D->Type]; + } + + std::vector<map_id_t> providers; + for (auto Prv = T.ProvidesList(); not Prv.end(); ++Prv) + { + if (D.IsIgnorable(Prv)) + continue; + auto const PV = Prv.OwnerVer(); + auto const PP = PV.ParentPkg(); + if (PV != Cache[PP].InstVerIter(Cache) || not D.IsSatisfied(Prv)) continue; + providers.push_back(PP->ID); } - Scores[T->ID] += DepMap[D->Type]; + std::sort(providers.begin(), providers.end()); + providers.erase(std::unique(providers.begin(), providers.end()), providers.end()); + for (auto const prv : providers) + Scores[prv] += DepMap[D->Type]; } } @@ -564,13 +583,25 @@ void pkgProblemResolver::MakeScores() provide important packages extremely important */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; ++P) + auto const transfer = abs(Scores[I->ID] - OldScores[I->ID]); + if (transfer == 0) + continue; + + std::vector<map_id_t> providers; + for (auto Prv = I.ProvidesList(); not Prv.end(); ++Prv) { - // Only do it once per package - if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer) + if (Prv.IsMultiArchImplicit()) + continue; + auto const PV = Prv.OwnerVer(); + auto const PP = PV.ParentPkg(); + if (PV != Cache[PP].InstVerIter(Cache)) continue; - Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]); + providers.push_back(PP->ID); } + std::sort(providers.begin(), providers.end()); + providers.erase(std::unique(providers.begin(), providers.end()), providers.end()); + for (auto const prv : providers) + Scores[prv] += transfer; } /* Protected things are pushed really high up. This number should put them diff --git a/test/integration/test-resolver-provider-exchange b/test/integration/test-resolver-provider-exchange new file mode 100755 index 000000000..3f5310fa6 --- /dev/null +++ b/test/integration/test-resolver-provider-exchange @@ -0,0 +1,107 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" +setupenvironment +configarchitecture 'amd64' + +insertinstalledpackage 'fuse' 'all' '2' +insertpackage 'unstable' 'fuse3' 'all' '3' 'Conflicts: fuse +Provides: fuse' + +insertpackage 'unstable' 'foobar-d' 'all' '1' 'Depends: fuse' +insertpackage 'unstable' 'foobar-d2' 'all' '1' 'Depends: fuse +Conflicts: fuse3' +insertpackage 'unstable' 'foobar-d3' 'all' '1' 'Depends: fuse3' +insertpackage 'unstable' 'foobar-r' 'all' '1' 'Recommends: fuse' +insertpackage 'unstable' 'foobar-r2' 'all' '1' 'Recommends: fuse +Conflicts: fuse3' +insertpackage 'unstable' 'foobar-r3' 'all' '1' 'Recommends: fuse3' + +setupaptarchive + +installfoobars() { + testsuccessequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foobar-d +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Inst foobar-d (1 unstable [all]) +Conf foobar-d (1 unstable [all])' apt install -s foobar-d + testsuccessequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foobar-d2 +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Inst foobar-d2 (1 unstable [all]) +Conf foobar-d2 (1 unstable [all])' apt install -s foobar-d2 + testsuccessequal "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + fuse3 +The following packages will be REMOVED: + fuse +The following NEW packages will be installed: + foobar-d3 fuse3 +0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv fuse [2]$1 +Inst fuse3 (3 unstable [all]) +Inst foobar-d3 (1 unstable [all]) +Conf fuse3 (3 unstable [all]) +Conf foobar-d3 (1 unstable [all])" apt install -s foobar-d3 + + testsuccessequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foobar-r +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Inst foobar-r (1 unstable [all]) +Conf foobar-r (1 unstable [all])' apt install -s foobar-r + testsuccessequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foobar-r2 +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Inst foobar-r2 (1 unstable [all]) +Conf foobar-r2 (1 unstable [all])' apt install -s foobar-r2 + if [ -z "$1" ]; then + testsuccessequal "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + fuse3 +The following packages will be REMOVED: + fuse +The following NEW packages will be installed: + foobar-r3 fuse3 +0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv fuse [2]$1 +Inst foobar-r3 (1 unstable [all]) +Inst fuse3 (3 unstable [all]) +Conf foobar-r3 (1 unstable [all]) +Conf fuse3 (3 unstable [all])" apt install -s foobar-r3 + else + testsuccessequal "Reading package lists... +Building dependency tree... +The following additional packages will be installed: + fuse3 +The following packages will be REMOVED: + fuse +The following NEW packages will be installed: + foobar-r3 fuse3 +0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv fuse [2]$1 +Inst fuse3 (3 unstable [all]) +Inst foobar-r3 (1 unstable [all]) +Conf fuse3 (3 unstable [all]) +Conf foobar-r3 (1 unstable [all])" apt install -s foobar-r3 + fi +} +msgmsg 'fuse has no installed dependers' +installfoobars + +for i in $(seq 0 10); do + insertinstalledpackage "stuff$i" 'all' '1' 'Depends: fuse' +done +msgmsg 'fuse has many dependers installed' +installfoobars ' [stuff10:amd64 stuff0:amd64 stuff1:amd64 stuff2:amd64 stuff3:amd64 stuff4:amd64 stuff5:amd64 stuff6:amd64 stuff7:amd64 stuff8:amd64 stuff9:amd64 ]' |