Merge lp:~gmb/launchpad/gbwnu-next-check-goodness-544943 into lp:launchpad/db-devel

Proposed by Graham Binns
Status: Merged
Approved by: Eleanor Berger
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~gmb/launchpad/gbwnu-next-check-goodness-544943
Merge into: lp:launchpad/db-devel
Diff against target: 589 lines (+115/-79)
17 files modified
database/sampledata/current.sql (+1/-1)
lib/lp/bugs/configure.zcml (+9/-1)
lib/lp/bugs/doc/bugtracker.txt (+25/-22)
lib/lp/bugs/doc/checkwatches.txt (+11/-10)
lib/lp/bugs/doc/externalbugtracker-bugzilla.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-debbugs.txt (+21/-7)
lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-mantis.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-trac.txt (+1/-1)
lib/lp/bugs/interfaces/bugtracker.py (+10/-6)
lib/lp/bugs/interfaces/bugwatch.py (+3/-0)
lib/lp/bugs/model/bugtracker.py (+10/-14)
lib/lp/bugs/model/bugwatch.py (+1/-0)
lib/lp/bugs/scripts/checkwatches.py (+7/-11)
lib/lp/bugs/scripts/tests/test_bugimport.py (+2/-2)
lib/lp/bugs/stories/webservice/xx-bug.txt (+2/-0)
lib/lp/testing/factory.py (+9/-1)
To merge this branch: bzr merge lp:~gmb/launchpad/gbwnu-next-check-goodness-544943
Reviewer Review Type Date Requested Status
Eleanor Berger (community) code Approve
Review via email: mp+22013@code.launchpad.net

Commit message

BugTracker.getBugWatchesNeedingUpdate() now looks at BugWatch.next_check rather than BugWatch.lastchecked.

Description of the change

This branch updates BugTracker.getBugWatchesNeedingUpdate() to use the BugWatch.next_check field rather than BugWatch.lastchecked to determine whether a bug watch needs to be updated.

I've updated the IBugTracker interface and BugTracker model accordingly, as well as associated tests. getBugWatchesNeedingUpdate() no longer accepts a hours_since_last_check parameter, so I've updated all the callsites to remove that.

To post a comment you must log in.
Revision history for this message
Eleanor Berger (intellectronica) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/sampledata/current.sql'
2--- database/sampledata/current.sql 2010-03-21 16:57:00 +0000
3+++ database/sampledata/current.sql 2010-03-24 22:10:48 +0000
4@@ -2486,7 +2486,7 @@
5 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (54, 'rosetta@launchpad.net', 30, 4, '2006-10-16 18:31:43.626521', NULL);
6 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (55, 'salgado@ubuntu.com', 29, 1, '2006-10-16 18:31:43.626932', 291);
7 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (56, 'cprov@ubuntu.com', 28, 2, '2006-10-16 18:31:43.627318', 281);
8-INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (57, 'bugwatch@bugs.launchpad.net', 62, 1, '2006-10-16 18:31:43.62774', 621);
9+INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (57, 'bugwatch@bugs.launchpad.net', 62, 4, '2006-10-16 18:31:43.62774', 621);
10 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (58, 'karl@canonical.com', 63, 4, '2006-10-16 18:31:43.628123', 631);
11 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (59, 'limi@plone.org', 10, 4, '2006-10-16 18:31:43.628504', 101);
12 INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (60, 'janitor@launchpad.net', 65, 4, '2006-10-17 23:23:23.232323', 651);
13
14=== modified file 'lib/lp/bugs/configure.zcml'
15--- lib/lp/bugs/configure.zcml 2010-03-19 17:42:12 +0000
16+++ lib/lp/bugs/configure.zcml 2010-03-24 22:10:48 +0000
17@@ -839,6 +839,7 @@
18 lastchanged
19 lastchecked
20 needscheck
21+ next_check
22 owner
23 remote_importance
24 remotebug
25@@ -858,7 +859,14 @@
26 addComment
27 updateImportance
28 updateStatus"
29- set_attributes="last_error_type lastchanged lastchecked needscheck remote_importance remotestatus"/>
30+ set_attributes="
31+ last_error_type
32+ lastchanged
33+ lastchecked
34+ needscheck
35+ next_check
36+ remote_importance
37+ remotestatus"/>
38 </class>
39
40 <!-- https://launchpad.net/bugs/98639 -->
41
42=== modified file 'lib/lp/bugs/doc/bugtracker.txt'
43--- lib/lp/bugs/doc/bugtracker.txt 2010-03-22 10:36:53 +0000
44+++ lib/lp/bugs/doc/bugtracker.txt 2010-03-24 22:10:48 +0000
45@@ -16,7 +16,7 @@
46
47 >>> def print_watches(bugtracker):
48 ... watches = sorted(
49- ... bugtracker.getBugWatchesNeedingUpdate(23),
50+ ... bugtracker.getBugWatchesNeedingUpdate(),
51 ... key=lambda watch: (watch.remotebug, watch.bug.id))
52 ...
53 ... for bug_watch in watches:
54@@ -28,8 +28,8 @@
55 >>> login('foo.bar@canonical.com')
56
57 We can get a list of all the bug tracker's bug watches needing to be
58-updated. The current criteria for needing a update is that it hasn't
59-been updated in the last 23 hours.
60+updated. A bug watch is considered to be needing an update when its
61+next_check time is in the past.
62
63 >>> bug_watches = mozilla_bugzilla.watches
64 >>> print bug_watches.count()
65@@ -37,7 +37,7 @@
66
67 >>> print bug_watches[0].remotebug, bug_watches[0].bug.id
68 2000 1
69- >>> bug_watches[0].lastchecked = None
70+ >>> bug_watches[0].next_check = now - timedelta(hours=1)
71
72 >>> print bug_watches[1].remotebug, bug_watches[1].bug.id
73 123543 1
74@@ -48,11 +48,11 @@
75
76 >>> print bug_watches[2].remotebug, bug_watches[2].bug.id
77 42 1
78- >>> bug_watches[2].lastchecked = now - timedelta(hours=36)
79+ >>> bug_watches[2].next_check = now - timedelta(hours=36)
80
81 >>> print bug_watches[3].remotebug, bug_watches[3].bug.id
82 42 2
83- >>> bug_watches[3].lastchecked = now - timedelta(days=1)
84+ >>> bug_watches[3].next_check = now - timedelta(days=1)
85
86 The watches needing updating should the ones with old statuses, 2000 and 42:
87
88@@ -593,31 +593,34 @@
89 resetWatches() method.
90
91 >>> from operator import attrgetter
92+ >>> from pytz import utc
93+ >>> definitely_now = datetime.now(utc)
94
95 >>> def print_tracker_watch_times(bugtracker):
96 ... for watch in sorted(
97 ... bugtracker.watches, key=attrgetter('id')):
98- ... if watch.lastchecked is not None:
99- ... print watch.bug.id, "not None"
100+ ... if watch.next_check != definitely_now:
101+ ... print watch.bug.id, "not now"
102 ... else:
103- ... print watch.bug.id, watch.lastchecked
104+ ... print watch.bug.id, "now"
105
106 >>> print_tracker_watch_times(mozilla_bugzilla)
107- 2 not None
108- 1 None
109- 1 not None
110- 1 not None
111-
112-Calling resetWatches() on mozilla_bugzilla will set all its
113-lastchecked times to None.
114-
115- >>> mozilla_bugzilla.resetWatches()
116+ 2 not now
117+ 1 not now
118+ 1 not now
119+ 1 not now
120+
121+Calling resetWatches() on mozilla_bugzilla will set all its next_check
122+times to datetime.now(). For testing purposes, we'll pass it a value to
123+use in place of now().
124+
125+ >>> mozilla_bugzilla.resetWatches(now=definitely_now)
126 >>> transaction.commit()
127 >>> print_tracker_watch_times(mozilla_bugzilla)
128- 2 None
129- 1 None
130- 1 None
131- 1 None
132+ 2 now
133+ 1 now
134+ 1 now
135+ 1 now
136
137 resetWatches() also clears the last_error_type field of the watches.
138
139
140=== modified file 'lib/lp/bugs/doc/checkwatches.txt'
141--- lib/lp/bugs/doc/checkwatches.txt 2010-03-24 06:53:49 +0000
142+++ lib/lp/bugs/doc/checkwatches.txt 2010-03-24 22:10:48 +0000
143@@ -103,6 +103,8 @@
144
145 First, we create some bug watches to test with:
146
147+ >>> from datetime import datetime
148+ >>> from pytz import utc
149 >>> from canonical.launchpad.database import BugTracker
150 >>> from canonical.launchpad.interfaces import (
151 ... BugTrackerType, IBugSet)
152@@ -128,6 +130,7 @@
153 >>> example_bugwatch = example_bug.addWatch(
154 ... example_bug_tracker, '1',
155 ... getUtility(ILaunchpadCelebrities).janitor)
156+ >>> example_bugwatch.next_check = datetime.now(utc)
157
158 >>> login('no-priv@canonical.com')
159
160@@ -206,7 +209,7 @@
161 ... bugtrackertype.name, bugtracker.name)
162
163 >>> login(ANONYMOUS)
164- >>> example_bugwatch.lastchecked = None
165+ >>> example_bugwatch.next_check = datetime.now(utc)
166 >>> try:
167 ... externalbugtracker.get_external_bugtracker = (
168 ... broken_get_external_bugtracker)
169@@ -242,6 +245,7 @@
170 ... example_bugwatch = example_bug.addWatch(
171 ... example_bug_tracker, str(bug_id),
172 ... getUtility(ILaunchpadCelebrities).janitor)
173+ ... example_bugwatch.next_check = datetime.now(utc)
174
175 Since we know how many bugwatches example_bug has we will be able to see
176 when checkwatches only updates a subset of them.
177@@ -294,15 +298,13 @@
178 We'll set the lastchecked time on that Savannah instance to make sure
179 that it looks as though it has been updated recently
180
181- >>> import pytz
182- >>> from datetime import datetime
183 >>> login('test@canonical.com')
184 >>> for watch in savannah.watches:
185- ... watch.lastchecked = datetime.now(pytz.timezone('UTC'))
186+ ... watch.lastchecked = datetime.now(utc)
187
188 So our Savannah instance now has no watches that need checking.
189
190- >>> savannah.getBugWatchesNeedingUpdate(23).count()
191+ >>> savannah.getBugWatchesNeedingUpdate().count()
192 0
193
194 However, forceUpdateAll() will update every watch, whether they've
195@@ -368,10 +370,11 @@
196 ... def _updateBugTracker(self, bug_tracker, batch_size):
197 ... # Update as many watches as the batch size says.
198 ... watches_to_update = (
199- ... bug_tracker.getBugWatchesNeedingUpdate(23)[:batch_size])
200+ ... bug_tracker.getBugWatchesNeedingUpdate()[:batch_size])
201 ...
202 ... for watch in watches_to_update:
203- ... watch.lastchecked = datetime.now(pytz.timezone('UTC'))
204+ ... watch.lastchecked = datetime.now(utc)
205+ ... watch.next_check = None
206
207 >>> non_connecting_updater = NonConnectingUpdater(transaction)
208 >>> non_connecting_updater.log = FakeLogger()
209@@ -397,8 +400,6 @@
210
211 We'll create a non-functioning ExternalBugtracker to demonstrate this.
212
213- >>> import pytz
214- >>> from datetime import datetime
215 >>> from zope.interface import implements
216 >>> from lp.bugs.interfaces.bugtask import (
217 ... BugTaskStatus, BugTaskImportance)
218@@ -407,7 +408,7 @@
219 ... ISupportsBackLinking)
220 >>> from lp.bugs.externalbugtracker.base import ExternalBugTracker
221
222- >>> nowish = datetime.now(pytz.timezone('UTC'))
223+ >>> nowish = datetime.now(utc)
224 >>> class UselessExternalBugTracker(ExternalBugTracker):
225 ...
226 ... implements(
227
228=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla.txt'
229--- lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-03-19 16:47:08 +0000
230+++ lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-03-24 22:10:48 +0000
231@@ -422,7 +422,7 @@
232
233 >>> from canonical.database.sqlbase import flush_database_updates
234 >>> flush_database_updates()
235- >>> gnome_bugzilla.getBugWatchesNeedingUpdate(23).count()
236+ >>> gnome_bugzilla.getBugWatchesNeedingUpdate().count()
237 0
238
239 If the status isn't different, the lastchanged attribute doesn't get
240
241=== modified file 'lib/lp/bugs/doc/externalbugtracker-debbugs.txt'
242--- lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-01-06 14:35:52 +0000
243+++ lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-03-24 22:10:48 +0000
244@@ -91,13 +91,27 @@
245
246 >>> from canonical.launchpad.interfaces import IBugTrackerSet
247 >>> debbugs = getUtility(IBugTrackerSet).getByName('debbugs')
248- >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate(23))
249+ >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate())
250+ >>> len(bug_watches)
251+ 0
252+
253+It looks as though there are no bug watches needing to be updated.
254+That's because the check for whether a bug watch needs to be updated
255+looks at its next_check field, which is None by default. Updating the
256+bug watches should solve that problem.
257+
258+ >>> from datetime import datetime
259+ >>> from pytz import utc
260+ >>> for watch in debbugs.watches:
261+ ... watch.next_check = datetime.now(utc)
262+
263+ >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate())
264 >>> len(bug_watches)
265 5
266
267-Log in and kick off the update. The importing of comments, which is
268-controlled by a configuration option, is disabled here and will be
269-tested later.
270+Now there are some watches to update we can run the update against them.
271+The importing of comments, which is controlled by a configuration
272+option, is disabled here and will be tested later.
273
274 >>> from lp.bugs.scripts.checkwatches import BugWatchUpdater
275 >>> bug_watch_updater = BugWatchUpdater(txn)
276@@ -116,11 +130,11 @@
277 327549: open important security
278 308994: open important
279
280-The lastchecked attribute got updated for each bug watch, so no more
281-watches are in need of an update.
282+The next_check value for all the watches got set to null when they
283+were updated, so there are no watches left needing an update.
284
285 >>> flush_database_updates()
286- >>> watches = debbugs.getBugWatchesNeedingUpdate(23)
287+ >>> watches = debbugs.getBugWatchesNeedingUpdate()
288 >>> watches.count()
289 0
290
291
292=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt'
293--- lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2009-10-09 20:56:00 +0000
294+++ lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-03-24 22:10:48 +0000
295@@ -164,7 +164,7 @@
296
297 >>> from canonical.database.sqlbase import flush_database_updates
298 >>> flush_database_updates()
299- >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()
300+ >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
301 0
302
303 If the status isn't different, the lastchanged attribute doesn't get
304
305=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis.txt'
306--- lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-03-17 13:40:49 +0000
307+++ lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-03-24 22:10:48 +0000
308@@ -179,7 +179,7 @@
309
310 >>> from canonical.database.sqlbase import flush_database_updates
311 >>> flush_database_updates()
312- >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()
313+ >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
314 0
315
316 If the status isn't different, the lastchanged attribute doesn't get
317
318=== modified file 'lib/lp/bugs/doc/externalbugtracker-trac.txt'
319--- lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-01-11 13:54:42 +0000
320+++ lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-03-24 22:10:48 +0000
321@@ -369,7 +369,7 @@
322 now no bug watches are in need of updating:
323
324 >>> flush_database_updates()
325- >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()
326+ >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
327 0
328
329 If the status isn't different, the lastchanged attribute doesn't get
330
331=== modified file 'lib/lp/bugs/interfaces/bugtracker.py'
332--- lib/lp/bugs/interfaces/bugtracker.py 2010-03-10 19:00:59 +0000
333+++ lib/lp/bugs/interfaces/bugtracker.py 2010-03-24 22:10:48 +0000
334@@ -273,12 +273,11 @@
335 def getBugsWatching(remotebug):
336 """Get the bugs watching the given remote bug in this bug tracker."""
337
338- def getBugWatchesNeedingUpdate(hours_since_last_check):
339+ def getBugWatchesNeedingUpdate():
340 """Get the bug watches needing to be updated.
341
342- All bug watches not being updated for the last
343- :hours_since_last_check: hours are considered needing to be
344- updated.
345+ All bug watches with a next_check time in the past are
346+ considered to be needing an update.
347 """
348
349 def getLinkedPersonByName(name):
350@@ -318,8 +317,13 @@
351 def destroySelf():
352 """Delete this bug tracker."""
353
354- def resetWatches():
355- """Reset the lastchecked times of this BugTracker's `BugWatch`es."""
356+ def resetWatches(now=None):
357+ """Reset the next_check times of this BugTracker's `BugWatch`es.
358+
359+ :param now: If specified, contains the datetime to which to set
360+ the BugWatches' next_check times. Defaults to
361+ datetime.now().
362+ """
363
364
365 class IBugTrackerSet(Interface):
366
367=== modified file 'lib/lp/bugs/interfaces/bugwatch.py'
368--- lib/lp/bugs/interfaces/bugwatch.py 2010-03-22 10:36:53 +0000
369+++ lib/lp/bugs/interfaces/bugwatch.py 2010-03-24 22:10:48 +0000
370@@ -136,6 +136,9 @@
371 Reference(title=_('Owner'), required=True,
372 readonly=True, schema=Interface))
373 activity = Attribute('The activity history of this BugWatch.')
374+ next_check = exported(
375+ Datetime(title=_('Next Check')),
376+ exported_as='date_next_checked')
377
378 # Useful joins.
379 bugtasks = exported(
380
381=== modified file 'lib/lp/bugs/model/bugtracker.py'
382--- lib/lp/bugs/model/bugtracker.py 2009-12-09 14:55:30 +0000
383+++ lib/lp/bugs/model/bugtracker.py 2010-03-24 22:10:48 +0000
384@@ -25,7 +25,7 @@
385 BoolCol, ForeignKey, OR, SQLMultipleJoin, SQLObjectNotFound, StringCol)
386 from sqlobject.sqlbuilder import AND
387
388-from storm.expr import Or
389+from storm.expr import Not, Or
390 from storm.locals import Bool
391 from storm.store import Store
392
393@@ -348,26 +348,19 @@
394 distinct=True,
395 orderBy=['datecreated']))
396
397- def getBugWatchesNeedingUpdate(self, hours_since_last_check):
398+ def getBugWatchesNeedingUpdate(self):
399 """See `IBugTracker`.
400
401 :return: The UNION of the bug watches that need checking and
402 those with unpushed comments.
403 """
404- lastchecked_cutoff = (
405- datetime.now(timezone('UTC')) -
406- timedelta(hours=hours_since_last_check))
407-
408- lastchecked_clause = Or(
409- BugWatch.lastchecked < lastchecked_cutoff,
410- BugWatch.lastchecked == None)
411-
412 store = Store.of(self)
413
414 bug_watches_needing_checking = store.find(
415 BugWatch,
416 BugWatch.bugtracker == self,
417- lastchecked_clause)
418+ Not(BugWatch.next_check == None),
419+ BugWatch.next_check <= datetime.now(timezone('UTC')))
420
421 bug_watches_with_unpushed_comments = store.find(
422 BugWatch,
423@@ -486,12 +479,15 @@
424
425 return person
426
427- def resetWatches(self):
428+ def resetWatches(self, now=None):
429 """See `IBugTracker`."""
430+ if now is None:
431+ now = datetime.now(timezone('UTC'))
432+
433 store = Store.of(self)
434 store.execute(
435- "UPDATE BugWatch SET lastchecked = NULL WHERE bugtracker = %s" %
436- sqlvalues(self))
437+ "UPDATE BugWatch SET next_check = %s WHERE bugtracker = %s" %
438+ sqlvalues(now, self))
439
440
441 class BugTrackerSet:
442
443=== modified file 'lib/lp/bugs/model/bugwatch.py'
444--- lib/lp/bugs/model/bugwatch.py 2010-03-22 13:57:43 +0000
445+++ lib/lp/bugs/model/bugwatch.py 2010-03-24 22:10:48 +0000
446@@ -83,6 +83,7 @@
447 owner = ForeignKey(
448 dbName='owner', foreignKey='Person',
449 storm_validator=validate_public_person, notNull=True)
450+ next_check = UtcDateTimeCol()
451
452 @property
453 def bugtasks(self):
454
455=== modified file 'lib/lp/bugs/scripts/checkwatches.py'
456--- lib/lp/bugs/scripts/checkwatches.py 2010-03-24 06:53:49 +0000
457+++ lib/lp/bugs/scripts/checkwatches.py 2010-03-24 22:10:48 +0000
458@@ -408,7 +408,7 @@
459 self.txn.begin()
460 if not self.updateBugTracker(bug_tracker, batch_size):
461 break
462- watches_left = bug_tracker.getBugWatchesNeedingUpdate(23).count()
463+ watches_left = bug_tracker.getBugWatchesNeedingUpdate().count()
464 self.log.info(
465 "%s watches left to check on bug tracker '%s'" %
466 (watches_left, bug_tracker_name))
467@@ -466,16 +466,7 @@
468
469 def _updateBugTracker(self, bug_tracker, batch_size=None):
470 """Updates the given bug trackers's bug watches."""
471- # XXX 2007-01-18 gmb:
472- # Once we start running checkwatches more frequently we need
473- # to update the comment and the call to
474- # getBugWatchesNeedingUpdate() below. We'll be checking
475- # those watches which haven't been checked for 24 hours, not
476- # 23.
477- # We want 1 day, but we'll use 23 hours because we can't count
478- # on the cron job hitting exactly the same time every day
479- bug_watches_to_update = (
480- bug_tracker.getBugWatchesNeedingUpdate(23))
481+ bug_watches_to_update = bug_tracker.getBugWatchesNeedingUpdate()
482
483 if bug_watches_to_update.count() > 0:
484 # XXX: GavinPanella 2010-01-18 bug=509223 : Ask remote
485@@ -495,6 +486,7 @@
486 for bug_watch in bug_watches_to_update:
487 bug_watch.last_error_type = error_type
488 bug_watch.lastchecked = UTC_NOW
489+ bug_watch.next_check = None
490
491 message = (
492 "ExternalBugtracker for BugTrackerType '%s' is not "
493@@ -734,6 +726,7 @@
494 for bug_watch_id in bug_watch_ids:
495 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)
496 bugwatch.lastchecked = UTC_NOW
497+ bugwatch.next_check = None
498 bugwatch.last_error_type = errortype
499 self.txn.commit()
500 raise
501@@ -764,6 +757,7 @@
502 for bug_watch_id in bug_watch_ids:
503 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)
504 bugwatch.lastchecked = UTC_NOW
505+ bugwatch.next_check = None
506 bugwatch.last_error_type = errortype
507 self.txn.commit()
508 raise
509@@ -817,6 +811,7 @@
510
511 for bug_watch in bug_watches:
512 bug_watch.lastchecked = UTC_NOW
513+ bug_watch.next_check = None
514 if remote_bug_id in unmodified_remote_ids:
515 continue
516
517@@ -911,6 +906,7 @@
518 errortype = get_bugwatcherrortype_for_error(error)
519 for bug_watch in bug_watches:
520 bug_watch.lastchecked = UTC_NOW
521+ bug_watch.next_check = None
522 bug_watch.last_error_type = errortype
523 bug_watch.addActivity(result=errortype, oops_id=oops_id)
524 # We need to commit the transaction, in case the next
525
526=== modified file 'lib/lp/bugs/scripts/tests/test_bugimport.py'
527--- lib/lp/bugs/scripts/tests/test_bugimport.py 2010-03-23 11:39:09 +0000
528+++ lib/lp/bugs/scripts/tests/test_bugimport.py 2010-03-24 22:10:48 +0000
529@@ -825,7 +825,7 @@
530 self.test_bug_one = test_bug_one
531 self.test_bug_two = test_bug_two
532
533- def getBugWatchesNeedingUpdate(self, hours):
534+ def getBugWatchesNeedingUpdate(self):
535 """Returns a sequence of teo bug watches for testing."""
536 return TestResultSequence([
537 TestBugWatch(1, self.test_bug_one, failing=True),
538@@ -905,7 +905,7 @@
539 """
540 return [
541 bug_watch for bug_watch in (
542- self.bugtracker.getBugWatchesNeedingUpdate(0))
543+ self.bugtracker.getBugWatchesNeedingUpdate())
544 if (bug_watch.remotebug == remote_bug_id and
545 bug_watch.id in bug_watch_ids)
546 ]
547
548=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
549--- lib/lp/bugs/stories/webservice/xx-bug.txt 2010-03-22 23:02:50 +0000
550+++ lib/lp/bugs/stories/webservice/xx-bug.txt 2010-03-24 22:10:48 +0000
551@@ -1025,6 +1025,7 @@
552 date_created: u'2004-10-04T01:00:00+00:00'
553 date_last_changed: u'2004-10-04T01:00:00+00:00'
554 date_last_checked: u'2004-10-04T01:00:00+00:00'
555+ date_next_checked: None
556 last_error_type: None
557 owner_link: u'http://.../~mark'
558 remote_bug: u'2000'
559@@ -1096,6 +1097,7 @@
560 date_created: u'...'
561 date_last_changed: None
562 date_last_checked: None
563+ date_next_checked: None
564 last_error_type: None
565 owner_link: u'http://.../~salgado'
566 remote_bug: u'9876'
567
568=== modified file 'lib/lp/testing/factory.py'
569--- lib/lp/testing/factory.py 2010-03-22 07:20:05 +0000
570+++ lib/lp/testing/factory.py 2010-03-24 22:10:48 +0000
571@@ -1209,9 +1209,17 @@
572 if owner is None:
573 owner = self.makePerson()
574
575- return getUtility(IBugWatchSet).createBugWatch(
576+ bug_watch = getUtility(IBugWatchSet).createBugWatch(
577 bug, owner, bugtracker, str(remote_bug))
578
579+ # You need to be an admin to set next_check on a BugWatch.
580+ def set_next_check(bug_watch):
581+ bug_watch.next_check = datetime.now(pytz.timezone('UTC'))
582+
583+ person = getUtility(IPersonSet).getByName('name16')
584+ run_with_login(person, set_next_check, bug_watch)
585+ return bug_watch
586+
587 def makeBugAttachment(self, bug=None, owner=None, data=None,
588 comment=None, filename=None, content_type=None,
589 description=None, is_patch=_DEFAULT):

Subscribers

People subscribed via source and target branches

to status/vote changes: