2015-05-21 18:02:24 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2017-05-12 20:21:22 +00:00
|
|
|
# Import Python libs
|
2018-01-18 16:55:07 +00:00
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
2017-05-12 20:21:22 +00:00
|
|
|
import os
|
2015-06-17 22:36:36 +00:00
|
|
|
|
2015-05-21 18:02:24 +00:00
|
|
|
# Import Salt Testing libs
|
2017-04-03 16:04:09 +00:00
|
|
|
from tests.support.case import ModuleCase
|
2017-04-02 16:09:47 +00:00
|
|
|
from tests.support.mixins import SaltReturnAssertsMixin
|
2017-02-27 13:58:07 +00:00
|
|
|
from tests.support.helpers import (
|
2015-05-21 18:02:24 +00:00
|
|
|
destructiveTest,
|
|
|
|
requires_network,
|
2016-02-23 22:22:14 +00:00
|
|
|
requires_salt_modules,
|
2015-05-21 18:02:24 +00:00
|
|
|
)
|
2017-05-04 21:13:41 +00:00
|
|
|
from tests.support.unit import skipIf
|
2015-05-21 18:02:24 +00:00
|
|
|
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-25 01:47:15 +00:00
|
|
|
# Import Salt libs
|
2017-05-12 20:21:22 +00:00
|
|
|
import salt.utils.pkg
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-25 01:47:15 +00:00
|
|
|
import salt.utils.platform
|
2017-05-04 22:45:58 +00:00
|
|
|
|
2017-05-16 21:53:11 +00:00
|
|
|
|
2017-04-03 16:04:09 +00:00
|
|
|
class PkgModuleTest(ModuleCase, SaltReturnAssertsMixin):
|
2015-05-21 18:02:24 +00:00
|
|
|
'''
|
|
|
|
Validate the pkg module
|
|
|
|
'''
|
2017-05-04 21:13:41 +00:00
|
|
|
def setUp(self):
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-25 01:47:15 +00:00
|
|
|
if salt.utils.platform.is_windows():
|
2017-05-04 21:13:41 +00:00
|
|
|
self.run_function('pkg.refresh_db')
|
|
|
|
|
2018-01-23 16:39:06 +00:00
|
|
|
os_release = self.run_function('grains.get', ['osrelease'])
|
|
|
|
|
2018-01-26 22:34:29 +00:00
|
|
|
if salt.utils.platform.is_darwin() and int(os_release.split('.')[1]) >= 13:
|
2018-01-23 16:39:06 +00:00
|
|
|
self.pkg = 'wget'
|
2018-01-26 22:34:29 +00:00
|
|
|
elif salt.utils.platform.is_windows():
|
2018-01-23 16:39:06 +00:00
|
|
|
self.pkg = 'putty'
|
2018-01-24 15:57:02 +00:00
|
|
|
else:
|
|
|
|
self.pkg = 'htop'
|
2018-01-23 16:39:06 +00:00
|
|
|
|
2015-05-21 18:02:24 +00:00
|
|
|
def test_list(self):
|
|
|
|
'''
|
|
|
|
verify that packages are installed
|
|
|
|
'''
|
|
|
|
ret = self.run_function('pkg.list_pkgs')
|
|
|
|
self.assertNotEqual(len(ret.keys()), 0)
|
|
|
|
|
2017-05-04 21:13:41 +00:00
|
|
|
@requires_salt_modules('pkg.version_cmp')
|
2015-05-21 18:02:24 +00:00
|
|
|
def test_version_cmp(self):
|
|
|
|
'''
|
|
|
|
test package version comparison on supported platforms
|
|
|
|
'''
|
|
|
|
func = 'pkg.version_cmp'
|
|
|
|
os_family = self.run_function('grains.item', ['os_family'])['os_family']
|
|
|
|
if os_family == 'Debian':
|
|
|
|
lt = ['0.2.4-0ubuntu1', '0.2.4.1-0ubuntu1']
|
|
|
|
eq = ['0.2.4-0ubuntu1', '0.2.4-0ubuntu1']
|
|
|
|
gt = ['0.2.4.1-0ubuntu1', '0.2.4-0ubuntu1']
|
|
|
|
|
2016-09-23 23:03:18 +00:00
|
|
|
self.assertEqual(self.run_function(func, lt), -1)
|
|
|
|
self.assertEqual(self.run_function(func, eq), 0)
|
|
|
|
self.assertEqual(self.run_function(func, gt), 1)
|
|
|
|
elif os_family == 'Suse':
|
|
|
|
lt = ['2.3.0-1', '2.3.1-15.1']
|
|
|
|
eq = ['2.3.1-15.1', '2.3.1-15.1']
|
|
|
|
gt = ['2.3.2-15.1', '2.3.1-15.1']
|
|
|
|
|
2015-05-21 18:02:24 +00:00
|
|
|
self.assertEqual(self.run_function(func, lt), -1)
|
|
|
|
self.assertEqual(self.run_function(func, eq), 0)
|
|
|
|
self.assertEqual(self.run_function(func, gt), 1)
|
|
|
|
else:
|
|
|
|
self.skipTest('{0} is unavailable on {1}'.format(func, os_family))
|
|
|
|
|
2017-05-04 21:13:41 +00:00
|
|
|
@requires_salt_modules('pkg.mod_repo', 'pkg.del_repo')
|
2015-05-21 18:02:24 +00:00
|
|
|
@requires_network()
|
|
|
|
@destructiveTest
|
|
|
|
def test_mod_del_repo(self):
|
|
|
|
'''
|
2015-06-01 04:23:17 +00:00
|
|
|
test modifying and deleting a software repository
|
2015-05-21 18:02:24 +00:00
|
|
|
'''
|
|
|
|
os_grain = self.run_function('grains.item', ['os'])['os']
|
|
|
|
|
2016-03-29 20:28:36 +00:00
|
|
|
try:
|
|
|
|
repo = None
|
|
|
|
if os_grain == 'Ubuntu':
|
2016-09-30 02:38:03 +00:00
|
|
|
repo = 'ppa:otto-kesselgulasch/gimp-edge'
|
|
|
|
uri = 'http://ppa.launchpad.net/otto-kesselgulasch/gimp-edge/ubuntu'
|
2016-03-29 20:28:36 +00:00
|
|
|
ret = self.run_function('pkg.mod_repo', [repo, 'comps=main'])
|
|
|
|
self.assertNotEqual(ret, {})
|
|
|
|
ret = self.run_function('pkg.get_repo', [repo])
|
|
|
|
self.assertEqual(ret['uri'], uri)
|
|
|
|
elif os_grain == 'CentOS':
|
|
|
|
major_release = int(
|
|
|
|
self.run_function(
|
|
|
|
'grains.item',
|
|
|
|
['osmajorrelease']
|
|
|
|
)['osmajorrelease']
|
|
|
|
)
|
|
|
|
repo = 'saltstack'
|
|
|
|
name = 'SaltStack repo for RHEL/CentOS {0}'.format(major_release)
|
|
|
|
baseurl = 'http://repo.saltstack.com/yum/redhat/{0}/x86_64/latest/'.format(major_release)
|
|
|
|
gpgkey = 'https://repo.saltstack.com/yum/rhel{0}/SALTSTACK-GPG-KEY.pub'.format(major_release)
|
|
|
|
gpgcheck = 1
|
|
|
|
enabled = 1
|
|
|
|
ret = self.run_function(
|
|
|
|
'pkg.mod_repo',
|
|
|
|
[repo],
|
|
|
|
name=name,
|
|
|
|
baseurl=baseurl,
|
|
|
|
gpgkey=gpgkey,
|
|
|
|
gpgcheck=gpgcheck,
|
|
|
|
enabled=enabled,
|
|
|
|
)
|
|
|
|
# return data from pkg.mod_repo contains the file modified at
|
|
|
|
# the top level, so use next(iter(ret)) to get that key
|
|
|
|
self.assertNotEqual(ret, {})
|
|
|
|
repo_info = ret[next(iter(ret))]
|
|
|
|
self.assertIn(repo, repo_info)
|
|
|
|
self.assertEqual(repo_info[repo]['baseurl'], baseurl)
|
|
|
|
ret = self.run_function('pkg.get_repo', [repo])
|
|
|
|
self.assertEqual(ret['baseurl'], baseurl)
|
|
|
|
finally:
|
|
|
|
if repo is not None:
|
|
|
|
self.run_function('pkg.del_repo', [repo])
|
2015-05-21 18:02:24 +00:00
|
|
|
|
2017-05-04 21:13:41 +00:00
|
|
|
@requires_salt_modules('pkg.owner')
|
2015-05-21 18:02:24 +00:00
|
|
|
def test_owner(self):
|
|
|
|
'''
|
|
|
|
test finding the package owning a file
|
|
|
|
'''
|
|
|
|
func = 'pkg.owner'
|
|
|
|
available = self.run_function('sys.doc', [func])
|
|
|
|
|
|
|
|
if available:
|
|
|
|
ret = self.run_function(func, ['/bin/ls'])
|
|
|
|
self.assertNotEqual(len(ret), 0)
|
|
|
|
else:
|
|
|
|
os_grain = self.run_function('grains.item', ['os'])['os']
|
|
|
|
self.skipTest('{0} is unavailable on {1}'.format(func, os_grain))
|
|
|
|
|
|
|
|
@requires_network()
|
|
|
|
@destructiveTest
|
|
|
|
def test_install_remove(self):
|
|
|
|
'''
|
|
|
|
successfully install and uninstall a package
|
|
|
|
'''
|
2018-01-23 16:39:06 +00:00
|
|
|
version = self.run_function('pkg.version', [self.pkg])
|
2015-05-21 18:02:24 +00:00
|
|
|
|
|
|
|
def test_install():
|
2018-01-23 16:39:06 +00:00
|
|
|
install_ret = self.run_function('pkg.install', [self.pkg])
|
|
|
|
self.assertIn(self.pkg, install_ret)
|
2015-05-21 18:02:24 +00:00
|
|
|
|
|
|
|
def test_remove():
|
2018-01-23 16:39:06 +00:00
|
|
|
remove_ret = self.run_function('pkg.remove', [self.pkg])
|
|
|
|
self.assertIn(self.pkg, remove_ret)
|
2015-05-21 18:02:24 +00:00
|
|
|
|
2017-05-05 22:29:56 +00:00
|
|
|
if version and isinstance(version, dict):
|
2018-01-23 16:42:49 +00:00
|
|
|
version = version[self.pkg]
|
2017-05-04 21:13:41 +00:00
|
|
|
|
2015-05-21 18:02:24 +00:00
|
|
|
if version:
|
|
|
|
test_remove()
|
|
|
|
test_install()
|
|
|
|
else:
|
|
|
|
test_install()
|
|
|
|
test_remove()
|
|
|
|
|
2017-05-04 21:13:41 +00:00
|
|
|
@requires_salt_modules('pkg.hold', 'pkg.unhold')
|
2015-05-21 18:02:24 +00:00
|
|
|
@requires_network()
|
|
|
|
@destructiveTest
|
|
|
|
def test_hold_unhold(self):
|
|
|
|
'''
|
|
|
|
test holding and unholding a package
|
|
|
|
'''
|
|
|
|
os_family = self.run_function('grains.item', ['os_family'])['os_family']
|
2015-06-11 20:54:40 +00:00
|
|
|
os_major_release = self.run_function('grains.item', ['osmajorrelease'])['osmajorrelease']
|
2015-06-01 17:30:02 +00:00
|
|
|
available = self.run_function('sys.doc', ['pkg.hold'])
|
|
|
|
|
|
|
|
if available:
|
2018-03-06 21:54:40 +00:00
|
|
|
self.run_function('pkg.install', [self.pkg])
|
2015-06-01 17:30:02 +00:00
|
|
|
if os_family == 'RedHat':
|
2015-06-11 20:54:40 +00:00
|
|
|
lock_pkg = 'yum-versionlock' if os_major_release == '5' else 'yum-plugin-versionlock'
|
|
|
|
versionlock = self.run_function('pkg.version', [lock_pkg])
|
2015-06-01 17:30:02 +00:00
|
|
|
if not versionlock:
|
2015-06-11 20:54:40 +00:00
|
|
|
self.run_function('pkg.install', [lock_pkg])
|
2015-06-01 17:30:02 +00:00
|
|
|
|
2018-01-23 16:39:06 +00:00
|
|
|
hold_ret = self.run_function('pkg.hold', [self.pkg])
|
|
|
|
self.assertIn(self.pkg, hold_ret)
|
|
|
|
self.assertTrue(hold_ret[self.pkg]['result'])
|
2015-06-01 17:30:02 +00:00
|
|
|
|
2018-01-23 16:39:06 +00:00
|
|
|
unhold_ret = self.run_function('pkg.unhold', [self.pkg])
|
|
|
|
self.assertIn(self.pkg, unhold_ret)
|
2018-03-06 21:54:40 +00:00
|
|
|
self.assertTrue(unhold_ret[self.pkg]['result'])
|
2015-06-01 17:30:02 +00:00
|
|
|
|
|
|
|
if os_family == 'RedHat':
|
|
|
|
if not versionlock:
|
2015-06-11 20:54:40 +00:00
|
|
|
self.run_function('pkg.remove', [lock_pkg])
|
2018-03-06 21:54:40 +00:00
|
|
|
self.run_function('pkg.remove', [self.pkg])
|
2015-05-21 18:02:24 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
os_grain = self.run_function('grains.item', ['os'])['os']
|
2015-06-01 17:30:02 +00:00
|
|
|
self.skipTest('{0} is unavailable on {1}'.format('pkg.hold', os_grain))
|
2015-05-21 18:02:24 +00:00
|
|
|
|
|
|
|
@requires_network()
|
|
|
|
@destructiveTest
|
|
|
|
def test_refresh_db(self):
|
|
|
|
'''
|
|
|
|
test refreshing the package database
|
|
|
|
'''
|
|
|
|
func = 'pkg.refresh_db'
|
|
|
|
os_family = self.run_function('grains.item', ['os_family'])['os_family']
|
|
|
|
|
2017-05-12 20:21:22 +00:00
|
|
|
rtag = salt.utils.pkg.rtag(self.minion_opts)
|
|
|
|
salt.utils.pkg.write_rtag(self.minion_opts)
|
|
|
|
self.assertTrue(os.path.isfile(rtag))
|
|
|
|
|
2015-05-21 18:02:24 +00:00
|
|
|
if os_family == 'RedHat':
|
|
|
|
ret = self.run_function(func)
|
|
|
|
self.assertIn(ret, (True, None))
|
2016-09-23 23:03:18 +00:00
|
|
|
elif os_family == 'Suse':
|
|
|
|
ret = self.run_function(func)
|
|
|
|
if not isinstance(ret, dict):
|
|
|
|
self.skipTest('Upstream repo did not return coherent results. Skipping test.')
|
|
|
|
self.assertNotEqual(ret, {})
|
2015-05-21 18:02:24 +00:00
|
|
|
elif os_family == 'Debian':
|
|
|
|
ret = self.run_function(func)
|
2016-06-17 15:35:47 +00:00
|
|
|
if not isinstance(ret, dict):
|
|
|
|
self.skipTest('{0} encountered an error: {1}'.format(func, ret))
|
2015-05-21 18:02:24 +00:00
|
|
|
self.assertNotEqual(ret, {})
|
2015-12-16 17:23:10 +00:00
|
|
|
if not isinstance(ret, dict):
|
|
|
|
self.skipTest('Upstream repo did not return coherent results. Skipping test.')
|
2015-05-21 18:02:24 +00:00
|
|
|
for source, state in ret.items():
|
|
|
|
self.assertIn(state, (True, False, None))
|
|
|
|
else:
|
|
|
|
os_grain = self.run_function('grains.item', ['os'])['os']
|
|
|
|
self.skipTest('{0} is unavailable on {1}'.format(func, os_grain))
|
|
|
|
|
2017-05-12 20:21:22 +00:00
|
|
|
self.assertFalse(os.path.isfile(rtag))
|
|
|
|
|
2016-02-23 22:22:14 +00:00
|
|
|
@requires_salt_modules('pkg.info_installed')
|
2016-02-23 00:02:34 +00:00
|
|
|
def test_pkg_info(self):
|
|
|
|
'''
|
|
|
|
Test returning useful information on Ubuntu systems.
|
|
|
|
'''
|
|
|
|
func = 'pkg.info_installed'
|
|
|
|
os_family = self.run_function('grains.item', ['os_family'])['os_family']
|
|
|
|
|
|
|
|
if os_family == 'Debian':
|
2016-02-24 16:50:52 +00:00
|
|
|
ret = self.run_function(func, ['bash-completion', 'dpkg'])
|
2016-02-23 00:02:34 +00:00
|
|
|
keys = ret.keys()
|
|
|
|
self.assertIn('bash-completion', keys)
|
2016-02-24 16:50:52 +00:00
|
|
|
self.assertIn('dpkg', keys)
|
|
|
|
elif os_family == 'RedHat':
|
2018-01-18 04:35:41 +00:00
|
|
|
ret = self.run_function(func, ['rpm', 'bash'])
|
2016-02-24 16:50:52 +00:00
|
|
|
keys = ret.keys()
|
|
|
|
self.assertIn('rpm', keys)
|
2018-01-18 04:35:41 +00:00
|
|
|
self.assertIn('bash', keys)
|
2017-05-16 12:42:07 +00:00
|
|
|
elif os_family == 'Suse':
|
2016-03-10 18:18:44 +00:00
|
|
|
ret = self.run_function(func, ['less', 'zypper'])
|
2016-02-24 16:50:52 +00:00
|
|
|
keys = ret.keys()
|
2016-03-10 18:18:44 +00:00
|
|
|
self.assertIn('less', keys)
|
2016-02-24 16:50:52 +00:00
|
|
|
self.assertIn('zypper', keys)
|
2016-02-23 00:02:34 +00:00
|
|
|
|
2016-09-23 23:03:18 +00:00
|
|
|
@requires_network()
|
|
|
|
@destructiveTest
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-25 01:47:15 +00:00
|
|
|
@skipIf(salt.utils.platform.is_windows(), 'pkg.upgrade not available on Windows')
|
2016-09-23 23:03:18 +00:00
|
|
|
def test_pkg_upgrade_has_pending_upgrades(self):
|
|
|
|
'''
|
|
|
|
Test running a system upgrade when there are packages that need upgrading
|
|
|
|
'''
|
|
|
|
func = 'pkg.upgrade'
|
|
|
|
os_family = self.run_function('grains.item', ['os_family'])['os_family']
|
|
|
|
|
|
|
|
# First make sure that an up-to-date copy of the package db is available
|
|
|
|
self.run_function('pkg.refresh_db')
|
|
|
|
|
|
|
|
if os_family == 'Suse':
|
2018-03-15 04:35:25 +00:00
|
|
|
# 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')
|
|
|
|
|
|
|
|
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
|
2016-12-06 23:07:56 +00:00
|
|
|
else:
|
2018-03-15 04:35:25 +00:00
|
|
|
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')
|
|
|
|
|
|
|
|
# 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.
|
2016-09-23 23:03:18 +00:00
|
|
|
ret = self.run_function(func)
|
|
|
|
|
|
|
|
# The changes dictionary should not be empty.
|
2016-09-30 22:33:21 +00:00
|
|
|
if 'changes' in ret:
|
2018-03-15 04:35:25 +00:00
|
|
|
self.assertIn(target, ret['changes'])
|
2016-09-30 22:33:21 +00:00
|
|
|
else:
|
2018-03-15 04:35:25 +00:00
|
|
|
self.assertIn(target, ret)
|
2016-09-23 23:03:18 +00:00
|
|
|
else:
|
2016-10-28 11:23:26 +00:00
|
|
|
ret = self.run_function('pkg.list_upgrades')
|
2016-10-11 22:50:50 +00:00
|
|
|
if ret == '' or ret == {}:
|
2016-09-23 23:03:18 +00:00
|
|
|
self.skipTest('No updates available for this machine. Skipping pkg.upgrade test.')
|
|
|
|
else:
|
|
|
|
ret = self.run_function(func)
|
|
|
|
self.assertNotEqual(ret, {})
|
2017-12-04 20:28:52 +00:00
|
|
|
|
|
|
|
@destructiveTest
|
2018-01-23 18:34:24 +00:00
|
|
|
@skipIf(salt.utils.platform.is_windows(), 'minion is windows')
|
|
|
|
@skipIf(salt.utils.platform.is_darwin(), 'minion is mac')
|
2017-12-04 20:28:52 +00:00
|
|
|
def test_pkg_latest_version(self):
|
|
|
|
'''
|
|
|
|
check that pkg.latest_version returns the latest version of the uninstalled package (it does not install the package, just checking the version)
|
|
|
|
'''
|
|
|
|
grains = self.run_function('grains.items')
|
2018-05-15 20:20:55 +00:00
|
|
|
remove = False
|
2018-05-23 16:35:47 +00:00
|
|
|
if salt.utils.platform.is_windows():
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_info = self.run_function('pkg.version', [self.pkg])
|
|
|
|
remove = False if cmd_info == '' else True
|
|
|
|
else:
|
|
|
|
cmd_info = self.run_function('pkg.info_installed', [self.pkg])
|
|
|
|
if cmd_info != 'ERROR: package {0} is not installed'.format(self.pkg):
|
|
|
|
remove = True
|
|
|
|
|
|
|
|
# remove package if its installed
|
|
|
|
if remove:
|
|
|
|
cmd_remove = self.run_function('pkg.remove', [self.pkg])
|
|
|
|
|
2017-12-19 19:45:19 +00:00
|
|
|
if grains['os_family'] == 'RedHat':
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_pkg = self.run_function('cmd.run', ['yum list {0}'.format(self.pkg)])
|
2018-05-23 16:35:47 +00:00
|
|
|
elif salt.utils.platform.is_windows():
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_pkg = self.run_function('pkg.list_available', [self.pkg])
|
2017-12-19 19:45:19 +00:00
|
|
|
elif grains['os_family'] == 'Debian':
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_pkg = self.run_function('cmd.run', ['apt list {0}'.format(self.pkg)])
|
2017-12-19 19:45:19 +00:00
|
|
|
elif grains['os_family'] == 'Arch':
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_pkg = self.run_function('cmd.run', ['pacman -Si {0}'.format(self.pkg)])
|
2017-12-19 19:45:19 +00:00
|
|
|
elif grains['os_family'] == 'Suse':
|
2018-05-15 20:20:55 +00:00
|
|
|
cmd_pkg = self.run_function('cmd.run', ['zypper info {0}'.format(self.pkg)])
|
|
|
|
pkg_latest = self.run_function('pkg.latest_version', [self.pkg])
|
|
|
|
self.assertIn(pkg_latest, cmd_pkg)
|