test_pkg.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. # -*- coding: utf-8 -*-
  2. '''
  3. tests for pkg state
  4. '''
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import functools
  8. import logging
  9. import os
  10. import time
  11. # Import Salt Testing libs
  12. from tests.support.case import ModuleCase
  13. from tests.support.mixins import SaltReturnAssertsMixin
  14. from tests.support.unit import skipIf
  15. # Import Salt libs
  16. import salt.utils.files
  17. import salt.utils.path
  18. import salt.utils.pkg.rpm
  19. import salt.utils.platform
  20. # Import 3rd-party libs
  21. import pytest
  22. from salt.ext import six
  23. from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
  24. try:
  25. from distro import LinuxDistribution
  26. pre_grains = LinuxDistribution()
  27. except ImportError:
  28. pre_grains = None
  29. log = logging.getLogger(__name__)
  30. _PKG_EPOCH_TARGETS = []
  31. _PKG_TARGETS = ['figlet', 'sl']
  32. _PKG_32_TARGETS = []
  33. _PKG_CAP_TARGETS = []
  34. _PKG_DOT_TARGETS = []
  35. _WILDCARDS_SUPPORTED = False
  36. _VERSION_SPEC_SUPPORTED = True
  37. if salt.utils.platform.is_windows():
  38. _PKG_TARGETS = ['7zip', 'putty']
  39. elif salt.utils.platform.is_freebsd:
  40. _VERSION_SPEC_SUPPORTED = False
  41. elif pre_grains:
  42. if any(arch in pre_grains.like() for arch in ('arch', 'archlinux')):
  43. _WILDCARDS_SUPPORTED = True
  44. elif 'debian' in pre_grains.like():
  45. _WILDCARDS_SUPPORTED = True
  46. elif 'rhel' in pre_grains.like():
  47. _PKG_TARGETS = ['units', 'zsh-html']
  48. _WILDCARDS_SUPPORTED = True
  49. if pre_grains.id() == 'centos':
  50. if pre_grains.major_version() == 5:
  51. _PKG_32_TARGETS = ['xz-devel.i386']
  52. else:
  53. _PKG_32_TARGETS.append('xz-devel.i686')
  54. if pre_grains.major_version() == 5:
  55. _PKG_DOT_TARGETS = ['python-migrate0.5']
  56. elif pre_grains.major_version() == 6:
  57. _PKG_DOT_TARGETS = ['tomcat6-el-2.1-api']
  58. elif pre_grains.major_version() == 7:
  59. _PKG_DOT_TARGETS = ['tomcat-el-2.2-api']
  60. _PKG_EPOCH_TARGETS = ['comps-extras']
  61. elif pre_grains.id() in ('sles', 'opensuse'):
  62. _PKG_TARGETS = ['figlet', 'htop']
  63. _PKG_CAP_TARGETS = [('perl(ZNC)', 'znc-perl')]
  64. def runs_on(platforms=None, os_like=None, reason=''):
  65. def decorator(caller):
  66. @functools.wraps(caller)
  67. def wrapper(cls):
  68. if platforms:
  69. if not any(getattr(salt.utils.platform, 'is_' + platform)() for platform in platforms):
  70. cls.skipTest(reason if reason else 'OS not in [{}]'.format(', '.join(platforms)))
  71. if pre_grains and os_like:
  72. if not any(x in pre_grains.like() for x in os_like):
  73. cls.skipTest(reason if reason else 'OS not similar to [{}]'.format(', '.join(os_like)))
  74. return caller(cls)
  75. return wrapper
  76. return decorator
  77. @pytest.mark.destructive_test
  78. @pytest.mark.windows_whitelisted
  79. class PkgTest(ModuleCase, SaltReturnAssertsMixin):
  80. @classmethod
  81. def setUpClass(cls):
  82. cls.ctx = {}
  83. @classmethod
  84. def tearDownClass(cls):
  85. del cls.ctx
  86. def latest_version(self, *names):
  87. '''
  88. Helper function which ensures that we don't make any unnecessary calls to
  89. pkg.latest_version to figure out what version we need to install. This
  90. won't stop pkg.latest_version from being run in a pkg.latest state, but it
  91. will reduce the amount of times we check the latest version here in the
  92. test suite.
  93. '''
  94. key = 'latest_version'
  95. if key not in self.ctx:
  96. self.ctx[key] = dict()
  97. targets = [x for x in names if x not in self.ctx[key]]
  98. if targets:
  99. result = self.run_function('pkg.latest_version', targets, refresh=False)
  100. try:
  101. self.ctx[key].update(result)
  102. except ValueError:
  103. # Only a single target, pkg.latest_version returned a string
  104. self.ctx[key][targets[0]] = result
  105. ret = dict([(x, self.ctx[key].get(x, '')) for x in names])
  106. if len(names) == 1:
  107. return ret[names[0]]
  108. return ret
  109. def setUp(self):
  110. super(PkgTest, self).setUp()
  111. if 'refresh' not in self.ctx:
  112. self.run_function('pkg.refresh_db')
  113. self.ctx['refresh'] = True
  114. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed')
  115. def test_pkg_001_installed(self):
  116. '''
  117. This is a destructive test as it installs and then removes a package
  118. '''
  119. target = _PKG_TARGETS[0]
  120. version = self.run_function('pkg.version', [target])
  121. # If this assert fails, we need to find new targets, this test needs to
  122. # be able to test successful installation of packages, so this package
  123. # needs to not be installed before we run the states below
  124. self.assertFalse(version)
  125. ret = self.run_state('pkg.installed', name=target, refresh=False)
  126. self.assertSaltTrueReturn(ret)
  127. ret = self.run_state('pkg.removed', name=target)
  128. self.assertSaltTrueReturn(ret)
  129. @skipIf(not _VERSION_SPEC_SUPPORTED, 'Version specification not supported')
  130. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  131. def test_pkg_002_installed_with_version(self):
  132. '''
  133. This is a destructive test as it installs and then removes a package
  134. '''
  135. if pre_grains and 'arch' in pre_grains.like():
  136. for idx in range(13):
  137. if idx == 12:
  138. raise Exception('Package database locked after 60 seconds, '
  139. 'bailing out')
  140. if not os.path.isfile('/var/lib/pacman/db.lck'):
  141. break
  142. time.sleep(5)
  143. target = _PKG_TARGETS[0]
  144. version = self.latest_version(target)
  145. # If this assert fails, we need to find new targets, this test needs to
  146. # be able to test successful installation of packages, so this package
  147. # needs to not be installed before we run the states below
  148. self.assertTrue(version)
  149. ret = self.run_state('pkg.installed',
  150. name=target,
  151. version=version,
  152. refresh=False)
  153. self.assertSaltTrueReturn(ret)
  154. ret = self.run_state('pkg.removed', name=target)
  155. self.assertSaltTrueReturn(ret)
  156. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  157. def test_pkg_003_installed_multipkg(self):
  158. '''
  159. This is a destructive test as it installs and then removes two packages
  160. '''
  161. version = self.run_function('pkg.version', _PKG_TARGETS)
  162. # If this assert fails, we need to find new targets, this test needs to
  163. # be able to test successful installation of packages, so these
  164. # packages need to not be installed before we run the states below
  165. self.assertFalse(any(version.values()))
  166. self.assertSaltTrueReturn(self.run_state('pkg.removed', name=None, pkgs=_PKG_TARGETS))
  167. try:
  168. ret = self.run_state('pkg.installed',
  169. name=None,
  170. pkgs=_PKG_TARGETS,
  171. refresh=False)
  172. self.assertSaltTrueReturn(ret)
  173. finally:
  174. ret = self.run_state('pkg.removed', name=None, pkgs=_PKG_TARGETS)
  175. self.assertSaltTrueReturn(ret)
  176. @skipIf(not _VERSION_SPEC_SUPPORTED, 'Version specification not supported')
  177. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  178. def test_pkg_004_installed_multipkg_with_version(self):
  179. '''
  180. This is a destructive test as it installs and then removes two packages
  181. '''
  182. if pre_grains and 'arch' in pre_grains.like():
  183. for idx in range(13):
  184. if idx == 12:
  185. raise Exception('Package database locked after 60 seconds, '
  186. 'bailing out')
  187. if not os.path.isfile('/var/lib/pacman/db.lck'):
  188. break
  189. time.sleep(5)
  190. version = self.latest_version(_PKG_TARGETS[0])
  191. # If this assert fails, we need to find new targets, this test needs to
  192. # be able to test successful installation of packages, so these
  193. # packages need to not be installed before we run the states below
  194. self.assertTrue(bool(version))
  195. pkgs = [{_PKG_TARGETS[0]: version}, _PKG_TARGETS[1]]
  196. try:
  197. ret = self.run_state('pkg.installed',
  198. name=None,
  199. pkgs=pkgs,
  200. refresh=False)
  201. self.assertSaltTrueReturn(ret)
  202. finally:
  203. ret = self.run_state('pkg.removed', name=None, pkgs=_PKG_TARGETS)
  204. self.assertSaltTrueReturn(ret)
  205. @skipIf(not _PKG_32_TARGETS, 'No 32 bit packages have been specified for testing')
  206. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed')
  207. def test_pkg_005_installed_32bit(self):
  208. '''
  209. This is a destructive test as it installs and then removes a package
  210. '''
  211. target = _PKG_32_TARGETS[0]
  212. # _PKG_TARGETS_32 is only populated for platforms for which Salt has to
  213. # munge package names for 32-bit-on-x86_64 (Currently only Ubuntu and
  214. # RHEL-based). Don't actually perform this test on other platforms.
  215. version = self.run_function('pkg.version', [target])
  216. # If this assert fails, we need to find a new target. This test
  217. # needs to be able to test successful installation of packages, so
  218. # the target needs to not be installed before we run the states
  219. # below
  220. self.assertFalse(version)
  221. ret = self.run_state('pkg.installed',
  222. name=target,
  223. refresh=False)
  224. self.assertSaltTrueReturn(ret)
  225. ret = self.run_state('pkg.removed', name=target)
  226. self.assertSaltTrueReturn(ret)
  227. @skipIf(not _PKG_32_TARGETS, 'No 32 bit packages have been specified for testing')
  228. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  229. def test_pkg_006_installed_32bit_with_version(self):
  230. '''
  231. This is a destructive test as it installs and then removes a package
  232. '''
  233. target = _PKG_32_TARGETS[0]
  234. # _PKG_TARGETS_32 is only populated for platforms for which Salt has to
  235. # munge package names for 32-bit-on-x86_64 (Currently only Ubuntu and
  236. # RHEL-based). Don't actually perform this test on other platforms.
  237. if pre_grains and 'arch' in pre_grains.like():
  238. for idx in range(13):
  239. if idx == 12:
  240. raise Exception('Package database locked after 60 seconds, '
  241. 'bailing out')
  242. if not os.path.isfile('/var/lib/pacman/db.lck'):
  243. break
  244. time.sleep(5)
  245. version = self.latest_version(target)
  246. # If this assert fails, we need to find a new target. This test
  247. # needs to be able to test successful installation of the package, so
  248. # the target needs to not be installed before we run the states
  249. # below
  250. self.assertTrue(version)
  251. ret = self.run_state('pkg.installed',
  252. name=target,
  253. version=version,
  254. refresh=False)
  255. self.assertSaltTrueReturn(ret)
  256. ret = self.run_state('pkg.removed', name=target)
  257. self.assertSaltTrueReturn(ret)
  258. @skipIf(not _PKG_DOT_TARGETS, 'No packages with "." in their name have been configured for')
  259. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  260. def test_pkg_007_with_dot_in_pkgname(self=None):
  261. '''
  262. This tests for the regression found in the following issue:
  263. https://github.com/saltstack/salt/issues/8614
  264. This is a destructive test as it installs a package
  265. '''
  266. target = _PKG_DOT_TARGETS[0]
  267. version = self.latest_version(target)
  268. # If this assert fails, we need to find a new target. This test
  269. # needs to be able to test successful installation of the package, so
  270. # the target needs to not be installed before we run the
  271. # pkg.installed state below
  272. self.assertTrue(bool(version))
  273. ret = self.run_state('pkg.installed', name=target, refresh=False)
  274. self.assertSaltTrueReturn(ret)
  275. ret = self.run_state('pkg.removed', name=target)
  276. self.assertSaltTrueReturn(ret)
  277. @skipIf(not _PKG_EPOCH_TARGETS, 'No targets have been configured with "epoch" in the version')
  278. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  279. def test_pkg_008_epoch_in_version(self):
  280. '''
  281. This tests for the regression found in the following issue:
  282. https://github.com/saltstack/salt/issues/8614
  283. This is a destructive test as it installs a package
  284. '''
  285. target = _PKG_EPOCH_TARGETS[0]
  286. version = self.latest_version(target)
  287. # If this assert fails, we need to find a new target. This test
  288. # needs to be able to test successful installation of the package, so
  289. # the target needs to not be installed before we run the
  290. # pkg.installed state below
  291. self.assertTrue(version)
  292. ret = self.run_state('pkg.installed',
  293. name=target,
  294. version=version,
  295. refresh=False)
  296. self.assertSaltTrueReturn(ret)
  297. ret = self.run_state('pkg.removed', name=target)
  298. self.assertSaltTrueReturn(ret)
  299. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.info_installed', 'pkg.installed', 'pkg.removed')
  300. @runs_on(platforms=['linux'], reason='This test only runs on linux')
  301. def test_pkg_009_latest_with_epoch(self):
  302. '''
  303. This tests for the following issue:
  304. https://github.com/saltstack/salt/issues/31014
  305. This is a destructive test as it installs a package
  306. '''
  307. package = 'bash-completion'
  308. pkgquery = 'version'
  309. ret = self.run_state('pkg.installed',
  310. name=package,
  311. refresh=False)
  312. self.assertSaltTrueReturn(ret)
  313. ret = self.run_function('pkg.info_installed', [package])
  314. self.assertTrue(pkgquery in six.text_type(ret))
  315. @pytest.mark.requires_salt_modules('pkg.latest', 'pkg.removed')
  316. def test_pkg_010_latest(self):
  317. '''
  318. This tests pkg.latest with a package that has no epoch (or a zero
  319. epoch).
  320. '''
  321. target = _PKG_TARGETS[0]
  322. version = self.latest_version(target)
  323. # If this assert fails, we need to find new targets, this test needs to
  324. # be able to test successful installation of packages, so this package
  325. # needs to not be installed before we run the states below
  326. self.assertTrue(version)
  327. ret = self.run_state('pkg.latest', name=target, refresh=False)
  328. self.assertSaltTrueReturn(ret)
  329. ret = self.run_state('pkg.removed', name=target)
  330. self.assertSaltTrueReturn(ret)
  331. @pytest.mark.requires_salt_modules('pkg.latest', 'pkg.list_pkgs', 'pkg.list_upgrades', 'pkg.version')
  332. @runs_on(platforms=['linux'], os_like=['debian'], reason='This test only runs on Debian based linux distributions')
  333. def test_pkg_011_latest_only_upgrade(self):
  334. '''
  335. WARNING: This test will pick a package with an available upgrade (if
  336. there is one) and upgrade it to the latest version.
  337. '''
  338. target = _PKG_TARGETS[0]
  339. # If this assert fails, we need to find new targets, this test needs to
  340. # be able to test that the state fails when you try to run the state
  341. # with only_upgrade=True on a package which is not already installed,
  342. # so the targeted package needs to not be installed before we run the
  343. # state below.
  344. version = self.latest_version(target)
  345. self.assertTrue(version)
  346. ret = self.run_state('pkg.latest', name=target, refresh=False, only_upgrade=True)
  347. self.assertSaltFalseReturn(ret)
  348. # Now look for updates and try to run the state on a package which is already up-to-date.
  349. installed_pkgs = self.run_function('pkg.list_pkgs')
  350. updates = self.run_function('pkg.list_upgrades', refresh=False)
  351. for pkgname in updates:
  352. if pkgname in installed_pkgs:
  353. target = pkgname
  354. break
  355. else:
  356. target = ''
  357. log.warning(
  358. 'No available upgrades to installed packages, skipping '
  359. 'only_upgrade=True test with already-installed package. For '
  360. 'best results run this test on a machine with upgrades '
  361. 'available.'
  362. )
  363. if target:
  364. ret = self.run_state('pkg.latest', name=target, refresh=False,
  365. only_upgrade=True)
  366. self.assertSaltTrueReturn(ret)
  367. new_version = self.run_function('pkg.version', [target])
  368. self.assertEqual(new_version, updates[target])
  369. ret = self.run_state('pkg.latest', name=target, refresh=False,
  370. only_upgrade=True)
  371. self.assertEqual(
  372. ret['pkg_|-{0}_|-{0}_|-latest'.format(target)]['comment'],
  373. 'Package {0} is already up-to-date'.format(target)
  374. )
  375. @skipIf(not _WILDCARDS_SUPPORTED, 'Wildcards in pkg.install are not supported')
  376. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed')
  377. def test_pkg_012_installed_with_wildcard_version(self):
  378. '''
  379. This is a destructive test as it installs and then removes a package
  380. '''
  381. target = _PKG_TARGETS[0]
  382. version = self.run_function('pkg.version', [target])
  383. # If this assert fails, we need to find new targets, this test needs to
  384. # be able to test successful installation of packages, so this package
  385. # needs to not be installed before we run the states below
  386. self.assertFalse(version)
  387. ret = self.run_state(
  388. 'pkg.installed',
  389. name=target,
  390. version='*',
  391. refresh=False,
  392. )
  393. self.assertSaltTrueReturn(ret)
  394. # Repeat state, should pass
  395. ret = self.run_state(
  396. 'pkg.installed',
  397. name=target,
  398. version='*',
  399. refresh=False,
  400. )
  401. expected_comment = (
  402. 'All specified packages are already installed and are at the '
  403. 'desired version'
  404. )
  405. self.assertSaltTrueReturn(ret)
  406. self.assertEqual(ret[next(iter(ret))]['comment'], expected_comment)
  407. # Repeat one more time with unavailable version, test should fail
  408. ret = self.run_state(
  409. 'pkg.installed',
  410. name=target,
  411. version='93413*',
  412. refresh=False,
  413. )
  414. self.assertSaltFalseReturn(ret)
  415. # Clean up
  416. ret = self.run_state('pkg.removed', name=target)
  417. self.assertSaltTrueReturn(ret)
  418. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.latest_version', 'pkg.installed', 'pkg.removed')
  419. @runs_on(platforms=['linux'], os_like=['debian', 'redhat'], reason='Comparison operator not specially implemented')
  420. def test_pkg_013_installed_with_comparison_operator(self):
  421. '''
  422. This is a destructive test as it installs and then removes a package
  423. '''
  424. target = _PKG_TARGETS[0]
  425. version = self.run_function('pkg.version', [target])
  426. # If this assert fails, we need to find new targets, this test needs to
  427. # be able to test successful installation of packages, so this package
  428. # needs to not be installed before we run the states below
  429. self.assertFalse(version)
  430. latest_version = self.run_function(
  431. 'pkg.latest_version',
  432. [target],
  433. refresh=False)
  434. try:
  435. ret = self.run_state(
  436. 'pkg.installed',
  437. name=target,
  438. version='<9999999',
  439. refresh=False,
  440. )
  441. self.assertSaltTrueReturn(ret)
  442. # The version that was installed should be the latest available
  443. version = self.run_function('pkg.version', [target])
  444. self.assertTrue(version, latest_version)
  445. finally:
  446. # Clean up
  447. ret = self.run_state('pkg.removed', name=target)
  448. self.assertSaltTrueReturn(ret)
  449. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed')
  450. @runs_on(platforms=['linux'], os_like=['redhat'], reason='Comparison operator not specially implemented')
  451. def test_pkg_014_installed_missing_release(self):
  452. '''
  453. Tests that a version number missing the release portion still resolves
  454. as correctly installed. For example, version 2.0.2 instead of 2.0.2-1.el7
  455. '''
  456. target = _PKG_TARGETS[0]
  457. version = self.run_function('pkg.version', [target])
  458. # If this assert fails, we need to find new targets, this test needs to
  459. # be able to test successful installation of packages, so this package
  460. # needs to not be installed before we run the states below
  461. self.assertFalse(version)
  462. ret = self.run_state(
  463. 'pkg.installed',
  464. name=target,
  465. version=salt.utils.pkg.rpm.version_to_evr(version)[1],
  466. refresh=False,
  467. )
  468. self.assertSaltTrueReturn(ret)
  469. # Clean up
  470. ret = self.run_state('pkg.removed', name=target)
  471. self.assertSaltTrueReturn(ret)
  472. @pytest.mark.requires_salt_modules('pkg.hold', 'pkg.unhold', 'pkg.installed', 'pkg.removed')
  473. def test_pkg_015_installed_held(self):
  474. '''
  475. Tests that a package can be held even when the package is already installed.
  476. '''
  477. if pre_grains and 'redhat' in pre_grains.like():
  478. # If we're in the Red Hat family first we ensure that
  479. # the yum-plugin-versionlock package is installed
  480. ret = self.run_state(
  481. 'pkg.installed',
  482. name='yum-plugin-versionlock',
  483. refresh=False,
  484. )
  485. self.assertSaltTrueReturn(ret)
  486. target = _PKG_TARGETS[0]
  487. # First we ensure that the package is installed
  488. ret = self.run_state(
  489. 'pkg.installed',
  490. name=target,
  491. refresh=False,
  492. )
  493. self.assertSaltTrueReturn(ret)
  494. # Then we check that the package is now held
  495. ret = self.run_state(
  496. 'pkg.installed',
  497. name=target,
  498. hold=True,
  499. refresh=False,
  500. )
  501. # changes from pkg.hold for Red Hat family are different
  502. if pre_grains:
  503. if 'redhat' in pre_grains.like():
  504. target_changes = {'new': 'hold', 'old': ''}
  505. elif 'debian' in pre_grains.like():
  506. target_changes = {'new': 'hold', 'old': 'install'}
  507. try:
  508. tag = 'pkg_|-{0}_|-{0}_|-installed'.format(target)
  509. self.assertSaltTrueReturn(ret)
  510. self.assertIn(tag, ret)
  511. self.assertIn('changes', ret[tag])
  512. self.assertIn(target, ret[tag]['changes'])
  513. self.assertEqual(ret[tag]['changes'][target], target_changes)
  514. finally:
  515. # Clean up, unhold package and remove
  516. self.run_function('pkg.unhold', name=target)
  517. ret = self.run_state('pkg.removed', name=target)
  518. self.assertSaltTrueReturn(ret)
  519. if pre_grains and 'redhat' in pre_grains.like():
  520. ret = self.run_state('pkg.removed',
  521. name='yum-plugin-versionlock')
  522. self.assertSaltTrueReturn(ret)
  523. @skipIf(not _PKG_CAP_TARGETS, 'Capability not provided')
  524. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed')
  525. def test_pkg_cap_001_installed(self):
  526. '''
  527. This is a destructive test as it installs and then removes a package
  528. '''
  529. target, realpkg = _PKG_CAP_TARGETS[0]
  530. version = self.run_function('pkg.version', [target])
  531. realver = self.run_function('pkg.version', [realpkg])
  532. # If this assert fails, we need to find new targets, this test needs to
  533. # be able to test successful installation of packages, so this package
  534. # needs to not be installed before we run the states below
  535. self.assertFalse(version)
  536. self.assertFalse(realver)
  537. try:
  538. ret = self.run_state('pkg.installed', name=target, refresh=False, resolve_capabilities=True, test=True)
  539. self.assertInSaltComment("The following packages would be installed/updated: {0}".format(realpkg), ret)
  540. ret = self.run_state('pkg.installed', name=target, refresh=False, resolve_capabilities=True)
  541. self.assertSaltTrueReturn(ret)
  542. finally:
  543. ret = self.run_state('pkg.removed', name=realpkg)
  544. self.assertSaltTrueReturn(ret)
  545. @skipIf(not _PKG_CAP_TARGETS, 'Capability not available')
  546. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  547. def test_pkg_cap_002_already_installed(self):
  548. '''
  549. This is a destructive test as it installs and then removes a package
  550. '''
  551. target, realpkg = _PKG_CAP_TARGETS[0]
  552. version = self.run_function('pkg.version', [target])
  553. realver = self.run_function('pkg.version', [realpkg])
  554. # If this assert fails, we need to find new targets, this test needs to
  555. # be able to test successful installation of packages, so this package
  556. # needs to not be installed before we run the states below
  557. self.assertFalse(version)
  558. self.assertFalse(realver)
  559. try:
  560. # install the package
  561. ret = self.run_state('pkg.installed', name=realpkg, refresh=False)
  562. self.assertSaltTrueReturn(ret)
  563. # Try to install again. Nothing should be installed this time.
  564. ret = self.run_state('pkg.installed', name=target, refresh=False, resolve_capabilities=True, test=True)
  565. self.assertInSaltComment("All specified packages are already installed", ret)
  566. ret = self.run_state('pkg.installed', name=target, refresh=False, resolve_capabilities=True)
  567. self.assertSaltTrueReturn(ret)
  568. self.assertInSaltComment("packages are already installed", ret)
  569. finally:
  570. ret = self.run_state('pkg.removed', name=realpkg)
  571. self.assertSaltTrueReturn(ret)
  572. @skipIf(not _PKG_CAP_TARGETS, 'Capability not available')
  573. @skipIf(not _VERSION_SPEC_SUPPORTED, 'Version specification not supported')
  574. @pytest.mark.requires_salt_modules('pkg.installed', 'pkg.removed')
  575. def test_pkg_cap_003_installed_multipkg_with_version(self):
  576. '''
  577. This is a destructive test as it installs and then removes two packages
  578. '''
  579. if pre_grains and ('arch' in pre_grains.like() or 'archlinux' in pre_grains.like()):
  580. for idx in range(13):
  581. if idx == 12:
  582. raise Exception('Package database locked after 60 seconds, '
  583. 'bailing out')
  584. if not os.path.isfile('/var/lib/pacman/db.lck'):
  585. break
  586. time.sleep(5)
  587. target, realpkg = _PKG_CAP_TARGETS[0]
  588. version = self.latest_version(target)
  589. realver = self.latest_version(realpkg)
  590. # If this assert fails, we need to find new targets, this test needs to
  591. # be able to test successful installation of packages, so these
  592. # packages need to not be installed before we run the states below
  593. self.assertTrue(version, 'new pkg cap targets required')
  594. self.assertTrue(realver, 'new pkg cap targets required')
  595. try:
  596. pkgs = [{_PKG_TARGETS[0]: version}, _PKG_TARGETS[1], {target: realver}]
  597. ret = self.run_state('pkg.installed',
  598. name='test_pkg_cap_003_installed_multipkg_with_version-install',
  599. pkgs=pkgs,
  600. refresh=False)
  601. self.assertSaltFalseReturn(ret)
  602. ret = self.run_state('pkg.installed',
  603. name='test_pkg_cap_003_installed_multipkg_with_version-install-capability',
  604. pkgs=pkgs,
  605. refresh=False, resolve_capabilities=True, test=True)
  606. self.assertInSaltComment("packages would be installed/updated", ret)
  607. self.assertInSaltComment("{0}={1}".format(realpkg, realver), ret)
  608. ret = self.run_state('pkg.installed',
  609. name='test_pkg_cap_003_installed_multipkg_with_version-install-capability',
  610. pkgs=pkgs,
  611. refresh=False, resolve_capabilities=True)
  612. self.assertSaltTrueReturn(ret)
  613. cleanup_pkgs = _PKG_TARGETS
  614. cleanup_pkgs.append(realpkg)
  615. finally:
  616. ret = self.run_state('pkg.removed',
  617. name='test_pkg_cap_003_installed_multipkg_with_version-remove',
  618. pkgs=cleanup_pkgs)
  619. self.assertSaltTrueReturn(ret)
  620. @skipIf(not _PKG_CAP_TARGETS, 'Capability not available')
  621. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.latest', 'pkg.removed')
  622. def test_pkg_cap_004_latest(self):
  623. '''
  624. This tests pkg.latest with a package that has no epoch (or a zero
  625. epoch).
  626. '''
  627. target, realpkg = _PKG_CAP_TARGETS[0]
  628. version = self.run_function('pkg.version', [target])
  629. realver = self.run_function('pkg.version', [realpkg])
  630. # If this assert fails, we need to find new targets, this test needs to
  631. # be able to test successful installation of packages, so this package
  632. # needs to not be installed before we run the states below
  633. self.assertFalse(version)
  634. self.assertFalse(realver)
  635. try:
  636. ret = self.run_state('pkg.latest', name=target, refresh=False, resolve_capabilities=True, test=True)
  637. self.assertInSaltComment("The following packages would be installed/upgraded: {0}".format(realpkg), ret)
  638. ret = self.run_state('pkg.latest', name=target, refresh=False, resolve_capabilities=True)
  639. self.assertSaltTrueReturn(ret)
  640. ret = self.run_state('pkg.latest', name=target, refresh=False, resolve_capabilities=True)
  641. self.assertSaltTrueReturn(ret)
  642. self.assertInSaltComment("is already up-to-date", ret)
  643. finally:
  644. ret = self.run_state('pkg.removed', name=realpkg)
  645. self.assertSaltTrueReturn(ret)
  646. @skipIf(not _PKG_CAP_TARGETS, 'Capability not available')
  647. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed', 'pkg.downloaded')
  648. def test_pkg_cap_005_downloaded(self):
  649. '''
  650. This is a destructive test as it installs and then removes a package
  651. '''
  652. target, realpkg = _PKG_CAP_TARGETS[0]
  653. version = self.run_function('pkg.version', [target])
  654. realver = self.run_function('pkg.version', [realpkg])
  655. # If this assert fails, we need to find new targets, this test needs to
  656. # be able to test successful installation of packages, so this package
  657. # needs to not be installed before we run the states below
  658. self.assertFalse(version)
  659. self.assertFalse(realver)
  660. ret = self.run_state('pkg.downloaded', name=target, refresh=False)
  661. self.assertSaltFalseReturn(ret)
  662. ret = self.run_state('pkg.downloaded', name=target, refresh=False, resolve_capabilities=True, test=True)
  663. self.assertInSaltComment("The following packages would be downloaded: {0}".format(realpkg), ret)
  664. ret = self.run_state('pkg.downloaded', name=target, refresh=False, resolve_capabilities=True)
  665. self.assertSaltTrueReturn(ret)
  666. @skipIf(not _PKG_CAP_TARGETS, 'Capability not available')
  667. @pytest.mark.requires_salt_modules('pkg.version', 'pkg.installed', 'pkg.removed', 'pkg.uptodate')
  668. def test_pkg_cap_006_uptodate(self):
  669. '''
  670. This is a destructive test as it installs and then removes a package
  671. '''
  672. target, realpkg = _PKG_CAP_TARGETS[0]
  673. version = self.run_function('pkg.version', [target])
  674. realver = self.run_function('pkg.version', [realpkg])
  675. # If this assert fails, we need to find new targets, this test needs to
  676. # be able to test successful installation of packages, so this package
  677. # needs to not be installed before we run the states below
  678. self.assertFalse(version)
  679. self.assertFalse(realver)
  680. try:
  681. ret = self.run_state('pkg.installed', name=target,
  682. refresh=False, resolve_capabilities=True)
  683. self.assertSaltTrueReturn(ret)
  684. ret = self.run_state('pkg.uptodate',
  685. name='test_pkg_cap_006_uptodate',
  686. pkgs=[target],
  687. refresh=False,
  688. resolve_capabilities=True)
  689. self.assertSaltTrueReturn(ret)
  690. self.assertInSaltComment("System is already up-to-date", ret)
  691. finally:
  692. ret = self.run_state('pkg.removed', name=realpkg)
  693. self.assertSaltTrueReturn(ret)