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
=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql 2010-03-21 16:57:00 +0000
+++ database/sampledata/current.sql 2010-03-24 22:10:48 +0000
@@ -2486,7 +2486,7 @@
2486INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (54, 'rosetta@launchpad.net', 30, 4, '2006-10-16 18:31:43.626521', NULL);2486INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (54, 'rosetta@launchpad.net', 30, 4, '2006-10-16 18:31:43.626521', NULL);
2487INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (55, 'salgado@ubuntu.com', 29, 1, '2006-10-16 18:31:43.626932', 291);2487INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (55, 'salgado@ubuntu.com', 29, 1, '2006-10-16 18:31:43.626932', 291);
2488INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (56, 'cprov@ubuntu.com', 28, 2, '2006-10-16 18:31:43.627318', 281);2488INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (56, 'cprov@ubuntu.com', 28, 2, '2006-10-16 18:31:43.627318', 281);
2489INSERT 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);2489INSERT 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);
2490INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (58, 'karl@canonical.com', 63, 4, '2006-10-16 18:31:43.628123', 631);2490INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (58, 'karl@canonical.com', 63, 4, '2006-10-16 18:31:43.628123', 631);
2491INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (59, 'limi@plone.org', 10, 4, '2006-10-16 18:31:43.628504', 101);2491INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (59, 'limi@plone.org', 10, 4, '2006-10-16 18:31:43.628504', 101);
2492INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (60, 'janitor@launchpad.net', 65, 4, '2006-10-17 23:23:23.232323', 651);2492INSERT INTO emailaddress (id, email, person, status, date_created, account) VALUES (60, 'janitor@launchpad.net', 65, 4, '2006-10-17 23:23:23.232323', 651);
24932493
=== modified file 'lib/lp/bugs/configure.zcml'
--- lib/lp/bugs/configure.zcml 2010-03-19 17:42:12 +0000
+++ lib/lp/bugs/configure.zcml 2010-03-24 22:10:48 +0000
@@ -839,6 +839,7 @@
839 lastchanged839 lastchanged
840 lastchecked840 lastchecked
841 needscheck841 needscheck
842 next_check
842 owner843 owner
843 remote_importance844 remote_importance
844 remotebug845 remotebug
@@ -858,7 +859,14 @@
858 addComment859 addComment
859 updateImportance860 updateImportance
860 updateStatus"861 updateStatus"
861 set_attributes="last_error_type lastchanged lastchecked needscheck remote_importance remotestatus"/>862 set_attributes="
863 last_error_type
864 lastchanged
865 lastchecked
866 needscheck
867 next_check
868 remote_importance
869 remotestatus"/>
862 </class>870 </class>
863871
864 <!-- https://launchpad.net/bugs/98639 -->872 <!-- https://launchpad.net/bugs/98639 -->
865873
=== modified file 'lib/lp/bugs/doc/bugtracker.txt'
--- lib/lp/bugs/doc/bugtracker.txt 2010-03-22 10:36:53 +0000
+++ lib/lp/bugs/doc/bugtracker.txt 2010-03-24 22:10:48 +0000
@@ -16,7 +16,7 @@
1616
17 >>> def print_watches(bugtracker):17 >>> def print_watches(bugtracker):
18 ... watches = sorted(18 ... watches = sorted(
19 ... bugtracker.getBugWatchesNeedingUpdate(23),19 ... bugtracker.getBugWatchesNeedingUpdate(),
20 ... key=lambda watch: (watch.remotebug, watch.bug.id))20 ... key=lambda watch: (watch.remotebug, watch.bug.id))
21 ...21 ...
22 ... for bug_watch in watches:22 ... for bug_watch in watches:
@@ -28,8 +28,8 @@
28 >>> login('foo.bar@canonical.com')28 >>> login('foo.bar@canonical.com')
2929
30We can get a list of all the bug tracker's bug watches needing to be30We can get a list of all the bug tracker's bug watches needing to be
31updated. The current criteria for needing a update is that it hasn't31updated. A bug watch is considered to be needing an update when its
32been updated in the last 23 hours.32next_check time is in the past.
3333
34 >>> bug_watches = mozilla_bugzilla.watches34 >>> bug_watches = mozilla_bugzilla.watches
35 >>> print bug_watches.count()35 >>> print bug_watches.count()
@@ -37,7 +37,7 @@
3737
38 >>> print bug_watches[0].remotebug, bug_watches[0].bug.id38 >>> print bug_watches[0].remotebug, bug_watches[0].bug.id
39 2000 139 2000 1
40 >>> bug_watches[0].lastchecked = None40 >>> bug_watches[0].next_check = now - timedelta(hours=1)
4141
42 >>> print bug_watches[1].remotebug, bug_watches[1].bug.id42 >>> print bug_watches[1].remotebug, bug_watches[1].bug.id
43 123543 143 123543 1
@@ -48,11 +48,11 @@
4848
49 >>> print bug_watches[2].remotebug, bug_watches[2].bug.id49 >>> print bug_watches[2].remotebug, bug_watches[2].bug.id
50 42 150 42 1
51 >>> bug_watches[2].lastchecked = now - timedelta(hours=36)51 >>> bug_watches[2].next_check = now - timedelta(hours=36)
5252
53 >>> print bug_watches[3].remotebug, bug_watches[3].bug.id53 >>> print bug_watches[3].remotebug, bug_watches[3].bug.id
54 42 254 42 2
55 >>> bug_watches[3].lastchecked = now - timedelta(days=1)55 >>> bug_watches[3].next_check = now - timedelta(days=1)
5656
57The watches needing updating should the ones with old statuses, 2000 and 42:57The watches needing updating should the ones with old statuses, 2000 and 42:
5858
@@ -593,31 +593,34 @@
593resetWatches() method.593resetWatches() method.
594594
595 >>> from operator import attrgetter595 >>> from operator import attrgetter
596 >>> from pytz import utc
597 >>> definitely_now = datetime.now(utc)
596598
597 >>> def print_tracker_watch_times(bugtracker):599 >>> def print_tracker_watch_times(bugtracker):
598 ... for watch in sorted(600 ... for watch in sorted(
599 ... bugtracker.watches, key=attrgetter('id')):601 ... bugtracker.watches, key=attrgetter('id')):
600 ... if watch.lastchecked is not None:602 ... if watch.next_check != definitely_now:
601 ... print watch.bug.id, "not None"603 ... print watch.bug.id, "not now"
602 ... else:604 ... else:
603 ... print watch.bug.id, watch.lastchecked605 ... print watch.bug.id, "now"
604606
605 >>> print_tracker_watch_times(mozilla_bugzilla)607 >>> print_tracker_watch_times(mozilla_bugzilla)
606 2 not None608 2 not now
607 1 None609 1 not now
608 1 not None610 1 not now
609 1 not None611 1 not now
610612
611Calling resetWatches() on mozilla_bugzilla will set all its613Calling resetWatches() on mozilla_bugzilla will set all its next_check
612lastchecked times to None.614times to datetime.now(). For testing purposes, we'll pass it a value to
613615use in place of now().
614 >>> mozilla_bugzilla.resetWatches()616
617 >>> mozilla_bugzilla.resetWatches(now=definitely_now)
615 >>> transaction.commit()618 >>> transaction.commit()
616 >>> print_tracker_watch_times(mozilla_bugzilla)619 >>> print_tracker_watch_times(mozilla_bugzilla)
617 2 None620 2 now
618 1 None621 1 now
619 1 None622 1 now
620 1 None623 1 now
621624
622resetWatches() also clears the last_error_type field of the watches.625resetWatches() also clears the last_error_type field of the watches.
623626
624627
=== modified file 'lib/lp/bugs/doc/checkwatches.txt'
--- lib/lp/bugs/doc/checkwatches.txt 2010-03-24 06:53:49 +0000
+++ lib/lp/bugs/doc/checkwatches.txt 2010-03-24 22:10:48 +0000
@@ -103,6 +103,8 @@
103103
104First, we create some bug watches to test with:104First, we create some bug watches to test with:
105105
106 >>> from datetime import datetime
107 >>> from pytz import utc
106 >>> from canonical.launchpad.database import BugTracker108 >>> from canonical.launchpad.database import BugTracker
107 >>> from canonical.launchpad.interfaces import (109 >>> from canonical.launchpad.interfaces import (
108 ... BugTrackerType, IBugSet)110 ... BugTrackerType, IBugSet)
@@ -128,6 +130,7 @@
128 >>> example_bugwatch = example_bug.addWatch(130 >>> example_bugwatch = example_bug.addWatch(
129 ... example_bug_tracker, '1',131 ... example_bug_tracker, '1',
130 ... getUtility(ILaunchpadCelebrities).janitor)132 ... getUtility(ILaunchpadCelebrities).janitor)
133 >>> example_bugwatch.next_check = datetime.now(utc)
131134
132 >>> login('no-priv@canonical.com')135 >>> login('no-priv@canonical.com')
133136
@@ -206,7 +209,7 @@
206 ... bugtrackertype.name, bugtracker.name)209 ... bugtrackertype.name, bugtracker.name)
207210
208 >>> login(ANONYMOUS)211 >>> login(ANONYMOUS)
209 >>> example_bugwatch.lastchecked = None212 >>> example_bugwatch.next_check = datetime.now(utc)
210 >>> try:213 >>> try:
211 ... externalbugtracker.get_external_bugtracker = (214 ... externalbugtracker.get_external_bugtracker = (
212 ... broken_get_external_bugtracker)215 ... broken_get_external_bugtracker)
@@ -242,6 +245,7 @@
242 ... example_bugwatch = example_bug.addWatch(245 ... example_bugwatch = example_bug.addWatch(
243 ... example_bug_tracker, str(bug_id),246 ... example_bug_tracker, str(bug_id),
244 ... getUtility(ILaunchpadCelebrities).janitor)247 ... getUtility(ILaunchpadCelebrities).janitor)
248 ... example_bugwatch.next_check = datetime.now(utc)
245249
246Since we know how many bugwatches example_bug has we will be able to see250Since we know how many bugwatches example_bug has we will be able to see
247when checkwatches only updates a subset of them.251when checkwatches only updates a subset of them.
@@ -294,15 +298,13 @@
294We'll set the lastchecked time on that Savannah instance to make sure298We'll set the lastchecked time on that Savannah instance to make sure
295that it looks as though it has been updated recently299that it looks as though it has been updated recently
296300
297 >>> import pytz
298 >>> from datetime import datetime
299 >>> login('test@canonical.com')301 >>> login('test@canonical.com')
300 >>> for watch in savannah.watches:302 >>> for watch in savannah.watches:
301 ... watch.lastchecked = datetime.now(pytz.timezone('UTC'))303 ... watch.lastchecked = datetime.now(utc)
302304
303So our Savannah instance now has no watches that need checking.305So our Savannah instance now has no watches that need checking.
304306
305 >>> savannah.getBugWatchesNeedingUpdate(23).count()307 >>> savannah.getBugWatchesNeedingUpdate().count()
306 0308 0
307309
308However, forceUpdateAll() will update every watch, whether they've310However, forceUpdateAll() will update every watch, whether they've
@@ -368,10 +370,11 @@
368 ... def _updateBugTracker(self, bug_tracker, batch_size):370 ... def _updateBugTracker(self, bug_tracker, batch_size):
369 ... # Update as many watches as the batch size says.371 ... # Update as many watches as the batch size says.
370 ... watches_to_update = (372 ... watches_to_update = (
371 ... bug_tracker.getBugWatchesNeedingUpdate(23)[:batch_size])373 ... bug_tracker.getBugWatchesNeedingUpdate()[:batch_size])
372 ...374 ...
373 ... for watch in watches_to_update:375 ... for watch in watches_to_update:
374 ... watch.lastchecked = datetime.now(pytz.timezone('UTC'))376 ... watch.lastchecked = datetime.now(utc)
377 ... watch.next_check = None
375378
376 >>> non_connecting_updater = NonConnectingUpdater(transaction)379 >>> non_connecting_updater = NonConnectingUpdater(transaction)
377 >>> non_connecting_updater.log = FakeLogger()380 >>> non_connecting_updater.log = FakeLogger()
@@ -397,8 +400,6 @@
397400
398We'll create a non-functioning ExternalBugtracker to demonstrate this.401We'll create a non-functioning ExternalBugtracker to demonstrate this.
399402
400 >>> import pytz
401 >>> from datetime import datetime
402 >>> from zope.interface import implements403 >>> from zope.interface import implements
403 >>> from lp.bugs.interfaces.bugtask import (404 >>> from lp.bugs.interfaces.bugtask import (
404 ... BugTaskStatus, BugTaskImportance)405 ... BugTaskStatus, BugTaskImportance)
@@ -407,7 +408,7 @@
407 ... ISupportsBackLinking)408 ... ISupportsBackLinking)
408 >>> from lp.bugs.externalbugtracker.base import ExternalBugTracker409 >>> from lp.bugs.externalbugtracker.base import ExternalBugTracker
409410
410 >>> nowish = datetime.now(pytz.timezone('UTC'))411 >>> nowish = datetime.now(utc)
411 >>> class UselessExternalBugTracker(ExternalBugTracker):412 >>> class UselessExternalBugTracker(ExternalBugTracker):
412 ...413 ...
413 ... implements(414 ... implements(
414415
=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla.txt'
--- lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-03-19 16:47:08 +0000
+++ lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-03-24 22:10:48 +0000
@@ -422,7 +422,7 @@
422422
423 >>> from canonical.database.sqlbase import flush_database_updates423 >>> from canonical.database.sqlbase import flush_database_updates
424 >>> flush_database_updates()424 >>> flush_database_updates()
425 >>> gnome_bugzilla.getBugWatchesNeedingUpdate(23).count()425 >>> gnome_bugzilla.getBugWatchesNeedingUpdate().count()
426 0426 0
427427
428If the status isn't different, the lastchanged attribute doesn't get428If the status isn't different, the lastchanged attribute doesn't get
429429
=== modified file 'lib/lp/bugs/doc/externalbugtracker-debbugs.txt'
--- lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-01-06 14:35:52 +0000
+++ lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-03-24 22:10:48 +0000
@@ -91,13 +91,27 @@
9191
92 >>> from canonical.launchpad.interfaces import IBugTrackerSet92 >>> from canonical.launchpad.interfaces import IBugTrackerSet
93 >>> debbugs = getUtility(IBugTrackerSet).getByName('debbugs')93 >>> debbugs = getUtility(IBugTrackerSet).getByName('debbugs')
94 >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate(23))94 >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate())
95 >>> len(bug_watches)
96 0
97
98It looks as though there are no bug watches needing to be updated.
99That's because the check for whether a bug watch needs to be updated
100looks at its next_check field, which is None by default. Updating the
101bug watches should solve that problem.
102
103 >>> from datetime import datetime
104 >>> from pytz import utc
105 >>> for watch in debbugs.watches:
106 ... watch.next_check = datetime.now(utc)
107
108 >>> bug_watches = list(debbugs.getBugWatchesNeedingUpdate())
95 >>> len(bug_watches)109 >>> len(bug_watches)
96 5110 5
97111
98Log in and kick off the update. The importing of comments, which is112Now there are some watches to update we can run the update against them.
99controlled by a configuration option, is disabled here and will be113The importing of comments, which is controlled by a configuration
100tested later.114option, is disabled here and will be tested later.
101115
102 >>> from lp.bugs.scripts.checkwatches import BugWatchUpdater116 >>> from lp.bugs.scripts.checkwatches import BugWatchUpdater
103 >>> bug_watch_updater = BugWatchUpdater(txn)117 >>> bug_watch_updater = BugWatchUpdater(txn)
@@ -116,11 +130,11 @@
116 327549: open important security130 327549: open important security
117 308994: open important131 308994: open important
118132
119The lastchecked attribute got updated for each bug watch, so no more133The next_check value for all the watches got set to null when they
120watches are in need of an update.134were updated, so there are no watches left needing an update.
121135
122 >>> flush_database_updates()136 >>> flush_database_updates()
123 >>> watches = debbugs.getBugWatchesNeedingUpdate(23)137 >>> watches = debbugs.getBugWatchesNeedingUpdate()
124 >>> watches.count()138 >>> watches.count()
125 0139 0
126140
127141
=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt'
--- lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2009-10-09 20:56:00 +0000
+++ lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-03-24 22:10:48 +0000
@@ -164,7 +164,7 @@
164164
165 >>> from canonical.database.sqlbase import flush_database_updates165 >>> from canonical.database.sqlbase import flush_database_updates
166 >>> flush_database_updates()166 >>> flush_database_updates()
167 >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()167 >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
168 0168 0
169169
170If the status isn't different, the lastchanged attribute doesn't get170If the status isn't different, the lastchanged attribute doesn't get
171171
=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis.txt'
--- lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-03-17 13:40:49 +0000
+++ lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-03-24 22:10:48 +0000
@@ -179,7 +179,7 @@
179179
180 >>> from canonical.database.sqlbase import flush_database_updates180 >>> from canonical.database.sqlbase import flush_database_updates
181 >>> flush_database_updates()181 >>> flush_database_updates()
182 >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()182 >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
183 0183 0
184184
185If the status isn't different, the lastchanged attribute doesn't get185If the status isn't different, the lastchanged attribute doesn't get
186186
=== modified file 'lib/lp/bugs/doc/externalbugtracker-trac.txt'
--- lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-01-11 13:54:42 +0000
+++ lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-03-24 22:10:48 +0000
@@ -369,7 +369,7 @@
369now no bug watches are in need of updating:369now no bug watches are in need of updating:
370370
371 >>> flush_database_updates()371 >>> flush_database_updates()
372 >>> example_bug_tracker.getBugWatchesNeedingUpdate(23).count()372 >>> example_bug_tracker.getBugWatchesNeedingUpdate().count()
373 0373 0
374374
375If the status isn't different, the lastchanged attribute doesn't get375If the status isn't different, the lastchanged attribute doesn't get
376376
=== modified file 'lib/lp/bugs/interfaces/bugtracker.py'
--- lib/lp/bugs/interfaces/bugtracker.py 2010-03-10 19:00:59 +0000
+++ lib/lp/bugs/interfaces/bugtracker.py 2010-03-24 22:10:48 +0000
@@ -273,12 +273,11 @@
273 def getBugsWatching(remotebug):273 def getBugsWatching(remotebug):
274 """Get the bugs watching the given remote bug in this bug tracker."""274 """Get the bugs watching the given remote bug in this bug tracker."""
275275
276 def getBugWatchesNeedingUpdate(hours_since_last_check):276 def getBugWatchesNeedingUpdate():
277 """Get the bug watches needing to be updated.277 """Get the bug watches needing to be updated.
278278
279 All bug watches not being updated for the last279 All bug watches with a next_check time in the past are
280 :hours_since_last_check: hours are considered needing to be280 considered to be needing an update.
281 updated.
282 """281 """
283282
284 def getLinkedPersonByName(name):283 def getLinkedPersonByName(name):
@@ -318,8 +317,13 @@
318 def destroySelf():317 def destroySelf():
319 """Delete this bug tracker."""318 """Delete this bug tracker."""
320319
321 def resetWatches():320 def resetWatches(now=None):
322 """Reset the lastchecked times of this BugTracker's `BugWatch`es."""321 """Reset the next_check times of this BugTracker's `BugWatch`es.
322
323 :param now: If specified, contains the datetime to which to set
324 the BugWatches' next_check times. Defaults to
325 datetime.now().
326 """
323327
324328
325class IBugTrackerSet(Interface):329class IBugTrackerSet(Interface):
326330
=== modified file 'lib/lp/bugs/interfaces/bugwatch.py'
--- lib/lp/bugs/interfaces/bugwatch.py 2010-03-22 10:36:53 +0000
+++ lib/lp/bugs/interfaces/bugwatch.py 2010-03-24 22:10:48 +0000
@@ -136,6 +136,9 @@
136 Reference(title=_('Owner'), required=True,136 Reference(title=_('Owner'), required=True,
137 readonly=True, schema=Interface))137 readonly=True, schema=Interface))
138 activity = Attribute('The activity history of this BugWatch.')138 activity = Attribute('The activity history of this BugWatch.')
139 next_check = exported(
140 Datetime(title=_('Next Check')),
141 exported_as='date_next_checked')
139142
140 # Useful joins.143 # Useful joins.
141 bugtasks = exported(144 bugtasks = exported(
142145
=== modified file 'lib/lp/bugs/model/bugtracker.py'
--- lib/lp/bugs/model/bugtracker.py 2009-12-09 14:55:30 +0000
+++ lib/lp/bugs/model/bugtracker.py 2010-03-24 22:10:48 +0000
@@ -25,7 +25,7 @@
25 BoolCol, ForeignKey, OR, SQLMultipleJoin, SQLObjectNotFound, StringCol)25 BoolCol, ForeignKey, OR, SQLMultipleJoin, SQLObjectNotFound, StringCol)
26from sqlobject.sqlbuilder import AND26from sqlobject.sqlbuilder import AND
2727
28from storm.expr import Or28from storm.expr import Not, Or
29from storm.locals import Bool29from storm.locals import Bool
30from storm.store import Store30from storm.store import Store
3131
@@ -348,26 +348,19 @@
348 distinct=True,348 distinct=True,
349 orderBy=['datecreated']))349 orderBy=['datecreated']))
350350
351 def getBugWatchesNeedingUpdate(self, hours_since_last_check):351 def getBugWatchesNeedingUpdate(self):
352 """See `IBugTracker`.352 """See `IBugTracker`.
353353
354 :return: The UNION of the bug watches that need checking and354 :return: The UNION of the bug watches that need checking and
355 those with unpushed comments.355 those with unpushed comments.
356 """356 """
357 lastchecked_cutoff = (
358 datetime.now(timezone('UTC')) -
359 timedelta(hours=hours_since_last_check))
360
361 lastchecked_clause = Or(
362 BugWatch.lastchecked < lastchecked_cutoff,
363 BugWatch.lastchecked == None)
364
365 store = Store.of(self)357 store = Store.of(self)
366358
367 bug_watches_needing_checking = store.find(359 bug_watches_needing_checking = store.find(
368 BugWatch,360 BugWatch,
369 BugWatch.bugtracker == self,361 BugWatch.bugtracker == self,
370 lastchecked_clause)362 Not(BugWatch.next_check == None),
363 BugWatch.next_check <= datetime.now(timezone('UTC')))
371364
372 bug_watches_with_unpushed_comments = store.find(365 bug_watches_with_unpushed_comments = store.find(
373 BugWatch,366 BugWatch,
@@ -486,12 +479,15 @@
486479
487 return person480 return person
488481
489 def resetWatches(self):482 def resetWatches(self, now=None):
490 """See `IBugTracker`."""483 """See `IBugTracker`."""
484 if now is None:
485 now = datetime.now(timezone('UTC'))
486
491 store = Store.of(self)487 store = Store.of(self)
492 store.execute(488 store.execute(
493 "UPDATE BugWatch SET lastchecked = NULL WHERE bugtracker = %s" %489 "UPDATE BugWatch SET next_check = %s WHERE bugtracker = %s" %
494 sqlvalues(self))490 sqlvalues(now, self))
495491
496492
497class BugTrackerSet:493class BugTrackerSet:
498494
=== modified file 'lib/lp/bugs/model/bugwatch.py'
--- lib/lp/bugs/model/bugwatch.py 2010-03-22 13:57:43 +0000
+++ lib/lp/bugs/model/bugwatch.py 2010-03-24 22:10:48 +0000
@@ -83,6 +83,7 @@
83 owner = ForeignKey(83 owner = ForeignKey(
84 dbName='owner', foreignKey='Person',84 dbName='owner', foreignKey='Person',
85 storm_validator=validate_public_person, notNull=True)85 storm_validator=validate_public_person, notNull=True)
86 next_check = UtcDateTimeCol()
8687
87 @property88 @property
88 def bugtasks(self):89 def bugtasks(self):
8990
=== modified file 'lib/lp/bugs/scripts/checkwatches.py'
--- lib/lp/bugs/scripts/checkwatches.py 2010-03-24 06:53:49 +0000
+++ lib/lp/bugs/scripts/checkwatches.py 2010-03-24 22:10:48 +0000
@@ -408,7 +408,7 @@
408 self.txn.begin()408 self.txn.begin()
409 if not self.updateBugTracker(bug_tracker, batch_size):409 if not self.updateBugTracker(bug_tracker, batch_size):
410 break410 break
411 watches_left = bug_tracker.getBugWatchesNeedingUpdate(23).count()411 watches_left = bug_tracker.getBugWatchesNeedingUpdate().count()
412 self.log.info(412 self.log.info(
413 "%s watches left to check on bug tracker '%s'" %413 "%s watches left to check on bug tracker '%s'" %
414 (watches_left, bug_tracker_name))414 (watches_left, bug_tracker_name))
@@ -466,16 +466,7 @@
466466
467 def _updateBugTracker(self, bug_tracker, batch_size=None):467 def _updateBugTracker(self, bug_tracker, batch_size=None):
468 """Updates the given bug trackers's bug watches."""468 """Updates the given bug trackers's bug watches."""
469 # XXX 2007-01-18 gmb:469 bug_watches_to_update = bug_tracker.getBugWatchesNeedingUpdate()
470 # Once we start running checkwatches more frequently we need
471 # to update the comment and the call to
472 # getBugWatchesNeedingUpdate() below. We'll be checking
473 # those watches which haven't been checked for 24 hours, not
474 # 23.
475 # We want 1 day, but we'll use 23 hours because we can't count
476 # on the cron job hitting exactly the same time every day
477 bug_watches_to_update = (
478 bug_tracker.getBugWatchesNeedingUpdate(23))
479470
480 if bug_watches_to_update.count() > 0:471 if bug_watches_to_update.count() > 0:
481 # XXX: GavinPanella 2010-01-18 bug=509223 : Ask remote472 # XXX: GavinPanella 2010-01-18 bug=509223 : Ask remote
@@ -495,6 +486,7 @@
495 for bug_watch in bug_watches_to_update:486 for bug_watch in bug_watches_to_update:
496 bug_watch.last_error_type = error_type487 bug_watch.last_error_type = error_type
497 bug_watch.lastchecked = UTC_NOW488 bug_watch.lastchecked = UTC_NOW
489 bug_watch.next_check = None
498490
499 message = (491 message = (
500 "ExternalBugtracker for BugTrackerType '%s' is not "492 "ExternalBugtracker for BugTrackerType '%s' is not "
@@ -734,6 +726,7 @@
734 for bug_watch_id in bug_watch_ids:726 for bug_watch_id in bug_watch_ids:
735 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)727 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)
736 bugwatch.lastchecked = UTC_NOW728 bugwatch.lastchecked = UTC_NOW
729 bugwatch.next_check = None
737 bugwatch.last_error_type = errortype730 bugwatch.last_error_type = errortype
738 self.txn.commit()731 self.txn.commit()
739 raise732 raise
@@ -764,6 +757,7 @@
764 for bug_watch_id in bug_watch_ids:757 for bug_watch_id in bug_watch_ids:
765 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)758 bugwatch = getUtility(IBugWatchSet).get(bug_watch_id)
766 bugwatch.lastchecked = UTC_NOW759 bugwatch.lastchecked = UTC_NOW
760 bugwatch.next_check = None
767 bugwatch.last_error_type = errortype761 bugwatch.last_error_type = errortype
768 self.txn.commit()762 self.txn.commit()
769 raise763 raise
@@ -817,6 +811,7 @@
817811
818 for bug_watch in bug_watches:812 for bug_watch in bug_watches:
819 bug_watch.lastchecked = UTC_NOW813 bug_watch.lastchecked = UTC_NOW
814 bug_watch.next_check = None
820 if remote_bug_id in unmodified_remote_ids:815 if remote_bug_id in unmodified_remote_ids:
821 continue816 continue
822817
@@ -911,6 +906,7 @@
911 errortype = get_bugwatcherrortype_for_error(error)906 errortype = get_bugwatcherrortype_for_error(error)
912 for bug_watch in bug_watches:907 for bug_watch in bug_watches:
913 bug_watch.lastchecked = UTC_NOW908 bug_watch.lastchecked = UTC_NOW
909 bug_watch.next_check = None
914 bug_watch.last_error_type = errortype910 bug_watch.last_error_type = errortype
915 bug_watch.addActivity(result=errortype, oops_id=oops_id)911 bug_watch.addActivity(result=errortype, oops_id=oops_id)
916 # We need to commit the transaction, in case the next912 # We need to commit the transaction, in case the next
917913
=== modified file 'lib/lp/bugs/scripts/tests/test_bugimport.py'
--- lib/lp/bugs/scripts/tests/test_bugimport.py 2010-03-23 11:39:09 +0000
+++ lib/lp/bugs/scripts/tests/test_bugimport.py 2010-03-24 22:10:48 +0000
@@ -825,7 +825,7 @@
825 self.test_bug_one = test_bug_one825 self.test_bug_one = test_bug_one
826 self.test_bug_two = test_bug_two826 self.test_bug_two = test_bug_two
827827
828 def getBugWatchesNeedingUpdate(self, hours):828 def getBugWatchesNeedingUpdate(self):
829 """Returns a sequence of teo bug watches for testing."""829 """Returns a sequence of teo bug watches for testing."""
830 return TestResultSequence([830 return TestResultSequence([
831 TestBugWatch(1, self.test_bug_one, failing=True),831 TestBugWatch(1, self.test_bug_one, failing=True),
@@ -905,7 +905,7 @@
905 """905 """
906 return [906 return [
907 bug_watch for bug_watch in (907 bug_watch for bug_watch in (
908 self.bugtracker.getBugWatchesNeedingUpdate(0))908 self.bugtracker.getBugWatchesNeedingUpdate())
909 if (bug_watch.remotebug == remote_bug_id and909 if (bug_watch.remotebug == remote_bug_id and
910 bug_watch.id in bug_watch_ids)910 bug_watch.id in bug_watch_ids)
911 ]911 ]
912912
=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
--- lib/lp/bugs/stories/webservice/xx-bug.txt 2010-03-22 23:02:50 +0000
+++ lib/lp/bugs/stories/webservice/xx-bug.txt 2010-03-24 22:10:48 +0000
@@ -1025,6 +1025,7 @@
1025 date_created: u'2004-10-04T01:00:00+00:00'1025 date_created: u'2004-10-04T01:00:00+00:00'
1026 date_last_changed: u'2004-10-04T01:00:00+00:00'1026 date_last_changed: u'2004-10-04T01:00:00+00:00'
1027 date_last_checked: u'2004-10-04T01:00:00+00:00'1027 date_last_checked: u'2004-10-04T01:00:00+00:00'
1028 date_next_checked: None
1028 last_error_type: None1029 last_error_type: None
1029 owner_link: u'http://.../~mark'1030 owner_link: u'http://.../~mark'
1030 remote_bug: u'2000'1031 remote_bug: u'2000'
@@ -1096,6 +1097,7 @@
1096 date_created: u'...'1097 date_created: u'...'
1097 date_last_changed: None1098 date_last_changed: None
1098 date_last_checked: None1099 date_last_checked: None
1100 date_next_checked: None
1099 last_error_type: None1101 last_error_type: None
1100 owner_link: u'http://.../~salgado'1102 owner_link: u'http://.../~salgado'
1101 remote_bug: u'9876'1103 remote_bug: u'9876'
11021104
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-03-22 07:20:05 +0000
+++ lib/lp/testing/factory.py 2010-03-24 22:10:48 +0000
@@ -1209,9 +1209,17 @@
1209 if owner is None:1209 if owner is None:
1210 owner = self.makePerson()1210 owner = self.makePerson()
12111211
1212 return getUtility(IBugWatchSet).createBugWatch(1212 bug_watch = getUtility(IBugWatchSet).createBugWatch(
1213 bug, owner, bugtracker, str(remote_bug))1213 bug, owner, bugtracker, str(remote_bug))
12141214
1215 # You need to be an admin to set next_check on a BugWatch.
1216 def set_next_check(bug_watch):
1217 bug_watch.next_check = datetime.now(pytz.timezone('UTC'))
1218
1219 person = getUtility(IPersonSet).getByName('name16')
1220 run_with_login(person, set_next_check, bug_watch)
1221 return bug_watch
1222
1215 def makeBugAttachment(self, bug=None, owner=None, data=None,1223 def makeBugAttachment(self, bug=None, owner=None, data=None,
1216 comment=None, filename=None, content_type=None,1224 comment=None, filename=None, content_type=None,
1217 description=None, is_patch=_DEFAULT):1225 description=None, is_patch=_DEFAULT):

Subscribers

People subscribed via source and target branches

to status/vote changes: