test_pkgrepo.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. """
  2. tests for pkgrepo states
  3. """
  4. import os
  5. import salt.utils.files
  6. import salt.utils.platform
  7. from tests.support.case import ModuleCase
  8. from tests.support.helpers import (
  9. destructiveTest,
  10. requires_salt_modules,
  11. requires_salt_states,
  12. requires_system_grains,
  13. runs_on,
  14. slowTest,
  15. )
  16. from tests.support.mixins import SaltReturnAssertsMixin
  17. from tests.support.pytest.helpers import temp_state_file
  18. from tests.support.unit import skipIf
  19. @destructiveTest
  20. @skipIf(salt.utils.platform.is_windows(), "minion is windows")
  21. class PkgrepoTest(ModuleCase, SaltReturnAssertsMixin):
  22. """
  23. pkgrepo state tests
  24. """
  25. @requires_salt_modules("pkgrepo.managed")
  26. @requires_system_grains
  27. def test_pkgrepo_01_managed(self, grains):
  28. """
  29. Test adding a repo
  30. """
  31. if grains["os"] == "Ubuntu" and grains["osrelease_info"] >= (15, 10):
  32. self.skipTest(
  33. "The PPA used for this test does not exist for Ubuntu Wily"
  34. " (15.10) and later."
  35. )
  36. if grains["os_family"] == "Debian":
  37. try:
  38. from aptsources import sourceslist # pylint: disable=unused-import
  39. except ImportError:
  40. self.skipTest("aptsources.sourceslist python module not found")
  41. ret = self.run_function("state.sls", mods="pkgrepo.managed", timeout=120)
  42. # If the below assert fails then no states were run, and the SLS in
  43. # tests/integration/files/file/base/pkgrepo/managed.sls needs to be
  44. # corrected.
  45. self.assertReturnNonEmptySaltType(ret)
  46. for state_id, state_result in ret.items():
  47. self.assertSaltTrueReturn(dict([(state_id, state_result)]))
  48. @requires_salt_modules("pkgrepo.absent")
  49. @requires_system_grains
  50. def test_pkgrepo_02_absent(self, grains):
  51. """
  52. Test removing the repo from the above test
  53. """
  54. if grains["os"] == "Ubuntu" and grains["osrelease_info"] >= (15, 10):
  55. self.skipTest(
  56. "The PPA used for this test does not exist for Ubuntu Wily"
  57. " (15.10) and later."
  58. )
  59. ret = self.run_function("state.sls", mods="pkgrepo.absent", timeout=120)
  60. # If the below assert fails then no states were run, and the SLS in
  61. # tests/integration/files/file/base/pkgrepo/absent.sls needs to be
  62. # corrected.
  63. self.assertReturnNonEmptySaltType(ret)
  64. for state_id, state_result in ret.items():
  65. self.assertSaltTrueReturn(dict([(state_id, state_result)]))
  66. @requires_salt_states("pkgrepo.absent", "pkgrepo.managed")
  67. @requires_system_grains
  68. @slowTest
  69. def test_pkgrepo_03_with_comments(self, grains):
  70. """
  71. Test adding a repo with comments
  72. """
  73. kwargs = {}
  74. if grains["os_family"] == "RedHat":
  75. kwargs = {
  76. "name": "examplerepo",
  77. "baseurl": "http://example.com/repo",
  78. "enabled": False,
  79. "comments": ["This is a comment"],
  80. }
  81. else:
  82. self.skipTest(
  83. "{}/{} test case needed".format(grains["os_family"], grains["os"])
  84. )
  85. try:
  86. # Run the state to add the repo
  87. ret = self.run_state("pkgrepo.managed", **kwargs)
  88. self.assertSaltTrueReturn(ret)
  89. # Run again with modified comments
  90. kwargs["comments"].append("This is another comment")
  91. ret = self.run_state("pkgrepo.managed", **kwargs)
  92. self.assertSaltTrueReturn(ret)
  93. ret = ret[next(iter(ret))]
  94. self.assertEqual(
  95. ret["changes"],
  96. {
  97. "comments": {
  98. "old": ["This is a comment"],
  99. "new": ["This is a comment", "This is another comment"],
  100. }
  101. },
  102. )
  103. # Run a third time, no changes should be made
  104. ret = self.run_state("pkgrepo.managed", **kwargs)
  105. self.assertSaltTrueReturn(ret)
  106. ret = ret[next(iter(ret))]
  107. self.assertFalse(ret["changes"])
  108. self.assertEqual(
  109. ret["comment"],
  110. "Package repo '{}' already configured".format(kwargs["name"]),
  111. )
  112. finally:
  113. # Clean up
  114. self.run_state("pkgrepo.absent", name=kwargs["name"])
  115. @requires_salt_states("pkgrepo.managed")
  116. @requires_system_grains
  117. @slowTest
  118. def test_pkgrepo_04_apt_with_architectures(self, grains):
  119. """
  120. Test managing a repo with architectures specified
  121. """
  122. if grains["os_family"].lower() != "debian":
  123. self.skipTest("APT-only test")
  124. name = "deb {{arch}}http://foo.com/bar/latest {oscodename} main".format(
  125. oscodename=grains["oscodename"]
  126. )
  127. def _get_arch(arch):
  128. return "[arch={}] ".format(arch) if arch else ""
  129. def _run(arch="", test=False):
  130. ret = self.run_state(
  131. "pkgrepo.managed",
  132. name=name.format(arch=_get_arch(arch)),
  133. file=fn_,
  134. refresh=False,
  135. test=test,
  136. )
  137. return ret[next(iter(ret))]
  138. fn_ = salt.utils.files.mkstemp(dir="/etc/apt/sources.list.d", suffix=".list")
  139. try:
  140. # Run with test=True
  141. ret = _run(test=True)
  142. assert ret["changes"] == {"repo": name.format(arch="")}, ret["changes"]
  143. assert "would be" in ret["comment"], ret["comment"]
  144. assert ret["result"] is None, ret["result"]
  145. # Run for real
  146. ret = _run()
  147. assert ret["changes"] == {"repo": name.format(arch="")}, ret["changes"]
  148. assert ret["comment"].startswith("Configured"), ret["comment"]
  149. assert ret["result"] is True, ret["result"]
  150. # Run again with test=True, should exit with no changes and a True
  151. # result.
  152. ret = _run(test=True)
  153. assert not ret["changes"], ret["changes"]
  154. assert "already" in ret["comment"], ret["comment"]
  155. assert ret["result"] is True, ret["result"]
  156. # Run for real again, results should be the same as above (i.e. we
  157. # should never get to the point where we exit with a None result).
  158. ret = _run()
  159. assert not ret["changes"], ret["changes"]
  160. assert "already" in ret["comment"], ret["comment"]
  161. assert ret["result"] is True, ret["result"]
  162. expected_changes = {
  163. "line": {
  164. "new": name.format(arch=_get_arch("amd64")),
  165. "old": name.format(arch=""),
  166. },
  167. "architectures": {"new": ["amd64"], "old": []},
  168. }
  169. # Run with test=True and the architecture set. We should get a None
  170. # result with some expected changes.
  171. ret = _run(arch="amd64", test=True)
  172. assert ret["changes"] == expected_changes, ret["changes"]
  173. assert "would be" in ret["comment"], ret["comment"]
  174. assert ret["result"] is None, ret["result"]
  175. # Run for real, with the architecture set. We should get a True
  176. # result with the same changes.
  177. ret = _run(arch="amd64")
  178. assert ret["changes"] == expected_changes, ret["changes"]
  179. assert ret["comment"].startswith("Configured"), ret["comment"]
  180. assert ret["result"] is True, ret["result"]
  181. # Run again with test=True, should exit with no changes and a True
  182. # result.
  183. ret = _run(arch="amd64", test=True)
  184. assert not ret["changes"], ret["changes"]
  185. assert "already" in ret["comment"], ret["comment"]
  186. assert ret["result"] is True, ret["result"]
  187. # Run for real again, results should be the same as above (i.e. we
  188. # should never get to the point where we exit with a None result).
  189. ret = _run(arch="amd64")
  190. assert not ret["changes"], ret["changes"]
  191. assert "already" in ret["comment"], ret["comment"]
  192. assert ret["result"] is True, ret["result"]
  193. expected_changes = {
  194. "line": {
  195. "new": name.format(arch=""),
  196. "old": name.format(arch=_get_arch("amd64")),
  197. },
  198. "architectures": {"new": [], "old": ["amd64"]},
  199. }
  200. # Run with test=True and the architecture set back to the original
  201. # value. We should get a None result with some expected changes.
  202. ret = _run(test=True)
  203. assert ret["changes"] == expected_changes, ret["changes"]
  204. assert "would be" in ret["comment"], ret["comment"]
  205. assert ret["result"] is None, ret["result"]
  206. # Run for real, with the architecture set. We should get a True
  207. # result with the same changes.
  208. ret = _run()
  209. assert ret["changes"] == expected_changes, ret["changes"]
  210. assert ret["comment"].startswith("Configured"), ret["comment"]
  211. assert ret["result"] is True, ret["result"]
  212. # Run again with test=True, should exit with no changes and a True
  213. # result.
  214. ret = _run(test=True)
  215. assert not ret["changes"], ret["changes"]
  216. assert "already" in ret["comment"], ret["comment"]
  217. assert ret["result"] is True, ret["result"]
  218. # Run for real again, results should be the same as above (i.e. we
  219. # should never get to the point where we exit with a None result).
  220. ret = _run()
  221. assert not ret["changes"], ret["changes"]
  222. assert "already" in ret["comment"], ret["comment"]
  223. assert ret["result"] is True, ret["result"]
  224. finally:
  225. try:
  226. os.remove(fn_)
  227. except OSError:
  228. pass
  229. @requires_salt_states("pkgrepo.absent", "pkgrepo.managed")
  230. @requires_system_grains
  231. @slowTest
  232. def test_pkgrepo_05_copr_with_comments(self, grains):
  233. """
  234. Test copr
  235. """
  236. kwargs = {}
  237. if grains["os_family"] == "RedHat":
  238. if (
  239. grains["osfinger"] == "CentOS Linux-7"
  240. or grains["osfinger"] == "Amazon Linux-2"
  241. ):
  242. self.skipTest("copr plugin not installed on Centos 7 CI")
  243. kwargs = {
  244. "name": "hello-copr",
  245. "copr": "mymindstorm/hello",
  246. "enabled": False,
  247. "comments": ["This is a comment"],
  248. }
  249. else:
  250. self.skipTest(
  251. "{}/{} test case needed".format(grains["os_family"], grains["os"])
  252. )
  253. try:
  254. # Run the state to add the repo
  255. ret = self.run_state("pkgrepo.managed", **kwargs)
  256. self.assertSaltTrueReturn(ret)
  257. # Run again with modified comments
  258. kwargs["comments"].append("This is another comment")
  259. ret = self.run_state("pkgrepo.managed", **kwargs)
  260. self.assertSaltTrueReturn(ret)
  261. ret = ret[next(iter(ret))]
  262. self.assertEqual(
  263. ret["changes"],
  264. {
  265. "comments": {
  266. "old": ["This is a comment"],
  267. "new": ["This is a comment", "This is another comment"],
  268. }
  269. },
  270. )
  271. # Run a third time, no changes should be made
  272. ret = self.run_state("pkgrepo.managed", **kwargs)
  273. self.assertSaltTrueReturn(ret)
  274. ret = ret[next(iter(ret))]
  275. self.assertFalse(ret["changes"])
  276. self.assertEqual(
  277. ret["comment"],
  278. "Package repo '{}' already configured".format(kwargs["name"]),
  279. )
  280. finally:
  281. # Clean up
  282. self.run_state("pkgrepo.absent", copr=kwargs["copr"])
  283. @runs_on(kernel="linux", os="Ubuntu")
  284. def test_managed_multiple_comps(self):
  285. state_file = """
  286. ubuntu-backports:
  287. pkgrepo.managed:
  288. - name: 'deb http://fi.archive.ubuntu.com/ubuntu focal-backports'
  289. - comps: main, restricted, universe, multiverse
  290. - refresh: false
  291. - disabled: false
  292. - clean_file: true
  293. - file: /etc/apt/sources.list.d/99-salt-archive-ubuntu-focal-backports.list
  294. - require_in:
  295. - pkgrepo: canonical-ubuntu
  296. canonical-ubuntu:
  297. pkgrepo.managed:
  298. - name: 'deb http://archive.canonical.com/ubuntu {{ salt['grains.get']('oscodename') }}'
  299. - comps: partner
  300. - refresh: false
  301. - disabled: false
  302. - clean_file: true
  303. - file: /etc/apt/sources.list.d/99-salt-canonical-ubuntu.list
  304. """
  305. def remove_apt_list_file(path):
  306. if os.path.exists(path):
  307. os.unlink(path)
  308. self.addCleanup(
  309. remove_apt_list_file,
  310. "/etc/apt/sources.list.d/99-salt-canonical-ubuntu.list",
  311. )
  312. self.addCleanup(
  313. remove_apt_list_file,
  314. "/etc/apt/sources.list.d/99-salt-archive-ubuntu-focal-backports.list",
  315. )
  316. with temp_state_file("multiple-comps-repos.sls", state_file):
  317. ret = self.run_function("state.sls", ["multiple-comps-repos"])
  318. for state_run in ret.values():
  319. # On the first run, we must have changes
  320. assert state_run["changes"]
  321. ret = self.run_function("state.sls", ["multiple-comps-repos"])
  322. for state_run in ret.values():
  323. # On the second run though, we shouldn't have changes made
  324. assert not state_run["changes"]