Merge lp:~jtv/launchpad/bug-594220 into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 11568
Proposed branch: lp:~jtv/launchpad/bug-594220
Merge into: lp:launchpad
Diff against target: 143 lines (+54/-20)
2 files modified
lib/lp/translations/scripts/po_import.py (+11/-3)
lib/lp/translations/scripts/tests/test_translations_import.py (+43/-17)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-594220
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+35770@code.launchpad.net

Commit message

Stop notifying vcs-imports about import of generated translation templates.

Description of the change

= Bug 594220 =

Translations uploads can enter the queue in several ways:
 * Soyuz can upload ones generated during package build.
 * Users can upload files.
 * We can import them from bzr branches.
 * The build farm can generate templates every time a branch changes.

In that last avenue, the resulting entries on the translations import queue are owned by whoever owns the branch. But what if the branch is mirrored? In that case, there is no reliably identifiable owner in Launchpad and such branches are owned by the vcs-imports celebrity.

Each of these imports normally results in an email message (either a success confirmation or a failure notice). And thus, vcs-imports got inundated with email when we implemented the generate-templates-from-branches feature. In this branch I stop these notifications from being sent.

We discussed alternatives, including sending the notifications to some other party, but we don't want to dump excessive email messages onto unsuspecting users. If there are problems with the imports that the emails would warn about, the import-queue UI will provide the same diagnostic information.

To test:
{{{
./bin/test -vvc lp.translations.scripts.tests.test_translations_import
}}}

For Q/A, we can verify that:
 * templates generated from mirrored branches still hit the import queue,
 * notification emails are still sent out, and
 * vcs-imports stops receiving emails.

What with email filtering on staging, the surest way to verify that last point is to inquire after rollout. We should do that in addition to pre-rollout Q/A.

No lint,

Jeroen

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/translations/scripts/po_import.py'
2--- lib/lp/translations/scripts/po_import.py 2010-08-20 20:31:18 +0000
3+++ lib/lp/translations/scripts/po_import.py 2010-09-17 08:04:48 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2009 Canonical Ltd. This software is licensed under the
6+# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """Functions used with the Rosetta PO import script."""
10@@ -119,13 +119,21 @@
11
12 return True
13
14+ def _shouldNotify(self, person):
15+ """Is `person` someone we should send notification emails?"""
16+ # We don't notify the vcs-imports team, which owns all mirrored
17+ # branches. Templates generated in the build farm based on
18+ # mirrored branches are uploaded in the name of this team, but
19+ # there is no point in sending out notifications to them.
20+ return person != getUtility(ILaunchpadCelebrities).vcs_imports
21+
22 def _importEntry(self, entry):
23 """Perform the import of one entry, and notify the uploader."""
24- self.logger.info('Importing: %s' % entry.import_into.title)
25 target = entry.import_into
26+ self.logger.info('Importing: %s' % target.title)
27 (mail_subject, mail_body) = target.importFromQueue(entry, self.logger)
28
29- if mail_subject is not None:
30+ if mail_subject is not None and self._shouldNotify(entry.importer):
31 # A `mail_subject` of None indicates that there
32 # is no notification worth sending out.
33 from_email = config.rosetta.admin_email
34
35=== modified file 'lib/lp/translations/scripts/tests/test_translations_import.py'
36--- lib/lp/translations/scripts/tests/test_translations_import.py 2010-08-20 20:31:18 +0000
37+++ lib/lp/translations/scripts/tests/test_translations_import.py 2010-09-17 08:04:48 +0000
38@@ -1,13 +1,17 @@
39-# Copyright 2009 Canonical Ltd. This software is licensed under the
40+# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
41 # GNU Affero General Public License version 3 (see the file LICENSE).
42
43 import logging
44 import re
45-from unittest import TestLoader
46+import transaction
47+from zope.component import getUtility
48
49+from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
50 from canonical.launchpad.webapp import errorlog
51 from canonical.testing.layers import LaunchpadScriptLayer
52+from lp.services.mail import stub
53 from lp.testing import TestCaseWithFactory
54+from lp.testing.fakemethod import FakeMethod
55 from lp.translations.interfaces.translationimportqueue import (
56 RosettaImportStatus,
57 )
58@@ -25,16 +29,6 @@
59 """Very serious system error."""
60
61
62-class Raiser:
63- """Raise a given exception."""
64- def __init__(self, exception):
65- self.exception = exception
66-
67- def __call__(self, *args, **kwargs):
68- """Whatever the arguments, just raise self.exception."""
69- raise self.exception
70-
71-
72 class TestTranslationsImport(TestCaseWithFactory):
73
74 layer = LaunchpadScriptLayer
75@@ -52,8 +46,26 @@
76
77 def _makeEntry(self, path, **kwargs):
78 """Produce a queue entry."""
79+ uploader = kwargs.pop('uploader', self.owner)
80 return self.queue.addOrUpdateEntry(
81- path, '# Nothing here', False, self.owner, **kwargs)
82+ path, '# Nothing here', False, uploader, **kwargs)
83+
84+ def _makeApprovedEntry(self, uploader):
85+ """Produce an approved queue entry."""
86+ path = '%s.pot' % self.factory.getUniqueString()
87+ series = self.factory.makeProductSeries()
88+ template = self.factory.makePOTemplate(series)
89+ entry = self._makeEntry(
90+ path, uploader=uploader, potemplate=template,
91+ productseries=template.productseries)
92+ entry.status = RosettaImportStatus.APPROVED
93+ return entry
94+
95+ def _getEmailRecipients(self):
96+ """List the recipients of all pending outgoing emails."""
97+ return sum([
98+ recipients
99+ for sender, recipients, text in stub.test_emails], [])
100
101 def test_describeEntry_without_target(self):
102 productseries = self._makeProductSeries()
103@@ -136,7 +148,8 @@
104 self.assertNotEqual(None, entry.import_into)
105
106 message = "The system has exploded."
107- self.script._importEntry = Raiser(OutrageousSystemError(message))
108+ self.script._importEntry = FakeMethod(
109+ failure=OutrageousSystemError(message))
110 self.assertRaises(OutrageousSystemError, self.script.main)
111
112 self.assertEqual(RosettaImportStatus.FAILED, entry.status)
113@@ -153,7 +166,8 @@
114 self.assertNotEqual(None, entry.import_into)
115
116 message = "Nobody expects the Spanish Inquisition!"
117- self.script._importEntry = Raiser(UnexpectedException(message))
118+ self.script._importEntry = FakeMethod(
119+ failure=UnexpectedException(message))
120 self.script.main()
121
122 self.assertEqual(RosettaImportStatus.FAILED, entry.status)
123@@ -167,6 +181,18 @@
124 self.assertEqual(default_reporting.oops_prefix,
125 errorlog.globalErrorUtility.oops_prefix)
126
127+ def test_notifies_uploader(self):
128+ entry = self._makeApprovedEntry(self.owner)
129+ transaction.commit()
130+ self.script._importEntry(entry)
131+ transaction.commit()
132+ self.assertEqual(
133+ [self.owner.preferredemail.email], self._getEmailRecipients())
134
135-def test_suite():
136- return TestLoader().loadTestsFromName(__name__)
137+ def test_does_not_notify_vcs_imports(self):
138+ vcs_imports = getUtility(ILaunchpadCelebrities).vcs_imports
139+ entry = self._makeApprovedEntry(vcs_imports)
140+ transaction.commit()
141+ self.script._importEntry(entry)
142+ transaction.commit()
143+ self.assertEqual([], self._getEmailRecipients())