Merge lp:~wgrant/launchpad/bug-761439 into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 12938
Proposed branch: lp:~wgrant/launchpad/bug-761439
Merge into: lp:launchpad
Diff against target: 90 lines (+47/-0)
2 files modified
lib/lp/soyuz/scripts/processaccepted.py (+9/-0)
lib/lp/soyuz/tests/test_processaccepted.py (+38/-0)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-761439
Reviewer Review Type Date Requested Status
Steve Kowalik (community) Approve
Review via email: mp+59317@code.launchpad.net

Commit message

[r=stevenk][bug=761439] process-accepted now commits after processing each upload.

Description of the change

Bug #761439 is caused by process-accepted not committing after each item is processed: sometimes they create library files that later items need to read, which can't happen before the transaction is committed. This branch changes process-accepted to commit after each upload, even on failure.

It seems unintuitive to commit on failure, but process-accepted makes changes to the on-disk archive. We can't roll back filesystem changes, so we need to commit a potentially partial acceptance to the DB too. The test is a bit awkward: a transaction synchronizer keeps track of the number of commits and ensures that only one item is processed per commit.

I've also added some more logging to process-accepted, to ease identification of the current queue item.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) wrote :

(Note that it already committed on failure anyway, just all in one huge transaction.)

Revision history for this message
Steve Kowalik (stevenk) wrote :

I agree the test is a little awkward, but I welcome the change, and more logging is nice.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/soyuz/scripts/processaccepted.py'
--- lib/lp/soyuz/scripts/processaccepted.py 2010-09-23 02:12:27 +0000
+++ lib/lp/soyuz/scripts/processaccepted.py 2011-04-28 05:36:31 +0000
@@ -268,6 +268,8 @@
268 queue_items = distroseries.getQueueItems(268 queue_items = distroseries.getQueueItems(
269 PackageUploadStatus.ACCEPTED, archive=archive)269 PackageUploadStatus.ACCEPTED, archive=archive)
270 for queue_item in queue_items:270 for queue_item in queue_items:
271 self.logger.debug(
272 "Processing queue item %d" % queue_item.id)
271 try:273 try:
272 queue_item.realiseUpload(self.logger)274 queue_item.realiseUpload(self.logger)
273 except Exception:275 except Exception:
@@ -280,7 +282,14 @@
280 self.logger.error('%s (%s)' % (message,282 self.logger.error('%s (%s)' % (message,
281 request.oopsid))283 request.oopsid))
282 else:284 else:
285 self.logger.debug(
286 "Successfully processed queue item %d" %
287 queue_item.id)
283 processed_queue_ids.append(queue_item.id)288 processed_queue_ids.append(queue_item.id)
289 # Commit even on error; we may have altered the
290 # on-disk archive, so the partial state must
291 # make it to the DB.
292 self.txn.commit()
284293
285 if not self.options.dryrun:294 if not self.options.dryrun:
286 self.txn.commit()295 self.txn.commit()
287296
=== modified file 'lib/lp/soyuz/tests/test_processaccepted.py'
--- lib/lp/soyuz/tests/test_processaccepted.py 2011-03-03 00:43:44 +0000
+++ lib/lp/soyuz/tests/test_processaccepted.py 2011-04-28 05:36:31 +0000
@@ -6,6 +6,7 @@
6from cStringIO import StringIO6from cStringIO import StringIO
77
8from debian.deb822 import Changes8from debian.deb822 import Changes
9from testtools.matchers import LessThan
910
10from canonical.config import config11from canonical.config import config
11from canonical.launchpad.webapp.errorlog import ErrorReportingUtility12from canonical.launchpad.webapp.errorlog import ErrorReportingUtility
@@ -15,6 +16,7 @@
15from lp.soyuz.enums import (16from lp.soyuz.enums import (
16 ArchivePurpose,17 ArchivePurpose,
17 PackagePublishingStatus,18 PackagePublishingStatus,
19 PackageUploadStatus,
18 )20 )
19from lp.soyuz.scripts.processaccepted import (21from lp.soyuz.scripts.processaccepted import (
20 get_bugs_from_changes_file,22 get_bugs_from_changes_file,
@@ -131,6 +133,42 @@
131 published_copy.status, PackagePublishingStatus.PENDING)133 published_copy.status, PackagePublishingStatus.PENDING)
132 self.assertEqual(copy_source, published_copy.sourcepackagerelease)134 self.assertEqual(copy_source, published_copy.sourcepackagerelease)
133135
136 def test_commits_after_each_item(self):
137 # Test that the script commits after each item, not just at the end.
138 uploads = [
139 self.createWaitingAcceptancePackage(
140 distroseries=
141 self.factory.makeDistroSeries(distribution=self.distro),
142 sourcename='source%d' % i)
143 for i in range(3)]
144
145 class UploadCheckingSynchronizer:
146
147 commit_count = 0
148
149 def beforeCompletion(inner_self, txn):
150 pass
151
152 def afterCompletion(inner_self, txn):
153 if txn.status != 'Committed':
154 return
155 inner_self.commit_count += 1
156 done_count = len([
157 upload for upload in uploads
158 if upload.package_upload.status ==
159 PackageUploadStatus.DONE])
160 self.assertEqual(
161 min(len(uploads), inner_self.commit_count),
162 done_count)
163
164 script = self.getScript([])
165 self.layer.txn.commit()
166 self.layer.switchDbUser(self.dbuser)
167 synch = UploadCheckingSynchronizer()
168 script.txn.registerSynch(synch)
169 script.main()
170 self.assertThat(len(uploads), LessThan(synch.commit_count))
171
134172
135class TestBugsFromChangesFile(TestCaseWithFactory):173class TestBugsFromChangesFile(TestCaseWithFactory):
136 """Test get_bugs_from_changes_file."""174 """Test get_bugs_from_changes_file."""