Commit b3a74887 authored by Damien Lespiau's avatar Damien Lespiau
Browse files

testresult: Send emails with test results



Hook sending emails to the test results API. We can now configure
patchwork to send emails with test results with the couple of per-test
settings introduced in the previous patch.
Signed-off-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
parent 20c2fe58
......@@ -47,6 +47,12 @@ class Person(models.Model):
else:
return self.email
def email_name(self):
if (self.name):
return "%s <%s>" % (self.name, self.email)
else:
return self.email
def __unicode__(self):
return self.display_name()
......
# Patchwork - automated patch tracking system
# coding=utf-8
#
# Copyright (C) 2015 Intel Corporation
#
# This file is part of the Patchwork package.
......@@ -17,6 +19,7 @@
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from django.core import mail
from django.test import Client
import patchwork.tests.test_series as test_series
from patchwork.tests.test_user import TestUser
......@@ -227,6 +230,17 @@ class TestResultTest(APITestBase):
result_url = 'http://example.org/logs/foo.txt'
result_summary = 'This contains a summary of the test results'
def _post_result(self, entry, test_name, state, summary=None, url=None):
data = {
'test_name': test_name,
'state': state,
}
if summary:
data['summary'] = summary
if url:
data['url'] = url
return self.post_json(entry, data=data, user=self.maintainer)
def testNoTestResults(self):
return
for url in self.test_urls:
......@@ -280,6 +294,7 @@ class TestResultTest(APITestBase):
def _cleanup_tests(self):
TestResult.objects.all().delete()
Test.objects.all().delete()
mail.outbox = []
def testInvalidSubmissions(self):
"""test_name and state are required fields"""
......@@ -392,3 +407,80 @@ class TestResultTest(APITestBase):
self.assertEqual(result.summary, self.result_summary)
self._cleanup_tests()
def testNoMailByDefault(self):
for url in self.test_urls:
self._post_result(url, 'new test', 'success')
self.assertEqual(len(mail.outbox), 0)
self._cleanup_tests()
def _configure_test(self, url, test_name, recipient, condition):
"""Create test_name and configure it"""
self._post_result(url, test_name, 'pending')
tests = Test.objects.all()
self.assertEqual(len(tests), 1)
test = tests[0]
test.mail_recipient = recipient
test.mail_condition = condition
test.save()
def testMailRecipient(self):
for url in self.test_urls:
self.assertEqual(len(mail.outbox), 0)
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ALWAYS)
self._post_result(url, 'super test', 'success')
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, [self.series.submitter.email_name()])
self.assertEqual(email.cc, [])
mail.outbox = []
self._configure_test(url, 'super test',
Test.RECIPIENT_MAILING_LIST, Test.CONDITION_ALWAYS)
self._post_result(url, 'super test', 'success')
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, [self.series.submitter.email_name()])
self.assertEqual(email.cc, [self.project.listemail])
self._cleanup_tests()
def testMailCondition(self):
for url in self.test_urls:
self.assertEqual(len(mail.outbox), 0)
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ALWAYS)
self._post_result(url, 'super test', 'success')
self.assertEqual(len(mail.outbox), 1)
mail.outbox = []
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ALWAYS)
self._post_result(url, 'super test', 'pending')
self.assertEqual(len(mail.outbox), 0)
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ON_FAILURE)
self._post_result(url, 'super test', 'success')
self.assertEqual(len(mail.outbox), 0)
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ON_FAILURE)
self._post_result(url, 'super test', 'pending')
self.assertEqual(len(mail.outbox), 0)
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ON_FAILURE)
self._post_result(url, 'super test', 'warning')
self.assertEqual(len(mail.outbox), 1)
mail.outbox = []
self._configure_test(url, 'super test',
Test.RECIPIENT_SUBMITTER, Test.CONDITION_ON_FAILURE)
self._post_result(url, 'super test', 'failure')
self.assertEqual(len(mail.outbox), 1)
mail.outbox = []
# Patchwork - automated patch tracking system
# Copyright (C) 2014 Intel Corporation
# coding=utf-8
#
# Copyright (C) 2014,2015 Intel Corporation
#
# This file is part of the Patchwork package.
#
......@@ -22,10 +24,12 @@ try:
from django.core.exceptions import FieldDoesNotExist
except:
from django.db.models.fields import FieldDoesNotExist
from django.conf import settings
from django.core import mail
from django.db.models import Q
from django.http import HttpResponse
from patchwork.models import Project, Series, SeriesRevision, Patch, EventLog, \
TestResult
Test, TestResult
from rest_framework import views, viewsets, mixins, generics, filters, \
permissions, status
from rest_framework.authentication import BasicAuthentication
......@@ -184,13 +188,37 @@ class RevisionViewSet(mixins.ListModelMixin, ListMixin,
return series_mbox(rev)
class ResultMixin(object):
def _prepare_mail(self, result):
if result.state == TestResult.STATE_SUCCESS:
tick = u"✓"
else:
tick = u"✗"
subject = tick + u" %s: %s" % (result.get_state_display(),
result.test.name)
body = ''
if result.summary:
body += "== Summary ==\n\n"
body += result.summary
if body.endswith('\n'):
body += "\n"
else:
body += "\n\n"
if result.url:
body += "== Logs ==\n\n"
body += "For more details see: " + result.url
body += "\n"
return (subject, body)
def handle_test_results(self, request, obj, check_obj, q, ctx):
# auth
if not 'test_name' in request.DATA:
return Response({'test_name': ['This field is required.', ]},
status=status.HTTP_400_BAD_REQUEST)
self.check_object_permissions(request, check_obj)
# update test result and prepare the JSON response
try:
test = request.DATA['test_name']
instance = TestResult.objects.get(q, test__name=test)
......@@ -205,7 +233,34 @@ class ResultMixin(object):
if not result.is_valid():
return Response(result.errors, status=status.HTTP_400_BAD_REQUEST)
result.save()
instance = result.save()
# mailing, done synchronously with the request, for now
to = []
cc = []
if instance.test.mail_recipient == Test.RECIPIENT_SUBMITTER:
to.append(check_obj.submitter.email_name())
elif instance.test.mail_recipient == Test.RECIPIENT_MAILING_LIST:
to.append(check_obj.submitter.email_name())
cc.append(check_obj.project.listemail)
if to:
# never send mail on pending
if instance.state == TestResult.STATE_PENDING:
to = []
if (instance.test.mail_condition == Test.CONDITION_ON_FAILURE and
instance.state not in (TestResult.STATE_WARNING,
TestResult.STATE_FAILURE)):
to = []
if to:
subject, body = self._prepare_mail(instance)
email = mail.EmailMessage(subject, body,
settings.DEFAULT_FROM_EMAIL,
to=to, cc=cc)
email.send()
return Response(result.data, status=status.HTTP_201_CREATED)
class RevisionResultViewSet(viewsets.ViewSet, ResultMixin):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment