[yum-git] test/depsolvetests.py yum/depsolve.py yum/__init__.py
Seth Vidal
skvidal at linux.duke.edu
Wed Apr 2 21:46:24 UTC 2008
test/depsolvetests.py | 31 ++++++-
yum/__init__.py | 1
yum/depsolve.py | 208 ++++++++++++++++++++++----------------------------
3 files changed, 120 insertions(+), 120 deletions(-)
New commits:
commit 166c85fbaa7e1a6c5fd8324319d30eac370d7ef8
Author: Seth Vidal <skvidal at fedoraproject.org>
Date: Wed Apr 2 17:43:20 2008 -0400
- __init__.py remove bogus print 1 in update()
- depsolve.py replace compare_providers()
- 'fix' arch-specific testcases in depsolvetests.py - we need to have arch be persistent and
probably settable in the config before we can implement a proper fix for this one.
diff --git a/test/depsolvetests.py b/test/depsolvetests.py
index dc11147..17cb537 100644
--- a/test/depsolvetests.py
+++ b/test/depsolvetests.py
@@ -1,5 +1,6 @@
import unittest
from testbase import *
+from rpmUtils import arch
class DepsolveTests(DepsolveTests):
def testEmpty(self):
@@ -606,7 +607,7 @@ class DepsolveTests(DepsolveTests):
(po, po1, po2) = self._setup_CompareProviders(arch='noarch')
self.assertEquals('ok', *self.resolveCode())
- self.assertResult((po, po1))
+ self.assertResult((po,), (po1,po2))
def testCompareProvidersSameLen2_64(self):
# Make sure they are still ok, the other way around
@@ -638,10 +639,16 @@ class DepsolveTests(DepsolveTests):
self.xsack.addPackage(po1)
self.assertEquals('ok', *self.resolveCode())
- self.assertResult((po, po1))
+ self.assertResult((po,), (po1,po2))
def testCompareProvidersSameLen2_noarch_to_64_1(self):
# Make sure they are still ok, the other way around
+ myarch = arch.getBaseArch(arch.getCanonArch())
+
+ if myarch not in ('i386', 'x86_64'):
+ return
+
+
po = FakePackage('abcd', arch='noarch')
po.addRequires('libxyz-1.so.0', None, (None, None, None))
self.tsInfo.addInstall(po)
@@ -654,10 +661,20 @@ class DepsolveTests(DepsolveTests):
self.xsack.addPackage(po1)
self.assertEquals('ok', *self.resolveCode())
- self.assertResult((po, po1))
+ if myarch == 'i386':
+ self.assertResult((po, po2))
+
+ if myarch == 'x86_64':
+ self.assertResult((po, po1))
+
def testCompareProvidersSameLen2_noarch_to_64_2(self):
# Make sure they are still ok, the other way around
+ myarch = arch.getBaseArch(arch.getCanonArch())
+
+ if myarch not in ('i386', 'x86_64'):
+ return
+
po = FakePackage('abcd', arch='noarch')
po.addRequires('libxyz-1.so.0', None, (None, None, None))
self.tsInfo.addInstall(po)
@@ -668,9 +685,13 @@ class DepsolveTests(DepsolveTests):
po1 = FakePackage('libfoo', arch='i386')
po1.addProvides('libxyz-1.so.0', None,(None,None,None))
self.xsack.addPackage(po1)
-
+
self.assertEquals('ok', *self.resolveCode())
- self.assertResult((po, po2))
+ if myarch == 'x86_64':
+ self.assertResult((po, po2))
+ if myarch == 'i386':
+ self.assertResult((po, po1))
+
def testCompareProvidersDiffLen_64(self):
(po, po1, po2) = self._setup_CompareProviders(name='libbarf')
diff --git a/yum/__init__.py b/yum/__init__.py
index 8d97b0e..510968b 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2327,7 +2327,6 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.log(logginglevels.DEBUG_2, _('Not Updating Package that is already obsoleted: %s.%s %s:%s-%s'),
installed_pkg.pkgtup)
else:
- print 1
txmbr = self.tsInfo.addUpdate(updating_pkg, installed_pkg)
if requiringPo:
txmbr.setAsDep(requiringPo)
diff --git a/yum/depsolve.py b/yum/depsolve.py
index d1b2272..8a707bd 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -25,7 +25,7 @@ import logging
import rpmUtils.transaction
import rpmUtils.miscutils
import rpmUtils.arch
-from rpmUtils.arch import archDifference, isMultiLibArch
+from rpmUtils.arch import archDifference, isMultiLibArch, getCanonArch
import misc
from misc import unique, version_tuple_to_string
import rpm
@@ -38,6 +38,7 @@ import Errors
from i18n import _
import warnings
warnings.simplefilter("ignore", Errors.YumFutureDeprecationWarning)
+from operator import itemgetter
try:
assert max(2, 4) == 4
@@ -502,19 +503,9 @@ class Depsolve(object):
newest = provSack.returnNewestByNameArch()
if len(newest) > 1: # there's no way this can be zero
- best = newest[0]
- old_best = None
- loop_run = 0
- while best != old_best:
- if loop_run >= len(newest)*2:
- msg = _('Failure finding best provider of %s for %s, exceeded maximum loop length' % (needname, requiringPo))
- errorlist.append(msg)
- self.verbose_logger.debug(msg)
- break
- loop_run += 1
- old_best = best
- best = self._compare_providers(newest, best, requiringPo)
-
+ pkgresults = self._compare_providers(newest, requiringPo)
+ # take the first one...
+ best = pkgresults[0][0]
elif len(newest) == 1:
best = newest[0]
@@ -913,14 +904,20 @@ class Depsolve(object):
return installed
_isPackageInstalled = isPackageInstalled
- def _compare_providers(self, pkgs, bestpkg, reqpo):
+ def _compare_providers(self, pkgs, reqpo):
+ """take the list of pkgs and score them based on the requesting package
+ return a dictionary of po=score"""
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _("Running compare_providers() for %s") %(str(pkgs)))
+
def _common_prefix_len(x, y, minlen=2):
num = min(len(x), len(y))
for off in range(num):
if x[off] != y[off]:
return max(off, minlen)
return max(num, minlen)
+
def _common_sourcerpm(x, y):
if not hasattr(x, 'sourcerpm'):
return False
@@ -928,116 +925,99 @@ class Depsolve(object):
return False
return x.sourcerpm == y.sourcerpm
- for po in pkgs:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("Comparing best: %s to po: %s") %(bestpkg, po))
+ def _compare_arch_distance(x, y, req_compare_arch):
+ # take X and Y package objects
+ # determine which has a closer archdistance to compare_arch
+ # if they are equal to compare_arch, compare which is closer to the
+ # running arch
+ # return the package which is closer or None for equal, or equally useless
+
+ x_dist = archDifference(req_compare_arch, x.arch)
+ if isMultiLibArch(): # only go to the next one if we're multilib -
+ if x_dist == 0: # can't really use best's arch anyway...
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _("better arch in po %s") %(y))
+ return y # just try the next one - can't be much worse
- if po == bestpkg: # if we're comparing the same one, skip it
+ y_dist = archDifference(req_compare_arch, y.arch)
+ if y_dist > 0 and x_dist > y_dist:
self.verbose_logger.log(logginglevels.DEBUG_4,
- _("Same: best %s == po: %s") %(bestpkg, po))
+ _("better arch in po %s") %(y))
- continue
- # if best is obsoleted by any of the packages, then the obsoleter
- # is the new best
- for obs in po.obsoletes:
- if bestpkg.inPrcoRange('provides', obs):
- # make sure the best doesn't obsolete this po - if it does we're done
- # we do this b/c it is possible for two entries to oscillate in this
- # test - obsolete should trump no matter what
- # NOTE: mutually obsoleting providers is completely and utterly doom
- # but this should 'break the loop'
- for obs in bestpkg.obsoletes:
- if po.inPrcoRange('provides', obs):
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("best %s obsoletes po: %s") %(bestpkg, po))
- return bestpkg
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s obsoletes best: %s") %(po, bestpkg))
-
- return po
+ return y
+ if y_dist == x_dist:
+ return None
+ return x
+
+ pkgresults = {}
- # just check if best obsoletes po
- for obs in bestpkg.obsoletes:
- if po.inPrcoRange('provides', obs):
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("best %s obsoletes po: %s") %(bestpkg, po))
- return bestpkg
+ for pkg in pkgs:
+ pkgresults[pkg] = 0
+
+ # go through each pkg and compare to others
+ # if it is same skip it
+ # if the pkg is obsoleted by any other of the packages
+ # then add -1024 to its score
+ # don't need to look for mutual obsoletes b/c each package
+ # is evaluated against all the others, so mutually obsoleting
+ # packages will have their scores diminished equally
+
+ # compare the arch vs each other pkg
+ # give each time it returns with a better arch a +5
-
- if reqpo.arch != 'noarch':
- best_dist = archDifference(reqpo.arch, bestpkg.arch)
- if isMultiLibArch(): # only go to the next one if we're multilib - i686 can satisfy i386 deps
- if best_dist == 0: # can't really use best's arch anyway...
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("better arch in po %s") %(po))
- return po # just try the next one - can't be much worse
+ # look for common source vs the reqpo - give a +10 if it has it
-
- po_dist = archDifference(reqpo.arch, po.arch)
- if po_dist > 0 and best_dist > po_dist:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("better arch in po %s") %(po))
-
- return po
-
- if best_dist == po_dist:
- csp = _common_sourcerpm(reqpo, po)
- csb = _common_sourcerpm(reqpo, bestpkg)
- if not csb and csp:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s shares a sourcerpm with %s") %(po, reqpo))
- return po
- if csb and not csp:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("best %s shares a sourcerpm with %s") %(bestpkg, reqpo))
- return bestpkg
-
- cplp = _common_prefix_len(reqpo.name, po.name)
- cplb = _common_prefix_len(reqpo.name, bestpkg.name)
- if cplp > cplb:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s shares more of the name prefix with %s") %(po, reqpo))
- return po
- if cplp == cplb and len(po.name) < len(bestpkg.name):
+ # look for common_prefix_len - add the length*2 to the score
+
+ # add the negative of the length of the name to the score
+
+ for po in pkgs:
+ for nextpo in pkgs:
+ if po == nextpo:
+ continue
+ obsoleted = False
+ for obs in nextpo.obsoletes:
+ if po.inPrcoRange('provides', obs):
+ obsoleted = True
+
self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s has a shorter name than best %s") %(po, bestpkg))
- return po
+ _("%s obsoletes %s") % (po, nextpo))
- # reqpo.arch == "noarch"
- elif (not _common_sourcerpm(reqpo, bestpkg) and
- _common_sourcerpm(reqpo, po)):
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s shares a sourcerpm with %s") %(po, reqpo))
- return po
- elif (_common_sourcerpm(reqpo, bestpkg) and
- not _common_sourcerpm(reqpo, po)):
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("best %s shares a sourcerpm with %s") %(bestpkg,reqpo))
- return bestpkg
- elif (_common_prefix_len(reqpo.name, po.name) >
- _common_prefix_len(reqpo.name, bestpkg.name)):
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s shares more of the name prefix with %s") %(po, reqpo))
- return po
- elif (_common_prefix_len(reqpo.name, po.name) <
- _common_prefix_len(reqpo.name, bestpkg.name)):
+ if obsoleted:
+ pkgresults[po] -= 1024
+ break
+
+ for thisarch in (reqpo.arch, getCanonArch()):
+ res = _compare_arch_distance(po, nextpo, thisarch)
+ if not res:
+ continue
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _('archdist compared %s to %s on %s\n Winner: %s' % (po, nextpo, thisarch, res)))
+
+ if res == po:
+ pkgresults[po] += 5
+
+ if _common_sourcerpm(po, reqpo):
self.verbose_logger.log(logginglevels.DEBUG_4,
- _("bestpkg %s shares more of the name prefix with %s") %(bestpkg, reqpo))
- return bestpkg
- elif len(po.name) < len(bestpkg.name):
+ _('common sourcerpm %s and %s' % (po, reqpo)))
+ pkgresults[po] += 20
+
+ cpl = _common_prefix_len(po.name, reqpo.name)
+ if cpl > 2:
self.verbose_logger.log(logginglevels.DEBUG_4,
- _("po %s has a shorter name than best %s") %(po, bestpkg))
- return po
- elif len(po.name) == len(bestpkg.name):
- # compare arch
- arch = rpmUtils.arch.getBestArchFromList([po.arch, bestpkg.arch])
- if arch == po.arch and arch != bestpkg.arch:
- self.verbose_logger.log(logginglevels.DEBUG_4,
- _("better arch in po %s") %(po))
- return po
+ _('common prefix of %s between %s and %s' % (cpl, po, reqpo)))
+
+ pkgresults[po] += cpl*2
+
+ pkgresults[po] += (len(po.name)*-1)
+
+ bestorder = sorted(pkgresults.items(), key=itemgetter(1), reverse=True)
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _('Best Order: %s' % str(bestorder)))
- # Nothing else was better, so this is it
- return bestpkg
+ return bestorder
+
+
class DepCheck(object):
More information about the Yum-cvs-commits
mailing list