[PATCH 11/15] tests: Add a utility class to create Series
Damien Lespiau
damien.lespiau at intel.com
Fri Oct 9 21:39:58 AEDT 2015
So far we've been using real emails stored on-disk. While it's
interesting to have real data as input for unit tests, it's not as
flexible as having generated data. With generated data we can easily
create corner cases to improve the test coverage of the parsing code.
This is just a start, adding a TestSeries classes that can create a
series with n patches with or without a cover letter.
Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
---
patchwork/tests/test_series.py | 51 ++++++++++++++++++++-----
patchwork/tests/utils.py | 86 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 126 insertions(+), 11 deletions(-)
diff --git a/patchwork/tests/test_series.py b/patchwork/tests/test_series.py
index e0408de..4c5d500 100644
--- a/patchwork/tests/test_series.py
+++ b/patchwork/tests/test_series.py
@@ -22,6 +22,7 @@ import os
from django.test import TestCase
from patchwork.models import Patch, Series, SeriesRevision, Project
from patchwork.tests.utils import read_mail
+from patchwork.tests.utils import defaults, read_mail, TestSeries
from patchwork.bin.parsemail import parse_mail
@@ -29,21 +30,23 @@ class SeriesTest(TestCase):
fixtures = ['default_states']
def setUp(self):
- # subclasses are responsible for defining those variables
self.assertTrue(self.project is not None)
- self.assertTrue(self.n_patches is not None)
- self.assertTrue(self.root_msgid is not None)
- self.assertTrue(self.series_name is not None)
-
self.project.save()
- # insert the mails
- self.n_mails = len(self.mails)
- for filename in self.mails:
- mail = read_mail(os.path.join('series', filename))
- parse_mail(mail)
+ # insert the mails. 'mails' is an optional field, for subclasses
+ # that do have a list of on-disk emails.
+ if hasattr(self, 'mails'):
+ self.n_mails = len(self.mails)
+ for filename in self.mails:
+ mail = read_mail(os.path.join('series', filename))
+ parse_mail(mail)
def commonInsertionChecks(self):
+ # subclasses are responsible for defining those variables
+ self.assertTrue(self.n_patches is not None)
+ self.assertTrue(self.root_msgid is not None)
+ self.assertTrue(self.series_name is not None)
+
# make sure the series has been correctly populated
series = Series.objects.all()
self.assertEquals(series.count(), 1)
@@ -70,6 +73,34 @@ class SeriesTest(TestCase):
patches = Patch.objects.all()
self.assertEquals(patches.count(), self.n_patches)
+class GeneratedSeriesTest(SeriesTest):
+ project = defaults.project
+
+ def _create_series(self, n_patches, has_cover_letter=True):
+ self.n_patches = n_patches
+ series = TestSeries(self.n_patches, has_cover_letter)
+ mails = series.create_mails()
+ self.root_msgid = mails[0].get('Message-Id')
+ self.has_cover_letter = has_cover_letter
+ if has_cover_letter:
+ self.series_name = defaults.series_name
+ self.cover_letter = defaults.series_cover_letter
+ else:
+ self.series_name = 'Untitled series'
+ self.cover_letter = None
+ return (series, mails)
+
+class BasicGeneratedSeriesTests(GeneratedSeriesTest):
+ def testInsertion(self):
+ (series, mails) = self._create_series(3)
+ series.insert(mails)
+ self.commonInsertionChecks()
+
+ def testInsertionNoCoverLetter(self):
+ (series, mails) = self._create_series(3, has_cover_letter=False)
+ series.insert(mails)
+ self.commonInsertionChecks()
+
class IntelGfxTest(SeriesTest):
project = Project(linkname = 'intel-gfx',
name = 'Intel Gfx',
diff --git a/patchwork/tests/utils.py b/patchwork/tests/utils.py
index 931462b..219e4bb 100644
--- a/patchwork/tests/utils.py
+++ b/patchwork/tests/utils.py
@@ -20,6 +20,7 @@
import os
import codecs
from patchwork.models import Project, Person
+from patchwork.bin.parsemail import parse_mail
from django.contrib.auth.models import User
from django.forms.fields import EmailField
@@ -47,6 +48,11 @@ class defaults(object):
subject = 'Test Subject'
+ series_name = 'Test Series'
+
+ series_cover_letter = """This is the test series cover letter.
+I hope you'll like it."""
+
patch_name = 'Test Patch'
patch = """--- /dev/null 2011-01-01 00:00:00.000000000 +0800
@@ -55,6 +61,8 @@ class defaults(object):
+a
"""
+ review = """This is a great addition!"""
+
error_strings = {
'email': 'Enter a valid email address.',
}
@@ -111,7 +119,8 @@ def read_mail(filename, project = None):
return mail
def create_email(content, subject = None, sender = None, multipart = False,
- project = None, content_encoding = None):
+ project = None, content_encoding = None, in_reply_to = None,
+ references = None):
if subject is None:
subject = defaults.subject
if sender is None:
@@ -134,5 +143,80 @@ def create_email(content, subject = None, sender = None, multipart = False,
msg['Subject'] = subject
msg['From'] = sender
msg['List-Id'] = project.listid
+ if in_reply_to and references:
+ msg['References'] = ' '.join([m.get('Message-Id') for m in references])
+ msg['In-Reply-To'] = in_reply_to
+ elif references:
+ msg['References'] = references
+ msg['In-Reply-To'] = references.split()[-1]
+ elif in_reply_to:
+ msg['References'] = in_reply_to
+ msg['In-Reply-To'] = in_reply_to
return msg
+
+class TestSeries(object):
+ def __init__(self, n_patches, has_cover_letter=True):
+ if n_patches < 1:
+ raise ValueError
+ self.n_patches = n_patches
+ self.has_cover_letter = has_cover_letter
+
+ def create_cover_letter(self):
+ return create_email(defaults.series_cover_letter,
+ subject='[PATCH 0/%d] %s' % (self.n_patches,
+ defaults.series_name))
+
+ # in_reply_to: a mail instance
+ def create_patch(self, n=0, in_reply_to=None, references=None,
+ subject_prefix='PATCH'):
+ in_reply_to_str = None
+ if in_reply_to:
+ in_reply_to_str = in_reply_to.get('Message-Id')
+
+ if n != 0:
+ subject='[%s %d/%d] %s' % (subject_prefix, n,
+ self.n_patches,
+ defaults.patch_name)
+ else:
+ subject='[%s] %s' % (subject_prefix, defaults.patch_name)
+
+ mail = create_email(defaults.patch, subject=subject,
+ in_reply_to=in_reply_to_str, references=references)
+ mail['X-Mailer'] = 'git-send-email 2.1.0'
+ return mail
+
+ def create_reply(self, mail, references=None):
+ if not references:
+ references = mail.get('References') + ' ' + mail.get('Message-Id')
+ return create_email(defaults.review,
+ subject='Re: ' + mail.get('Subject'),
+ references=references)
+
+ def create_mails(self):
+ mails = []
+ root_msg = None
+
+ # cover letter
+ if self.has_cover_letter:
+ cover_letter = self.create_cover_letter()
+ mails.append(cover_letter)
+ root_msg = cover_letter
+
+ # insert the first patch
+ patch = self.create_patch(1, root_msg)
+ mails.append(patch)
+ if not root_msg:
+ root_msg = patch
+
+ # and the remaining patches
+ for i in range(2, self.n_patches + 1):
+ mails.append(self.create_patch(i, root_msg))
+
+ return mails
+
+ def insert(self, mails=[]):
+ if not mails:
+ mails = self.create_mails()
+ for mail in mails:
+ parse_mail(mail)
--
2.1.0
More information about the Patchwork
mailing list