test_daemons.py 7.8 KB

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