Code review comment for lp:~henninge/launchpad/bug-523810-needs-information-age

Revision history for this message
Henning Eggers (henninge) wrote :

> Hi Henning,

Hallo Abel!

> overall a nice branc, but I have a couple of questions, see
> below.

Thanks for the review, though. ;)

> > === modified file
'lib/lp/translations/interfaces/translationimportqueue.py'
> > --- lib/lp/translations/interfaces/translationimportqueue.py 2010-02-05
> 10:39:45 +0000
> > +++ lib/lp/translations/interfaces/translationimportqueue.py 2010-02-19
> 09:03:16 +0000
> > @@ -3,6 +3,8 @@
> >
> > # pylint: disable-msg=E0211,E0213
> >
> > +from datetime import timedelta
> > +
> > from zope.interface import Interface, Attribute
> > from zope.schema import (
> > Bool, Choice, Datetime, Field, Int, Object, Text, TextLine)
> > @@ -39,6 +41,7 @@
> > 'RosettaImportStatus',
> > 'SpecialTranslationImportTargetFilter',
> > 'TranslationFileType',
> > + 'TranslationImportQueueEntryAge',
> > 'UserCannotSetTranslationImportStatus',
> > ]
> >
> > @@ -111,6 +114,22 @@
> > """)
> >
> >
> > +# Some time spans in days.
> > +_month = 30
> > +_half_year = 366 / 2
>
> This being constants, they should be defined as MONTH and HALF_YEAR,
> I think, but...
>
> > +
> > +
> > +# Period after which entries with certain statuses are culled from the
> > +# queue.
> > +TranslationImportQueueEntryAge = {
> > + RosettaImportStatus.DELETED: timedelta(days=3),
> > + RosettaImportStatus.FAILED: timedelta(days=_month),
>
> ...seeing this, I think the constants are probably better called
> DAYS_OF_MONTH/DAYS_OF_HALF_YEAR or DAYS_IN_MONTH/DAYS_IN_HALF_YEAR.

Yes, you are right about the capitalization. And the names are good
suggestions, too. Fixed that.

>
> > + RosettaImportStatus.IMPORTED: timedelta(days=3),
> > + RosettaImportStatus.NEEDS_INFORMATION: timedelta(days=_half_year),
> > + RosettaImportStatus.NEEDS_REVIEW: timedelta(days=_half_year),
> > +}
>
> Our coding style convetions say that this should called
> translation_import_queue_entry_age. Also, I don't think that you
> need to define it in the interfaces module, you could also
> add it to the __all__ list of the model module.

I renamed it but left it in place here, as per our discussion on IRC. We
agreed that the general rule is that tests should not import from model
code. I also noted that I consider these expiration times as
implementation-independent and I don't see a pressing reason *not* to
have this here in the interface module. You agreed to the latter.

>
> > +
> > +
> > class SpecialTranslationImportTargetFilter(DBEnumeratedType):
> > """Special "meta-targets" to filter the queue view by."""
> >
> >
> > === modified file 'lib/lp/translations/model/translationimportqueue.py'
[...]
> > === modified file 'lib/lp/translations/tests/test_autoapproval.py'
> > --- lib/lp/translations/tests/test_autoapproval.py 2010-01-26
15:25:53
> +0000
> > +++ lib/lp/translations/tests/test_autoapproval.py 2010-02-19
09:03:16
> +0000
> > @@ -8,6 +8,9 @@
> > through the possibilities should go here.
> > """
> >
> > +from __future__ import with_statement
> > +
> > +from contextlib import contextmanager
> > from datetime import datetime, timedelta
> > from pytz import UTC
> > import transaction
> > @@ -31,17 +34,28 @@
> > TranslationImportQueue, TranslationImportQueueEntry)
> > from lp.translations.interfaces.customlanguagecode import
> ICustomLanguageCode
> > from lp.translations.interfaces.translationimportqueue import (
> > - RosettaImportStatus)
> > + RosettaImportStatus, TranslationImportQueueEntryAge)
> > from lp.testing import TestCaseWithFactory
> > from lp.testing.factory import LaunchpadObjectFactory
> > from canonical.launchpad.webapp.testing import verifyObject
> > from canonical.testing import LaunchpadZopelessLayer
> >
> >
> > -def become_the_gardener(layer):
> > +class GardenerDbUserMixin(object):
> > """Switch to the translations import queue gardener database
role."""
> > - transaction.commit()
> > - layer.switchDbUser('translations_import_queue_gardener')
> > +
> > + def become_the_gardener(self):
>
> The method name should be camelCased.

Right, fixed.

>
> > + """Switch the user once."""
> > + transaction.commit()
> > + self.layer.switchDbUser('translations_import_queue_gardener')
> > +
> > + @contextmanager
> > + def being_the_gardener(self):
>
> I think this name should also be camelCased, but I am not sure --
> do we consider context meanagers to be similar to methods or similar
> to properties?

It needs to be called(), so I'd consider it a method. Changed to camelCase.

>
> > + """Context manager to restore the launchpad user."""
> > + self.become_the_gardener()
> > + yield
> > + transaction.commit()
> > + self.layer.switchDbUser('launchpad')
>
> Did you consider to drop the method become_the_gardener() and
> to include the code directly in the context manager? I see
> that you call become_the_gardener() quite often in the tests,
> but you could also use "with self.being_the-gardener()" there.
> OK, that would add the second commit() and switchDbUser()
> calls to all these tests, but would this be a noticable slow down?

I try to avoid any slowdown in tests. I documented this as a "one-way"
function now, so this should be clearer.

>
> Perhaps it is a sign that I need even more coffee this morning,
> but my first thought seeing this code was "the code before and
> after the 'yield' looks somewhat asymmetric, and why do we need
> to commit() and switchDbUser() as a cleanup?" Sure, it dawned to
> me that these calls are needed due to the corresponding calls in
> become_teh_gardener(), but at least for my coffee-starved brain
> that was slightly difficult ;)

Sorry about that. I noticed the asymmetry, too, but did nothing about
it. Shame on me. It looks nice and symmetric now. ;-)

>
> [...]
>
> > - def test_cleanUpObsoleteEntries_needs_review(self):
> > - # _cleanUpObsoleteEntries cleans up entries in Needs Review
> > - # state after a very long wait.
> > - entry = self._makeProductEntry()
> > - entry.potemplate = self.factory.makePOTemplate()
> > - self._setStatus(entry, RosettaImportStatus.NEEDS_REVIEW, None)
> > - entry_id = entry.id
> > -
> > - self.queue._cleanUpObsoleteEntries(self.store)
> > - self.assertTrue(self._exists(entry_id))
> > -
> > - entry.date_status_changed -= timedelta(days=200)
> > - entry.syncUpdate()
> > -
> > - become_the_gardener(self.layer)
> > - self.queue._cleanUpObsoleteEntries(self.store)
> > - self.assertFalse(self._exists(entry_id))
> > + affected_statuses = [
> > + RosettaImportStatus.DELETED,
> > + RosettaImportStatus.FAILED,
> > + RosettaImportStatus.IMPORTED,
> > + RosettaImportStatus.NEEDS_INFORMATION,
> > + RosettaImportStatus.NEEDS_REVIEW,
> > + ]
> > + for status in affected_statuses:
> > + entry = self._makeProductEntry()
> > + entry.potemplate = self.factory.makePOTemplate()
> > + maximum_age = TranslationImportQueueEntryAge[status]
> > + # Avoid the exact date here by a day because that could
> introduce
> > + # spurious test failures.
> > + almost_oldest_possible_date = (
> > + datetime.now(UTC) - maximum_age + timedelta(days=1))
> > + self._setStatus(entry, status, almost_oldest_possible_date)
> > + entry_id = entry.id
> > +
> > + self.queue._cleanUpObsoleteEntries(self.store)
> > + self.assertTrue(self._exists(entry_id))
>
> so, here _cleanUpObsoleteEntries(self.store) is called by the
> regular user...
>
> > +
> > + # Now cross the border, again cushoning it by a day.
> > + entry.date_status_changed -= timedelta(days=2)
> > + entry.syncUpdate()
> > +
> > + with self.being_the_gardener():
> > + self.queue._cleanUpObsoleteEntries(self.store)
> > + self.assertFalse(
> > + self._exists(entry_id),
> > + "Queue entry in state '%s' was not removed." %
status)
>
> while it is called here by the gardener? While I'm writing this
> comments, it dawns to me that the former call does not involve
> any DB write or delete operations, while the latter does, but
> this might be worth a short comment.

Comment added.

Thank you for the review! ;-)

1=== modified file 'lib/lp/translations/interfaces/translationimportqueue.py'
2--- lib/lp/translations/interfaces/translationimportqueue.py 2010-02-19 08:37:27 +0000
3+++ lib/lp/translations/interfaces/translationimportqueue.py 2010-02-19 10:36:42 +0000
4@@ -41,7 +41,7 @@
5 'RosettaImportStatus',
6 'SpecialTranslationImportTargetFilter',
7 'TranslationFileType',
8- 'TranslationImportQueueEntryAge',
9+ 'translation_import_queue_entry_age',
10 'UserCannotSetTranslationImportStatus',
11 ]
12
13@@ -115,18 +115,18 @@
14
15
16 # Some time spans in days.
17-_month = 30
18-_half_year = 366 / 2
19+DAYS_IN_MONTH = 30
20+DAYS_IN_HALF_YEAR = 366 / 2
21
22
23 # Period after which entries with certain statuses are culled from the
24 # queue.
25-TranslationImportQueueEntryAge = {
26+translation_import_queue_entry_age = {
27 RosettaImportStatus.DELETED: timedelta(days=3),
28- RosettaImportStatus.FAILED: timedelta(days=_month),
29+ RosettaImportStatus.FAILED: timedelta(days=DAYS_IN_MONTH),
30 RosettaImportStatus.IMPORTED: timedelta(days=3),
31- RosettaImportStatus.NEEDS_INFORMATION: timedelta(days=_half_year),
32- RosettaImportStatus.NEEDS_REVIEW: timedelta(days=_half_year),
33+ RosettaImportStatus.NEEDS_INFORMATION: timedelta(days=DAYS_IN_HALF_YEAR),
34+ RosettaImportStatus.NEEDS_REVIEW: timedelta(days=DAYS_IN_HALF_YEAR),
35 }
36
37
38
39=== modified file 'lib/lp/translations/model/translationimportqueue.py'
40--- lib/lp/translations/model/translationimportqueue.py 2010-02-19 07:46:41 +0000
41+++ lib/lp/translations/model/translationimportqueue.py 2010-02-19 10:56:20 +0000
42@@ -58,7 +58,7 @@
43 RosettaImportStatus,
44 SpecialTranslationImportTargetFilter,
45 TranslationImportQueueConflictError,
46- TranslationImportQueueEntryAge,
47+ translation_import_queue_entry_age,
48 UserCannotSetTranslationImportStatus)
49 from lp.translations.interfaces.potemplate import IPOTemplate
50 from lp.translations.interfaces.translations import TranslationConstants
51@@ -1244,7 +1244,7 @@
52 """
53 now = datetime.datetime.now(pytz.UTC)
54 deletion_clauses = []
55- for status, max_age in TranslationImportQueueEntryAge.iteritems():
56+ for status, max_age in translation_import_queue_entry_age.iteritems():
57 cutoff = now - max_age
58 deletion_clauses.append(And(
59 TranslationImportQueueEntry.status == status,
60
61=== modified file 'lib/lp/translations/tests/test_autoapproval.py'
62--- lib/lp/translations/tests/test_autoapproval.py 2010-02-19 09:01:21 +0000
63+++ lib/lp/translations/tests/test_autoapproval.py 2010-02-19 10:57:42 +0000
64@@ -34,7 +34,7 @@
65 TranslationImportQueue, TranslationImportQueueEntry)
66 from lp.translations.interfaces.customlanguagecode import ICustomLanguageCode
67 from lp.translations.interfaces.translationimportqueue import (
68- RosettaImportStatus, TranslationImportQueueEntryAge)
69+ RosettaImportStatus, translation_import_queue_entry_age)
70 from lp.testing import TestCaseWithFactory
71 from lp.testing.factory import LaunchpadObjectFactory
72 from canonical.launchpad.webapp.testing import verifyObject
73@@ -42,20 +42,26 @@
74
75
76 class GardenerDbUserMixin(object):
77- """Switch to the translations import queue gardener database role."""
78-
79- def become_the_gardener(self):
80- """Switch the user once."""
81+ """Switch to the translations import queue gardener database role.
82+
83+ Admittedly, this might be a little over-engineered but it looks good. ;)
84+ """
85+
86+ def _become(self, dbuser):
87+ """Switch to a different db user."""
88 transaction.commit()
89- self.layer.switchDbUser('translations_import_queue_gardener')
90+ self.layer.switchDbUser(dbuser)
91+
92+ def becomeTheGardener(self):
93+ """One-way method to avoid unnecessary switch back."""
94+ self._become('translations_import_queue_gardener')
95
96 @contextmanager
97- def being_the_gardener(self):
98+ def beingTheGardener(self):
99 """Context manager to restore the launchpad user."""
100- self.become_the_gardener()
101+ self._become('translations_import_queue_gardener')
102 yield
103- transaction.commit()
104- self.layer.switchDbUser('launchpad')
105+ self._become('launchpad')
106
107
108 class TestCustomLanguageCode(unittest.TestCase):
109@@ -191,7 +197,7 @@
110 # Of course matching will work without custom language codes.
111 tr_file = self._makePOFile('tr')
112 entry = self._makeQueueEntry('tr')
113- self.become_the_gardener()
114+ self.becomeTheGardener()
115 self.assertEqual(entry.getGuessedPOFile(), tr_file)
116
117 def test_CustomLanguageCodeEnablesMatch(self):
118@@ -203,7 +209,7 @@
119
120 self._setCustomLanguageCode('fy_NL', 'fy')
121
122- self.become_the_gardener()
123+ self.becomeTheGardener()
124 self.assertEqual(entry.getGuessedPOFile(), fy_file)
125
126 def test_CustomLanguageCodeParsesBogusLanguage(self):
127@@ -214,7 +220,7 @@
128
129 self._setCustomLanguageCode('flemish', 'nl')
130
131- self.become_the_gardener()
132+ self.becomeTheGardener()
133 nl_file = entry.getGuessedPOFile()
134 self.assertEqual(nl_file.language.code, 'nl')
135
136@@ -227,7 +233,7 @@
137
138 self._setCustomLanguageCode('sv', None)
139
140- self.become_the_gardener()
141+ self.becomeTheGardener()
142 self.assertEqual(entry.getGuessedPOFile(), None)
143 self.assertEqual(entry.status, RosettaImportStatus.DELETED)
144
145@@ -240,7 +246,7 @@
146
147 self._setCustomLanguageCode('elx', 'el')
148
149- self.become_the_gardener()
150+ self.becomeTheGardener()
151 el_file = entry.getGuessedPOFile()
152 self.failIfEqual(el_file, elx_file)
153 self.assertEqual(el_file.language.code, 'el')
154@@ -255,7 +261,7 @@
155
156 self._setCustomLanguageCode('nb', 'nn')
157
158- self.become_the_gardener()
159+ self.becomeTheGardener()
160 self.assertEqual(entry.getGuessedPOFile(), nn_file)
161
162 def test_CustomLanguageCodeReplacesMatch(self):
163@@ -268,7 +274,7 @@
164 self._setCustomLanguageCode('pt', None)
165 self._setCustomLanguageCode('pt_PT', 'pt')
166
167- self.become_the_gardener()
168+ self.becomeTheGardener()
169 self.assertEqual(pt_entry.getGuessedPOFile(), None)
170 self.assertEqual(pt_PT_entry.getGuessedPOFile(), pt_file)
171
172@@ -282,7 +288,7 @@
173 self._setCustomLanguageCode('zh_CN', 'zh_TW')
174 self._setCustomLanguageCode('zh_TW', 'zh_CN')
175
176- self.become_the_gardener()
177+ self.becomeTheGardener()
178 self.assertEqual(zh_CN_entry.getGuessedPOFile(), zh_TW_file)
179 self.assertEqual(zh_TW_entry.getGuessedPOFile(), zh_CN_file)
180
181@@ -327,7 +333,7 @@
182 # When multiple templates match for a product series,
183 # getPOTemplateByPathAndOrigin returns none.
184 self._setUpProduct()
185- self.become_the_gardener()
186+ self.becomeTheGardener()
187 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
188 'test.pot', productseries=self.productseries)
189 self.assertEqual(None, guessed_template)
190@@ -336,7 +342,7 @@
191 # When multiple templates match on sourcepackagename,
192 # getPOTemplateByPathAndOrigin returns none.
193 self._setUpDistro()
194- self.become_the_gardener()
195+ self.becomeTheGardener()
196 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
197 'test.pot', sourcepackagename=self.packagename)
198 self.assertEqual(None, guessed_template)
199@@ -345,7 +351,7 @@
200 # When multiple templates match on from_sourcepackagename,
201 # getPOTemplateByPathAndOrigin returns none.
202 self._setUpDistro()
203- self.become_the_gardener()
204+ self.becomeTheGardener()
205 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
206 'test.pot', sourcepackagename=self.from_packagename)
207 self.assertEqual(None, guessed_template)
208@@ -379,7 +385,7 @@
209 self.distrotemplate1.sourcepackagename = match_package
210 self.distrotemplate2.from_sourcepackagename = match_package
211
212- self.become_the_gardener()
213+ self.becomeTheGardener()
214 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
215 'test.pot', sourcepackagename=match_package)
216 self.assertEqual(self.distrotemplate2, guessed_template)
217@@ -390,7 +396,7 @@
218 self._setUpProduct()
219 self.producttemplate1.iscurrent = False
220 self.producttemplate2.iscurrent = True
221- self.become_the_gardener()
222+ self.becomeTheGardener()
223 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
224 'test.pot', productseries=self.productseries)
225 self.assertEqual(guessed_template, self.producttemplate2)
226@@ -400,7 +406,7 @@
227 self._setUpProduct()
228 self.producttemplate1.iscurrent = False
229 self.producttemplate2.iscurrent = False
230- self.become_the_gardener()
231+ self.becomeTheGardener()
232 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
233 'test.pot', productseries=self.productseries)
234 self.assertEqual(guessed_template, None)
235@@ -414,7 +420,7 @@
236 self.distrotemplate2.iscurrent = True
237 self.distrotemplate1.from_sourcepackagename = None
238 self.distrotemplate2.from_sourcepackagename = None
239- self.become_the_gardener()
240+ self.becomeTheGardener()
241 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
242 'test.pot', distroseries=self.distroseries,
243 sourcepackagename=self.packagename)
244@@ -427,7 +433,7 @@
245 self.distrotemplate2.iscurrent = False
246 self.distrotemplate1.from_sourcepackagename = None
247 self.distrotemplate2.from_sourcepackagename = None
248- self.become_the_gardener()
249+ self.becomeTheGardener()
250 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
251 'test.pot', distroseries=self.distroseries,
252 sourcepackagename=self.packagename)
253@@ -442,7 +448,7 @@
254 self.distrotemplate2.iscurrent = True
255 self.distrotemplate1.from_sourcepackagename = self.from_packagename
256 self.distrotemplate2.from_sourcepackagename = self.from_packagename
257- self.become_the_gardener()
258+ self.becomeTheGardener()
259 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
260 'test.pot', distroseries=self.distroseries,
261 sourcepackagename=self.from_packagename)
262@@ -456,7 +462,7 @@
263 self.distrotemplate2.iscurrent = False
264 self.distrotemplate1.from_sourcepackagename = self.from_packagename
265 self.distrotemplate2.from_sourcepackagename = self.from_packagename
266- self.become_the_gardener()
267+ self.becomeTheGardener()
268 guessed_template = self.templateset.getPOTemplateByPathAndOrigin(
269 'test.pot', distroseries=self.distroseries,
270 sourcepackagename=self.from_packagename)
271@@ -467,7 +473,7 @@
272 # translation domain.
273 self._setUpDistro()
274 subset = POTemplateSubset(distroseries=self.distroseries)
275- self.become_the_gardener()
276+ self.becomeTheGardener()
277 potemplate = subset.getPOTemplateByTranslationDomain('test1')
278 self.assertEqual(potemplate, self.distrotemplate1)
279
280@@ -475,7 +481,7 @@
281 # Test getPOTemplateByTranslationDomain for the zero-match case.
282 self._setUpDistro()
283 subset = POTemplateSubset(distroseries=self.distroseries)
284- self.become_the_gardener()
285+ self.becomeTheGardener()
286 potemplate = subset.getPOTemplateByTranslationDomain('notesthere')
287 self.assertEqual(potemplate, None)
288
289@@ -490,7 +496,7 @@
290 clashing_template = other_subset.new(
291 'test3', 'test1', 'test3.pot', self.distro.owner)
292 distro_subset = POTemplateSubset(distroseries=self.distroseries)
293- self.become_the_gardener()
294+ self.becomeTheGardener()
295 potemplate = distro_subset.getPOTemplateByTranslationDomain('test1')
296 self.assertEqual(potemplate, None)
297
298@@ -520,7 +526,7 @@
299 'program/nl.po', 'other contents', False, template.owner,
300 productseries=template.productseries, potemplate=template)
301
302- self.become_the_gardener()
303+ self.becomeTheGardener()
304 entry1.getGuessedPOFile()
305
306 self.assertEqual(entry1.potemplate, None)
307@@ -642,7 +648,7 @@
308 poname, self.pocontents, False, self.distroseries.owner,
309 sourcepackagename=self.kde_i18n_ca,
310 distroseries=self.distroseries)
311- self.become_the_gardener()
312+ self.becomeTheGardener()
313 pofile = entry.getGuessedPOFile()
314 self.assertEqual(pofile, self.pofile_ca)
315
316@@ -654,7 +660,7 @@
317 poname, self.pocontents, False, self.distroseries.owner,
318 sourcepackagename=self.kde_l10n_nl,
319 distroseries=self.distroseries)
320- self.become_the_gardener()
321+ self.becomeTheGardener()
322 pofile = entry.getGuessedPOFile()
323 self.assertEqual(pofile, self.pofile_nl)
324
325@@ -682,7 +688,7 @@
326 entry = self.queue.addOrUpdateEntry(
327 'nl.po', '# ...', False, template.owner, productseries=trunk)
328
329- self.become_the_gardener()
330+ self.becomeTheGardener()
331 pofile = entry._get_pofile_from_language('nl', 'domain')
332 self.assertNotEqual(None, pofile)
333
334@@ -700,7 +706,7 @@
335 entry = self.queue.addOrUpdateEntry(
336 'nl.po', '# ...', False, template.owner, productseries=trunk)
337
338- self.become_the_gardener()
339+ self.becomeTheGardener()
340 pofile = entry._get_pofile_from_language('nl', 'domain')
341 self.assertEqual(None, pofile)
342
343@@ -720,7 +726,7 @@
344 entry = self.queue.addOrUpdateEntry(
345 'nl.po', '# ...', False, template.owner, productseries=trunk)
346
347- self.become_the_gardener()
348+ self.becomeTheGardener()
349 pofile = entry._get_pofile_from_language('nl', 'domain')
350 self.assertNotEqual(None, pofile)
351
352@@ -778,10 +784,14 @@
353 entry_id = entry.id
354
355 self._setStatus(entry, RosettaImportStatus.APPROVED, one_year_ago)
356+ # No write or delete action expected, so no reason to switch the
357+ # database user. If it writes or deletes, the test has failed anyway.
358 self.queue._cleanUpObsoleteEntries(self.store)
359 self.assertTrue(self._exists(entry_id))
360
361 self._setStatus(entry, RosettaImportStatus.BLOCKED, one_year_ago)
362+ # No write or delete action expected, so no reason to switch the
363+ # database user. If it writes or deletes, the test has failed anyway.
364 self.queue._cleanUpObsoleteEntries(self.store)
365 self.assertTrue(self._exists(entry_id))
366
367@@ -799,7 +809,7 @@
368 for status in affected_statuses:
369 entry = self._makeProductEntry()
370 entry.potemplate = self.factory.makePOTemplate()
371- maximum_age = TranslationImportQueueEntryAge[status]
372+ maximum_age = translation_import_queue_entry_age[status]
373 # Avoid the exact date here by a day because that could introduce
374 # spurious test failures.
375 almost_oldest_possible_date = (
376@@ -807,14 +817,17 @@
377 self._setStatus(entry, status, almost_oldest_possible_date)
378 entry_id = entry.id
379
380+ # No write or delete action expected, so no reason to switch the
381+ # database user. If it writes or deletes, the test has failed
382+ # anyway.
383 self.queue._cleanUpObsoleteEntries(self.store)
384 self.assertTrue(self._exists(entry_id))
385
386- # Now cross the border, again cushoning it by a day.
387+ # Now cross the border, again cushioning it by a day.
388 entry.date_status_changed -= timedelta(days=2)
389 entry.syncUpdate()
390
391- with self.being_the_gardener():
392+ with self.beingTheGardener():
393 self.queue._cleanUpObsoleteEntries(self.store)
394 self.assertFalse(
395 self._exists(entry_id),
396@@ -833,7 +846,7 @@
397 entry.productseries.product.active = False
398 entry.productseries.product.syncUpdate()
399
400- self.become_the_gardener()
401+ self.becomeTheGardener()
402 self.queue._cleanUpInactiveProductEntries(self.store)
403 self.assertFalse(self._exists(entry_id))
404
405@@ -849,7 +862,7 @@
406 entry.distroseries.status = SeriesStatus.OBSOLETE
407 entry.distroseries.syncUpdate()
408
409- self.become_the_gardener()
410+ self.becomeTheGardener()
411 self.queue._cleanUpObsoleteDistroEntries(self.store)
412 self.assertFalse(self._exists(entry_id))
413
414@@ -885,7 +898,7 @@
415 entry = self._makeQueueEntry(trunk)
416 rosetta_experts = getUtility(ILaunchpadCelebrities).rosetta_experts
417
418- self.become_the_gardener()
419+ self.becomeTheGardener()
420
421 pofile = entry.getGuessedPOFile()
422
423@@ -903,7 +916,7 @@
424
425 entry = self._makeQueueEntry(trunk)
426
427- self.become_the_gardener()
428+ self.becomeTheGardener()
429
430 pofile = entry.getGuessedPOFile()
431

« Back to merge proposal