test_pkg.py 33 KB

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