test_daemons.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Bo Maryniuk <bo@suse.de>
  4. """
  5. # Import python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import logging
  8. import multiprocessing
  9. # Import Salt libs
  10. import salt.cli.daemons as daemons
  11. from tests.support.helpers import slowTest
  12. from tests.support.mixins import SaltClientTestCaseMixin
  13. from tests.support.mock import MagicMock, patch
  14. # Import Salt Testing libs
  15. from tests.support.unit import TestCase
  16. log = logging.getLogger(__name__)
  17. class LoggerMock(object):
  18. """
  19. Logger data collector
  20. """
  21. def __init__(self):
  22. """
  23. init
  24. :return:
  25. """
  26. self.reset()
  27. def reset(self):
  28. """
  29. Reset values
  30. :return:
  31. """
  32. self.messages = []
  33. def info(self, message, *args, **kwargs):
  34. """
  35. Collects the data from the logger of info type.
  36. :param data:
  37. :return:
  38. """
  39. self.messages.append(
  40. {"message": message, "args": args, "kwargs": kwargs, "type": "info"}
  41. )
  42. def warning(self, message, *args, **kwargs):
  43. """
  44. Collects the data from the logger of warning type.
  45. :param data:
  46. :return:
  47. """
  48. self.messages.append(
  49. {"message": message, "args": args, "kwargs": kwargs, "type": "warning"}
  50. )
  51. def has_message(self, msg, log_type=None):
  52. """
  53. Check if log has message.
  54. :param data:
  55. :return:
  56. """
  57. for data in self.messages:
  58. log_str = (
  59. data["message"] % data["args"]
  60. ) # pylint: disable=incompatible-py3-code
  61. if (data["type"] == log_type or not log_type) and log_str.find(msg) > -1:
  62. return True
  63. return False
  64. def _master_exec_test(child_pipe):
  65. def _create_master():
  66. """
  67. Create master instance
  68. :return:
  69. """
  70. obj = daemons.Master()
  71. obj.config = {"user": "dummy", "hash_type": alg}
  72. for attr in ["start_log_info", "prepare", "shutdown", "master"]:
  73. setattr(obj, attr, MagicMock())
  74. return obj
  75. _logger = LoggerMock()
  76. ret = True
  77. try:
  78. with patch("salt.cli.daemons.check_user", MagicMock(return_value=True)):
  79. with patch("salt.cli.daemons.log", _logger):
  80. for alg in ["md5", "sha1"]:
  81. _create_master().start()
  82. ret = ret and _logger.has_message(
  83. "Do not use {alg}".format(alg=alg), log_type="warning"
  84. )
  85. _logger.reset()
  86. for alg in ["sha224", "sha256", "sha384", "sha512"]:
  87. _create_master().start()
  88. ret = (
  89. ret
  90. and _logger.messages
  91. and not _logger.has_message("Do not use ")
  92. )
  93. except Exception: # pylint: disable=broad-except
  94. log.exception("Exception raised in master daemon unit test")
  95. ret = False
  96. child_pipe.send(ret)
  97. child_pipe.close()
  98. def _minion_exec_test(child_pipe):
  99. def _create_minion():
  100. """
  101. Create minion instance
  102. :return:
  103. """
  104. obj = daemons.Minion()
  105. obj.config = {"user": "dummy", "hash_type": alg}
  106. for attr in ["start_log_info", "prepare", "shutdown"]:
  107. setattr(obj, attr, MagicMock())
  108. setattr(obj, "minion", MagicMock(restart=False))
  109. return obj
  110. ret = True
  111. try:
  112. _logger = LoggerMock()
  113. with patch("salt.cli.daemons.check_user", MagicMock(return_value=True)):
  114. with patch("salt.cli.daemons.log", _logger):
  115. for alg in ["md5", "sha1"]:
  116. _create_minion().start()
  117. ret = ret and _logger.has_message(
  118. "Do not use {alg}".format(alg=alg), log_type="warning"
  119. )
  120. _logger.reset()
  121. for alg in ["sha224", "sha256", "sha384", "sha512"]:
  122. _create_minion().start()
  123. ret = (
  124. ret
  125. and _logger.messages
  126. and not _logger.has_message("Do not use ")
  127. )
  128. except Exception: # pylint: disable=broad-except
  129. log.exception("Exception raised in minion daemon unit test")
  130. ret = False
  131. child_pipe.send(ret)
  132. child_pipe.close()
  133. def _proxy_exec_test(child_pipe):
  134. def _create_proxy_minion():
  135. """
  136. Create proxy minion instance
  137. :return:
  138. """
  139. obj = daemons.ProxyMinion()
  140. obj.config = {"user": "dummy", "hash_type": alg}
  141. for attr in ["minion", "start_log_info", "prepare", "shutdown", "tune_in"]:
  142. setattr(obj, attr, MagicMock())
  143. obj.minion.restart = False
  144. return obj
  145. ret = True
  146. try:
  147. _logger = LoggerMock()
  148. with patch("salt.cli.daemons.check_user", MagicMock(return_value=True)):
  149. with patch("salt.cli.daemons.log", _logger):
  150. for alg in ["md5", "sha1"]:
  151. _create_proxy_minion().start()
  152. ret = ret and _logger.has_message(
  153. "Do not use {alg}".format(alg=alg), log_type="warning"
  154. )
  155. _logger.reset()
  156. for alg in ["sha224", "sha256", "sha384", "sha512"]:
  157. _create_proxy_minion().start()
  158. ret = (
  159. ret
  160. and _logger.messages
  161. and not _logger.has_message("Do not use ")
  162. )
  163. except Exception: # pylint: disable=broad-except
  164. log.exception("Exception raised in proxy daemon unit test")
  165. ret = False
  166. child_pipe.send(ret)
  167. child_pipe.close()
  168. def _syndic_exec_test(child_pipe):
  169. def _create_syndic():
  170. """
  171. Create syndic instance
  172. :return:
  173. """
  174. obj = daemons.Syndic()
  175. obj.config = {"user": "dummy", "hash_type": alg}
  176. for attr in ["syndic", "start_log_info", "prepare", "shutdown"]:
  177. setattr(obj, attr, MagicMock())
  178. return obj
  179. ret = True
  180. try:
  181. _logger = LoggerMock()
  182. with patch("salt.cli.daemons.check_user", MagicMock(return_value=True)):
  183. with patch("salt.cli.daemons.log", _logger):
  184. for alg in ["md5", "sha1"]:
  185. _create_syndic().start()
  186. ret = ret and _logger.has_message(
  187. "Do not use {alg}".format(alg=alg), log_type="warning"
  188. )
  189. _logger.reset()
  190. for alg in ["sha224", "sha256", "sha384", "sha512"]:
  191. _create_syndic().start()
  192. ret = (
  193. ret
  194. and _logger.messages
  195. and not _logger.has_message("Do not use ")
  196. )
  197. except Exception: # pylint: disable=broad-except
  198. log.exception("Exception raised in syndic daemon unit test")
  199. ret = False
  200. child_pipe.send(ret)
  201. child_pipe.close()
  202. class DaemonsStarterTestCase(TestCase, SaltClientTestCaseMixin):
  203. """
  204. Unit test for the daemons starter classes.
  205. """
  206. def _multiproc_exec_test(self, exec_test):
  207. m_parent, m_child = multiprocessing.Pipe()
  208. p_ = multiprocessing.Process(target=exec_test, args=(m_child,))
  209. p_.start()
  210. self.assertTrue(m_parent.recv())
  211. p_.join()
  212. @slowTest
  213. def test_master_daemon_hash_type_verified(self):
  214. """
  215. Verify if Master is verifying hash_type config option.
  216. :return:
  217. """
  218. self._multiproc_exec_test(_master_exec_test)
  219. @slowTest
  220. def test_minion_daemon_hash_type_verified(self):
  221. """
  222. Verify if Minion is verifying hash_type config option.
  223. :return:
  224. """
  225. self._multiproc_exec_test(_minion_exec_test)
  226. @slowTest
  227. def test_proxy_minion_daemon_hash_type_verified(self):
  228. """
  229. Verify if ProxyMinion is verifying hash_type config option.
  230. :return:
  231. """
  232. self._multiproc_exec_test(_proxy_exec_test)
  233. @slowTest
  234. def test_syndic_daemon_hash_type_verified(self):
  235. """
  236. Verify if Syndic is verifying hash_type config option.
  237. :return:
  238. """
  239. self._multiproc_exec_test(_syndic_exec_test)