Merge lp:~michael.nelson/launchpad/530180-partner-permissions into lp:launchpad
- 530180-partner-permissions
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Michael Nelson |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~michael.nelson/launchpad/530180-partner-permissions |
Merge into: | lp:launchpad |
Diff against target: |
473 lines (+257/-51) 8 files modified
lib/canonical/launchpad/security.py (+2/-1) lib/lp/soyuz/browser/queue.py (+1/-1) lib/lp/soyuz/browser/tests/test_queue.py (+191/-0) lib/lp/soyuz/doc/archivepermission.txt (+3/-2) lib/lp/soyuz/interfaces/archivepermission.py (+2/-1) lib/lp/soyuz/model/archivepermission.py (+12/-7) lib/lp/soyuz/stories/soyuz/xx-queue-pages.txt (+42/-35) lib/lp/soyuz/tests/test_publishing.py (+4/-4) |
To merge this branch: | bzr merge lp:~michael.nelson/launchpad/530180-partner-permissions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Graham Binns (community) | code | Approve | |
Review via email: mp+20947@code.launchpad.net |
Commit message
If a person has permission to administer the queue page for one of the main archives then the view will allow them to post (while still checking individual queue items).
Description of the change
Summary
=======
This branch ensures that if a person has permission to administer the queue for one of the main archives for a distro, then they the /distro/
Previously the security adapter checked only for permissions on the primary archive. The provided unit test show that now it is possible to have permission for the partner archive only, and be able to post to the view.
Note: the view still checks the permission on each individual item, also shown in the new unit tests.
To test:
bin/test -vv -t doc/archiveperm
The tests were originally written to demonstrate bug 530180, but as identified there, they actually showed that the original problem on the bug was related to incorrect permissions.
Preview Diff
1 | === modified file 'lib/canonical/launchpad/security.py' | |||
2 | --- lib/canonical/launchpad/security.py 2010-03-09 08:24:53 +0000 | |||
3 | +++ lib/canonical/launchpad/security.py 2010-03-09 15:41:38 +0000 | |||
4 | @@ -1360,7 +1360,8 @@ | |||
5 | 1360 | 1360 | ||
6 | 1361 | permission_set = getUtility(IArchivePermissionSet) | 1361 | permission_set = getUtility(IArchivePermissionSet) |
7 | 1362 | permissions = permission_set.componentsForQueueAdmin( | 1362 | permissions = permission_set.componentsForQueueAdmin( |
9 | 1363 | self.obj.distroseries.main_archive, user.person) | 1363 | self.obj.distroseries.distribution.all_distro_archives, |
10 | 1364 | user.person) | ||
11 | 1364 | return permissions.count() > 0 | 1365 | return permissions.count() > 0 |
12 | 1365 | 1366 | ||
13 | 1366 | 1367 | ||
14 | 1367 | 1368 | ||
15 | === modified file 'lib/lp/soyuz/browser/queue.py' | |||
16 | --- lib/lp/soyuz/browser/queue.py 2009-07-19 04:41:14 +0000 | |||
17 | +++ lib/lp/soyuz/browser/queue.py 2010-03-09 15:41:38 +0000 | |||
18 | @@ -283,7 +283,7 @@ | |||
19 | 283 | self.error = "Invalid component: %s" % component_override | 283 | self.error = "Invalid component: %s" % component_override |
20 | 284 | return | 284 | return |
21 | 285 | 285 | ||
23 | 286 | # Get a list of components that the user has rights to accept and | 286 | # Get a list of components for which the user has rights to |
24 | 287 | # override to or from. | 287 | # override to or from. |
25 | 288 | permission_set = getUtility(IArchivePermissionSet) | 288 | permission_set = getUtility(IArchivePermissionSet) |
26 | 289 | permissions = permission_set.componentsForQueueAdmin( | 289 | permissions = permission_set.componentsForQueueAdmin( |
27 | 290 | 290 | ||
28 | === added file 'lib/lp/soyuz/browser/tests/test_queue.py' | |||
29 | --- lib/lp/soyuz/browser/tests/test_queue.py 1970-01-01 00:00:00 +0000 | |||
30 | +++ lib/lp/soyuz/browser/tests/test_queue.py 2010-03-09 15:41:38 +0000 | |||
31 | @@ -0,0 +1,191 @@ | |||
32 | 1 | # Copyright 2010 Canonical Ltd. This software is licensed under the | ||
33 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
34 | 3 | |||
35 | 4 | """Unit tests for QueueItemsView.""" | ||
36 | 5 | |||
37 | 6 | __metaclass__ = type | ||
38 | 7 | __all__ = [ | ||
39 | 8 | 'TestAcceptPartnerArchive', | ||
40 | 9 | 'test_suite', | ||
41 | 10 | ] | ||
42 | 11 | |||
43 | 12 | import transaction | ||
44 | 13 | import unittest | ||
45 | 14 | from zope.component import getUtility, queryMultiAdapter | ||
46 | 15 | |||
47 | 16 | from canonical.launchpad.webapp.servers import LaunchpadTestRequest | ||
48 | 17 | from canonical.testing import LaunchpadFunctionalLayer | ||
49 | 18 | |||
50 | 19 | from lp.archiveuploader.tests import datadir | ||
51 | 20 | from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet | ||
52 | 21 | from lp.soyuz.interfaces.queue import IPackageUploadSet, PackageUploadStatus | ||
53 | 22 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher | ||
54 | 23 | from lp.testing import login, logout, TestCaseWithFactory | ||
55 | 24 | |||
56 | 25 | |||
57 | 26 | class TestAcceptQueueUploads(TestCaseWithFactory): | ||
58 | 27 | """Uploads for the partner archive can be accepted with the relevant | ||
59 | 28 | permissions. | ||
60 | 29 | """ | ||
61 | 30 | |||
62 | 31 | layer = LaunchpadFunctionalLayer | ||
63 | 32 | |||
64 | 33 | def setUp(self): | ||
65 | 34 | """Create two new uploads in the new state and a person with | ||
66 | 35 | permission to upload to the partner archive.""" | ||
67 | 36 | super(TestAcceptQueueUploads, self).setUp() | ||
68 | 37 | login('admin@canonical.com') | ||
69 | 38 | self.test_publisher = SoyuzTestPublisher() | ||
70 | 39 | self.test_publisher.prepareBreezyAutotest() | ||
71 | 40 | distribution = self.test_publisher.distroseries.distribution | ||
72 | 41 | self.main_archive = distribution.getArchiveByComponent('main') | ||
73 | 42 | self.partner_archive = distribution.getArchiveByComponent('partner') | ||
74 | 43 | |||
75 | 44 | # Get some sample changes file content for the new uploads. | ||
76 | 45 | changes_file = open( | ||
77 | 46 | datadir('suite/bar_1.0-1/bar_1.0-1_source.changes')) | ||
78 | 47 | changes_file_content = changes_file.read() | ||
79 | 48 | changes_file.close() | ||
80 | 49 | |||
81 | 50 | self.partner_spr = self.test_publisher.getPubSource( | ||
82 | 51 | sourcename='partner-upload', spr_only=True, | ||
83 | 52 | component='partner', changes_file_content=changes_file_content, | ||
84 | 53 | archive=self.partner_archive) | ||
85 | 54 | self.partner_spr.package_upload.setNew() | ||
86 | 55 | self.main_spr = self.test_publisher.getPubSource( | ||
87 | 56 | sourcename='main-upload', spr_only=True, | ||
88 | 57 | component='main', changes_file_content=changes_file_content) | ||
89 | 58 | self.main_spr.package_upload.setNew() | ||
90 | 59 | |||
91 | 60 | # Define the form that will be used to post to the view. | ||
92 | 61 | self.form = { | ||
93 | 62 | 'queue_state': PackageUploadStatus.NEW.value, | ||
94 | 63 | 'Accept': 'Accept', | ||
95 | 64 | } | ||
96 | 65 | |||
97 | 66 | # Create a user with queue admin rights for main, and a separate | ||
98 | 67 | # user with queue admin rights for partner (on the partner | ||
99 | 68 | # archive). | ||
100 | 69 | self.main_queue_admin = self.factory.makePerson( | ||
101 | 70 | email='main-queue@example.org') | ||
102 | 71 | getUtility(IArchivePermissionSet).newQueueAdmin( | ||
103 | 72 | distribution.getArchiveByComponent('main'), | ||
104 | 73 | self.main_queue_admin, self.main_spr.component) | ||
105 | 74 | self.partner_queue_admin = self.factory.makePerson( | ||
106 | 75 | email='partner-queue@example.org') | ||
107 | 76 | getUtility(IArchivePermissionSet).newQueueAdmin( | ||
108 | 77 | distribution.getArchiveByComponent('partner'), | ||
109 | 78 | self.partner_queue_admin, self.partner_spr.component) | ||
110 | 79 | |||
111 | 80 | |||
112 | 81 | # We need to commit to ensure the changes file exists in the | ||
113 | 82 | # librarian. | ||
114 | 83 | transaction.commit() | ||
115 | 84 | logout() | ||
116 | 85 | |||
117 | 86 | def setupQueueView(self, request): | ||
118 | 87 | """A helper to create and setup the view for testing.""" | ||
119 | 88 | view = queryMultiAdapter( | ||
120 | 89 | (self.test_publisher.distroseries, request), name="+queue") | ||
121 | 90 | view.setupQueueList() | ||
122 | 91 | view.performQueueAction() | ||
123 | 92 | return view | ||
124 | 93 | |||
125 | 94 | def test_main_admin_can_accept_main_upload(self): | ||
126 | 95 | # A person with queue admin access for main | ||
127 | 96 | # can accept uploads to the main archive. | ||
128 | 97 | login('main-queue@example.org') | ||
129 | 98 | self.assertTrue( | ||
130 | 99 | self.main_archive.canAdministerQueue( | ||
131 | 100 | self.main_queue_admin, self.main_spr.component)) | ||
132 | 101 | |||
133 | 102 | package_upload_id = self.main_spr.package_upload.id | ||
134 | 103 | self.form['QUEUE_ID'] = [package_upload_id] | ||
135 | 104 | request = LaunchpadTestRequest(form=self.form) | ||
136 | 105 | request.method = 'POST' | ||
137 | 106 | view = self.setupQueueView(request) | ||
138 | 107 | |||
139 | 108 | self.assertEquals( | ||
140 | 109 | 'DONE', | ||
141 | 110 | getUtility(IPackageUploadSet).get(package_upload_id).status.name) | ||
142 | 111 | |||
143 | 112 | def test_main_admin_cannot_accept_partner_upload(self): | ||
144 | 113 | # A person with queue admin access for main cannot necessarily | ||
145 | 114 | # accept uploads to partner. | ||
146 | 115 | login('main-queue@example.org') | ||
147 | 116 | self.assertFalse( | ||
148 | 117 | self.partner_archive.canAdministerQueue( | ||
149 | 118 | self.main_queue_admin, self.partner_spr.component)) | ||
150 | 119 | |||
151 | 120 | package_upload_id = self.partner_spr.package_upload.id | ||
152 | 121 | self.form['QUEUE_ID'] = [package_upload_id] | ||
153 | 122 | request = LaunchpadTestRequest(form=self.form) | ||
154 | 123 | request.method = 'POST' | ||
155 | 124 | view = self.setupQueueView(request) | ||
156 | 125 | |||
157 | 126 | self.assertEquals( | ||
158 | 127 | "FAILED: partner-upload (You have no rights to accept " | ||
159 | 128 | "component(s) 'partner')", | ||
160 | 129 | view.request.response.notifications[0].message) | ||
161 | 130 | self.assertEquals( | ||
162 | 131 | 'NEW', | ||
163 | 132 | getUtility(IPackageUploadSet).get(package_upload_id).status.name) | ||
164 | 133 | |||
165 | 134 | def test_admin_can_accept_partner_upload(self): | ||
166 | 135 | # An admin can always accept packages, even for the | ||
167 | 136 | # partner archive (note, this is *not* an archive admin). | ||
168 | 137 | login('admin@canonical.com') | ||
169 | 138 | |||
170 | 139 | package_upload_id = self.partner_spr.package_upload.id | ||
171 | 140 | self.form['QUEUE_ID'] = [package_upload_id] | ||
172 | 141 | request = LaunchpadTestRequest(form=self.form) | ||
173 | 142 | request.method = 'POST' | ||
174 | 143 | view = self.setupQueueView(request) | ||
175 | 144 | |||
176 | 145 | self.assertEquals( | ||
177 | 146 | 'DONE', | ||
178 | 147 | getUtility(IPackageUploadSet).get(package_upload_id).status.name) | ||
179 | 148 | |||
180 | 149 | def test_partner_admin_can_accept_partner_upload(self): | ||
181 | 150 | # A person with queue admin access for partner | ||
182 | 151 | # can accept uploads to the partner archive. | ||
183 | 152 | login('partner-queue@example.org') | ||
184 | 153 | self.assertTrue( | ||
185 | 154 | self.partner_archive.canAdministerQueue( | ||
186 | 155 | self.partner_queue_admin, self.partner_spr.component)) | ||
187 | 156 | |||
188 | 157 | package_upload_id = self.partner_spr.package_upload.id | ||
189 | 158 | self.form['QUEUE_ID'] = [package_upload_id] | ||
190 | 159 | request = LaunchpadTestRequest(form=self.form) | ||
191 | 160 | request.method = 'POST' | ||
192 | 161 | view = self.setupQueueView(request) | ||
193 | 162 | |||
194 | 163 | self.assertEquals( | ||
195 | 164 | 'DONE', | ||
196 | 165 | getUtility(IPackageUploadSet).get(package_upload_id).status.name) | ||
197 | 166 | |||
198 | 167 | def test_partner_admin_cannot_accept_main_upload(self): | ||
199 | 168 | # A person with queue admin access for partner cannot necessarily | ||
200 | 169 | # accept uploads to main. | ||
201 | 170 | login('partner-queue@example.org') | ||
202 | 171 | self.assertFalse( | ||
203 | 172 | self.main_archive.canAdministerQueue( | ||
204 | 173 | self.partner_queue_admin, self.main_spr.component)) | ||
205 | 174 | |||
206 | 175 | package_upload_id = self.main_spr.package_upload.id | ||
207 | 176 | self.form['QUEUE_ID'] = [package_upload_id] | ||
208 | 177 | request = LaunchpadTestRequest(form=self.form) | ||
209 | 178 | request.method = 'POST' | ||
210 | 179 | view = self.setupQueueView(request) | ||
211 | 180 | |||
212 | 181 | self.assertEquals( | ||
213 | 182 | "FAILED: main-upload (You have no rights to accept " | ||
214 | 183 | "component(s) 'main')", | ||
215 | 184 | view.request.response.notifications[0].message) | ||
216 | 185 | self.assertEquals( | ||
217 | 186 | 'NEW', | ||
218 | 187 | getUtility(IPackageUploadSet).get(package_upload_id).status.name) | ||
219 | 188 | |||
220 | 189 | def test_suite(): | ||
221 | 190 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
222 | 191 | |||
223 | 0 | 192 | ||
224 | === modified file 'lib/lp/soyuz/doc/archivepermission.txt' | |||
225 | --- lib/lp/soyuz/doc/archivepermission.txt 2009-12-24 01:41:54 +0000 | |||
226 | +++ lib/lp/soyuz/doc/archivepermission.txt 2010-03-09 15:41:38 +0000 | |||
227 | @@ -236,7 +236,8 @@ | |||
228 | 236 | 236 | ||
229 | 237 | componentsForQueueAdmin() returns the ArchivePermission records for all | 237 | componentsForQueueAdmin() returns the ArchivePermission records for all |
230 | 238 | the components that the supplied user has permission to administer in | 238 | the components that the supplied user has permission to administer in |
232 | 239 | the distroseries queue. | 239 | the distroseries queue. It can be passed a single archive or an |
233 | 240 | enumeration of archives. | ||
234 | 240 | 241 | ||
235 | 241 | >>> name12 = getUtility(IPersonSet).getByName("name12") | 242 | >>> name12 = getUtility(IPersonSet).getByName("name12") |
236 | 242 | >>> permissions = permission_set.componentsForQueueAdmin( | 243 | >>> permissions = permission_set.componentsForQueueAdmin( |
237 | @@ -250,7 +251,7 @@ | |||
238 | 250 | 251 | ||
239 | 251 | >>> no_team = getUtility(IPersonSet).getByName("no-team-memberships") | 252 | >>> no_team = getUtility(IPersonSet).getByName("no-team-memberships") |
240 | 252 | >>> permissions = permission_set.componentsForQueueAdmin( | 253 | >>> permissions = permission_set.componentsForQueueAdmin( |
242 | 253 | ... ubuntu.main_archive, no_team) | 254 | ... ubuntu.all_distro_archives, no_team) |
243 | 254 | >>> for permission in sorted(permissions, key=operator.attrgetter("id")): | 255 | >>> for permission in sorted(permissions, key=operator.attrgetter("id")): |
244 | 255 | ... print permission.component.name | 256 | ... print permission.component.name |
245 | 256 | universe | 257 | universe |
246 | 257 | 258 | ||
247 | === modified file 'lib/lp/soyuz/interfaces/archivepermission.py' | |||
248 | --- lib/lp/soyuz/interfaces/archivepermission.py 2009-11-03 18:44:59 +0000 | |||
249 | +++ lib/lp/soyuz/interfaces/archivepermission.py 2010-03-09 15:41:38 +0000 | |||
250 | @@ -323,7 +323,8 @@ | |||
251 | 323 | def componentsForQueueAdmin(archive, person): | 323 | def componentsForQueueAdmin(archive, person): |
252 | 324 | """Return `ArchivePermission` for the person's queue admin components. | 324 | """Return `ArchivePermission` for the person's queue admin components. |
253 | 325 | 325 | ||
255 | 326 | :param archive: The context `IArchive` for the permission check. | 326 | :param archive: The context `IArchive` for the permission check, or |
256 | 327 | an iterable of `IArchive`s. | ||
257 | 327 | :param person: An `IPerson` for whom you want to find out which | 328 | :param person: An `IPerson` for whom you want to find out which |
258 | 328 | components he has access to. | 329 | components he has access to. |
259 | 329 | 330 | ||
260 | 330 | 331 | ||
261 | === modified file 'lib/lp/soyuz/model/archivepermission.py' | |||
262 | --- lib/lp/soyuz/model/archivepermission.py 2009-11-03 18:44:59 +0000 | |||
263 | +++ lib/lp/soyuz/model/archivepermission.py 2010-03-09 15:41:38 +0000 | |||
264 | @@ -23,7 +23,7 @@ | |||
265 | 23 | from canonical.database.sqlbase import sqlvalues, SQLBase | 23 | from canonical.database.sqlbase import sqlvalues, SQLBase |
266 | 24 | 24 | ||
267 | 25 | from lp.registry.interfaces.distribution import IDistributionSet | 25 | from lp.registry.interfaces.distribution import IDistributionSet |
269 | 26 | from lp.soyuz.interfaces.archive import ComponentNotFound | 26 | from lp.soyuz.interfaces.archive import ComponentNotFound, IArchive |
270 | 27 | from lp.soyuz.interfaces.archivepermission import ( | 27 | from lp.soyuz.interfaces.archivepermission import ( |
271 | 28 | ArchivePermissionType, IArchivePermission, IArchivePermissionSet, | 28 | ArchivePermissionType, IArchivePermission, IArchivePermissionSet, |
272 | 29 | IArchiveUploader, IArchiveQueueAdmin) | 29 | IArchiveUploader, IArchiveQueueAdmin) |
273 | @@ -92,7 +92,7 @@ | |||
274 | 92 | def component_name(self): | 92 | def component_name(self): |
275 | 93 | """See `IArchivePermission`""" | 93 | """See `IArchivePermission`""" |
276 | 94 | if self.component: | 94 | if self.component: |
278 | 95 | return self.component.name | 95 | return self.component.name |
279 | 96 | else: | 96 | else: |
280 | 97 | return None | 97 | return None |
281 | 98 | 98 | ||
282 | @@ -189,17 +189,22 @@ | |||
283 | 189 | TeamParticipation.team = ArchivePermission.person) | 189 | TeamParticipation.team = ArchivePermission.person) |
284 | 190 | """ % sqlvalues(archive, person)) | 190 | """ % sqlvalues(archive, person)) |
285 | 191 | 191 | ||
287 | 192 | def _componentsFor(self, archive, person, permission_type): | 192 | def _componentsFor(self, archives, person, permission_type): |
288 | 193 | """Helper function to get ArchivePermission objects.""" | 193 | """Helper function to get ArchivePermission objects.""" |
289 | 194 | if IArchive.providedBy(archives): | ||
290 | 195 | archive_ids = [archives.id] | ||
291 | 196 | else: | ||
292 | 197 | archive_ids = [archive.id for archive in archives] | ||
293 | 198 | |||
294 | 194 | return ArchivePermission.select(""" | 199 | return ArchivePermission.select(""" |
296 | 195 | ArchivePermission.archive = %s AND | 200 | ArchivePermission.archive IN %s AND |
297 | 196 | ArchivePermission.permission = %s AND | 201 | ArchivePermission.permission = %s AND |
298 | 197 | ArchivePermission.component IS NOT NULL AND | 202 | ArchivePermission.component IS NOT NULL AND |
299 | 198 | EXISTS (SELECT TeamParticipation.person | 203 | EXISTS (SELECT TeamParticipation.person |
300 | 199 | FROM TeamParticipation | 204 | FROM TeamParticipation |
301 | 200 | WHERE TeamParticipation.person = %s AND | 205 | WHERE TeamParticipation.person = %s AND |
302 | 201 | TeamParticipation.team = ArchivePermission.person) | 206 | TeamParticipation.team = ArchivePermission.person) |
304 | 202 | """ % sqlvalues(archive, permission_type, person), | 207 | """ % sqlvalues(archive_ids, permission_type, person), |
305 | 203 | prejoins=["component"]) | 208 | prejoins=["component"]) |
306 | 204 | 209 | ||
307 | 205 | def componentsForUploader(self, archive, person): | 210 | def componentsForUploader(self, archive, person): |
308 | @@ -504,7 +509,7 @@ | |||
309 | 504 | # Query parameters for the first WHERE clause. | 509 | # Query parameters for the first WHERE clause. |
310 | 505 | (archive.id, distroseries.id, sourcepackagename.id) + | 510 | (archive.id, distroseries.id, sourcepackagename.id) + |
311 | 506 | # Query parameters for the second WHERE clause. | 511 | # Query parameters for the second WHERE clause. |
313 | 507 | permission_params + archive_params + | 512 | permission_params + archive_params + |
314 | 508 | # Query parameters for the third WHERE clause. | 513 | # Query parameters for the third WHERE clause. |
315 | 509 | permission_params + archive_params) | 514 | permission_params + archive_params) |
316 | 510 | 515 | ||
317 | @@ -521,7 +526,7 @@ | |||
318 | 521 | THEN ( | 526 | THEN ( |
319 | 522 | SELECT COUNT(ap.id) | 527 | SELECT COUNT(ap.id) |
320 | 523 | FROM | 528 | FROM |
322 | 524 | packagesetsources pss, archivepermission ap, packageset ps, | 529 | packagesetsources pss, archivepermission ap, packageset ps, |
323 | 525 | teamparticipation tp | 530 | teamparticipation tp |
324 | 526 | WHERE | 531 | WHERE |
325 | 527 | pss.sourcepackagename = %s | 532 | pss.sourcepackagename = %s |
326 | 528 | 533 | ||
327 | === modified file 'lib/lp/soyuz/stories/soyuz/xx-queue-pages.txt' | |||
328 | --- lib/lp/soyuz/stories/soyuz/xx-queue-pages.txt 2009-07-16 00:31:36 +0000 | |||
329 | +++ lib/lp/soyuz/stories/soyuz/xx-queue-pages.txt 2010-03-09 15:41:38 +0000 | |||
330 | @@ -195,37 +195,33 @@ | |||
331 | 195 | 195 | ||
332 | 196 | >>> from zope.component import getUtility | 196 | >>> from zope.component import getUtility |
333 | 197 | >>> from canonical.launchpad.ftests import login, logout | 197 | >>> from canonical.launchpad.ftests import login, logout |
337 | 198 | >>> from canonical.launchpad.interfaces import ( | 198 | >>> from canonical.launchpad.interfaces import IDistributionSet |
338 | 199 | ... IDistributionSet, ILibraryFileAliasSet) | 199 | >>> from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
336 | 200 | >>> from canonical.launchpad.ftests import syncUpdate | ||
339 | 201 | 200 | ||
340 | 202 | >>> login('foo.bar@canonical.com') | 201 | >>> login('foo.bar@canonical.com') |
341 | 203 | 202 | ||
342 | 204 | >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | 203 | >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
344 | 205 | >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1] | 204 | |
345 | 206 | >>> breezy_autotest = ubuntu.getSeries('breezy-autotest') | 205 | >>> breezy_autotest = ubuntu.getSeries('breezy-autotest') |
368 | 207 | >>> new_chroot = breezy_autotest["i386"].addOrUpdateChroot(fake_chroot) | 206 | >>> test_publisher = SoyuzTestPublisher() |
369 | 208 | >>> syncUpdate(new_chroot) | 207 | >>> ignore = test_publisher.setUpDefaultDistroSeries(breezy_autotest) |
370 | 209 | 208 | >>> test_publisher.addFakeChroots(distroseries=breezy_autotest) | |
371 | 210 | Upload a new "bar" source so we can accept it later. We need to login to | 209 | |
372 | 211 | upload. | 210 | Upload a new "bar" source so we can accept it later. |
373 | 212 | 211 | ||
374 | 213 | >>> from lp.archiveuploader.tests import ( | 212 | >>> from lp.archiveuploader.tests import datadir |
375 | 214 | ... datadir, getPolicy, mock_logger_quiet) | 213 | >>> changes_file = open( |
376 | 215 | >>> from lp.archiveuploader.nascentupload import NascentUpload | 214 | ... datadir('suite/bar_1.0-1/bar_1.0-1_source.changes')) |
377 | 216 | 215 | >>> changes_file_content = changes_file.read() | |
378 | 217 | >>> sync_policy = getPolicy( | 216 | >>> changes_file.close() |
379 | 218 | ... name='sync', distro='ubuntu', distroseries='breezy-autotest') | 217 | |
380 | 219 | >>> bar_src = NascentUpload( | 218 | >>> bar_src = test_publisher.getPubSource( |
381 | 220 | ... datadir('suite/bar_1.0-1/bar_1.0-1_source.changes'), | 219 | ... sourcename='bar', distroseries=breezy_autotest, spr_only=True, |
382 | 221 | ... sync_policy, mock_logger_quiet) | 220 | ... version='1.0-1', component='universe', section='devel', |
383 | 222 | >>> bar_src.process() | 221 | ... changes_file_content=changes_file_content) |
384 | 223 | >>> bar_src.do_accept() | 222 | |
385 | 224 | True | 223 | >>> bar_src.package_upload.setNew() |
386 | 225 | >>> bar_queue_id = str(bar_src.queue_root.id) | 224 | >>> bar_queue_id = bar_src.package_upload.id |
365 | 226 | |||
366 | 227 | >>> import transaction | ||
367 | 228 | >>> transaction.commit() | ||
387 | 229 | >>> logout() | 225 | >>> logout() |
388 | 230 | 226 | ||
389 | 231 | Swallow any email generated at the upload: | 227 | Swallow any email generated at the upload: |
390 | @@ -246,8 +242,18 @@ | |||
391 | 246 | 242 | ||
392 | 247 | >>> upload_manager_browser.open( | 243 | >>> upload_manager_browser.open( |
393 | 248 | ... "http://localhost/ubuntu/breezy-autotest/+queue") | 244 | ... "http://localhost/ubuntu/breezy-autotest/+queue") |
394 | 245 | >>> print_queue(upload_manager_browser.contents) | ||
395 | 246 | Package Version Component Section Priority Pocket When | ||
396 | 247 | bar (source) 1.0-1 universe devel low Release ... | ||
397 | 248 | netapplet...ddtp... - Release 2006-... | ||
398 | 249 | netapplet...dist... - Release 2006-... | ||
399 | 250 | alsa-utils (source) 1.0.9a-4... main base low Release 2006-... | ||
400 | 251 | netapplet (source) 0.99.6-1 main web low Release 2006-... | ||
401 | 252 | pmount (i386) 0.1-1 Release 2006-... | ||
402 | 253 | moz...irefox (i386) 0.9 Release 2006-... | ||
403 | 254 | |||
404 | 249 | >>> upload_manager_browser.getControl( | 255 | >>> upload_manager_browser.getControl( |
406 | 250 | ... name="QUEUE_ID").value = [bar_queue_id] | 256 | ... name="QUEUE_ID").value = [str(bar_queue_id)] |
407 | 251 | >>> upload_manager_browser.getControl(name="Accept").click() | 257 | >>> upload_manager_browser.getControl(name="Accept").click() |
408 | 252 | >>> print_queue(upload_manager_browser.contents) | 258 | >>> print_queue(upload_manager_browser.contents) |
409 | 253 | Package Version Component Section Priority Pocket When | 259 | Package Version Component Section Priority Pocket When |
410 | @@ -258,22 +264,23 @@ | |||
411 | 258 | pmount (i386) 0.1-1 Release 2006-... | 264 | pmount (i386) 0.1-1 Release 2006-... |
412 | 259 | moz...irefox (i386) 0.9 Release 2006-... | 265 | moz...irefox (i386) 0.9 Release 2006-... |
413 | 260 | 266 | ||
417 | 261 | Accepting queue items results in an email to the uploader and (usually) an | 267 | Accepting queue items results in an email to the uploader (and the changer |
418 | 262 | email to the distroseries' announcement list (see | 268 | if it is someone other than the uploader) and (usually) an email to the |
419 | 263 | nascentupload-announcements.txt). | 269 | distroseries' announcement list (see nascentupload-announcements.txt). |
420 | 264 | 270 | ||
421 | 265 | >>> [notification, announcement] = pop_notifications() | 271 | >>> [notification, announcement] = pop_notifications() |
426 | 266 | >>> notification['To'] | 272 | >>> print notification['To'] |
427 | 267 | 'Daniel Silverstone <daniel.silverstone@canonical.com>' | 273 | Foo Bar <foo.bar@canonical.com>, |
428 | 268 | >>> announcement['To'] | 274 | Daniel Silverstone <daniel.silverstone@canonical.com> |
429 | 269 | 'autotest_changes@ubuntu.com' | 275 | >>> print announcement['To'] |
430 | 276 | autotest_changes@ubuntu.com | ||
431 | 270 | 277 | ||
432 | 271 | Forcing a duplicated submission on a queue item is recognised. Here we | 278 | Forcing a duplicated submission on a queue item is recognised. Here we |
433 | 272 | submit the same form again via a different browser instance, which simulates | 279 | submit the same form again via a different browser instance, which simulates |
434 | 273 | a double post. | 280 | a double post. |
435 | 274 | 281 | ||
436 | 275 | >>> duplicate_submission_browser.getControl( | 282 | >>> duplicate_submission_browser.getControl( |
438 | 276 | ... name="QUEUE_ID").value = [bar_queue_id] | 283 | ... name="QUEUE_ID").value = [str(bar_queue_id)] |
439 | 277 | >>> duplicate_submission_browser.getControl(name="Accept").click() | 284 | >>> duplicate_submission_browser.getControl(name="Accept").click() |
440 | 278 | >>> for message in get_feedback_messages( | 285 | >>> for message in get_feedback_messages( |
441 | 279 | ... duplicate_submission_browser.contents): | 286 | ... duplicate_submission_browser.contents): |
442 | 280 | 287 | ||
443 | === modified file 'lib/lp/soyuz/tests/test_publishing.py' | |||
444 | --- lib/lp/soyuz/tests/test_publishing.py 2010-02-27 20:20:03 +0000 | |||
445 | +++ lib/lp/soyuz/tests/test_publishing.py 2010-03-09 15:41:38 +0000 | |||
446 | @@ -219,15 +219,15 @@ | |||
447 | 219 | upload_status=upload_status) | 219 | upload_status=upload_status) |
448 | 220 | package_upload.addSource(spr) | 220 | package_upload.addSource(spr) |
449 | 221 | 221 | ||
450 | 222 | if spr_only: | ||
451 | 223 | return spr | ||
452 | 224 | |||
453 | 225 | if filename is None: | 222 | if filename is None: |
454 | 226 | filename = "%s_%s.dsc" % (sourcename, version) | 223 | filename = "%s_%s.dsc" % (sourcename, version) |
455 | 227 | alias = self.addMockFile( | 224 | alias = self.addMockFile( |
456 | 228 | filename, filecontent, restricted=archive.private) | 225 | filename, filecontent, restricted=archive.private) |
457 | 229 | spr.addFile(alias) | 226 | spr.addFile(alias) |
458 | 230 | 227 | ||
459 | 228 | if spr_only: | ||
460 | 229 | return spr | ||
461 | 230 | |||
462 | 231 | if status == PackagePublishingStatus.PUBLISHED: | 231 | if status == PackagePublishingStatus.PUBLISHED: |
463 | 232 | datepublished = UTC_NOW | 232 | datepublished = UTC_NOW |
464 | 233 | else: | 233 | else: |
465 | @@ -405,7 +405,7 @@ | |||
466 | 405 | """File with given name fragment in directory tree starting at top.""" | 405 | """File with given name fragment in directory tree starting at top.""" |
467 | 406 | for root, dirs, files in os.walk(top, topdown=False): | 406 | for root, dirs, files in os.walk(top, topdown=False): |
468 | 407 | for name in files: | 407 | for name in files: |
470 | 408 | if (name.endswith('.changes') and | 408 | if (name.endswith('.changes') and |
471 | 409 | name.find(name_fragment) > -1): | 409 | name.find(name_fragment) > -1): |
472 | 410 | return os.path.join(root, name) | 410 | return os.path.join(root, name) |
473 | 411 | return None | 411 | return None |
Hi Michael,
You need to change the copyright notice in your unit test to read 2010 instead of 2009 (and if you'd do the templates as well I'd be grateful).
Other than that this branch looks fine. r=me.