Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize pkg integration tests and add a couple new tests #34377

Merged
merged 9 commits into from
Jun 30, 2016
7 changes: 7 additions & 0 deletions salt/states/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,10 @@ def installed(
pkg.installed:
- only_upgrade: True

.. note::
If this parameter is set to True and the package is not already
installed, the state will fail.

:return:
A dictionary containing the state of the software installation
:rtype dict:
Expand Down Expand Up @@ -1506,6 +1510,9 @@ def latest(
pkg.latest:
- only_upgrade: True

.. note::
If this parameter is set to True and the package is not already
installed, the state will fail.
'''
rtag = __gen_rtag()
refresh = bool(
Expand Down
3 changes: 0 additions & 3 deletions tests/integration/files/file/base/pkg_latest_epoch.sls

This file was deleted.

187 changes: 169 additions & 18 deletions tests/integration/states/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'''
# Import python libs
from __future__ import absolute_import
import logging
import os
import time

Expand All @@ -25,6 +26,10 @@
# Import 3rd-party libs
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin

log = logging.getLogger(__name__)

__testcontext__ = {}

_PKG_TARGETS = {
'Arch': ['python2-django', 'libpng'],
'Debian': ['python-plist', 'apg'],
Expand Down Expand Up @@ -109,13 +114,48 @@ def get_lock(path):
return True


def latest_version(run_function, *names):
'''
Helper function which ensures that we don't make any unnecessary calls to
pkg.latest_version to figure out what version we need to install. This
won't stop pkg.latest_version from being run in a pkg.latest state, but it
will reduce the amount of times we check the latest version here in the
test suite.
'''
key = 'latest_version'
if key not in __testcontext__:
__testcontext__[key] = {}
targets = [x for x in names if x not in __testcontext__[key]]
if targets:
result = run_function('pkg.latest_version', targets, refresh=False)
try:
__testcontext__[key].update(result)
except ValueError:
# Only a single target, pkg.latest_version returned a string
__testcontext__[key][targets[0]] = result

ret = dict([(x, __testcontext__[key][x]) for x in names])
if len(names) == 1:
return ret[names[0]]
return ret


@destructiveTest
@requires_salt_modules('pkg.version', 'pkg.latest_version')
class PkgTest(integration.ModuleCase,
integration.SaltReturnAssertsMixIn):
'''
pkg.installed state tests
'''
def setUp(self):
'''
Ensure that we only refresh the first time we run a test
'''
super(PkgTest, self).setUp()
if 'refresh' not in __testcontext__:
self.run_function('pkg.refresh_db')
__testcontext__['refresh'] = True

@skipIf(salt.utils.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_001_installed(self, grains=None):
Expand All @@ -142,7 +182,7 @@ def test_pkg_001_installed(self, grains=None):
# needs to not be installed before we run the states below
self.assertFalse(version)

ret = self.run_state('pkg.installed', name=target)
ret = self.run_state('pkg.installed', name=target, refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
Expand Down Expand Up @@ -180,14 +220,17 @@ def test_pkg_002_installed_with_version(self, grains=None):
time.sleep(5)

target = pkg_targets[0]
version = self.run_function('pkg.latest_version', [target])
version = latest_version(self.run_function, target)

# If this assert fails, we need to find new targets, this test needs to
# be able to test successful installation of packages, so this package
# needs to not be installed before we run the states below
self.assertTrue(version)

ret = self.run_state('pkg.installed', name=target, version=version)
ret = self.run_state('pkg.installed',
name=target,
version=version,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
Expand Down Expand Up @@ -216,7 +259,10 @@ def test_pkg_003_installed_multipkg(self, grains=None):
# packages need to not be installed before we run the states below
self.assertFalse(any(version.values()))

ret = self.run_state('pkg.installed', name=None, pkgs=pkg_targets)
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkg_targets,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
Expand Down Expand Up @@ -253,7 +299,7 @@ def test_pkg_004_installed_multipkg_with_version(self, grains=None):
break
time.sleep(5)

version = self.run_function('pkg.latest_version', [pkg_targets[0]])
version = latest_version(self.run_function, pkg_targets[0])

# If this assert fails, we need to find new targets, this test needs to
# be able to test successful installation of packages, so these
Expand All @@ -262,7 +308,10 @@ def test_pkg_004_installed_multipkg_with_version(self, grains=None):

pkgs = [{pkg_targets[0]: version}, pkg_targets[1]]

ret = self.run_state('pkg.installed', name=None, pkgs=pkgs)
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkgs,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
Expand Down Expand Up @@ -297,7 +346,9 @@ def test_pkg_005_installed_32bit(self, grains=None):
# below
self.assertFalse(bool(version))

ret = self.run_state('pkg.installed', name=target)
ret = self.run_state('pkg.installed',
name=target,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
Expand Down Expand Up @@ -333,15 +384,18 @@ def test_pkg_006_installed_32bit_with_version(self, grains=None):
and grains['osrelease'].startswith('5.'):
target = target.replace('.i686', '.i386')

version = self.run_function('pkg.latest_version', [target])
version = latest_version(self.run_function, target)

# If this assert fails, we need to find a new target. This test
# needs to be able to test successful installation of the package, so
# the target needs to not be installed before we run the states
# below
self.assertTrue(bool(version))

ret = self.run_state('pkg.installed', name=target, version=version)
ret = self.run_state('pkg.installed',
name=target,
version=version,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)
Expand All @@ -363,20 +417,20 @@ def test_pkg_007_with_dot_in_pkgname(self, grains=None):
os_version = grains.get('osmajorrelease', [''])[0]
target = _PKG_TARGETS_DOT.get(os_family, {}).get(os_version)
if target:
version = self.run_function('pkg.latest_version', [target])
version = latest_version(self.run_function, target)
# If this assert fails, we need to find a new target. This test
# needs to be able to test successful installation of the package, so
# the target needs to not be installed before we run the
# pkg.installed state below
self.assertTrue(bool(version))
ret = self.run_state('pkg.installed', name=target)
ret = self.run_state('pkg.installed', name=target, refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)

@skipIf(salt.utils.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_with_epoch_in_version(self, grains=None):
def test_pkg_008_epoch_in_version(self, grains=None):
'''
This tests for the regression found in the following issue:
https://github.com/saltstack/salt/issues/8614
Expand All @@ -391,20 +445,22 @@ def test_pkg_with_epoch_in_version(self, grains=None):
os_version = grains.get('osmajorrelease', [''])[0]
target = _PKG_TARGETS_EPOCH.get(os_family, {}).get(os_version)
if target:
version = self.run_function('pkg.latest_version', [target])
version = latest_version(self.run_function, target)
# If this assert fails, we need to find a new target. This test
# needs to be able to test successful installation of the package, so
# the target needs to not be installed before we run the
# pkg.installed state below
self.assertTrue(bool(version))
ret = self.run_state('pkg.installed', name=target, version=version)
ret = self.run_state('pkg.installed',
name=target,
version=version,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)

@destructiveTest
@skipIf(salt.utils.is_windows(), 'minion is windows')
def test_pkg_008_latest_with_epoch(self):
def test_pkg_009_latest_with_epoch(self):
'''
This tests for the following issue:
https://github.com/saltstack/salt/issues/31014
Expand All @@ -415,11 +471,14 @@ def test_pkg_008_latest_with_epoch(self):
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
self.skipTest('Package manager is not available')

ret = self.run_function('state.sls', mods='pkg_latest_epoch')
ret = self.run_state('pkg.installed',
name='bash-completion',
refresh=False)
self.assertSaltTrueReturn(ret)

@skipIf(salt.utils.is_windows(), 'minion is windows')
@requires_salt_modules('pkg.info_installed')
def test_pkg_009_latest_with_epoch_and_info_installed(self):
def test_pkg_010_latest_with_epoch_and_info_installed(self):
'''
Need to check to ensure the package has been
installed after the pkg_latest_epoch sls
Expand All @@ -437,6 +496,98 @@ def test_pkg_009_latest_with_epoch_and_info_installed(self):
ret = self.run_function('pkg.info_installed', [package])
self.assertTrue(pkgquery in str(ret))

@skipIf(salt.utils.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_011_latest(self, grains=None):
'''
This tests pkg.latest with a package that has no epoch (or a zero
epoch).
'''
# Skip test if package manager not available
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
self.skipTest('Package manager is not available')

os_family = grains.get('os_family', '')
pkg_targets = _PKG_TARGETS.get(os_family, [])

# Make sure that we have targets that match the os_family. If this
# fails then the _PKG_TARGETS dict above needs to have an entry added,
# with two packages that are not installed before these tests are run
self.assertTrue(pkg_targets)

target = pkg_targets[0]
version = latest_version(self.run_function, target)

# If this assert fails, we need to find new targets, this test needs to
# be able to test successful installation of packages, so this package
# needs to not be installed before we run the states below
self.assertTrue(version)

ret = self.run_state('pkg.latest', name=target, refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=target)
self.assertSaltTrueReturn(ret)

@skipIf(salt.utils.is_windows(), 'minion is windows')
@requires_system_grains
def test_pkg_012_latest_only_upgrade(self, grains=None):
'''
WARNING: This test will pick a package with an available upgrade (if
there is one) and upgrade it to the latest version.
'''
os_family = grains.get('os_family', '')
if os_family != 'Debian':
self.skipTest('Minion is not Debian/Ubuntu')

# Skip test if package manager not available
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
self.skipTest('Package manager is not available')

pkg_targets = _PKG_TARGETS.get(os_family, [])

# Make sure that we have targets that match the os_family. If this
# fails then the _PKG_TARGETS dict above needs to have an entry added,
# with two packages that are not installed before these tests are run
self.assertTrue(pkg_targets)

target = pkg_targets[0]
version = latest_version(self.run_function, target)

# If this assert fails, we need to find new targets, this test needs to
# be able to test that the state fails when you try to run the state
# with only_upgrade=True on a package which is not already installed,
# so the targeted package needs to not be installed before we run the
# state below.
self.assertTrue(version)

ret = self.run_state('pkg.latest', name=target, refresh=False,
only_upgrade=True)
self.assertSaltFalseReturn(ret)

# Now look for updates and try to run the state on a package which is
# already up-to-date.
updates = self.run_function('pkg.list_upgrades', refresh=False)
try:
target = next(iter(updates))
except StopIteration:
log.warning(
'No available upgrades, skipping only_upgrade=True test with '
'already-installed package. For best results run this test '
'on a machine with upgrades available.'
)
else:
ret = self.run_state('pkg.latest', name=target, refresh=False,
only_upgrade=True)
self.assertSaltTrueReturn(ret)
new_version = self.run_function('pkg.version', [target])
self.assertEqual(new_version, updates[target])
ret = self.run_state('pkg.latest', name=target, refresh=False,
only_upgrade=True)
self.assertEqual(
ret['pkg_|-{0}_|-{0}_|-latest'.format(target)]['comment'],
'Package {0} is already up-to-date'.format(target)
)

if __name__ == '__main__':
from integration import run_tests
run_tests(PkgTest)