[Yum-devel] [PATCH] Fix bugs in the skip-broken code, this should fix some of the weird cases where skip-broken fails today

Tim Lauridsen tim.lauridsen at gmail.com
Thu Mar 31 08:23:23 UTC 2011


---
 test/skipbroken-tests.py |   76 ++++++++++++++++++++++++++++++++++++++++++++++
 yum/__init__.py          |    5 ++-
 yum/depsolve.py          |    3 ++
 3 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/test/skipbroken-tests.py b/test/skipbroken-tests.py
index 36a4a6d..812785a 100644
--- a/test/skipbroken-tests.py
+++ b/test/skipbroken-tests.py
@@ -733,6 +733,82 @@ class SkipBrokenTests(DepsolveTests):
         members.append(u4)
         self.assertEquals('ok', *self.resolveCode(skip=True))
         self.assertResult(members)
+
+    def test_skipbroken_001(self):
+        ''' 
+        this will pass
+        https://bugzilla.redhat.com/show_bug.cgi?id=656057
+        '''
+        members = []
+        # Installed package conflicts with ux1
+        ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686')
+        ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac')
+        members.append(ix0)
+        ix1 = self.instString('openssl-1.0.0a-2.fc14.i686')
+        ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac")
+        ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686')
+        ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac")
+        self.tsInfo.addUpdate(ux1, oldpo=ix1)
+        members.append(ix1)
+        self.assertEquals('empty', *self.resolveCode(skip=True))
+        self.assertResult(members)
+
+
+    def test_skipbroken_002(self):
+        ''' 
+        this will pass
+        https://bugzilla.redhat.com/show_bug.cgi?id=656057
+        '''
+        members = []
+        # Installed package conflicts with ux1
+        ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686')
+        ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac')
+        members.append(ix0)
+        ix1 = self.instString('openssl-1.0.0a-2.fc14.i686')
+        ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac")
+        ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686')
+        ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac")
+        self.tsInfo.addUpdate(ux1, oldpo=ix1)
+        members.append(ix1)
+        # this is just junk to make the transaction big
+        i1 = self.instString('afoobar-0.4.12-2.fc12.noarch')
+        u1 = self.repoString('afoobar-0.4.14-1.fc14.noarch')
+        self.tsInfo.addUpdate(u1, oldpo=i1)
+        members.append(u1)
+        self.assertEquals('ok', *self.resolveCode(skip=True))
+        self.assertResult(members)
+
+    def test_skipbroken_003(self):
+        ''' 
+        this will fail, because of a bug in the skip-broken code.
+        it will remove the wrong package (zfoobar) instead of openssl.
+        the problem is that self._working_po is not set with the right value
+        when checking file requires for installed packages after the transaction
+        if resolved. (_resolveRequires)
+        if fails because self._working_po contains the last package processed in the transaction
+        zfoobar, so it will be removed.
+        https://bugzilla.redhat.com/show_bug.cgi?id=656057
+        
+        This should not fail anymore, after the the self._working_po is reset in depsolver
+        '''
+        members = []
+        # Installed package conflicts with ux1
+        ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686')
+        ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac')
+        members.append(ix0)
+        ix1 = self.instString('openssl-1.0.0a-2.fc14.i686')
+        ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac")
+        ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686')
+        ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac")
+        self.tsInfo.addUpdate(ux1, oldpo=ix1)
+        members.append(ix1)
+        # this is just junk to make the transaction big
+        i1 = self.instString('zfoobar-0.4.12-2.fc12.noarch')
+        u1 = self.repoString('zfoobar-0.4.14-1.fc14.noarch')
+        self.tsInfo.addUpdate(u1, oldpo=i1)
+        members.append(u1)
+        self.assertEquals('ok', *self.resolveCode(skip=True))
+        self.assertResult(members)
     
     
     def resolveCode(self,skip = False):
diff --git a/yum/__init__.py b/yum/__init__.py
index d1f07d0..4336655 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1125,6 +1125,9 @@ class YumBase(depsolve.Depsolve):
             self.rpmdb.transactionReset()
             self.installedFileRequires = None # Kind of hacky
             self.verbose_logger.debug("SKIPBROKEN: ########### Round %i ################" , count)
+            if count == 30: # Failsafe, to avoid endless looping
+                self.verbose_logger.debug('SKIPBROKEN: Too many loops ')
+                break
             self._printTransaction()        
             depTree = self._buildDepTree()
             startTs = set(self.tsInfo)
@@ -1140,7 +1143,7 @@ class YumBase(depsolve.Depsolve):
                 for skip in skipped:
                     skipped_po.add(skip)
                     # make sure we get the compat arch packages skip from pkgSack and up too.
-                    if skip not in removed_from_sack and skip.repoid == 'installed':
+                    if skip not in removed_from_sack and skip.repoid != 'installed':
                         _remove_from_sack(skip)
             # Nothing was removed, so we still got a problem
              # the first time we get here we reset the resolved members of
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 388811d..44ccfd7 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -350,6 +350,7 @@ class Depsolve(object):
             providers = self.rpmdb.getProvides(needname, needflags, needversion)
 
         for inst_po in providers:
+            self._working_po = inst_po # store the last provider
             inst_str = '%s.%s %s:%s-%s' % inst_po.pkgtup
             (i_n, i_a, i_e, i_v, i_r) = inst_po.pkgtup
             self.verbose_logger.log(logginglevels.DEBUG_2,
@@ -753,6 +754,7 @@ class Depsolve(object):
 
 
             # check global FileRequires
+            self._working_po = None # reset the working po
             if CheckRemoves:
                 CheckRemoves = False
                 for po, dep in self._checkFileRequires():
@@ -766,6 +768,7 @@ class Depsolve(object):
                     continue
 
             # check Conflicts
+            self._working_po = None # reset the working po
             if CheckInstalls:
                 CheckInstalls = False
                 for conflict in self._checkConflicts():
-- 
1.7.4



More information about the Yum-devel mailing list