Merge "[tempestmail] Custom email for different matchers"
This commit is contained in:
commit
9092591efe
@ -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
|
gate-tripleo-ci-centos-7-ovb-containers-oooq has a test failure that matches
|
||||||
the regex.
|
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:
|
So, the order is:
|
||||||
|
|
||||||
1. If there's no jobs list the user will receive all the emails.
|
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):
|
def filter_emails(self, job, data):
|
||||||
has_errors = False
|
has_errors = False
|
||||||
addresses = []
|
bookaddr = {}
|
||||||
|
|
||||||
for error in [data.get(x, []) for x in ('new', 'failed', 'errors')]:
|
for error in [data.get(x, []) for x in ('new', 'failed', 'errors')]:
|
||||||
if error:
|
if error:
|
||||||
@ -123,24 +123,33 @@ class Mail(object):
|
|||||||
m.get('jobs') or not
|
m.get('jobs') or not
|
||||||
m.get('jobs')]
|
m.get('jobs')]
|
||||||
|
|
||||||
# Now we filter for regex if doesn't exists
|
# Add all addresses except those that regex don't match
|
||||||
addresses = [m.get('mail') for m in emails if not m.get('regex')]
|
|
||||||
|
|
||||||
# And finally, if regex exists
|
|
||||||
for email in emails:
|
for email in emails:
|
||||||
for r in email.get('regex'):
|
add = True
|
||||||
if len(filter(r.search, data.get('new'))):
|
if email.get('regex'):
|
||||||
addresses.append(email.get('mail'))
|
for r in email.get('regex'):
|
||||||
break
|
if len(filter(r.search, data.get('new'))):
|
||||||
|
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:
|
else:
|
||||||
self.log.debug('No failures send email to everybody')
|
self.log.debug('No failures send email to everybody')
|
||||||
addresses = [m.get('mail') for m in self.config.emails
|
addresses = [m.get('mail') for m in self.config.emails
|
||||||
if not m.get('fail_only')]
|
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
|
data['has_errors'] = has_errors
|
||||||
|
|
||||||
return addresses
|
return bookaddr
|
||||||
|
|
||||||
def _send_mail_local(self, addresses, message, subject, output):
|
def _send_mail_local(self, addresses, message, subject, output):
|
||||||
msg = MIMEText(message, 'html')
|
msg = MIMEText(message, 'html')
|
||||||
@ -167,14 +176,16 @@ class Mail(object):
|
|||||||
requests.post(self.config.api_server, data=data)
|
requests.post(self.config.api_server, data=data)
|
||||||
|
|
||||||
def send_mail(self, job, data, output):
|
def send_mail(self, job, data, output):
|
||||||
addresses = self.filter_emails(job, data)
|
bookaddr = self.filter_emails(job, data)
|
||||||
message = self.render_template(data)
|
message = self.render_template(data)
|
||||||
subject = 'Job {} results'.format(job)
|
|
||||||
|
|
||||||
if self.config.use_api_server:
|
# Send a separate email to the addresses grouped by topics
|
||||||
self._send_mail_api(addresses, message, subject)
|
for topics, addresses in bookaddr.items():
|
||||||
else:
|
subject = '{} Job {} results'.format(topics, job).lstrip()
|
||||||
self._send_mail_local(addresses, message, subject, output)
|
if self.config.use_api_server:
|
||||||
|
self._send_mail_api(addresses, message, subject)
|
||||||
|
else:
|
||||||
|
self._send_mail_local(addresses, message, subject, output)
|
||||||
|
|
||||||
|
|
||||||
class TempestMailCmd(object):
|
class TempestMailCmd(object):
|
||||||
@ -367,6 +378,7 @@ class TempestMailCmd(object):
|
|||||||
'mail': e.get('mail'),
|
'mail': e.get('mail'),
|
||||||
'jobs': e.get('jobs', []),
|
'jobs': e.get('jobs', []),
|
||||||
'regex': regex,
|
'regex': regex,
|
||||||
|
'topics': e.get('topics'),
|
||||||
'fail_only': e.get('fail_only', False)})
|
'fail_only': e.get('fail_only', False)})
|
||||||
for t in config.get('known_failures', []):
|
for t in config.get('known_failures', []):
|
||||||
known_failures.append({'test': t.get('test'),
|
known_failures.append({'test': t.get('test'),
|
||||||
|
@ -2,6 +2,7 @@ import datetime
|
|||||||
import mock
|
import mock
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
import re
|
||||||
|
|
||||||
from tempestmail import Config
|
from tempestmail import Config
|
||||||
from tempestmail import Mail
|
from tempestmail import Mail
|
||||||
@ -29,9 +30,9 @@ class MailTest(unittest.TestCase):
|
|||||||
config.require_auth = True
|
config.require_auth = True
|
||||||
config.emails = [
|
config.emails = [
|
||||||
{'mail': 'email1@example.com', 'name': 'name 1',
|
{'mail': 'email1@example.com', 'name': 'name 1',
|
||||||
'jobs': [], 'regex': []},
|
'jobs': [], 'regex': [], 'topics': ''},
|
||||||
{'mail': 'email2@example.com', 'name': 'name 2',
|
{'mail': 'email2@example.com', 'name': 'name 2',
|
||||||
'jobs': [], 'regex': []}
|
'jobs': [], 'regex': [], 'topics': ''}
|
||||||
]
|
]
|
||||||
config.template = 'template.html'
|
config.template = 'template.html'
|
||||||
return config
|
return config
|
||||||
@ -87,16 +88,45 @@ class MailTest(unittest.TestCase):
|
|||||||
self.assertEquals(self.data.get('has_errors'), None)
|
self.assertEquals(self.data.get('has_errors'), None)
|
||||||
addresses = mail.filter_emails(
|
addresses = mail.filter_emails(
|
||||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
'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)
|
addresses)
|
||||||
mail.config.emails[0]['jobs'].append('another-job')
|
mail.config.emails[0]['jobs'].append('another-job')
|
||||||
addresses = mail.filter_emails(
|
addresses = mail.filter_emails(
|
||||||
'periodic-tripleo-ci-centos-7-ovb-ha-tempest', self.data)
|
'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)
|
self.assertEquals(self.data['has_errors'], True)
|
||||||
mail.config.emails[0]['jobs'] = []
|
mail.config.emails[0]['jobs'] = []
|
||||||
mail.config.emails[0]['regex'].append('tempest.some.regex')
|
mail.config.emails[0]['regex'].append(re.compile(
|
||||||
self.assertEquals(['email2@example.com'], addresses)
|
'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_api')
|
||||||
@mock.patch('tempestmail.Mail._send_mail_local')
|
@mock.patch('tempestmail.Mail._send_mail_local')
|
||||||
|
Loading…
Reference in New Issue
Block a user