[Yum-devel] [RFC PATCH] add depsolver unit tests
James Bowes
jbowes at redhat.com
Tue Jun 5 00:54:10 UTC 2007
---
Here's a first cut at unit tests for the logic in depsolve.
A few points:
* I'm trying to keep things focused on the depsolver. As a result,
other complex bits (the rpmsack, sqlite code) is replaced with fake
objects.
* The above point means that a fair bit of logic will be duplicated.
Hopefully the code in here will be simple enough that this won't
matter.
* Rather than reimplementing some parts of YumBase, I figured they
mayaswell be moved to Depsolve (see isPackageInstalled)
Feedback is appriciated. More test cases are even more appriciated.
-James
test/alltests.py | 2 +
test/depsolvetests.py | 151 +++++++++++++++++++++++++++++++++++++++++++++++++
yum/__init__.py | 16 -----
yum/depsolve.py | 19 ++++++-
4 files changed, 171 insertions(+), 17 deletions(-)
create mode 100644 test/depsolvetests.py
diff --git a/test/alltests.py b/test/alltests.py
index 66eb0ec..90f8e12 100644
--- a/test/alltests.py
+++ b/test/alltests.py
@@ -1,12 +1,14 @@
import unittest
import settestpath
+import depsolvetests
import packagetests
def suite():
# Append all test suites here:
return unittest.TestSuite((
+ depsolvetests.suite(),
packagetests.suite(),
))
diff --git a/test/depsolvetests.py b/test/depsolvetests.py
new file mode 100644
index 0000000..ab4fe18
--- /dev/null
+++ b/test/depsolvetests.py
@@ -0,0 +1,151 @@
+import unittest
+import settestpath
+
+from yum import depsolve
+from yum import transactioninfo
+from yum import packages
+from yum import packageSack
+
+
+class FakeConf(object):
+
+ def __init__(self):
+ self.installonlypkgs = []
+
+
+class FakeRepo(object):
+
+ def __init__(self):
+ self.id = None
+
+
+class FakePackage(packages.PackageObject, packages.RpmBase):
+
+ def __init__(self, name, version, release, epoch, arch):
+ packages.PackageObject.__init__(self)
+ packages.RpmBase.__init__(self)
+
+ self.name = name
+ self.version = version
+ self.ver = version
+ self.release = release
+ self.rel = release
+ self.epoch = epoch
+ self.arch = arch
+
+ self.prco['provides'].append((name, '=', (epoch, version, release)))
+
+ self.repo = FakeRepo()
+ self.repoid = None
+
+ def addRequires(self, name, flag, evr):
+ self.prco['requires'].append((name, flag, evr))
+
+
+class FakeRpmDb(object):
+
+ def __init__(self):
+ self.packages = []
+
+ def addPackage(self, po):
+ self.packages.append(po)
+
+ def whatProvides(self, name, flag, evr):
+ results = []
+ for package in self.packages:
+ if package.checkPrco('provides', (name, flag, evr)):
+ results.append(package.pkgtup)
+ return results
+
+ def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
+ # Create a match closure for what is being searched for
+ lookfor = [] # A list of (search_name, search_value)
+ loc = locals()
+ for arg in ('name', 'arch', 'epoch', 'ver', 'rel'):
+ val = loc[arg]
+ if val != None:
+ lookfor.append((arg, val))
+
+ ret = []
+ for package in self.packages:
+ ok = True
+ for name, val in lookfor:
+ if getattr(package, name) != val:
+ ok = False
+ break
+ if ok:
+ ret.append(package)
+ return ret
+
+ def installed(self, name):
+ for package in self.packages:
+ if package.name == name:
+ return True
+ return False
+
+class TestingDepsolve(depsolve.Depsolve):
+
+ def getInstalledPackageObject(self, pkgtup):
+ return self.rpmdb.searchNevra(pkgtup[0], pkgtup[2], pkgtup[3],
+ pkgtup[4], pkgtup[1])[0]
+
+
+def build_depsolver(tsInfo, rpmdb=FakeRpmDb(),
+ pkgSack=packageSack.PackageSack()):
+ solver = TestingDepsolve()
+ solver.conf = FakeConf()
+ solver.tsInfo = tsInfo
+ solver.rpmdb = rpmdb
+ solver.pkgSack = pkgSack
+ return solver
+
+
+class DepsolveTests(unittest.TestCase):
+
+ def testInstallSinglePackageNoRequires(self):
+ po = FakePackage('zsh', '1', '1', None, 'i386')
+
+ tsInfo = transactioninfo.TransactionData()
+ tsInfo.addInstall(po)
+
+ solver = build_depsolver(tsInfo)
+
+ res = solver.resolveDeps()
+ self.assertEquals(2, res[0])
+
+ def testInstallSinglePackageRequireNotProvided(self):
+ po = FakePackage('zsh', '1', '1', None, 'i386')
+ po.addRequires('zip', None, (None, None, None))
+
+ tsInfo = transactioninfo.TransactionData()
+ tsInfo.addInstall(po)
+
+ solver = build_depsolver(tsInfo)
+
+ res = solver.resolveDeps()
+ self.assertEquals(1, res[0])
+
+ def testInstallSinglePackageRequireInstalled(self):
+ po = FakePackage('zsh', '1', '1', None, 'i386')
+ po.addRequires('zip', None, (None, None, None))
+
+ tsInfo = transactioninfo.TransactionData()
+ tsInfo.addInstall(po)
+
+ installedpo = FakePackage('zip', '1', '1', None, 'i386')
+ rpmdb = FakeRpmDb()
+ rpmdb.addPackage(installedpo)
+
+ solver = build_depsolver(tsInfo, rpmdb)
+
+ res = solver.resolveDeps()
+ self.assertEquals(2, res[0])
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(DepsolveTests))
+ return suite
+
+if __name__ == "__main__":
+ unittest.main(defaultTest="suite")
diff --git a/yum/__init__.py b/yum/__init__.py
index 555f750..37f841b 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1975,22 +1975,6 @@ class YumBase(depsolve.Depsolve):
return returndict
- def isPackageInstalled(self, pkgname):
- installed = False
- if self.rpmdb.installed(name = pkgname):
- installed = True
-
- lst = self.tsInfo.matchNaevr(name = pkgname)
- for txmbr in lst:
- if txmbr.output_state in TS_INSTALL_STATES:
- return True
- if installed and len(lst) > 0:
- # if we get here, then it was installed, but it's in the tsInfo
- # for an erase or obsoleted --> not going to be installed at end
- return False
- return installed
- _isPackageInstalled = isPackageInstalled
-
def getKeyForPackage(self, po, askcb = None, fullaskcb = None):
"""Retrieve a key for a package. If needed, prompt for if the
key should be imported using askcb.
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 59cd9b4..7e7583e 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -1168,7 +1168,24 @@ class Depsolve(object):
removeList.append(instpo)
self._removing.append(instpo.pkgtup)
return removeList
-
+
+ def isPackageInstalled(self, pkgname):
+ installed = False
+ if self.rpmdb.installed(name = pkgname):
+ installed = True
+
+ lst = self.tsInfo.matchNaevr(name = pkgname)
+ for txmbr in lst:
+ if txmbr.output_state in TS_INSTALL_STATES:
+ return True
+ if installed and len(lst) > 0:
+ # if we get here, then it was installed, but it's in the tsInfo
+ # for an erase or obsoleted --> not going to be installed at end
+ return False
+ return installed
+ _isPackageInstalled = isPackageInstalled
+
+
class DepCheck(object):
"""object that YumDepsolver uses to see what things are needed to close
the transaction set. attributes: requires, conflicts are a list of
--
1.5.2.1.844.g7cda
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.baseurl.org/pipermail/yum-devel/attachments/20070604/82e7de0f/attachment.pgp
More information about the Yum-devel
mailing list