From 54e501a7225d30695bdcc2edb3b406986290e6e6 Mon Sep 17 00:00:00 2001 From: Michal Minar Date: Wed, 12 Dec 2012 10:51:40 +0100 Subject: fixed test selection, when launching tests with run particular tests can be selected like this: * # runs all tests defined by this test case ./run.py -- TestSoftwarePackage * # runs single test defined by TestSoftwarePackage TestCase ./run.py -- TestSoftwarePackage.test_get_instance added comments for each assert made results of tests a lot more readable different file mode for symlinks passes like in rpm -V increased number of packages for testing to 5 --- src/software/openlmi/software/util/common.py | 42 ++- src/software/test/common.py | 29 +- src/software/test/rpmcache.py | 169 ++++++--- src/software/test/run.py | 15 +- src/software/test/test_software_file_check.py | 377 ++++++++++++++------- .../test/test_software_installed_package.py | 110 +++--- src/software/test/test_software_package.py | 43 ++- 7 files changed, 524 insertions(+), 261 deletions(-) (limited to 'src') diff --git a/src/software/openlmi/software/util/common.py b/src/software/openlmi/software/util/common.py index a5b7c60..685171a 100644 --- a/src/software/openlmi/software/util/common.py +++ b/src/software/openlmi/software/util/common.py @@ -699,15 +699,22 @@ class SoftwareFileCheck: """ if not isinstance(file_check, SoftwareFileCheck.FileCheck): raise TypeError("file_check must be an instance of FileCheck") - return ( file_check.exists - and all( val[0] == val[1] - #pylint: disable=W0212 - for k, val in file_check._asdict().items() - if ( isinstance(val, tuple) - and ( k != "last_modification_time" - or file_check.file_type[0] == \ - SoftwareFileCheck.filetype_str2pywbem("file") - )))) + passed = file_check.exists + for k, val in file_check._asdict().items(): + if not passed: + break + if not isinstance(val, tuple): + continue + if ( k == "last_modification_time" + and file_check.file_type[0] != \ + SoftwareFileCheck.filetype_str2pywbem("file")): + continue + if ( k == "file_mode" + and file_check.file_type[0] == \ + SoftwareFileCheck.filetype_str2pywbem("symlink")): + continue + passed = val[0] == val[1] + return passed @staticmethod def _filecheck2model_flags(file_check): @@ -718,14 +725,21 @@ class SoftwareFileCheck: flags = [] for k, value in file_check._asdict().items(): #pylint: disable=W0212 if isinstance(value, tuple): - if ( k != "last_modification_time" - or file_check.file_type[0] == - SoftwareFileCheck.filetype_str2pywbem('file')): + if ( k == "last_modification_time" + and file_check.file_type[0] != \ + SoftwareFileCheck.filetype_str2pywbem('file')): # last_modification_time check is valid only for # regular files - flag = file_check.exists and value[0] == value[1] + flag = file_check.exists + elif ( k == "file_mode" + and file_check.file_type[0] == \ + SoftwareFileCheck.filetype_str2pywbem('symlink')): + # do not check mode of symlinks + flag = ( file_check.exists + and ( file_check.file_type[0] + == file_check.file_type[1])) else: - flag = True + flag = file_check.exists and value[0] == value[1] flags.append(flag) elif isinstance(value, bool): flags.append(value) diff --git a/src/software/test/common.py b/src/software/test/common.py index 0d199b2..ef3d157 100644 --- a/src/software/test/common.py +++ b/src/software/test/common.py @@ -24,10 +24,9 @@ Common utilities and base class for all software tests. import os import pywbem import re -import subprocess import tempfile import unittest -from subprocess import check_output +from subprocess import call, check_output import rpmcache @@ -42,7 +41,7 @@ def remove_pkg(pkg, *args): """ if isinstance(pkg, rpmcache.Package): pkg = pkg.name - subprocess.call(["rpm", "--quiet"] + list(args) + ["-e", pkg]) + call(["rpm", "--quiet"] + list(args) + ["-e", pkg]) def install_pkg(pkg, newer=True): """ @@ -53,12 +52,12 @@ def install_pkg(pkg, newer=True): if isinstance(pkg, rpmcache.Package): try: rpm_name = rpmcache.get_rpm_name(pkg, newer=newer) - subprocess.call(["rpm", "--quiet", "-i", rpm_name]) + call(["rpm", "--quiet", "-i", rpm_name]) return except rpmcache.MissingRPM: pass pkg = pkg.name - subprocess.call(["yum", "-q", "-y", "install", pkg]) + call(["yum", "-q", "-y", "install", pkg]) def is_installed(pkg, newer=True): """ @@ -66,25 +65,13 @@ def is_installed(pkg, newer=True): Accepts the same parameters as install_pkg. @see install_pkg """ - if not isinstance(pkg, rpmcache.Package): - return subprocess.call(["rpm", "--quiet", "-q", pkg]) == 0 - else: - try: - cmd = [ "rpm", "-q", "--qf", "%{EPOCH}:%{NVRA}", pkg.name ] - out = subprocess.check_output(cmd) - epoch, nvra = out.split(':') #pylint: disable=E1103 - if not epoch or epoch == "(none)": - epoch = "0" - return ( epoch == pkg.epoch - and nvra == pkg.get_nevra(newer=newer, with_epoch="NEVER")) - except subprocess.CalledProcessError: - return False + return rpmcache.is_installed(pkg, newer) def verify_pkg(name): """ @return output of command rpm, with verification output for package """ - return subprocess.call(["rpm", "--quiet", "-Va", name]) == 0 + return call(["rpm", "--quiet", "-Va", name]) == 0 def mark_dangerous(method): """ @@ -152,6 +139,10 @@ class SoftwareBaseTestCase(unittest.TestCase): #pylint: disable=R0904 CLASS_NAME = "Define in subclass" + def __init__(self, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + self.longMessage = True + def setUp(self): unittest.TestCase.setUp(self) self.objpath = pywbem.CIMInstanceName( diff --git a/src/software/test/rpmcache.py b/src/software/test/rpmcache.py index af64fe3..f68f128 100644 --- a/src/software/test/rpmcache.py +++ b/src/software/test/rpmcache.py @@ -27,7 +27,44 @@ import os import pickle import re from collections import defaultdict -from subprocess import call, check_output +from subprocess import call, check_output, CalledProcessError + +DB_BACKUP_FILE = 'lmi_software_test_cache' + +RE_AVAIL_PKG = re.compile( + r'^(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' + r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' + r'-(?P[a-zA-Z0-9_.]+)\s+' + r'(?P[a-zA-Z0-9_-]+)\s*$', re.MULTILINE) +# this won't match the last entry, unless "package\n" is not appended +# at the end of the string +RE_PKG_DEPS = re.compile( + r'^package:\s*(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' + r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' + r'-(?P[a-zA-Z0-9_.]+)\s+(?P.*?)' + r'(?=^package|\Z)', re.MULTILINE | re.DOTALL) +RE_DEPS_PROVIDERS = re.compile( + r'^\s*dependency:\s*(?P.+?)\s*' + r'(?P(^\s+provider:.+?$)+)', re.MULTILINE | re.IGNORECASE) +RE_PROVIDER = re.compile( + r'^\s+provider:\s*(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' + r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' + r'-(?P[a-zA-Z0-9_.]+)\s*$', re.IGNORECASE | re.MULTILINE) +RE_PKG_INFO = re.compile( + r'^Name\s*:\s*(?P[^\s]+).*?' + r'^(Epoch\s*:\s*(?P[0-9]+)\s+)?' + r'^Version\s*:\s*(?P[a-zA-Z0-9._+-]+)\s+' + r'^Release\s*:\s*(?P[^\s]+)\s+.*?' + r'^Size\s*:\s*(?P\d+(\.\d+)?)( *(?P[kMG]))?', + re.MULTILINE | re.DOTALL | re.IGNORECASE) +RE_REPO = re.compile( + r'(?:^\*?)(?P[^\s/]+\b)(?!\s+id)', re.MULTILINE | re.IGNORECASE) + +# maximum number of packages, that will be selected for testing +MAX_PKG_DB_SIZE = 5 +# step used to iterate over package names used to check for thery dependencies +# it's a number of packages, that will be passed to yum command at once +PKG_DEPS_ITER_STEP = 50 class InvalidTestCache(Exception): """Exception saying, that rpm test cache is not valiid.""" @@ -80,6 +117,9 @@ class Package(object): #pylint: disable=R0902 self._up_rel = up_rel self._up_repo = up_repo + def __str__(self): + return self.get_nevra() + @property def name(self): return self._name #pylint: disable=C0111,C0321 @property @@ -120,50 +160,30 @@ class Package(object): #pylint: disable=R0902 return make_nevra(*[getattr(self, '_'+a) for a in attrs], with_epoch=with_epoch) -DB_BACKUP_FILE = 'lmi_software_test_cache' - -RE_AVAIL_PKG = re.compile( - r'^(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' - r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' - r'-(?P[a-zA-Z0-9_.]+)\s+' - r'(?P[a-zA-Z0-9_-]+)\s*$', re.MULTILINE) -# this won't match the last entry, unless "package\n" is not appended -# at the end of the string -RE_PKG_DEPS = re.compile( - r'^package:\s*(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' - r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' - r'-(?P[a-zA-Z0-9_.]+)\s+(?P.*?)' - r'(?=^package|\Z)', re.MULTILINE | re.DOTALL) -RE_DEPS_PROVIDERS = re.compile( - r'^\s+provider:\s*(?P[^\s]+)\.(?P[a-zA-Z0-9_]+)' - r'\s+(?P([0-9]+:)?)(?P[a-zA-Z0-9._+-]+)' - r'-(?P[a-zA-Z0-9_.]+)\s*$', re.IGNORECASE | re.MULTILINE) -RE_PKG_INFO = re.compile( - r'^Name\s*:\s*(?P[^\s]+).*?' - r'^(Epoch\s*:\s*(?P[0-9]+)\s+)?' - r'^Version\s*:\s*(?P[a-zA-Z0-9._+-]+)\s+' - r'^Release\s*:\s*(?P[^\s]+)\s+.*?' - r'^Size\s*:\s*(?P\d+(\.\d+)?)( *(?P[kMG]))?', - re.MULTILINE | re.DOTALL | re.IGNORECASE) -RE_REPO = re.compile( - r'(?:^\*?)(?P[^\s/]+\b)(?!\s+id)', re.MULTILINE | re.IGNORECASE) - -# maximum number of packages, that will be selected for testing -MAX_PKG_DB_SIZE = 3 -# step used to iterate over package names used to check for thery dependencies -# it's a number of packages, that will be passed to yum command at once -PKG_DEPS_ITER_STEP = 50 - def _match_nevr(match): """ @param match is a regexp match object with parsed rpm package @return tuple (name, epoch, version, release) """ + epoch = match.group('epoch') return ( match.group('name') - , match.group('epoch') + , epoch[:-1] if epoch else "0" , match.group('version') , match.group('release')) +def _match2pkg(match): + """ + @param match is a regexp match object with attributes: + name, epoch, version, release, arch + @return instance of Package + """ + return Package( + match.group('name'), + match.group('epoch')[:-1] if match.group('epoch') else '0', + match.group('version'), match.group('release'), + match.group('arch'), match.groupdict().get('repository', None), + None, None, None, None) + def _filter_duplicates(installed, avail_str): """ Parse output of "yum list available" command and retuns only those @@ -174,11 +194,6 @@ def _filter_duplicates(installed, avail_str): Each sublist of result contain at least 2 elements, that are instances of Package. """ - m2pkg = lambda m: Package(m.group('name'), - m.group('epoch')[:-1] if m.group('epoch') else '0', - m.group('version'), m.group('release'), - m.group('arch'), m.group('repository'), - None, None, None, None) dups_list = [] cur_package_matches = [] prev_match = None @@ -194,15 +209,38 @@ def _filter_duplicates(installed, avail_str): if prev_match and prev_match.group('name') != match.group('name'): if ( len(cur_package_matches) > 1 and not cur_package_matches[0].group('name') in installed): - pkgs = [ m2pkg(m) for m in cur_package_matches ] + pkgs = [ _match2pkg(m) for m in cur_package_matches ] dups_list.append(pkgs) cur_package_matches = [] cur_package_matches.append(match) prev_match = match if len(cur_package_matches) > 1: - dups_list.append([ m2pkg(m) for m in cur_package_matches ]) + dups_list.append([ _match2pkg(m) for m in cur_package_matches ]) return dups_list +def _check_single_pkg_deps( + installed, + dependencies_str): + """ + Each package has zero or more dependencies. Each dependency + has at least one provider. One of these provider must be installed + for each such dependency. + @param dependencies of single package + @return True if all dependencies have at least one provider installed + """ + for match_deps in RE_DEPS_PROVIDERS.finditer(dependencies_str): + providers = [] + for match_dep in RE_PROVIDER.finditer(match_deps.group('providers')): + if match_dep.group('name') not in installed: + continue + providers.append(_match2pkg(match_dep)) + for provider in providers: + if is_installed(provider, False): + break + else: # no provider is installed + return False + return True + def _check_pkg_dependencies( installed, dup_list, @@ -218,15 +256,28 @@ def _check_pkg_dependencies( dups_part = dup_list[i:i+PKG_DEPS_ITER_STEP] cmd = cmd[:2] for dups in dups_part: - cmd.append(dups[0].name) + cmd.extend([d.get_nevra(newer=False) for d in dups]) deplist_str = check_output(cmd) - for pkgs, match_pkg in zip(dups_part, - RE_PKG_DEPS.finditer(deplist_str)): - for match_dep in RE_DEPS_PROVIDERS.finditer( - match_pkg.group('dep_list')): - if match_dep.group('name') not in installed: + matches = RE_PKG_DEPS.finditer(deplist_str) + prev_match = None + for pkgs in dups_part: + satisfied = True + remains = len(pkgs) + for match_pkg in matches: + if ( prev_match + and _match_nevr(prev_match) == _match_nevr(match_pkg)): + # there sometimes appear duplicates in yum deplist + # output, so let's skip them + continue + if satisfied and not _check_single_pkg_deps( + installed, match_pkg.group('dep_list')): + satisfied = False + prev_match = match_pkg + remains -= 1 + if remains <= 0: break - else: + if satisfied: + # all packages from pkgs have satisfied dependencies dups_no_deps.append(pkgs) if len(dups_no_deps) >= number_of_packages: break @@ -317,6 +368,24 @@ def _make_rpm_path(pkg, cache_dir='', newer=True, without_epoch=False): with_epoch='NEVER' if without_epoch else 'NOT_ZERO') return os.path.join(cache_dir, nevra) + '.rpm' +def is_installed(pkg, newer=True): + """ + Check, whether package is installed. + """ + if not isinstance(pkg, Package): + return call(["rpm", "--quiet", "-q", pkg]) == 0 + else: + try: + cmd = [ "rpm", "-q", "--qf", "%{EPOCH}:%{NVRA}", pkg.name ] + out = check_output(cmd) + epoch, nvra = out.split(':') #pylint: disable=E1103 + if not epoch or epoch == "(none)": + epoch = "0" + return ( epoch == pkg.epoch + and nvra == pkg.get_nevra(newer=newer, with_epoch="NEVER")) + except CalledProcessError: + return False + def rpm_exists(pkg, cache_dir='', newer=True): """ @return True, when rpm package is in cache. diff --git a/src/software/test/run.py b/src/software/test/run.py index 002bf77..aba362f 100755 --- a/src/software/test/run.py +++ b/src/software/test/run.py @@ -44,6 +44,11 @@ import rpmcache # argument CACHE_DIR = '' +class NotFound(Exception): + """Raised when test of particular name could no be found.""" + def __init__(self, name): + Exception.__init__(self, "Test \"%s\" could not be found!" % name) + def parse_cmd_line(): """ Use ArgumentParser to parse command line arguments. @@ -179,13 +184,18 @@ class LMITestLoader(unittest.TestLoader): @param name is a name of test to find @return desired TestCase or test function """ + if ( isinstance(node, unittest.TestSuite) + and isinstance(next(iter(node)), unittest.TestCase) + and next(iter(node)).__class__.__name__ == name): + return node for subnode in node: if isinstance(subnode, unittest.TestSuite): subnode = LMITestLoader.find_in_test_nodes(subnode, name) if subnode is not None: return subnode elif isinstance(subnode, unittest.TestCase): - if name == subnode.__class__.__name__: + if ( name == subnode.__class__.__name__ + or name == subnode._testMethodName): return subnode elif inspect.isfunction(subnode) and name == subnode.__name__: return subnode @@ -201,8 +211,7 @@ class LMITestLoader(unittest.TestLoader): for part in parts: node = LMITestLoader.find_in_test_nodes(node, part) if node is None: - # name not found - return unittest.TestLoader.loadTestsFromName(self, name, module) + raise NotFound(name) return node def unwind_test_suite_tree(node): diff --git a/src/software/test/test_software_file_check.py b/src/software/test/test_software_file_check.py index d44fd10..4228c18 100755 --- a/src/software/test/test_software_file_check.py +++ b/src/software/test/test_software_file_check.py @@ -87,20 +87,20 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): objpath["SoftwareElementID"] = pkg.get_nevra(newer) return objpath - def assertEqualSEID(self, id1, id2): + def assertEqualSEID(self, id1, id2, msg=None): """ This is for comparison of SoftwareElementID property values. """ if ( not isinstance(id1, basestring) or not isinstance(id2, basestring)): - return common.SoftwareBaseTestCase.assertEqual(self, id1, id2) + return common.SoftwareBaseTestCase.assertEqual(self, id1, id2, msg) match1 = common.RE_NEVRA.match(id1) match2 = common.RE_NEVRA.match(id2) if not match1 or not match2: - return common.SoftwareBaseTestCase.assertEqual(self, id1, id2) + return common.SoftwareBaseTestCase.assertEqual(self, id1, id2, msg) if any( match1.group(g) != match2.group(g) for g in ('name', 'ver', 'rel', 'arch')): - return common.SoftwareBaseTestCase.assertEqual(self, id1, id2) + return common.SoftwareBaseTestCase.assertEqual(self, id1, id2, msg) epoch1 = match1.group('epoch') epoch2 = match2.group('epoch') if not epoch1: @@ -108,10 +108,10 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): if not epoch2: epoch2 = '0' if epoch1 != epoch2: - return common.SoftwareBaseTestCase.assertEqual(self, id1, id2) + return common.SoftwareBaseTestCase.assertEqual(self, id1, id2, msg) return True - def assertEqual(self, op1, op2): + def assertEqual(self, op1, op2, msg=None): """ This is override for object paths, that allows some differences (like missing epoch in SoftwareElementID). @@ -124,10 +124,9 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): or any(op1[a] != op2[a] for a in ( 'Name', 'Version', 'CheckID', 'SoftwareElementState' , 'TargetOperatingSystem'))): - return common.SoftwareBaseTestCase.assertEqual(self, op1, op2) + return common.SoftwareBaseTestCase.assertEqual(self, op1, op2, msg) return self.assertEqualSEID( - op1['SoftwareElementID'], op2['SoftwareElementID']) - return True + op1['SoftwareElementID'], op2['SoftwareElementID'], msg) def make_checksum_str(self, csumnum, filename): """ @@ -136,23 +135,31 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): return RE_CHECKSUM.match(subprocess.check_output([ self.hash_num2cmd[csumnum], filename])).group(1).lower() - def do_check_symlink(self, filepath, inst): + def do_check_symlink(self, pkg, filepath, inst): """ Assert some details about symlink. """ target = os.readlink(filepath) stats = os.lstat(filepath) - self.assertEqual(inst["FileType"], pywbem.Uint16(3)) - self.assertEqual(inst["FileUserID"], stats.st_uid) - self.assertEqual(inst["FileGroupID"], stats.st_gid) - self.assertEqual(inst["FileMode"], stats.st_mode) - self.assertEqual(inst["FileSize"], stats.st_size) - self.assertEqual(inst["LinkTarget"], target) - self.assertEqual(inst["FileChecksum"], - "0"*self.hash_num2length[inst["FileChecksumType"]]) - self.assertEqual(inst["LastModificationTime"], - int(stats.st_mtime)) + self.assertEqual(pywbem.Uint16(3), inst["FileType"], + "Unexpected file type of symlink for %s:%s"%( + pkg.name, filepath)) + self.assertEqual(stats.st_uid, inst["FileUserID"], + "Unexpected uid of symlink for %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_gid, inst["FileGroupID"], + "Unexpected gid of symlink for %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_mode, inst["FileMode"], + "Unexpected mode of symlink for %s:%s" %(pkg.name, filepath)) + self.assertEqual(stats.st_size, inst["FileSize"], + "Unexpected size of symlink for %s:%s"%(pkg.name, filepath)) + self.assertEqual(target, inst["LinkTarget"], + "Unexpected size of symlink for %s:%s"%(pkg.name, filepath)) + self.assertEqual("0"*self.hash_num2length[inst["FileChecksumType"]], + inst["FileChecksum"], + "Unexpected hash of symlink for %s:%s"%(pkg.name, filepath)) + self.assertEqual(int(stats.st_mtime), inst["LastModificationTime"], + "Unexpected mtime of symlink for %s:%s"%(pkg.name, filepath)) # modify owner prev_user = inst["FileUserID"] @@ -160,22 +167,40 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): #prev_pflags = PassedFlags(*inst["PassedFlags"]) os.lchown(filepath, stats.st_uid + 1, -1) inst = self.conn.GetInstance(InstanceName=inst.path) - self.assertEqual(inst["FileUserID"], inst["ExpectedFileUserID"] + 1) - self.assertEqual(inst["FileUserID"], prev_user + 1) - self.assertEqual(inst["FileGroupID"], stats.st_gid) + self.assertEqual(inst["ExpectedFileUserID"] + 1, inst["FileUserID"], + "Unexpected uid of modified symlink for %s:%s"%( + pkg.name, filepath)) + self.assertEqual(prev_user + 1, inst["FileUserID"], + "Unexpected uid of modified symlink for %s:%s"%( + pkg.name, filepath)) + self.assertEqual(stats.st_gid, inst["FileGroupID"], + "Unexpected gid of modified symlink for %s:%s"%( + pkg.name, filepath)) cur_pflags = PassedFlags(*inst["PassedFlags"]) #self.assertGreater(inst["LastModificationTime"], prev_mtime) - self.assertTrue(cur_pflags.exists) - self.assertTrue(cur_pflags.type) - self.assertTrue(cur_pflags.size) - self.assertTrue(cur_pflags.mode) - self.assertTrue(cur_pflags.checksum) - self.assertTrue(cur_pflags.dev) - self.assertTrue(cur_pflags.ltarget) - self.assertFalse(cur_pflags.uid) - self.assertTrue(cur_pflags.gid) - self.assertTrue(cur_pflags.mtime) + self.assertTrue(cur_pflags.exists, + "Symlink %s:%s should exist." %(pkg.name, filepath)) + self.assertTrue(cur_pflags.type, + "File type should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.size, + "File size should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.mode, + "File mode should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.checksum, + "File checksum should match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.dev, + "Device number should match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.ltarget, + "Link target should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.uid, + "Uid should not match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.gid, + "Gid shoud match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.mtime, + "Mtime should match for symlink %s:%s"%(pkg.name, filepath)) # modify link_target os.remove(filepath) @@ -188,72 +213,116 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): self.assertGreater(len(inst["LinkTarget"]), len(inst["ExpectedLinkTarget"])) - self.assertTrue(cur_pflags.exists) - self.assertTrue(cur_pflags.type) - self.assertFalse(cur_pflags.size) - self.assertTrue(cur_pflags.mode) - self.assertTrue(cur_pflags.checksum) - self.assertTrue(cur_pflags.dev) - self.assertFalse(cur_pflags.ltarget) - self.assertTrue(cur_pflags.uid) - self.assertTrue(cur_pflags.gid) - self.assertTrue(cur_pflags.mtime) - - def do_check_directory(self, filepath, inst): + self.assertTrue(cur_pflags.exists, + "File %s:%s should exist"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.type, + "File type should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.size, + "File size should not match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.mode, + "File mode should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.checksum, + "Checksum should match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.dev, + "Device numbers should match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.ltarget, + "Link target should not match for symlink %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.uid, + "File uid should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.gid, + "File gid should match for symlink %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.mtime, + "File mtime should match for symlink %s:%s"%(pkg.name, filepath)) + + def do_check_directory(self, pkg, filepath, inst): """ Assert some details about directory. """ stats = os.lstat(filepath) - self.assertEqual(inst["FileType"], pywbem.Uint16(2)) - self.assertEqual(inst["FileUserID"], stats.st_uid) - self.assertEqual(inst["FileGroupID"], stats.st_gid) - self.assertEqual(inst["FileMode"], stats.st_mode) - self.assertEqual(inst["FileSize"], stats.st_size) + self.assertEqual(pywbem.Uint16(2), inst["FileType"], + "Unexpected type for directory %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_uid, inst["FileUserID"], + "Unexpected uid for directory %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_gid, inst["FileGroupID"], + "Unexpected gid for directory %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_mode, inst["FileMode"], + "Unexpected mode for directory %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_size, inst["FileSize"], + "Unexpected size for directory %s:%s"%(pkg.name, filepath)) self.assertIs(inst["LinkTarget"], None) - self.assertEqual(inst["FileChecksum"], - "0"*self.hash_num2length[inst["FileChecksumType"]]) - self.assertEqual(inst["LastModificationTime"], - int(stats.st_mtime)) + self.assertEqual("0"*self.hash_num2length[inst["FileChecksumType"]], + inst["FileChecksum"], + "Unexpected checksum for directory %s:%s"%(pkg.name, filepath)) + self.assertEqual(int(stats.st_mtime), inst["LastModificationTime"], + "Unexpected mtime for directory %s:%s"%(pkg.name, filepath)) - def do_check_file(self, filepath, inst): + def do_check_file(self, pkg, filepath, inst): """ Assert some details about regurar file. """ stats = os.lstat(filepath) - self.assertEqual(inst["FileType"], pywbem.Uint16(1)) - self.assertEqual(inst["FileUserID"], stats.st_uid) - self.assertEqual(inst["FileGroupID"], stats.st_gid) - self.assertEqual(inst["FileMode"], stats.st_mode) - self.assertEqual(inst["FileSize"], stats.st_size) + self.assertEqual(pywbem.Uint16(1), inst["FileType"], + "Unexpected file type for %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_uid, inst["FileUserID"], + "Unexpected file uid for %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_gid, inst["FileGroupID"], + "Unexpected gid for regular file %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_mode, inst["FileMode"], + "Unexpected mode for reqular file %s:%s"%(pkg.name, filepath)) + self.assertEqual(stats.st_size, inst["FileSize"], + "Unexpected size for reqular file %s:%s"%(pkg.name, filepath)) self.assertIs(inst["LinkTarget"], None) csum = self.make_checksum_str(inst['FileChecksumType'], filepath) - self.assertEqual(inst["FileChecksum"].lower(), csum) - self.assertEqual(inst["ExpectedLastModificationTime"], - inst["LastModificationTime"]) + self.assertEqual(csum, inst["FileChecksum"].lower(), + "Unexpected checksum for reqular file %s:%s"%(pkg.name, filepath)) self.assertEqual(inst["LastModificationTime"], - int(stats.st_mtime)) + inst["ExpectedLastModificationTime"], + "Unexpected mtime for reqular file %s:%s"%(pkg.name, filepath)) + self.assertEqual(int(stats.st_mtime), inst["LastModificationTime"], + "Unexpected mtime for reqular file %s:%s"%(pkg.name, filepath)) # make it longer with open(filepath, "a+") as fobj: fobj.write("data\n") inst = self.conn.GetInstance(InstanceName=inst.path) cur_pflags = PassedFlags(*inst["PassedFlags"]) - self.assertGreater(inst["FileSize"], inst["ExpectedFileSize"]) + self.assertGreater(inst["FileSize"], inst["ExpectedFileSize"], + "File size should be greater, then expected for reqular file" + " %s:%s"%(pkg.name, filepath)) self.assertGreater(inst["LastModificationTime"], - inst["ExpectedLastModificationTime"]) - - self.assertTrue(cur_pflags.exists) - self.assertTrue(cur_pflags.type) - self.assertFalse(cur_pflags.size) - self.assertTrue(cur_pflags.mode) - self.assertFalse(cur_pflags.checksum) - self.assertTrue(cur_pflags.dev) - self.assertTrue(cur_pflags.ltarget) - self.assertTrue(cur_pflags.uid) - self.assertTrue(cur_pflags.gid) - self.assertFalse(cur_pflags.mtime) + inst["ExpectedLastModificationTime"], + "Unexpected mtime for reqular file %s:%s"%(pkg.name, filepath)) + + self.assertTrue(cur_pflags.exists, + "Regular file should exist %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.type, + "Type of regular file should match for %s:%s"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.size, + "Size should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.mode, + "Mode should match for regular file %s:%s"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.checksum, + "Checksum should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.dev, + "Device number should match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.ltarget, + "Link target should match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.uid, + "File uid should match for %s:%s"%(pkg.name, filepath)) + self.assertTrue(cur_pflags.gid, + "File gid should match for %s:%s"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.mtime, + "File mtime should not match for %s:%s"%(pkg.name, filepath)) # change file type os.remove(filepath) @@ -262,30 +331,59 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): inst["ExpectedFileGroupID"]) inst = self.conn.GetInstance(InstanceName=inst.path) cur_pflags = PassedFlags(*inst["PassedFlags"]) - self.assertNotEqual(inst["LinkTarget"], inst["ExpectedLinkTarget"]) - self.assertNotEqual(inst["FileSize"], inst["ExpectedFileSize"]) + self.assertNotEqual(inst["ExpectedLinkTarget"], inst["LinkTarget"], + "Link target should not match for %s:%s"%(pkg.name, filepath)) + self.assertNotEqual(inst["ExpectedFileSize"], inst["FileSize"], + "File size should not match for %s:%s"%(pkg.name, filepath)) self.assertGreater(inst["LastModificationTime"], - inst["ExpectedLastModificationTime"]) - self.assertNotEqual(inst["FileType"], inst["ExpectedFileType"]) - self.assertEqual(inst["FileType"], pywbem.Uint16(3)) - - self.assertTrue(cur_pflags.exists) - self.assertFalse(cur_pflags.type) - self.assertFalse(cur_pflags.size) - self.assertFalse(cur_pflags.mode) - self.assertFalse(cur_pflags.checksum) - self.assertTrue(cur_pflags.dev) - self.assertFalse(cur_pflags.ltarget) - self.assertTrue(cur_pflags.uid) - self.assertTrue(cur_pflags.gid) - self.assertFalse(cur_pflags.mtime) + inst["ExpectedLastModificationTime"], + "File mtime should be greater than expected for %s:%s"%( + pkg.name, filepath)) + self.assertNotEqual(inst["ExpectedFileType"], inst["FileType"], + "File type should not match for %s:%s"%(pkg.name, filepath)) + self.assertEqual(pywbem.Uint16(3), inst["FileType"], + "File type should match for %s:%s"%(pkg.name, filepath)) + + self.assertTrue(cur_pflags.exists, + "Regular file %s:%s should exist"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.type, + "Regular file type should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.size, + "Size should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.mode, + "File mode should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.checksum, + "Checksum should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.dev, + "Device should match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.ltarget, + "Link target should not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.uid, + "Regular file's uid should match for %s:%s"%( + pkg.name, filepath)) + self.assertTrue(cur_pflags.gid, + "Regular file's gid should match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.mtime, + "Regular file's mtime should not match for %s:%s"%( + pkg.name, filepath)) # remove it os.remove(filepath) inst = self.conn.GetInstance(InstanceName=inst.path) cur_pflags = PassedFlags(*inst["PassedFlags"]) - self.assertEqual(inst["LinkTarget"], inst["ExpectedLinkTarget"]) - self.assertNotEqual(inst["FileSize"], inst["ExpectedFileSize"]) + self.assertEqual(inst["ExpectedLinkTarget"], inst["LinkTarget"], + "Link target does not match for regular file %s:%s"%( + pkg.name, filepath)) + self.assertNotEqual(inst["ExpectedFileSize"], inst["FileSize"], + "File size should not match for regular file %s:%s"%( + pkg.name, filepath)) self.assertIsNone(inst["LastModificationTime"]) self.assertIsNone(inst["FileType"]) self.assertIsNone(inst["FileChecksum"]) @@ -293,16 +391,35 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): self.assertIsNone(inst["FileUserID"]) self.assertIsNone(inst["FileGroupID"]) - self.assertFalse(cur_pflags.exists) - self.assertFalse(cur_pflags.type) - self.assertFalse(cur_pflags.size) - self.assertFalse(cur_pflags.mode) - self.assertFalse(cur_pflags.checksum) - self.assertFalse(cur_pflags.dev) - self.assertFalse(cur_pflags.ltarget) - self.assertFalse(cur_pflags.uid) - self.assertFalse(cur_pflags.gid) - self.assertFalse(cur_pflags.mtime) + self.assertFalse(cur_pflags.exists, + "Regular file %s:%s should not exist"%(pkg.name, filepath)) + self.assertFalse(cur_pflags.type, + "Regular file's type should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.size, + "Regular file's size should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.mode, + "Regular file's mode should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.checksum, + "Regular file's checksum should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.dev, + "Regular file's dev number should not match %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.ltarget, + "Regular file's link target should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.uid, + "Regular file's uid should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.gid, + "Regular file's guid should not match for %s:%s"%( + pkg.name, filepath)) + self.assertFalse(cur_pflags.mtime, + "Regular file's mtime should not match for %s:%s"%( + pkg.name, filepath)) @common.mark_dangerous def test_get_instance(self): @@ -316,7 +433,9 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): common.remove_pkg(pkg.name) if not common.is_installed(pkg.name): common.install_pkg(pkg) - self.assertTrue(common.is_installed(pkg)) + self.assertTrue(common.is_installed(pkg), + "Package %s must be installed"%pkg) + for filepath in files: objpath = self.make_op(pkg, filepath) @@ -324,27 +443,38 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): InstanceName=objpath, LocalOnly=False) self.assertIsInstance(inst, pywbem.CIMInstance) - self.assertEqual(inst.path, objpath) + self.assertEqual(objpath, inst.path, + msg="Object paths of instance must match for %s:%s"%( + pkg.name, filepath)) for key in self.KEYS: if key.lower() == "softwareelementid": - self.assertEqualSEID(inst[key], objpath[key]) + self.assertEqualSEID(inst[key], objpath[key], + "OP keys should match for %s:%s"%( + pkg.name, filepath)) else: - self.assertEqual(inst[key], objpath[key]) - - self.assertTrue(inst["FileExists"]) - self.assertEqual(len(inst["PassedFlags"]), 10) - self.assertTrue(all( filepath is True - for filepath in inst["PassedFlags"])) + self.assertEqual(objpath[key], inst[key], + "OP keys should match for %s:%s"%( + pkg.name, filepath)) + + self.assertTrue(inst["FileExists"], + "File %s:%s must exist"%(pkg.name, filepath)) + self.assertEqual(10, len(inst["PassedFlags"]), + "PassedFlags must have constant length") + for i, flag in enumerate(inst["PassedFlags"]): + self.assertTrue(flag is True, + "Flag \"%s\" should all match for file %s:%s"%( + inst["PassedFlagsDescriptions"][i], pkg.name, filepath)) for prop in ( "FileType", "FileUserID", "FileGroupID" , "FileMode", "FileSize", "LinkTarget" , "FileChecksum", "FileModeFlags"): - self.assertEqual(inst["Expected"+prop], inst[prop]) + self.assertEqual(inst["Expected"+prop], inst[prop], + "%s should match for %s:%s"%(prop, pkg.name, filepath)) if os.path.islink(filepath): - self.do_check_symlink(filepath, inst) + self.do_check_symlink(pkg, filepath, inst) elif os.path.isdir(filepath): - self.do_check_directory(filepath, inst) + self.do_check_directory(pkg, filepath, inst) elif os.path.isfile(filepath): - self.do_check_file(filepath, inst) + self.do_check_file(pkg, filepath, inst) @common.mark_dangerous def test_invoke_method(self): @@ -357,14 +487,17 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): common.remove_pkg(pkg.name) if not common.is_installed(pkg.name): common.install_pkg(pkg) - self.assertTrue(common.is_installed(pkg)) + self.assertTrue(common.is_installed(pkg), + "Package %s must be installed"%pkg) for filepath in files: objpath = self.make_op(pkg, filepath) (rval, _) = self.conn.InvokeMethod( MethodName="Invoke", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(0)) + self.assertEqual(pywbem.Uint32(0), rval, + msg="InvokeMethod should be successful for %s:%s"%( + pkg.name, filepath)) # modify file if os.path.isfile(filepath): @@ -374,7 +507,9 @@ class TestSoftwareFileCheck(common.SoftwareBaseTestCase): (rval, _) = self.conn.InvokeMethod( MethodName="Invoke", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(2)) + self.assertEqual(pywbem.Uint32(2), rval, + "InvokeMethod should not pass for modified file %s:%s"%( + pkg.name, filepath)) def suite(): """For unittest loaders.""" diff --git a/src/software/test/test_software_installed_package.py b/src/software/test/test_software_installed_package.py index c6e64de..9de627a 100755 --- a/src/software/test/test_software_installed_package.py +++ b/src/software/test/test_software_installed_package.py @@ -79,15 +79,18 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): inst.path['System'].classname, objpath['System'].classname) self.assertIsSubclass(inst.path['Software'].classname, objpath['Software'].classname) - self.assertEqual(len(inst.path.keys()), 2) + self.assertEqual(2, len(inst.path.keys())) for key in self.KEYS: - self.assertEqual(inst[key], inst.path[key]) - self.assertEqual(inst['Software'], objpath['Software']) + self.assertEqual(inst[key], inst.path[key], + "Object paths should be the same for %s"%pkg) + self.assertEqual(inst['Software'], objpath['Software'], + "Software key reference should match for %s"%pkg) common.remove_pkg(pkg.name) objpath['Software']['SoftwareElementState'] = pywbem.Uint16(1) with self.assertRaises(pywbem.CIMError) as cmngr: self.conn.GetInstance(InstanceName=objpath, LocalOnly=False) - self.assertEqual(cmngr.exception.args[0], pywbem.CIM_ERR_NOT_FOUND) + self.assertEqual(pywbem.CIM_ERR_NOT_FOUND, cmngr.exception.args[0], + "Package %s should not be installed"%pkg) @common.mark_dangerous def test_enum_instances(self): @@ -129,7 +132,8 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): for pkg in self.pkgdb: if common.is_installed(pkg.name): common.remove_pkg(pkg.name) - self.assertFalse(common.is_installed(pkg.name)) + self.assertFalse(common.is_installed(pkg.name), + "Package %s should not be installed"%pkg) objpath = self.make_op(pkg, ses=1) inst = pywbem.CIMInstance(classname=objpath.classname, path=objpath) inst["Software"] = objpath["Software"] @@ -137,17 +141,21 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): iname = self.conn.CreateInstance(NewInstance=inst) self.assertIsInstance(iname, pywbem.CIMInstanceName) objpath["Software"]["SoftwareElementState"] = pywbem.Uint16(2) - self.assertEqual(iname["Software"], objpath["Software"]) + self.assertEqual(iname["Software"], objpath["Software"], + "Software key reference should match for %s"%pkg) self.assertIsInstance(iname["System"], pywbem.CIMInstanceName) self.assertIsSubclass(iname["System"].classname, objpath["System"].classname) - self.assertEqual(set(iname.keys()), set(objpath.keys())) - self.assertTrue(common.is_installed(pkg.name)) + self.assertEqual(set(iname.keys()), set(objpath.keys()), + "Keys of object paths should be the same for %s"%pkg) + self.assertTrue(common.is_installed(pkg.name), + "Package %s should be installed"%pkg) with self.assertRaises(pywbem.CIMError) as cmngr: self.conn.CreateInstance(NewInstance=inst) - self.assertEqual(cmngr.exception.args[0], - pywbem.CIM_ERR_ALREADY_EXISTS) + self.assertEqual(pywbem.CIM_ERR_ALREADY_EXISTS, + cmngr.exception.args[0], + "Package %s should already be installed"%pkg) @common.mark_dangerous def test_delete_instance(self): @@ -157,13 +165,16 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): for pkg in self.pkgdb: if not common.is_installed(pkg.name): common.install_pkg(pkg) - self.assertTrue(common.is_installed(pkg.name)) + self.assertTrue(common.is_installed(pkg.name), + "Package %s must be installed"%pkg) objpath = self.make_op(pkg) self.conn.DeleteInstance(objpath) - self.assertFalse(common.is_installed(pkg.name)) + self.assertFalse(common.is_installed(pkg.name), + "Package %s must be uninstalled"%pkg) with self.assertRaises(pywbem.CIMError) as cmngr: self.conn.DeleteInstance(objpath) - self.assertEqual(cmngr.exception.args[0], pywbem.CIM_ERR_NOT_FOUND) + self.assertEqual(pywbem.CIM_ERR_NOT_FOUND, cmngr.exception.args[0], + "Package %s can not be uninstalled again"%pkg) @common.mark_dangerous def test_check_integrity(self): @@ -180,16 +191,19 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): common.remove_pkg(pkg.name) if not common.is_installed(pkg.name): common.install_pkg(pkg) - self.assertTrue(common.is_installed(pkg)) + self.assertTrue(common.is_installed(pkg), + "Package %s must be installed"%pkg) objpath = self.make_op(pkg) (rval, oparms) = self.conn.InvokeMethod( MethodName="CheckIntegrity", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(0)) # check passed - self.assertEqual(len(oparms), 1) + self.assertEqual(pywbem.Uint32(0), rval, + "IntegrityCheck should pass for %s"%pkg.name) # check passed + self.assertEqual(1, len(oparms)) self.assertIn("Failed", oparms) - self.assertEqual(len(oparms["Failed"]), 0) + self.assertEqual(0, len(oparms["Failed"]), + "IntegrityCheck should not fail for %s"%pkg.name) cnt_bad = 0 for file_path in files: @@ -202,7 +216,8 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): MethodName="CheckIntegrity", ObjectName=objpath) # symlink must pass - self.assertEqual(len(oparms["Failed"]), cnt_bad) + self.assertEqual(cnt_bad, len(oparms["Failed"]), + "Symlink %s:%s should pass"%(pkg.name, file_path)) os.remove(file_path) # now change target os.symlink("wrong_link_target", file_path) @@ -212,7 +227,8 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): MethodName="CheckIntegrity", ObjectName=objpath) # dir must pass - self.assertEqual(len(oparms["Failed"]), cnt_bad) + self.assertEqual(cnt_bad, len(oparms["Failed"]), + "Directory %s:%s should pass"%(pkg.name, file_path)) # modify read access of directory os.chmod(file_path, stats.st_mode ^ stat.S_IROTH) else: # modify regular file @@ -223,11 +239,15 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): (rval, oparms) = self.conn.InvokeMethod( MethodName="CheckIntegrity", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(1)) - self.assertEqual(len(oparms), 1) + self.assertEqual(pywbem.Uint32(1), rval, + "File %s:%s should not pass"%(pkg.name, file_path)) + self.assertEqual(1, len(oparms)) self.assertIn("Failed", oparms) - self.assertEqual(len(oparms["Failed"]), cnt_bad) - self.assertIn(file_path, (p["Name"] for p in oparms["Failed"])) + self.assertEqual(len(oparms["Failed"]), cnt_bad, + "Number of errors should match number of elements in" + " Failed for %s:%s"%(pkg.name, file_path)) + self.assertIn(file_path, (p["Name"] for p in oparms["Failed"]), + "File %s:%s should also be in failed"%(pkg.name, file_path)) @common.mark_dangerous def test_method_update(self): @@ -240,34 +260,42 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): common.remove_pkg(pkg.name) if not common.is_installed(pkg.name): common.install_pkg(pkg, False) - self.assertTrue(common.is_installed(pkg, False)) + self.assertTrue(common.is_installed(pkg, False), + "Package %s must be installed"%pkg.get_nevra(False)) objpath = self.make_op(pkg, False) op_up = self.make_op(pkg) (rval, oparms) = self.conn.InvokeMethod( MethodName="Update", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint16(1)) - self.assertEqual(len(oparms), 1) + self.assertEqual(pywbem.Uint16(1), rval, + "Update should succed for %s"%pkg.get_nevra(False)) + self.assertEqual(1, len(oparms)) self.assertIn("Installed", oparms) - self.assertEqual(oparms["Installed"], op_up["Software"]) - self.assertTrue(common.is_installed(pkg)) + self.assertEqual(oparms["Installed"], op_up["Software"], + "Object paths should match for %s"%pkg) + self.assertTrue(common.is_installed(pkg), + "Package %s must be installed"%pkg) (rval, oparms) = self.conn.InvokeMethod( MethodName="Update", ObjectName=op_up) - self.assertEqual(rval, pywbem.Uint16(0)) - self.assertEqual(len(oparms), 1) - self.assertEqual(oparms["Installed"], op_up["Software"]) - self.assertTrue(common.is_installed(pkg.name)) - self.assertFalse(common.is_installed(pkg, False)) + self.assertEqual(pywbem.Uint16(0), rval, + "Package %s should be already updated"%pkg) + self.assertEqual(1, len(oparms)) + self.assertEqual(oparms["Installed"], op_up["Software"], + "Object paths should match for %s"%pkg) + self.assertTrue(common.is_installed(pkg.name), + "Package %s must be installed"%pkg) + self.assertFalse(common.is_installed(pkg, False), + "Older package %s must not be installed"%pkg.get_nevra(False)) with self.assertRaises(pywbem.CIMError) as cmngr: self.conn.InvokeMethod( MethodName="Update", ObjectName=objpath) - self.assertEqual(cmngr.exception.args[0], - pywbem.CIM_ERR_NOT_FOUND) + self.assertEqual(pywbem.CIM_ERR_NOT_FOUND, cmngr.exception.args[0], + "Older package %s should not be installed"%pkg.get_nevra(False)) common.remove_pkg(pkg.name) common.install_pkg(pkg, False) @@ -279,8 +307,10 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): Epoch=pkg.epoch, Version=pkg.ver, Release=pkg.rel) - self.assertEqual(rval, pywbem.Uint16(0)) - self.assertEqual(oparms["Installed"], objpath["Software"]) + self.assertEqual(pywbem.Uint16(0), rval, + "Update of package %s should succeed"%pkg) + self.assertEqual(oparms["Installed"], objpath["Software"], + "Object paths should be the same for package %s"%pkg) (rval, oparms) = self.conn.InvokeMethod( MethodName="Update", @@ -288,8 +318,10 @@ class TestSoftwareInstalledPackage(common.SoftwareBaseTestCase): Epoch=pkg.up_epoch, Version=pkg.up_ver, Release=pkg.up_rel) - self.assertEqual(rval, pywbem.Uint16(1)) - self.assertEqual(oparms["Installed"], op_up["Software"]) + self.assertEqual(pywbem.Uint16(1), rval, + "Package %s can not be updated twice to highest version"%pkg) + self.assertEqual(oparms["Installed"], op_up["Software"], + "Object paths should match for package %s"%pkg) def suite(): """For unittest loaders.""" diff --git a/src/software/test/test_software_package.py b/src/software/test/test_software_package.py index d0144ca..3411678 100755 --- a/src/software/test/test_software_package.py +++ b/src/software/test/test_software_package.py @@ -61,15 +61,20 @@ class TestSoftwarePackage(common.SoftwareBaseTestCase): #pylint: disable=R0904 common.remove_pkg(pkg.name) objpath = self.make_op(pkg, ses=1) inst = self.conn.GetInstance(InstanceName=objpath, LocalOnly=False) - self.assertEqual(inst.path, objpath) + self.assertEqual(inst.path, objpath, + "Object paths should match for %s"%pkg) for key in self.KEYS: - self.assertTrue(inst.properties.has_key(key)) - self.assertEqual(inst.path[key], inst[key]) - self.assertEqual(inst['Release'], pkg.up_rel) + self.assertTrue(inst.properties.has_key(key), + "OP is missing \"%s\" key for package %s"%(key, pkg)) + self.assertEqual(inst.path[key], inst[key], + "Object paths of instance should match for %s"%pkg) + self.assertEqual(pkg.up_rel, inst['Release'], + "Release property should match for %s"%pkg) common.install_pkg(pkg) objpath['SoftwareElementState'] = pywbem.Uint16(2) inst = self.conn.GetInstance(InstanceName=objpath, LocalOnly=False) - self.assertEqual(inst.path, objpath) + self.assertEqual(inst.path, objpath, + "Object paths should match for %s"%pkg) # try to leave out epoch part if pkg.epoch == "0": @@ -93,18 +98,23 @@ class TestSoftwarePackage(common.SoftwareBaseTestCase): #pylint: disable=R0904 (rval, oparms) = self.conn.InvokeMethod( MethodName="Install", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(1)) - self.assertEqual(len(oparms), 1) + self.assertEqual(pywbem.Uint32(1), rval, + "Installation of %s should be successful"%pkg) + self.assertEqual(1, len(oparms)) self.assertTrue(oparms.has_key('Installed')) objpath['SoftwareElementState'] = pywbem.Uint16(2) - self.assertEqual(oparms['Installed'], objpath) - self.assertTrue(common.is_installed(pkg.name)) + self.assertEqual(oparms['Installed'], objpath, + "Object paths should match for %s"%pkg) + self.assertTrue(common.is_installed(pkg.name), + "Package %s must be installed"%pkg) (rval, oparms) = self.conn.InvokeMethod( MethodName="Install", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(0)) + self.assertEqual(pywbem.Uint32(0), rval, + "Installation of %s should fail"%pkg) self.assertEqual(len(oparms), 1) - self.assertEqual(oparms['Installed'], objpath) + self.assertEqual(oparms['Installed'], objpath, + "Object paths should match for %s"%pkg) @common.mark_dangerous def test_method_remove(self): @@ -118,14 +128,17 @@ class TestSoftwarePackage(common.SoftwareBaseTestCase): #pylint: disable=R0904 (rval, oparms) = self.conn.InvokeMethod( MethodName="Remove", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint16(1)) - self.assertEqual(len(oparms), 0) - self.assertFalse(common.is_installed(pkg.name)) + self.assertEqual(pywbem.Uint16(1), rval, + "Removal of package should succeed"%pkg) + self.assertEqual(0, len(oparms)) + self.assertFalse(common.is_installed(pkg.name), + "Package %s should not be installed"%pkg) objpath["SoftwareElementState"] = pywbem.Uint16(1) (rval, oparms) = self.conn.InvokeMethod( MethodName="Remove", ObjectName=objpath) - self.assertEqual(rval, pywbem.Uint32(0)) + self.assertEqual(pywbem.Uint32(0), rval, + "Removal of %s should fail"%pkg) self.assertEqual(len(oparms), 0) def suite(): -- cgit