test_pkg.py 35 KB

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