test_pkg.py 35 KB

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