alerta-contrib/integrations/mailer/test_rules.py
2023-03-21 00:15:34 +01:00

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')