Merge pull request #46551 from terminalmage/salt-jenkins-885

Fix failing pkg integration test on OpenSUSE
This commit is contained in:
Nicole Thomas 2018-03-19 07:50:11 -04:00 committed by GitHub
commit e6682c660c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 165 additions and 24 deletions

View File

@ -706,6 +706,123 @@ def list_pkgs(versions_as_list=False, **kwargs):
return ret
def list_repo_pkgs(*args, **kwargs):
'''
.. versionadded:: 2017.7.5,2018.3.1
Returns all available packages. Optionally, package names (and name globs)
can be passed and the results will be filtered to packages matching those
names. This is recommended as it speeds up the function considerably.
This function can be helpful in discovering the version or repo to specify
in a :mod:`pkg.installed <salt.states.pkg.installed>` state.
The return data will be a dictionary mapping package names to a list of
version numbers, ordered from newest to oldest. If ``byrepo`` is set to
``True``, then the return dictionary will contain repository names at the
top level, and each repository will map packages to lists of version
numbers. For example:
.. code-block:: python
# With byrepo=False (default)
{
'bash': ['4.3-83.3.1',
'4.3-82.6'],
'vim': ['7.4.326-12.1']
}
{
'OSS': {
'bash': ['4.3-82.6'],
'vim': ['7.4.326-12.1']
},
'OSS Update': {
'bash': ['4.3-83.3.1']
}
}
fromrepo : None
Only include results from the specified repo(s). Multiple repos can be
specified, comma-separated.
byrepo : False
When ``True``, the return data for each package will be organized by
repository.
CLI Examples:
.. code-block:: bash
salt '*' pkg.list_repo_pkgs
salt '*' pkg.list_repo_pkgs foo bar baz
salt '*' pkg.list_repo_pkgs 'python2-*' byrepo=True
salt '*' pkg.list_repo_pkgs 'python2-*' fromrepo='OSS Updates'
'''
byrepo = kwargs.pop('byrepo', False)
fromrepo = kwargs.pop('fromrepo', '') or ''
ret = {}
targets = [
arg if isinstance(arg, six.string_types) else six.text_type(arg)
for arg in args
]
def _is_match(pkgname):
'''
When package names are passed to a zypper search, they will be matched
anywhere in the package name. This makes sure that only exact or
fnmatch matches are identified.
'''
if not args:
# No package names passed, everyone's a winner!
return True
for target in targets:
if fnmatch.fnmatch(pkgname, target):
return True
return False
for node in __zypper__.xml.call('se', '-s', *targets).getElementsByTagName('solvable'):
pkginfo = dict(node.attributes.items())
try:
if pkginfo['kind'] != 'package':
continue
reponame = pkginfo['repository']
if fromrepo and reponame != fromrepo:
continue
pkgname = pkginfo['name']
pkgversion = pkginfo['edition']
except KeyError:
continue
else:
if _is_match(pkgname):
repo_dict = ret.setdefault(reponame, {})
version_list = repo_dict.setdefault(pkgname, set())
version_list.add(pkgversion)
if byrepo:
for reponame in ret:
# Sort versions newest to oldest
for pkgname in ret[reponame]:
sorted_versions = sorted(
[LooseVersion(x) for x in ret[reponame][pkgname]],
reverse=True
)
ret[reponame][pkgname] = [x.vstring for x in sorted_versions]
return ret
else:
byrepo_ret = {}
for reponame in ret:
for pkgname in ret[reponame]:
byrepo_ret.setdefault(pkgname, []).extend(ret[reponame][pkgname])
for pkgname in byrepo_ret:
sorted_versions = sorted(
[LooseVersion(x) for x in byrepo_ret[pkgname]],
reverse=True
)
byrepo_ret[pkgname] = [x.vstring for x in sorted_versions]
return byrepo_ret
def _get_configured_repos():
'''
Get all the info about repositories from the configurations.
@ -1088,6 +1205,15 @@ def install(name=None,
return {}
version_num = Wildcard(__zypper__)(name, version)
if version_num:
if pkgs is None and sources is None:
# Allow "version" to work for single package target
pkg_params = {name: version_num}
else:
log.warning('"version" parameter will be ignored for multiple '
'package targets')
if pkg_type == 'repository':
targets = []
problems = []

View File

@ -272,38 +272,53 @@ class PkgModuleTest(ModuleCase, SaltReturnAssertsMixin):
self.run_function('pkg.refresh_db')
if os_family == 'Suse':
# pkg.latest version returns empty if the latest version is already installed
vim_version_dict = self.run_function('pkg.latest_version', ['vim'])
vim_info = self.run_function('pkg.info_available', ['vim'])['vim']
if vim_version_dict == {}:
# Latest version is installed, get its version and construct
# a version selector so the immediately previous version is selected
vim_version = 'version=<'+vim_info['version']
else:
# Vim was not installed, so pkg.latest_version returns the latest one.
# Construct a version selector so immediately previous version is selected
vim_version = 'version=<'+vim_version_dict
# This test assumes that there are multiple possible versions of a
# package available. That makes it brittle if you pick just one
# target, as changes in the available packages will break the test.
# Therefore, we'll choose from several packages to make sure we get
# one that is suitable for this test.
packages = ('hwinfo', 'avrdude', 'diffoscope', 'vim')
# Only install a new version of vim if vim is up-to-date, otherwise we don't
# need this check. (And the test will fail when we check for the empty dict
# since vim gets upgraded in the install step.)
if 'out-of-date' not in vim_info['status']:
# Install a version of vim that should need upgrading
ret = self.run_function('pkg.install', ['vim', vim_version])
if not isinstance(ret, dict):
if ret.startswith('ERROR'):
self.skipTest('Could not install earlier vim to complete test.')
available = self.run_function('pkg.list_repo_pkgs', packages)
versions = self.run_function('pkg.version', packages)
for package in packages:
try:
new, old = available[package][:2]
except (KeyError, ValueError):
# Package not available, or less than 2 versions
# available. This is not a suitable target.
continue
else:
self.assertNotEqual(ret, {})
target = package
current = versions[target]
break
else:
# None of the packages have more than one version available, so
# we need to find new package(s). pkg.list_repo_pkgs can be
# used to get an overview of the available packages. We should
# try to find packages with few dependencies and small download
# sizes, to keep this test from taking longer than necessary.
self.fail('No suitable package found for this test')
# Run a system upgrade, which should catch the fact that Vim needs upgrading, and upgrade it.
# Make sure we have the 2nd-oldest available version installed
ret = self.run_function('pkg.install', [target], version=old)
if not isinstance(ret, dict):
if ret.startswith('ERROR'):
self.skipTest(
'Could not install older {0} to complete '
'test.'.format(target)
)
# Run a system upgrade, which should catch the fact that the
# targeted package needs upgrading, and upgrade it.
ret = self.run_function(func)
# The changes dictionary should not be empty.
if 'changes' in ret:
self.assertIn('vim', ret['changes'])
self.assertIn(target, ret['changes'])
else:
self.assertIn('vim', ret)
self.assertIn(target, ret)
else:
ret = self.run_function('pkg.list_upgrades')
if ret == '' or ret == {}: