Commit 8738d513 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler

parsemail: Catch errors caused by duplicate patches in revision

Let's assume mail structure with replies like this:

[1/2] Patch 1
  |- [2/2] Patch 2
  |- [2/2] Another Patch 2

When the "Another Patch 2" comes in, it's going to get inserted in the
same revision at the same place as the original "Patch 2", which results
in integrity error.

This is the single most common reason for administration notifications.

There is not really much we can do, as the reasons for such emails are
so ambiguous that the best we can do is to discard them, just like we
are doing now. So let's make it silent.
Signed-off-by: Arkadiusz Hiler's avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent 3345a2ba
......@@ -45,6 +45,7 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import MultipleObjectsReturned
from django.db.models import Q
from django.db import IntegrityError
from django.utils.log import AdminEmailHandler
from django.utils import six
from django.utils.six.moves import map
......@@ -815,7 +816,10 @@ def parse_mail(mail):
patch.delegate = delegate
patch.save()
if revision:
revision.add_patch(patch, content.patch_order)
try:
revision.add_patch(patch, content.patch_order)
except IntegrityError:
LOGGER.debug('Duplicate patch in revision, ignoring')
LOGGER.debug('Patch saved')
if comment:
......
......@@ -21,7 +21,7 @@ from email import message_from_string
from email.mime.text import MIMEText
from email.utils import make_msgid
from django.test import TestCase
from django.test import TestCase, TransactionTestCase
from patchwork.bin.parsemail import (find_content, find_author, find_project,
parse_mail, split_prefixes, clean_subject,
......@@ -337,6 +337,28 @@ class MultipleProjectPatchTest(TestCase):
self.p2.delete()
class DuplicatePatchInRevision(TransactionTestCase):
fixtures = ['default_states', 'default_events']
test_comment = 'Test Comment'
patch_filename = '0001-add-line.patch'
def testParsedProjects(self):
patch = read_patch(self.patch_filename)
patch1 = create_email(self.test_comment + '\n' + patch,
subject="[PATCH 1/2] Meep Meep]")
patch2 = create_email(self.test_comment + '\n' + patch,
subject="[PATCH 2/2] Meep Meep2]",
in_reply_to=patch1['Message-Id'])
parse_mail(patch1)
parse_mail(patch2)
del patch2['Message-Id']
patch2['Message-Id'] = '<1@example.com>'
parse_mail(patch2)
class MultipleProjectPatchCommentTest(MultipleProjectPatchTest):
"""Test that followups to multiple-project patches end up on the
......
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