165 lines
5.2 KiB
Python
165 lines
5.2 KiB
Python
'''
|
|
Unit test definitions for all rules
|
|
'''
|
|
import mailer
|
|
import pytest
|
|
from alertaclient.models.alert import Alert
|
|
from mock import DEFAULT, MagicMock, patch
|
|
|
|
|
|
def test_rules_dont_exist():
|
|
'''
|
|
Test the rules file is read
|
|
'''
|
|
with patch('mailer.os') as system_os:
|
|
system_os.path.exists.return_value = False
|
|
# res = mailer.parse_group_rules('config_file')
|
|
system_os.path.exists.called_once_with('confile_file')
|
|
# assert res is None
|
|
|
|
|
|
def test_rules_parsing():
|
|
'''
|
|
Test the rules file is properly read
|
|
'''
|
|
with patch.multiple(mailer, os=DEFAULT, open=DEFAULT,
|
|
json=DEFAULT, validate_rules=DEFAULT) as mocks:
|
|
mocks['os'].path.exists.return_value = True
|
|
mocks['os'].walk().__iter__\
|
|
.return_value = [('/', None,
|
|
['cantopen.json', 'invalid.json', 'valid.json'])]
|
|
invalid_file = MagicMock()
|
|
valid_file = MagicMock()
|
|
mocks['open'].side_effect = [IOError, invalid_file, valid_file]
|
|
doc = [{'notify': {'fields': []}}]
|
|
mocks['json'].load.side_effect = [TypeError, doc]
|
|
mocks['validate_rules'].return_value = doc
|
|
res = mailer.parse_group_rules('config_file')
|
|
|
|
# Assert that we checked for folder existence
|
|
mocks['os'].path.exists.called_once_with('confile_file')
|
|
|
|
# Check that validation was called for valid file
|
|
mocks['validate_rules'].assert_called_once_with(doc)
|
|
assert mocks['validate_rules'].call_count == 1
|
|
|
|
# Assert that we tried to open all 3 files
|
|
assert mocks['open'].call_count == 3
|
|
# Assert that we tried to load 2 files only
|
|
assert mocks['json'].load.call_count == 2
|
|
# Assert that we have proper return value
|
|
assert res == doc
|
|
|
|
|
|
TESTDOCS = [
|
|
('', False),
|
|
('String', False),
|
|
({}, False),
|
|
([], True),
|
|
([
|
|
{'name': 'invalid_no_fields',
|
|
'contacts': []}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_empty_fields',
|
|
'fields': [],
|
|
'contacts': []}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_no_contacts',
|
|
'fields': [{'field': 'resource', 'regex': r'\d{4}'}]}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_no_field_on_fields',
|
|
'fields': [{'regex': r'\d{4}'}],
|
|
'contacts': []}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_fields_not_list',
|
|
'fields': {'regex': r'\d{4}'},
|
|
'contacts': []}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_no_fields_regex',
|
|
'fields': [{'field': 'test'}],
|
|
'contacts': []}
|
|
], False),
|
|
([
|
|
{'name': 'invalid_no_fields_regex',
|
|
'fields': [{'field': 'tags', 'regex': 'atag'}],
|
|
'exclude': True,
|
|
'contacts': []}
|
|
], True),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize('doc, is_valid', TESTDOCS)
|
|
def test_rules_validation(doc, is_valid):
|
|
'''
|
|
Test rule validation
|
|
'''
|
|
res = mailer.validate_rules(doc)
|
|
if is_valid:
|
|
assert res is not None and res == doc
|
|
else:
|
|
assert res is None or res == []
|
|
|
|
|
|
RULES_DATA = [
|
|
# ({'resource': 'server-1234', 'event': '5678'}, [], []),
|
|
({'resource': '1234', 'event': '5678'},
|
|
[{'name': 'Test1',
|
|
'fields': [{'field': 'resource', 'regex': r'(\w.*)?\d{4}'}],
|
|
'contacts': ['test@example.com']}],
|
|
['test@example.com'])
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize('alert_spec, input_rules, expected_contacts',
|
|
RULES_DATA)
|
|
def test_rules_evaluation(alert_spec, input_rules, expected_contacts):
|
|
'''
|
|
Test that rules are properly evaluated
|
|
'''
|
|
with patch.dict(mailer.OPTIONS, mailer.DEFAULT_OPTIONS):
|
|
mailer.OPTIONS['mail_to'] = []
|
|
mailer.OPTIONS['group_rules'] = input_rules
|
|
mail_sender = mailer.MailSender()
|
|
with patch.object(mail_sender, '_send_email_message') as _sem:
|
|
alert = Alert.parse(alert_spec)
|
|
_, emailed_contacts = mail_sender.send_email(alert)
|
|
assert _sem.call_count == 1
|
|
assert emailed_contacts == expected_contacts
|
|
|
|
|
|
def test_rule_matches_list():
|
|
'''
|
|
Test regex matching is working properly
|
|
for a list
|
|
'''
|
|
# Mock options to instantiate mailer
|
|
with patch.dict(mailer.OPTIONS, mailer.DEFAULT_OPTIONS):
|
|
mail_sender = mailer.MailSender()
|
|
with patch.object(mailer, 're') as regex:
|
|
regex.match.side_effect = [MagicMock(), None]
|
|
assert mail_sender._rule_matches('regex', ['item1']) is True
|
|
regex.match.assert_called_with('regex', 'item1')
|
|
assert mail_sender._rule_matches('regex', ['item2']) is False
|
|
regex.match.assert_called_with('regex', 'item2')
|
|
|
|
|
|
def test_rule_matches_string():
|
|
'''
|
|
Test regex matching is working properly
|
|
for a string
|
|
'''
|
|
# Mock options to instantiate mailer
|
|
with patch.dict(mailer.OPTIONS, mailer.DEFAULT_OPTIONS):
|
|
mail_sender = mailer.MailSender()
|
|
with patch.object(mailer, 're') as regex:
|
|
regex.search.side_effect = [MagicMock(), None]
|
|
assert mail_sender._rule_matches('regex', 'value1') is True
|
|
regex.search.assert_called_with('regex', 'value1')
|
|
assert mail_sender._rule_matches('regex', 'value2') is False
|
|
regex.search.assert_called_with('regex', 'value2')
|