mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
2926834423
https://github.com/saltstack/salt/pull/45583 was opened to fix some test failures in the daemons tests. However, with the way that the tests were written, `_multiproc_exec_test` was waiting for a response from the child function, which would never come due to the error raised during the test. This means that any exception raised during the test would stop the test suite dead in its tracks, causing it to eventually end in a timeout. This commit addresses this design flaw by wrapping the test logic in a try/except, and ensuring that we always return a response from the child function. The tests will instead log the exception and gracefully fail the test, allowing whomever troubleshoots the failures to consult the salt-runtests.log to see the traceback.
270 lines
7.9 KiB
Python
270 lines
7.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: :email:`Bo Maryniuk <bo@suse.de>`
|
|
'''
|
|
|
|
# Import python libs
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
import logging
|
|
import multiprocessing
|
|
|
|
# Import Salt Testing libs
|
|
from tests.support.unit import TestCase, skipIf
|
|
from tests.support.mock import patch, MagicMock, NO_MOCK, NO_MOCK_REASON
|
|
from tests.support.mixins import SaltClientTestCaseMixin
|
|
|
|
# Import Salt libs
|
|
import salt.cli.daemons as daemons
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class LoggerMock(object):
|
|
'''
|
|
Logger data collector
|
|
'''
|
|
|
|
def __init__(self):
|
|
'''
|
|
init
|
|
:return:
|
|
'''
|
|
self.reset()
|
|
|
|
def reset(self):
|
|
'''
|
|
Reset values
|
|
|
|
:return:
|
|
'''
|
|
self.messages = []
|
|
|
|
def info(self, message, *args, **kwargs):
|
|
'''
|
|
Collects the data from the logger of info type.
|
|
|
|
:param data:
|
|
:return:
|
|
'''
|
|
self.messages.append({'message': message, 'args': args,
|
|
'kwargs': kwargs, 'type': 'info'})
|
|
|
|
def warning(self, message, *args, **kwargs):
|
|
'''
|
|
Collects the data from the logger of warning type.
|
|
|
|
:param data:
|
|
:return:
|
|
'''
|
|
self.messages.append({'message': message, 'args': args,
|
|
'kwargs': kwargs, 'type': 'warning'})
|
|
|
|
def has_message(self, msg, log_type=None):
|
|
'''
|
|
Check if log has message.
|
|
|
|
:param data:
|
|
:return:
|
|
'''
|
|
for data in self.messages:
|
|
log_str = data['message'] % data['args'] # pylint: disable=incompatible-py3-code
|
|
if (data['type'] == log_type or not log_type) and log_str.find(msg) > -1:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def _master_exec_test(child_pipe):
|
|
def _create_master():
|
|
'''
|
|
Create master instance
|
|
:return:
|
|
'''
|
|
obj = daemons.Master()
|
|
obj.config = {'user': 'dummy', 'hash_type': alg}
|
|
for attr in ['start_log_info', 'prepare', 'shutdown', 'master']:
|
|
setattr(obj, attr, MagicMock())
|
|
|
|
return obj
|
|
|
|
_logger = LoggerMock()
|
|
ret = True
|
|
try:
|
|
with patch('salt.cli.daemons.check_user', MagicMock(return_value=True)):
|
|
with patch('salt.cli.daemons.log', _logger):
|
|
for alg in ['md5', 'sha1']:
|
|
_create_master().start()
|
|
ret = ret and _logger.has_message(
|
|
'Do not use {alg}'.format(alg=alg),
|
|
log_type='warning')
|
|
|
|
_logger.reset()
|
|
|
|
for alg in ['sha224', 'sha256', 'sha384', 'sha512']:
|
|
_create_master().start()
|
|
ret = ret and _logger.messages \
|
|
and not _logger.has_message('Do not use ')
|
|
except Exception:
|
|
log.exception('Exception raised in master daemon unit test')
|
|
ret = False
|
|
child_pipe.send(ret)
|
|
child_pipe.close()
|
|
|
|
|
|
def _minion_exec_test(child_pipe):
|
|
def _create_minion():
|
|
'''
|
|
Create minion instance
|
|
:return:
|
|
'''
|
|
obj = daemons.Minion()
|
|
obj.config = {'user': 'dummy', 'hash_type': alg}
|
|
for attr in ['start_log_info', 'prepare', 'shutdown']:
|
|
setattr(obj, attr, MagicMock())
|
|
setattr(obj, 'minion', MagicMock(restart=False))
|
|
|
|
return obj
|
|
|
|
ret = True
|
|
try:
|
|
_logger = LoggerMock()
|
|
with patch('salt.cli.daemons.check_user', MagicMock(return_value=True)):
|
|
with patch('salt.cli.daemons.log', _logger):
|
|
for alg in ['md5', 'sha1']:
|
|
_create_minion().start()
|
|
ret = ret and _logger.has_message(
|
|
'Do not use {alg}'.format(alg=alg),
|
|
log_type='warning')
|
|
_logger.reset()
|
|
|
|
for alg in ['sha224', 'sha256', 'sha384', 'sha512']:
|
|
_create_minion().start()
|
|
ret = ret and _logger.messages \
|
|
and not _logger.has_message('Do not use ')
|
|
except Exception:
|
|
log.exception('Exception raised in minion daemon unit test')
|
|
ret = False
|
|
child_pipe.send(ret)
|
|
child_pipe.close()
|
|
|
|
|
|
def _proxy_exec_test(child_pipe):
|
|
def _create_proxy_minion():
|
|
'''
|
|
Create proxy minion instance
|
|
:return:
|
|
'''
|
|
obj = daemons.ProxyMinion()
|
|
obj.config = {'user': 'dummy', 'hash_type': alg}
|
|
for attr in ['minion', 'start_log_info', 'prepare', 'shutdown', 'tune_in']:
|
|
setattr(obj, attr, MagicMock())
|
|
|
|
obj.minion.restart = False
|
|
return obj
|
|
|
|
ret = True
|
|
try:
|
|
_logger = LoggerMock()
|
|
with patch('salt.cli.daemons.check_user', MagicMock(return_value=True)):
|
|
with patch('salt.cli.daemons.log', _logger):
|
|
for alg in ['md5', 'sha1']:
|
|
_create_proxy_minion().start()
|
|
ret = ret and _logger.has_message(
|
|
'Do not use {alg}'.format(alg=alg),
|
|
log_type='warning')
|
|
|
|
_logger.reset()
|
|
|
|
for alg in ['sha224', 'sha256', 'sha384', 'sha512']:
|
|
_create_proxy_minion().start()
|
|
ret = ret and _logger.messages \
|
|
and not _logger.has_message('Do not use ')
|
|
except Exception:
|
|
log.exception('Exception raised in proxy daemon unit test')
|
|
ret = False
|
|
child_pipe.send(ret)
|
|
child_pipe.close()
|
|
|
|
|
|
def _syndic_exec_test(child_pipe):
|
|
def _create_syndic():
|
|
'''
|
|
Create syndic instance
|
|
:return:
|
|
'''
|
|
obj = daemons.Syndic()
|
|
obj.config = {'user': 'dummy', 'hash_type': alg}
|
|
for attr in ['syndic', 'start_log_info', 'prepare', 'shutdown']:
|
|
setattr(obj, attr, MagicMock())
|
|
|
|
return obj
|
|
|
|
ret = True
|
|
try:
|
|
_logger = LoggerMock()
|
|
with patch('salt.cli.daemons.check_user', MagicMock(return_value=True)):
|
|
with patch('salt.cli.daemons.log', _logger):
|
|
for alg in ['md5', 'sha1']:
|
|
_create_syndic().start()
|
|
ret = ret and _logger.has_message(
|
|
'Do not use {alg}'.format(alg=alg),
|
|
log_type='warning')
|
|
|
|
_logger.reset()
|
|
|
|
for alg in ['sha224', 'sha256', 'sha384', 'sha512']:
|
|
_create_syndic().start()
|
|
ret = ret and _logger.messages \
|
|
and not _logger.has_message('Do not use ')
|
|
except Exception:
|
|
log.exception('Exception raised in syndic daemon unit test')
|
|
ret = False
|
|
child_pipe.send(ret)
|
|
child_pipe.close()
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
class DaemonsStarterTestCase(TestCase, SaltClientTestCaseMixin):
|
|
'''
|
|
Unit test for the daemons starter classes.
|
|
'''
|
|
|
|
def _multiproc_exec_test(self, exec_test):
|
|
m_parent, m_child = multiprocessing.Pipe()
|
|
p_ = multiprocessing.Process(target=exec_test, args=(m_child,))
|
|
p_.start()
|
|
self.assertTrue(m_parent.recv())
|
|
p_.join()
|
|
|
|
def test_master_daemon_hash_type_verified(self):
|
|
'''
|
|
Verify if Master is verifying hash_type config option.
|
|
|
|
:return:
|
|
'''
|
|
self._multiproc_exec_test(_master_exec_test)
|
|
|
|
def test_minion_daemon_hash_type_verified(self):
|
|
'''
|
|
Verify if Minion is verifying hash_type config option.
|
|
|
|
:return:
|
|
'''
|
|
self._multiproc_exec_test(_minion_exec_test)
|
|
|
|
def test_proxy_minion_daemon_hash_type_verified(self):
|
|
'''
|
|
Verify if ProxyMinion is verifying hash_type config option.
|
|
|
|
:return:
|
|
'''
|
|
self._multiproc_exec_test(_proxy_exec_test)
|
|
|
|
def test_syndic_daemon_hash_type_verified(self):
|
|
'''
|
|
Verify if Syndic is verifying hash_type config option.
|
|
|
|
:return:
|
|
'''
|
|
self._multiproc_exec_test(_syndic_exec_test)
|