[tempestmail] Custom email for different matchers
Define a set of custom tags for each filter block to be added to the email subject. A separate email will be sent to each email address that matches the criteria. Change-Id: I6be404c8b25eeefc1f9574c8a26a5b320d62d2c6 Closes-Bug: #1730409
This commit is contained in:
parent
f31bedca94
commit
18a3287dac
@ -96,6 +96,26 @@ gate-tripleo-ci-centos-7-ovb-ha-oooq or
|
||||
gate-tripleo-ci-centos-7-ovb-containers-oooq has a test failure that matches
|
||||
the regex.
|
||||
|
||||
```yaml
|
||||
...
|
||||
emails:
|
||||
- mail: fail1@example.com
|
||||
regex: '.*foo.*'
|
||||
topics: foo1
|
||||
- mail: fail1@example.com
|
||||
regex: '.*bar.*'
|
||||
topics: bar1
|
||||
- mail: fail2@example.com
|
||||
regex: '.*bar.*'
|
||||
topics: bar2,extra
|
||||
...
|
||||
```
|
||||
|
||||
if a jobs contains tests matching both 'foo' and 'bar', then:
|
||||
* fail1@ will receive an email '[foo1]...' and an email '[bar1]...'
|
||||
* fail2@ will receive an email '[bar2][extra]...'
|
||||
|
||||
|
||||
So, the order is:
|
||||
|
||||
1. If there's no jobs list the user will receive all the emails.
|
||||
|
@ -108,7 +108,7 @@ class Mail(object):
|
||||
|
||||
def filter_emails(self, job, data):
|
||||
has_errors = False
|
||||
addresses = []
|
||||
bookaddr = {}
|
||||
|
||||
for error in [data.get(x, []) for x in ('new', 'failed', 'errors')]:
|
||||
if error:
|
||||
@ -123,24 +123,33 @@ class Mail(object):
|
||||
m.get('jobs') or not
|
||||
m.get('jobs')]
|
||||
|
||||
# Now we filter for regex if doesn't exists
|
||||
addresses = [m.get('mail') for m in emails if not m.get('regex')]
|
||||
|
||||
# And finally, if regex exists
|
||||
# Add all addresses except those that regex don't match
|
||||
for email in emails:
|
||||
add = True
|
||||
if email.get('regex'):
|
||||
for r in email.get('regex'):
|
||||
if len(filter(r.search, data.get('new'))):
|
||||
addresses.append(email.get('mail'))
|
||||
break
|
||||
|
||||
add = False
|
||||
if add:
|
||||
topics = ''
|
||||
if email.get('topics'):
|
||||
# Parse topics and format it between brackets
|
||||
t = email.get('topics').split(',')
|
||||
topics = ''.join('[{}]'.format(s) for s in t)
|
||||
# Add the address to the bookaddr dict
|
||||
# {'[foo][bar]' : ['john@redhat.com', 'mary@redhat.com']}
|
||||
bookaddr.setdefault(topics, []).append(email.get('mail'))
|
||||
else:
|
||||
self.log.debug('No failures send email to everybody')
|
||||
addresses = [m.get('mail') for m in self.config.emails
|
||||
if not m.get('fail_only')]
|
||||
# Single group with empty topic is added to the bookaddr
|
||||
bookaddr.setdefault('', []).append(addresses)
|
||||
|
||||
data['has_errors'] = has_errors
|
||||
|
||||
return addresses
|
||||
return bookaddr
|
||||
|
||||
def _send_mail_local(self, addresses, message, subject, output):
|
||||
msg = MIMEText(message, 'html')
|
||||
@ -167,10 +176,12 @@ class Mail(object):
|
||||
requests.post(self.config.api_server, data=data)
|
||||
|
||||
def send_mail(self, job, data, output):
|
||||
addresses = self.filter_emails(job, data)
|
||||
bookaddr = self.filter_emails(job, data)
|
||||
message = self.render_template(data)
|
||||
subject = 'Job {} results'.format(job)
|
||||
|
||||
# Send a separate email to the addresses grouped by topics
|
||||
for topics, addresses in bookaddr.items():
|
||||
subject = '{} Job {} results'.format(topics, job).lstrip()
|
||||
if self.config.use_api_server:
|
||||
self._send_mail_api(addresses, message, subject)
|
||||
else:
|
||||
@ -367,6 +378,7 @@ class TempestMailCmd(object):
|
||||
'mail': e.get('mail'),
|
||||
'jobs': e.get('jobs', []),
|
||||
'regex': regex,
|
||||
'topics': e.get('topics'),
|
||||
'fail_only': e.get('fail_only', False)})
|
||||
for t in config.get('known_failures', []):
|
||||
known_failures.append({'test': t.get('test'),
|
||||
|
@ -2,6 +2,7 @@ import datetime
|
||||
import mock
|
||||
import tempfile
|
||||
import unittest
|
||||
import re
|
||||
|
||||
from tempestmail import Config
|
||||
from tempestmail import Mail
|
||||
@ -29,9 +30,9 @@ class MailTest(unittest.TestCase):
|
||||
config.require_auth = True
|
||||
config.emails = [
|
||||
{'mail': 'email1@example.com', 'name': 'name 1',
|
||||
'jobs': [], 'regex': []},
|
||||
'jobs': [], 'regex': [], 'topics': ''},
|
||||
{'mail': 'email2@example.com', 'name': 'name 2',
|
||||
'jobs': [], 'regex': []}
|
||||
'jobs': [], 'regex': [], 'topics': ''}
|
||||
]
|
||||
config.template = 'template.html'
|
||||
return config
|
||||
@ -87,16 +88,45 @@ class MailTest(unittest.TestCase):
|
||||
self.assertEquals(self.data.get('has_errors'), None)
|
||||
addresses = mail.filter_emails(
|
||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
||||
self.assertEquals(['email1@example.com', 'email2@example.com'],
|
||||
self.assertEquals({'' : ['email1@example.com', 'email2@example.com']},
|
||||
addresses)
|
||||
mail.config.emails[0]['jobs'].append('another-job')
|
||||
addresses = mail.filter_emails(
|
||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
||||
self.assertEquals(['email2@example.com'], addresses)
|
||||
self.assertEquals({'' : ['email2@example.com']}, addresses)
|
||||
self.assertEquals(self.data['has_errors'], True)
|
||||
mail.config.emails[0]['jobs'] = []
|
||||
mail.config.emails[0]['regex'].append('tempest.some.regex')
|
||||
self.assertEquals(['email2@example.com'], addresses)
|
||||
mail.config.emails[0]['regex'].append(re.compile(
|
||||
'tempest.some.regex'))
|
||||
self.assertEquals({'' : ['email2@example.com']}, addresses)
|
||||
|
||||
def test_filter_emails_topics(self):
|
||||
mail = Mail(self.config)
|
||||
addresses = mail.filter_emails(
|
||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
||||
self.assertEquals({'' : ['email1@example.com',
|
||||
'email2@example.com']},
|
||||
addresses)
|
||||
mail.config.emails[0]['jobs'].append(
|
||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest')
|
||||
mail.config.emails[0]['regex'].append(re.compile(
|
||||
'upload_too_many_objects'))
|
||||
mail.config.emails[0]['topics'] = 'many_objects'
|
||||
mail.config.emails[1]['regex'].append(re.compile(
|
||||
'upload_valid_object'))
|
||||
mail.config.emails[1]['topics'] = 'valid_object'
|
||||
new = {'mail': 'email2@example.com', 'name': 'name 2',
|
||||
'jobs': ['periodic-tripleo-ci-centos-7-ovb-ha-tempest'],
|
||||
'regex': [re.compile('upload_valid_object')],
|
||||
'topics': 'valid_object,object_storage'}
|
||||
mail.config.emails.append(new)
|
||||
addresses = mail.filter_emails(
|
||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
||||
bookaddr = {'[many_objects]' : ['email1@example.com'],
|
||||
'[valid_object]' : ['email2@example.com'],
|
||||
'[valid_object][object_storage]' : ['email2@example.com']
|
||||
}
|
||||
self.assertEquals(bookaddr, addresses)
|
||||
|
||||
@mock.patch('tempestmail.Mail._send_mail_api')
|
||||
@mock.patch('tempestmail.Mail._send_mail_local')
|
||||
|
Loading…
Reference in New Issue
Block a user