test_dpkg_lowpkg.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import logging
  8. import os
  9. # Import Salt Libs
  10. import salt.modules.dpkg_lowpkg as dpkg
  11. # Import Salt Testing Libs
  12. from tests.support.mixins import LoaderModuleMockMixin
  13. from tests.support.mock import MagicMock, patch
  14. from tests.support.unit import TestCase
  15. DPKG_ERROR_MSG = """dpkg-query: package 'httpd' is not installed
  16. Use dpkg --contents (= dpkg-deb --contents) to list archive files contents.
  17. """
  18. DPKG_L_OUTPUT = {
  19. "hostname": """\
  20. /.
  21. /bin
  22. /bin/hostname
  23. /usr
  24. /usr/share
  25. /usr/share/doc
  26. /usr/share/doc/hostname
  27. /usr/share/doc/hostname/changelog.gz
  28. /usr/share/doc/hostname/copyright
  29. /usr/share/man
  30. /usr/share/man/man1
  31. /usr/share/man/man1/hostname.1.gz
  32. /bin/dnsdomainname
  33. /bin/domainname
  34. /bin/nisdomainname
  35. /bin/ypdomainname
  36. /usr/share/man/man1/dnsdomainname.1.gz
  37. /usr/share/man/man1/domainname.1.gz
  38. /usr/share/man/man1/nisdomainname.1.gz
  39. /usr/share/man/man1/ypdomainname.1.gz
  40. """
  41. }
  42. class DpkgTestCase(TestCase, LoaderModuleMockMixin):
  43. """
  44. Test cases for salt.modules.dpkg
  45. """
  46. def setUp(self):
  47. dpkg_lowpkg_logger = logging.getLogger("salt.modules.dpkg_lowpkg")
  48. self.level = dpkg_lowpkg_logger.level
  49. dpkg_lowpkg_logger.setLevel(logging.FATAL)
  50. def tearDown(self):
  51. logging.getLogger("salt.modules.dpkg_lowpkg").setLevel(self.level)
  52. def dpkg_L_side_effect(self, cmd, **kwargs):
  53. self.assertEqual(cmd[:2], ["dpkg", "-L"])
  54. package = cmd[2]
  55. return DPKG_L_OUTPUT[package]
  56. def setup_loader_modules(self):
  57. return {dpkg: {}}
  58. # 'unpurge' function tests: 2
  59. def test_unpurge(self):
  60. """
  61. Test if it change package selection for each package
  62. specified to 'install'
  63. """
  64. mock = MagicMock(return_value=[])
  65. with patch.dict(dpkg.__salt__, {"pkg.list_pkgs": mock, "cmd.run": mock}):
  66. self.assertDictEqual(dpkg.unpurge("curl"), {})
  67. def test_unpurge_empty_package(self):
  68. """
  69. Test if it change package selection for each package
  70. specified to 'install'
  71. """
  72. self.assertDictEqual(dpkg.unpurge(), {})
  73. # 'list_pkgs' function tests: 1
  74. def test_list_pkgs(self):
  75. """
  76. Test if it lists the packages currently installed
  77. """
  78. mock = MagicMock(
  79. return_value={
  80. "retcode": 0,
  81. "stderr": "",
  82. "stdout": "installed\thostname\t3.21",
  83. }
  84. )
  85. with patch.dict(dpkg.__salt__, {"cmd.run_all": mock}):
  86. self.assertDictEqual(dpkg.list_pkgs("hostname"), {"hostname": "3.21"})
  87. mock = MagicMock(
  88. return_value={
  89. "retcode": 1,
  90. "stderr": "dpkg-query: no packages found matching httpd",
  91. "stdout": "",
  92. }
  93. )
  94. with patch.dict(dpkg.__salt__, {"cmd.run_all": mock}):
  95. self.assertEqual(
  96. dpkg.list_pkgs("httpd"),
  97. "Error: dpkg-query: no packages found matching httpd",
  98. )
  99. # 'file_list' function tests: 1
  100. def test_file_list(self):
  101. """
  102. Test if it lists the files that belong to a package.
  103. """
  104. dpkg_query_mock = MagicMock(
  105. return_value={"retcode": 0, "stderr": "", "stdout": "installed\thostname"}
  106. )
  107. dpkg_L_mock = MagicMock(side_effect=self.dpkg_L_side_effect)
  108. with patch.dict(
  109. dpkg.__salt__, {"cmd.run_all": dpkg_query_mock, "cmd.run": dpkg_L_mock}
  110. ):
  111. self.assertDictEqual(
  112. dpkg.file_list("hostname"),
  113. {
  114. "errors": [],
  115. "files": [
  116. "/.",
  117. "/bin",
  118. "/bin/dnsdomainname",
  119. "/bin/domainname",
  120. "/bin/hostname",
  121. "/bin/nisdomainname",
  122. "/bin/ypdomainname",
  123. "/usr",
  124. "/usr/share",
  125. "/usr/share/doc",
  126. "/usr/share/doc/hostname",
  127. "/usr/share/doc/hostname/changelog.gz",
  128. "/usr/share/doc/hostname/copyright",
  129. "/usr/share/man",
  130. "/usr/share/man/man1",
  131. "/usr/share/man/man1/dnsdomainname.1.gz",
  132. "/usr/share/man/man1/domainname.1.gz",
  133. "/usr/share/man/man1/hostname.1.gz",
  134. "/usr/share/man/man1/nisdomainname.1.gz",
  135. "/usr/share/man/man1/ypdomainname.1.gz",
  136. ],
  137. },
  138. )
  139. mock = MagicMock(
  140. return_value={"retcode": 1, "stderr": DPKG_ERROR_MSG, "stdout": ""}
  141. )
  142. with patch.dict(dpkg.__salt__, {"cmd.run_all": mock}):
  143. self.assertEqual(dpkg.file_list("httpd"), "Error: " + DPKG_ERROR_MSG)
  144. # 'file_dict' function tests: 1
  145. def test_file_dict(self):
  146. """
  147. Test if it lists the files that belong to a package, grouped by package
  148. """
  149. dpkg_query_mock = MagicMock(
  150. return_value={"retcode": 0, "stderr": "", "stdout": "installed\thostname"}
  151. )
  152. dpkg_L_mock = MagicMock(side_effect=self.dpkg_L_side_effect)
  153. with patch.dict(
  154. dpkg.__salt__, {"cmd.run_all": dpkg_query_mock, "cmd.run": dpkg_L_mock}
  155. ):
  156. expected = {
  157. "errors": [],
  158. "packages": {
  159. "hostname": [
  160. "/.",
  161. "/bin",
  162. "/bin/hostname",
  163. "/usr",
  164. "/usr/share",
  165. "/usr/share/doc",
  166. "/usr/share/doc/hostname",
  167. "/usr/share/doc/hostname/changelog.gz",
  168. "/usr/share/doc/hostname/copyright",
  169. "/usr/share/man",
  170. "/usr/share/man/man1",
  171. "/usr/share/man/man1/hostname.1.gz",
  172. "/bin/dnsdomainname",
  173. "/bin/domainname",
  174. "/bin/nisdomainname",
  175. "/bin/ypdomainname",
  176. "/usr/share/man/man1/dnsdomainname.1.gz",
  177. "/usr/share/man/man1/domainname.1.gz",
  178. "/usr/share/man/man1/nisdomainname.1.gz",
  179. "/usr/share/man/man1/ypdomainname.1.gz",
  180. ]
  181. },
  182. }
  183. self.assertDictEqual(dpkg.file_dict("hostname"), expected)
  184. mock = MagicMock(
  185. return_value={"retcode": 1, "stderr": DPKG_ERROR_MSG, "stdout": ""}
  186. )
  187. with patch.dict(dpkg.__salt__, {"cmd.run_all": mock}):
  188. self.assertEqual(dpkg.file_dict("httpd"), "Error: " + DPKG_ERROR_MSG)
  189. def test_info(self):
  190. """
  191. Test package info
  192. """
  193. mock = MagicMock(
  194. return_value={
  195. "retcode": 0,
  196. "stderr": "",
  197. "stdout": os.linesep.join(
  198. [
  199. "package:bash",
  200. "revision:",
  201. "architecture:amd64",
  202. "maintainer:Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>",
  203. "summary:",
  204. "source:bash",
  205. "version:4.4.18-2ubuntu1",
  206. "section:shells",
  207. "installed_size:1588",
  208. "size:",
  209. "MD5:",
  210. "SHA1:",
  211. "SHA256:",
  212. "origin:",
  213. "homepage:http://tiswww.case.edu/php/chet/bash/bashtop.html",
  214. "status:ii ",
  215. "======",
  216. "description:GNU Bourne Again SHell",
  217. " Bash is an sh-compatible command language interpreter that executes",
  218. " commands read from the standard input or from a file. Bash also",
  219. " incorporates useful features from the Korn and C shells (ksh and csh).",
  220. " .",
  221. " Bash is ultimately intended to be a conformant implementation of the",
  222. " IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).",
  223. " .",
  224. " The Programmable Completion Code, by Ian Macdonald, is now found in",
  225. " the bash-completion package.",
  226. "------",
  227. ]
  228. ),
  229. }
  230. )
  231. with patch.dict(dpkg.__salt__, {"cmd.run_all": mock}), patch.dict(
  232. dpkg.__grains__, {"os": "Ubuntu", "osrelease_info": (18, 4)}
  233. ), patch("salt.utils.path.which", MagicMock(return_value=False)), patch(
  234. "os.path.exists", MagicMock(return_value=False)
  235. ), patch(
  236. "os.path.getmtime", MagicMock(return_value=1560199259.0)
  237. ):
  238. self.assertDictEqual(
  239. dpkg.info("bash"),
  240. {
  241. "bash": {
  242. "architecture": "amd64",
  243. "description": os.linesep.join(
  244. [
  245. "GNU Bourne Again SHell",
  246. " Bash is an sh-compatible command language interpreter that executes",
  247. " commands read from the standard input or from a file. Bash also",
  248. " incorporates useful features from the Korn and C shells (ksh and csh).",
  249. " .",
  250. " Bash is ultimately intended to be a conformant implementation of the",
  251. " IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).",
  252. " .",
  253. " The Programmable Completion Code, by Ian Macdonald, is now found in",
  254. " the bash-completion package." + os.linesep,
  255. ]
  256. ),
  257. "homepage": "http://tiswww.case.edu/php/chet/bash/bashtop.html",
  258. "maintainer": "Ubuntu Developers "
  259. "<ubuntu-devel-discuss@lists.ubuntu.com>",
  260. "package": "bash",
  261. "section": "shells",
  262. "source": "bash",
  263. "status": "ii",
  264. "version": "4.4.18-2ubuntu1",
  265. }
  266. },
  267. )