summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2013-12-05 11:04:12 +0100
committerMichal Minar <miminar@redhat.com>2013-12-12 15:04:10 +0100
commitc5671a8b538c64acc4083a5c044c9dd99dfb6184 (patch)
tree806456e4d175a781ed0a09d06b0bda4e01394384 /src
parentb7387a18343cc00d0465b734b85a9bdc2204f34c (diff)
downloadopenlmi-providers-c5671a8b538c64acc4083a5c044c9dd99dfb6184.tar.gz
openlmi-providers-c5671a8b538c64acc4083a5c044c9dd99dfb6184.tar.xz
openlmi-providers-c5671a8b538c64acc4083a5c044c9dd99dfb6184.zip
software: test improvements
Speeded up test initialization and cleanup. Use as few calls to subprocesses as possible.
Diffstat (limited to 'src')
-rw-r--r--src/software/test/package.py94
-rw-r--r--src/software/test/repository.py17
-rw-r--r--src/software/test/swbase.py72
-rw-r--r--src/software/test/test_software_identity.py17
-rw-r--r--src/software/test/test_software_identity_file_check.py2
-rw-r--r--src/software/test/test_software_identity_resource.py6
-rw-r--r--src/software/test/util.py26
7 files changed, 156 insertions, 78 deletions
diff --git a/src/software/test/package.py b/src/software/test/package.py
index 500f8b5..c4b7dfa 100644
--- a/src/software/test/package.py
+++ b/src/software/test/package.py
@@ -21,10 +21,14 @@
Abstraction for RPM package for test purposes.
"""
+import re
import subprocess
import util
+RE_NOT_INSTALLED = re.compile(r'package\s+([^[:space:]]+)\s+is not installed',
+ re.IGNORECASE)
+
class Package(object):
"""
Element of test package database. It's a container for package
@@ -171,8 +175,7 @@ def is_pkg_installed(pkg):
if not isinstance(pkg, Package):
return subprocess.call(["rpm", "--quiet", "-q", pkg]) == 0
else:
- cmd = [ "rpm", "-q", "--qf", "%{EPOCH}:%{NVRA}\n", pkg.get_nevra(
- with_epoch='NEVER') ]
+ cmd = ["/usr/bin/rpm", "-q", "--qf", "%{EPOCH}:%{NVRA}\n", pkg.nevra]
try:
out = subprocess.check_output(cmd).splitlines()[0]
epoch, _ = out.split(':')
@@ -182,7 +185,58 @@ def is_pkg_installed(pkg):
except subprocess.CalledProcessError:
return False
-def remove_pkg(pkg, *args):
+def filter_installed_packages(pkgs, installed=True):
+ """
+ Filter the package set returning only installed or not installed packages.
+
+ :param list pkgs: Packages to filter. If removed packages are requested
+ only Package objects may be present, otherwise package names or nevra
+ strings are allowed.
+ :param boolean installed: Whether to return installed or uninstalled
+ packages.
+ :returns: Filtered packages. Nevra strings are returned for any installed
+ packages from *pkgs* represented by strings (either by name or nevra),
+ package objects will be returned as package objects.
+ :rtype: set
+ """
+ if len(pkgs) < 1:
+ return set()
+ pkg_strings = []
+ pkg_map = {}
+ for pkg in pkgs:
+ if isinstance(pkg, Package):
+ pkg_map[pkg.nevra] = pkg
+ pkg = pkg.nevra
+ elif not installed:
+ raise TypeError("packages must be objects of Package")
+ pkg_strings.append(pkg)
+ cmd = [ "/usr/bin/rpm", "-q", "--qf"
+ , "%{NAME}-%{EPOCH}:%{VERSION}-%{RELEASE}.%{ARCH}\n"]
+ cmd.extend(pkg_strings)
+ process = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE, stderr=util.DEV_NULL)
+ out, _ = process.communicate()
+ if installed:
+ result = set()
+ for line in out.splitlines():
+ if not util.RE_NEVRA.match(line):
+ continue
+ if line in result:
+ continue
+ result.add(pkg_map.get(line, line))
+ else:
+ result = set(pkg_strings)
+ for match in RE_NOT_INSTALLED.finditer(out):
+ if match.group(1) not in pkg_strings:
+ raise ValueError('got unexpected package nevra "%s" which'
+ ' should be one of: %s'
+ % (match.group(1), str(pkg_strings)))
+ pkg_strings.remove(match.group(1))
+ result.remove(result)
+ result = {pkg_map.get(pstr, pstr) for pstr in result}
+ return result
+
+def remove_pkgs(pkgs, *args):
"""
Remove package with rpm command.
@@ -191,21 +245,35 @@ def remove_pkg(pkg, *args):
version must be installed for command to be successful.
:param list args: List of parameters for rpm command.
"""
- cmd = ["rpm", "--quiet"] + list(args)
- if isinstance(pkg, Package):
- cmd.extend(["-e", pkg.get_nevra()])
- else:
- cmd.extend(["-e", pkg])
- subprocess.call(cmd)
+ cmd = ["rpm", "--quiet"] + list(args) + ['-e']
+ if isinstance(pkgs, (basestring, Package)):
+ pkgs = [pkgs]
+ pkg_strings = []
+ for pkg in pkgs:
+ if isinstance(pkg, Package):
+ pkg_strings.append(pkg.nevra)
+ else:
+ pkg_strings.append(pkg)
+ if len(pkg_strings) > 0:
+ cmd.extend(pkg_strings)
+ subprocess.call(cmd)
-def install_pkg(pkg):
+def install_pkgs(pkgs, *args):
"""
Install a specific package.
:param pkg: Package object.
:type pkg: :py:class:`Package`
"""
- if not isinstance(pkg, Package):
- raise TypeError("pkg must be a Package instance")
- subprocess.call(["rpm", "--quiet", "-i", pkg.rpm_path])
+ cmd = ["rpm", "--quiet"] + list(args) + ["-i"]
+ if isinstance(pkgs, Package):
+ pkgs = [pkgs]
+ pkg_paths = []
+ for pkg in pkgs:
+ if not isinstance(pkg, Package):
+ raise TypeError("pkg must be a Package instance")
+ pkg_paths.append(pkg.rpm_path)
+ if len(pkg_paths) > 0:
+ cmd.extend(pkg_paths)
+ subprocess.call(cmd)
diff --git a/src/software/test/repository.py b/src/software/test/repository.py
index cf80385..fce1707 100644
--- a/src/software/test/repository.py
+++ b/src/software/test/repository.py
@@ -376,15 +376,22 @@ def is_repo_enabled(repo):
match = RE_REPO_ENABLED.search(out)
return bool(match) and match.group(1).lower() in {"true", "yes", "1"}
-def set_repo_enabled(repo, enable):
+def set_repos_enabled(repos, enable=True):
"""
Enables or disables repository in its configuration file.
:param repo: Eiether a repository id or instance of :py:class:`Repository`.
:param boolean enable: New state of repository.
"""
- if isinstance(repo, Repository):
- repo = repo.repoid
- cmd = ["yum-config-manager", "--enable" if enable else "--disable", repo]
- call(cmd, stdout=util.DEV_NULL, stderr=util.DEV_NULL)
+ cmd = ["yum-config-manager", "--enable" if enable else "--disable"]
+ repoids = []
+ if isinstance(repos, (basestring, Repository)):
+ repos = [repos]
+ for repo in repos:
+ if isinstance(repo, Repository):
+ repo = repo.repoid
+ repoids.append(repo)
+ if len(repoids) > 0:
+ cmd.extend(repoids)
+ call(cmd, stdout=util.DEV_NULL, stderr=util.DEV_NULL)
diff --git a/src/software/test/swbase.py b/src/software/test/swbase.py
index ccf2b78..8ef4b3b 100644
--- a/src/software/test/swbase.py
+++ b/src/software/test/swbase.py
@@ -64,14 +64,22 @@ def test_with_repos(*enable_repos, **repos_dict):
to_enable.update(
set(reposetup.full_repo_name(r)
for r, v in repos_dict.items() if v))
+ to_enable_final = []
+ to_disable = []
for repoid in self.repodb:
enable = ( repoid in to_enable
or bool(repos_dict.get(repoid, False)))
repo = self.repodb[repoid]
repo.refresh()
if enable != repo.status:
- repository.set_repo_enabled(repo, enable)
- repo.refresh()
+ if enable:
+ to_enable_final.append(repoid)
+ else:
+ to_disable.append(repoid)
+ repository.set_repos_enabled(to_enable_final, True)
+ repository.set_repos_enabled(to_disable, False)
+ for repoid in itertools.chain(to_enable_final, to_disable):
+ self.repodb[repoid].refresh()
return func(self, *args, **kwargs)
return _wrapper
@@ -131,39 +139,27 @@ def test_with_packages(*install_pkgs, **enable_dict):
pkgs = list(repo.packages)
else:
pkgs = [repo[reposetup.full_pkg_name(pkg_name)]]
+ for pkg in pkgs:
+ if not enable_dict.get(repopkg, True):
+ to_remove.add(pkg)
+ else:
+ to_install.append(pkg)
elif enable_dict.get(repopkg, True) is False:
# package is given as string (with just name)
- repopkg = reposetup.full_pkg_name(repopkg)
- if package.is_pkg_installed(repopkg):
- present = []
- # remove any instances of Package with the same name
- # from *to_remove* set
- for pkg in to_remove:
- if ( isinstance(pkg, package.Package)
- and pkg.name == repopkg):
- present.append(pkg)
- for pkg in present:
- to_remove.remove(pkg)
- # now let's add the pkg name
- to_remove.add(repopkg)
+ to_remove.add(reposetup.full_pkg_name(repopkg))
continue
else:
raise ValueError(
'invalid format of repo#package string: "%s"'
% repopkg)
- for pkg in pkgs:
- installed = package.is_pkg_installed(pkg)
- if installed and not enable_dict.get(repopkg, True):
- if pkg.name not in to_remove:
- to_remove.add(pkg)
- elif not installed and enable_dict.get(repopkg, True):
- to_install.append(pkg)
- for pkg in to_remove:
- package.remove_pkg(pkg)
- for pkg in to_install:
- if package.is_pkg_installed(pkg.name):
- package.remove_pkg(pkg.name)
- package.install_pkg(pkg)
+ #if func.__name__ in ('test_install_package_same_arch', 'test_install_package'):
+ #import pdb; pdb.set_trace()
+ to_remove = package.filter_installed_packages(
+ to_remove.union(set(p.name for p in to_install)))
+ package.remove_pkgs(to_remove)
+ to_install = package.filter_installed_packages(
+ to_install, installed=False)
+ package.install_pkgs(to_install)
return func(self, *args, **kwargs)
return _wrapper
@@ -257,8 +253,9 @@ class SwTestCase(LmiTestCase):
for repoid in repository.get_repo_list('enabled'):
if repoid in SwTestCase.other_repos:
SwTestCase._restore_repos.append(repoid)
- repository.set_repo_enabled(repoid, False)
- SwTestCase.other_repos[repoid].refresh()
+ repository.set_repos_enabled(SwTestCase._restore_repos, False)
+ for repoid in SwTestCase._restore_repos:
+ SwTestCase.other_repos[repoid].refresh()
SwTestCase.TEST_CASES_INSTANTIATED += 1
@classmethod
@@ -268,17 +265,14 @@ class SwTestCase(LmiTestCase):
for repo in SwTestCase.repodb.values():
for pkg in repo.packages:
to_uninstall.add(pkg.name)
- if not SwTestCase._cleanup_db:
- repository.set_repo_enabled(repo.repoid, False)
- else:
+ if SwTestCase._cleanup_db:
os.remove(repo.config_path)
- to_uninstall = [ p for p in to_uninstall
- if package.is_pkg_installed(p)]
+ if not SwTestCase._cleanup_db:
+ repository.set_repos_enabled(SwTestCase.repodb.keys(), False)
+ to_uninstall = package.filter_installed_packages(to_uninstall)
if to_uninstall:
- subprocess.call([
- '/usr/bin/rpm', '--quiet', '-e'] + to_uninstall)
- for repoid in cls._restore_repos:
- repository.set_repo_enabled(repoid, True)
+ package.remove_pkgs(to_uninstall)
+ repository.set_repos_enabled(cls._restore_repos, True)
if SwTestCase._cleanup_db:
shutil.rmtree(cls.repos_dir)
if os.environ.get('LMI_SOFTWARE_DB_CACHE', None):
diff --git a/src/software/test/test_software_identity.py b/src/software/test/test_software_identity.py
index 05ce92d..7988164 100644
--- a/src/software/test/test_software_identity.py
+++ b/src/software/test/test_software_identity.py
@@ -29,6 +29,7 @@ import unittest
from lmi.test.lmibase import enable_lmi_exceptions
import package
import swbase
+import util
class TestSoftwareIdentity(swbase.SwTestCase):
"""
@@ -43,13 +44,7 @@ class TestSoftwareIdentity(swbase.SwTestCase):
:returns: Object path of ``LMI_SoftwareIdentity``
:rtype: :py:class:`lmi.shell.LMIInstanceName`
"""
- if isinstance(pkg, package.Package):
- nevra = pkg.nevra
- else:
- nevra = pkg
- return self.cim_class.new_instance_name({
- "InstanceID" : 'LMI:LMI_SoftwareIdentity:' + nevra
- })
+ return util.make_pkg_op(self.ns, pkg)
def _check_package_instance(self, pkg, inst):
"""
@@ -100,8 +95,8 @@ class TestSoftwareIdentity(swbase.SwTestCase):
installed package.
"""
pkg = self.get_repo('stable')['pkg1']
- package.remove_pkg(pkg.name)
- package.install_pkg(pkg)
+ package.remove_pkgs(pkg.name)
+ package.install_pkgs(pkg)
self.assertTrue(package.is_pkg_installed(pkg))
objpath = self.make_op(pkg)
@@ -155,7 +150,7 @@ class TestSoftwareIdentity(swbase.SwTestCase):
self._check_package_instance(pkg, inst)
# install it
- package.install_pkg(pkg)
+ package.install_pkgs(pkg)
self.assertTrue(package.is_pkg_installed(pkg))
inst.refresh()
self.assertNotEqual(inst.InstallDate, None)
@@ -175,7 +170,7 @@ class TestSoftwareIdentity(swbase.SwTestCase):
self._check_package_instance(pkg, inst)
# install it
- package.remove_pkg(pkg.name)
+ package.remove_pkgs(pkg.name)
self.assertFalse(package.is_pkg_installed(pkg))
inst.refresh()
self.assertEqual(inst.InstallDate, None)
diff --git a/src/software/test/test_software_identity_file_check.py b/src/software/test/test_software_identity_file_check.py
index 10db11f..bb2a933 100644
--- a/src/software/test/test_software_identity_file_check.py
+++ b/src/software/test/test_software_identity_file_check.py
@@ -649,7 +649,7 @@ class TestSoftwareIdentityFileCheck(swbase.SwTestCase):
objpath = self.make_op(pkg, fp)
inst = objpath.to_instance()
self.assertNotEqual(inst, None)
- package.remove_pkg(pkg.name)
+ package.remove_pkgs(pkg.name)
self.assertRaisesCIM(pywbem.CIM_ERR_NOT_FOUND, inst.Invoke)
@swbase.test_with_packages('stable#pkg2')
diff --git a/src/software/test/test_software_identity_resource.py b/src/software/test/test_software_identity_resource.py
index 2e6fa86..be48200 100644
--- a/src/software/test/test_software_identity_resource.py
+++ b/src/software/test/test_software_identity_resource.py
@@ -232,7 +232,7 @@ class TestSoftwareIdentityResource(swbase.SwTestCase):
self.assertEqual(inst.OperationalStatus, [OPERATIONAL_STATUS_OK])
self.assertEqual(inst.PrimaryStatus, PRIMARY_STATUS_OK)
- repository.set_repo_enabled(repo, False)
+ repository.set_repos_enabled(repo, False)
repo.refresh()
self.assertFalse(repo.status)
time.sleep(0.1)
@@ -264,7 +264,7 @@ class TestSoftwareIdentityResource(swbase.SwTestCase):
self.assertEqual(inst.OperationalStatus, [OPERATIONAL_STATUS_OK])
self.assertEqual(inst.PrimaryStatus, PRIMARY_STATUS_OK)
- repository.set_repo_enabled(repo, True)
+ repository.set_repos_enabled(repo, True)
repo.refresh()
self.assertTrue(repo.status)
inst.refresh()
@@ -406,7 +406,7 @@ class TestSoftwareIdentityResource(swbase.SwTestCase):
DUMMY_TEST_REPO + ".repo")
shutil.copy2("%s.repo" % DUMMY_TEST_REPO, repo_file_path)
try:
- repository.set_repo_enabled(DUMMY_TEST_REPO, True)
+ repository.set_repos_enabled(DUMMY_TEST_REPO, True)
subprocess.call(["/usr/bin/yum-config-manager",
"--enable", DUMMY_TEST_REPO],
stdout=util.DEV_NULL, stderr=util.DEV_NULL)
diff --git a/src/software/test/util.py b/src/software/test/util.py
index 3999a09..6532a2b 100644
--- a/src/software/test/util.py
+++ b/src/software/test/util.py
@@ -30,14 +30,14 @@ import re
from subprocess import call, check_output
RE_NEVRA = re.compile(
- r'^(?P<name>.+)-(?P<evra>(?P<epoch>\d+):(?P<ver>[^-]+)'
- r'-(?P<rel>.+)\.(?P<arch>[^.]+))$')
+ r'^(?P<name>[^\s]+)-(?P<evra>(?P<epoch>\d+):(?P<ver>[^-\s]+)'
+ r'-(?P<rel>[^\s]+)\.(?P<arch>[^.\s]+))$')
RE_NEVRA_OPT_EPOCH = re.compile(
- r'^(?P<name>.+)-(?P<evra>((?P<epoch>\d+):)?(?P<ver>[^-]+)'
- r'-(?P<rel>.+)\.(?P<arch>[^.]+))$')
+ r'^(?P<name>[^\s]+)-(?P<evra>((?P<epoch>\d+):)?(?P<ver>[^-\s]+)'
+ r'-(?P<rel>[^\s]+)\.(?P<arch>[^.\s]+))$')
RE_ENVRA = re.compile(
- r'^(?P<epoch>\d+|\(none\)):(?P<name>.+)-(?P<ver>[^-]+)'
- r'-(?P<rel>.+)\.(?P<arch>[^.]+)$')
+ r'^(?P<epoch>\d+|\(none\)):(?P<name>[^\s]+)-(?P<ver>[^-\s]+)'
+ r'-(?P<rel>[^\s]+)\.(?P<arch>[^.\s]+)$')
RE_REPO = re.compile(
r'(?:^\*?)(?P<name>[^\s/]+\b)(?!\s+id)', re.MULTILINE | re.IGNORECASE)
@@ -158,3 +158,17 @@ def get_installed_packages():
package_list.append(package.replace("(none)", "0"))
return package_list
+def make_pkg_op(ns, pkg):
+ """
+ :returns: Object path of ``LMI_SoftwareIdentity``
+ :rtype: :py:class:`lmi.shell.LMIInstanceName`
+ """
+ if not isinstance(pkg, basestring):
+ nevra = pkg.nevra
+ else:
+ nevra = pkg
+ return ns.LMI_SoftwareIdentity.new_instance_name({
+ "InstanceID" : 'LMI:LMI_SoftwareIdentity:' + nevra
+ })
+
+