Merge lp:~james-w/launchpad/no-more-sampledata-1 into lp:launchpad
- no-more-sampledata-1
- Merge into devel
Proposed by
James Westby
Status: | Merged |
---|---|
Approved by: | Jonathan Lange |
Approved revision: | no longer in the source branch. |
Merged at revision: | 11295 |
Proposed branch: | lp:~james-w/launchpad/no-more-sampledata-1 |
Merge into: | lp:launchpad |
Prerequisite: | lp:~james-w/launchpad/no-more-sampledata-0 |
Diff against target: |
1552 lines (+599/-557) 11 files modified
lib/lp/archiveuploader/tests/nascentupload-packageset.txt (+2/-2) lib/lp/archiveuploader/tests/nascentupload.txt (+2/-2) lib/lp/archiveuploader/tests/test_permission.py (+0/-242) lib/lp/buildmaster/interfaces/packagebuild.py (+2/-2) lib/lp/soyuz/model/archive.py (+19/-17) lib/lp/soyuz/model/buildpackagejob.py (+2/-3) lib/lp/soyuz/stories/webservice/xx-archive.txt (+2/-2) lib/lp/soyuz/tests/test_archive.py (+505/-283) lib/lp/soyuz/tests/test_buildpackagejob.py (+20/-1) lib/lp/testing/factory.py (+11/-3) lib/lp/testing/tests/test_factory.py (+34/-0) |
To merge this branch: | bzr merge lp:~james-w/launchpad/no-more-sampledata-1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonathan Lange (community) | Approve | ||
Review via email: mp+31493@code.launchpad.net |
Commit message
Description of the change
Hi,
Here's some more cleanup of test_archive to remove reliance on
sampledata (or at least SoyuzTestPublis
There are a couple of fixes here too, one for bug 612351, and one
where the build scoring code assumed it new the complete list of
components, but they are stored in the db, not in an enum or similar.
Thanks,
James
To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote : | # |
Revision history for this message
Jonathan Lange (jml) wrote : | # |
As per my email comments.
review:
Needs Fixing
Revision history for this message
James Westby (james-w) wrote : | # |
Hi,
All suggested changes made.
Thanks,
James
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/archiveuploader/tests/nascentupload-packageset.txt' | |||
2 | --- lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-05-11 14:09:44 +0000 | |||
3 | +++ lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-08-04 22:02:48 +0000 | |||
4 | @@ -39,8 +39,8 @@ | |||
5 | 39 | >>> bar_failed.is_rejected | 39 | >>> bar_failed.is_rejected |
6 | 40 | True | 40 | True |
7 | 41 | >>> print bar_failed.rejection_message | 41 | >>> print bar_failed.rejection_message |
10 | 42 | The signer of this package is lacking the upload rights for the source | 42 | The signer of this package has no upload rights to this distribution's |
11 | 43 | package, component or package set in question. | 43 | primary archive. Did you mean to upload to a PPA? |
12 | 44 | 44 | ||
13 | 45 | 45 | ||
14 | 46 | We can grant selective, package set based upload permissions to the user | 46 | We can grant selective, package set based upload permissions to the user |
15 | 47 | 47 | ||
16 | === modified file 'lib/lp/archiveuploader/tests/nascentupload.txt' | |||
17 | --- lib/lp/archiveuploader/tests/nascentupload.txt 2010-07-24 09:12:37 +0000 | |||
18 | +++ lib/lp/archiveuploader/tests/nascentupload.txt 2010-08-04 22:02:48 +0000 | |||
19 | @@ -879,8 +879,8 @@ | |||
20 | 879 | >>> bar_failed.is_rejected | 879 | >>> bar_failed.is_rejected |
21 | 880 | True | 880 | True |
22 | 881 | >>> print bar_failed.rejection_message | 881 | >>> print bar_failed.rejection_message |
25 | 882 | The signer of this package is lacking the upload rights for the source | 882 | The signer of this package has no upload rights to this distribution's |
26 | 883 | package, component or package set in question. | 883 | primary archive. Did you mean to upload to a PPA? |
27 | 884 | 884 | ||
28 | 885 | Even in a rejected upload using 'insecure' policy, the DSC signing key | 885 | Even in a rejected upload using 'insecure' policy, the DSC signing key |
29 | 886 | and the changesfile sigining key are stored in NascentUpload instance | 886 | and the changesfile sigining key are stored in NascentUpload instance |
30 | 887 | 887 | ||
31 | === removed file 'lib/lp/archiveuploader/tests/test_permission.py' | |||
32 | --- lib/lp/archiveuploader/tests/test_permission.py 2010-07-18 00:26:33 +0000 | |||
33 | +++ lib/lp/archiveuploader/tests/test_permission.py 1970-01-01 00:00:00 +0000 | |||
34 | @@ -1,242 +0,0 @@ | |||
35 | 1 | # Copyright 2009-2010 Canonical Ltd. This software is licensed under the | ||
36 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
37 | 3 | |||
38 | 4 | """Tests for the permissions for uploading to an archive.""" | ||
39 | 5 | |||
40 | 6 | __metaclass__ = type | ||
41 | 7 | |||
42 | 8 | from zope.component import getUtility | ||
43 | 9 | from zope.security.proxy import removeSecurityProxy | ||
44 | 10 | |||
45 | 11 | from canonical.testing import DatabaseFunctionalLayer | ||
46 | 12 | |||
47 | 13 | from lp.registry.interfaces.series import SeriesStatus | ||
48 | 14 | from lp.registry.interfaces.pocket import PackagePublishingPocket | ||
49 | 15 | from lp.soyuz.interfaces.archive import ArchivePurpose | ||
50 | 16 | from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet | ||
51 | 17 | from lp.testing import TestCaseWithFactory | ||
52 | 18 | |||
53 | 19 | |||
54 | 20 | class TestComponents(TestCaseWithFactory): | ||
55 | 21 | |||
56 | 22 | layer = DatabaseFunctionalLayer | ||
57 | 23 | |||
58 | 24 | def test_no_components_for_arbitrary_person(self): | ||
59 | 25 | # By default, a person cannot upload to any component of an archive. | ||
60 | 26 | archive = self.factory.makeArchive() | ||
61 | 27 | person = self.factory.makePerson() | ||
62 | 28 | self.assertEqual(set(), | ||
63 | 29 | set(archive.getComponentsForUploader(person))) | ||
64 | 30 | |||
65 | 31 | def test_components_for_person_with_permissions(self): | ||
66 | 32 | # If a person has been explicitly granted upload permissions to a | ||
67 | 33 | # particular component, then those components are included in | ||
68 | 34 | # IArchive.getComponentsForUploader. | ||
69 | 35 | archive = self.factory.makeArchive() | ||
70 | 36 | component = self.factory.makeComponent() | ||
71 | 37 | person = self.factory.makePerson() | ||
72 | 38 | # Only admins or techboard members can add permissions normally. That | ||
73 | 39 | # restriction isn't relevant to this test. | ||
74 | 40 | ap_set = removeSecurityProxy(getUtility(IArchivePermissionSet)) | ||
75 | 41 | ap = ap_set.newComponentUploader(archive, person, component) | ||
76 | 42 | self.assertEqual(set([ap]), | ||
77 | 43 | set(archive.getComponentsForUploader(person))) | ||
78 | 44 | |||
79 | 45 | |||
80 | 46 | class TestPermission(TestCaseWithFactory): | ||
81 | 47 | |||
82 | 48 | layer = DatabaseFunctionalLayer | ||
83 | 49 | |||
84 | 50 | def setUp(self): | ||
85 | 51 | TestCaseWithFactory.setUp(self) | ||
86 | 52 | permission_set = getUtility(IArchivePermissionSet) | ||
87 | 53 | # Only admins or techboard members can add permissions normally. That | ||
88 | 54 | # restriction isn't relevant to these tests. | ||
89 | 55 | self.permission_set = removeSecurityProxy(permission_set) | ||
90 | 56 | |||
91 | 57 | def assertCanUpload(self, person, spn, archive, component, | ||
92 | 58 | strict_component=True, distroseries=None): | ||
93 | 59 | """Assert that 'person' can upload 'spn' to 'archive'.""" | ||
94 | 60 | # For now, just check that doesn't raise an exception. | ||
95 | 61 | if distroseries is None: | ||
96 | 62 | distroseries = self.factory.makeDistroSeries( | ||
97 | 63 | distribution=archive.distribution) | ||
98 | 64 | pocket = PackagePublishingPocket.RELEASE | ||
99 | 65 | self.assertIs( | ||
100 | 66 | None, | ||
101 | 67 | archive.checkUpload( | ||
102 | 68 | person, distroseries, spn, component, pocket, | ||
103 | 69 | strict_component)) | ||
104 | 70 | |||
105 | 71 | def assertCannotUpload(self, reason, person, spn, archive, component, | ||
106 | 72 | distroseries=None): | ||
107 | 73 | """Assert that 'person' cannot upload to the archive. | ||
108 | 74 | |||
109 | 75 | :param reason: The expected reason for not being able to upload. A | ||
110 | 76 | string. | ||
111 | 77 | :param person: The person trying to upload. | ||
112 | 78 | :param spn: The `ISourcePackageName` being uploaded to. None if the | ||
113 | 79 | package does not yet exist. | ||
114 | 80 | :param archive: The `IArchive` being uploaded to. | ||
115 | 81 | :param component: The IComponent to which the package belongs. | ||
116 | 82 | :param distroseries: The upload's target distro series. | ||
117 | 83 | """ | ||
118 | 84 | if distroseries is None: | ||
119 | 85 | distroseries = self.factory.makeDistroSeries() | ||
120 | 86 | pocket = PackagePublishingPocket.RELEASE | ||
121 | 87 | exception = archive.checkUpload( | ||
122 | 88 | person, distroseries, spn, component, pocket) | ||
123 | 89 | self.assertEqual(reason, str(exception)) | ||
124 | 90 | |||
125 | 91 | def test_random_person_cannot_upload_to_ppa(self): | ||
126 | 92 | # Arbitrary people cannot upload to a PPA. | ||
127 | 93 | person = self.factory.makePerson() | ||
128 | 94 | ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA) | ||
129 | 95 | spn = self.factory.makeSourcePackageName() | ||
130 | 96 | self.assertCannotUpload( | ||
131 | 97 | 'Signer has no upload rights to this PPA.', | ||
132 | 98 | person, spn, ppa, None) | ||
133 | 99 | |||
134 | 100 | def test_owner_can_upload_to_ppa(self): | ||
135 | 101 | # If the archive is a PPA, and you own it, then you can upload pretty | ||
136 | 102 | # much anything to it. | ||
137 | 103 | team = self.factory.makeTeam() | ||
138 | 104 | ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA, owner=team) | ||
139 | 105 | person = self.factory.makePerson() | ||
140 | 106 | removeSecurityProxy(team).addMember(person, team.teamowner) | ||
141 | 107 | spn = self.factory.makeSourcePackageName() | ||
142 | 108 | self.assertCanUpload(person, spn, ppa, None) | ||
143 | 109 | |||
144 | 110 | def test_owner_can_upload_to_ppa_no_sourcepackage(self): | ||
145 | 111 | # The owner can upload to PPAs even if the source package doesn't | ||
146 | 112 | # exist yet. | ||
147 | 113 | team = self.factory.makeTeam() | ||
148 | 114 | ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA, owner=team) | ||
149 | 115 | person = self.factory.makePerson() | ||
150 | 116 | removeSecurityProxy(team).addMember(person, team.teamowner) | ||
151 | 117 | self.assertCanUpload(person, None, ppa, None) | ||
152 | 118 | |||
153 | 119 | def test_can_upload_to_ppa_for_old_series(self): | ||
154 | 120 | # You can upload whatever you want to a PPA, regardless of the upload | ||
155 | 121 | # policy. | ||
156 | 122 | person = self.factory.makePerson() | ||
157 | 123 | ppa = self.factory.makeArchive( | ||
158 | 124 | purpose=ArchivePurpose.PPA, owner=person) | ||
159 | 125 | spn = self.factory.makeSourcePackageName() | ||
160 | 126 | distroseries = self.factory.makeDistroSeries( | ||
161 | 127 | status=SeriesStatus.CURRENT) | ||
162 | 128 | self.assertCanUpload( | ||
163 | 129 | person, spn, ppa, None, distroseries=distroseries) | ||
164 | 130 | |||
165 | 131 | def test_arbitrary_person_cannot_upload_to_primary_archive(self): | ||
166 | 132 | # By default, you can't upload to the primary archive. | ||
167 | 133 | person = self.factory.makePerson() | ||
168 | 134 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
169 | 135 | spn = self.factory.makeSourcePackageName() | ||
170 | 136 | self.assertCannotUpload( | ||
171 | 137 | ("The signer of this package is lacking the upload rights for " | ||
172 | 138 | "the source package, component or package set in question."), | ||
173 | 139 | person, spn, archive, None) | ||
174 | 140 | |||
175 | 141 | def test_package_specific_rights(self): | ||
176 | 142 | # A person can be granted specific rights for uploading a package, | ||
177 | 143 | # based only on the source package name. If they have these rights, | ||
178 | 144 | # they can upload to the package. | ||
179 | 145 | person = self.factory.makePerson() | ||
180 | 146 | spn = self.factory.makeSourcePackageName() | ||
181 | 147 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
182 | 148 | # We can't use a PPA, because they have a different logic for | ||
183 | 149 | # permissions. We can't create an arbitrary archive, because there's | ||
184 | 150 | # only one primary archive per distro. | ||
185 | 151 | self.permission_set.newPackageUploader(archive, person, spn) | ||
186 | 152 | self.assertCanUpload(person, spn, archive, None) | ||
187 | 153 | |||
188 | 154 | def test_packageset_specific_rights(self): | ||
189 | 155 | # A person with rights to upload to the package set can upload the | ||
190 | 156 | # package set to the archive. | ||
191 | 157 | person = self.factory.makePerson() | ||
192 | 158 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
193 | 159 | spn = self.factory.makeSourcePackageName() | ||
194 | 160 | distroseries = self.factory.makeDistroSeries() | ||
195 | 161 | package_set = self.factory.makePackageset( | ||
196 | 162 | packages=[spn], distroseries=distroseries) | ||
197 | 163 | self.permission_set.newPackagesetUploader( | ||
198 | 164 | archive, person, package_set) | ||
199 | 165 | self.assertCanUpload( | ||
200 | 166 | person, spn, archive, None, distroseries=distroseries) | ||
201 | 167 | |||
202 | 168 | def test_packageset_wrong_distroseries(self): | ||
203 | 169 | # A person with rights to upload to the package set in distro | ||
204 | 170 | # series K may not upload with these same rights to a different | ||
205 | 171 | # distro series L. | ||
206 | 172 | distroseries_K = self.factory.makeDistroRelease() | ||
207 | 173 | distroseries_L = self.factory.makeDistroRelease() | ||
208 | 174 | person = self.factory.makePerson() | ||
209 | 175 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
210 | 176 | spn = self.factory.makeSourcePackageName() | ||
211 | 177 | package_set = self.factory.makePackageset( | ||
212 | 178 | packages=[spn], distroseries=distroseries_K) | ||
213 | 179 | self.permission_set.newPackagesetUploader( | ||
214 | 180 | archive, person, package_set) | ||
215 | 181 | self.assertCanUpload( | ||
216 | 182 | person, spn, archive, None, distroseries=distroseries_K) | ||
217 | 183 | self.assertCannotUpload( | ||
218 | 184 | ("The signer of this package is lacking the upload rights for " | ||
219 | 185 | "the source package, component or package set in question."), | ||
220 | 186 | person, spn, archive, None, distroseries=distroseries_L) | ||
221 | 187 | |||
222 | 188 | def test_component_rights(self): | ||
223 | 189 | # A person allowed to upload to a particular component of an archive | ||
224 | 190 | # can upload basically whatever they want to that component. | ||
225 | 191 | person = self.factory.makePerson() | ||
226 | 192 | spn = self.factory.makeSourcePackageName() | ||
227 | 193 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
228 | 194 | component = self.factory.makeComponent() | ||
229 | 195 | self.permission_set.newComponentUploader(archive, person, component) | ||
230 | 196 | self.assertCanUpload(person, spn, archive, component) | ||
231 | 197 | |||
232 | 198 | def test_incorrect_component_rights(self): | ||
233 | 199 | # Even if a person has upload rights for a particular component in an | ||
234 | 200 | # archive, it doesn't mean they have upload rights for everything in | ||
235 | 201 | # that archive. | ||
236 | 202 | person = self.factory.makePerson() | ||
237 | 203 | spn = self.factory.makeSourcePackageName() | ||
238 | 204 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
239 | 205 | permitted_component = self.factory.makeComponent() | ||
240 | 206 | forbidden_component = self.factory.makeComponent() | ||
241 | 207 | self.permission_set.newComponentUploader( | ||
242 | 208 | archive, person, permitted_component) | ||
243 | 209 | self.assertCannotUpload( | ||
244 | 210 | u"Signer is not permitted to upload to the component '%s'." % ( | ||
245 | 211 | forbidden_component.name), | ||
246 | 212 | person, spn, archive, forbidden_component) | ||
247 | 213 | |||
248 | 214 | def test_component_rights_no_package(self): | ||
249 | 215 | # A person allowed to upload to a particular component of an archive | ||
250 | 216 | # can upload basically whatever they want to that component, even if | ||
251 | 217 | # the package doesn't exist yet. | ||
252 | 218 | person = self.factory.makePerson() | ||
253 | 219 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
254 | 220 | component = self.factory.makeComponent() | ||
255 | 221 | self.permission_set.newComponentUploader(archive, person, component) | ||
256 | 222 | self.assertCanUpload(person, None, archive, component) | ||
257 | 223 | |||
258 | 224 | def test_non_strict_component_rights(self): | ||
259 | 225 | # If we aren't testing strict component access, then we only need to | ||
260 | 226 | # have access to an arbitrary component. | ||
261 | 227 | person = self.factory.makePerson() | ||
262 | 228 | spn = self.factory.makeSourcePackageName() | ||
263 | 229 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
264 | 230 | component_a = self.factory.makeComponent() | ||
265 | 231 | component_b = self.factory.makeComponent() | ||
266 | 232 | self.permission_set.newComponentUploader(archive, person, component_b) | ||
267 | 233 | self.assertCanUpload( | ||
268 | 234 | person, spn, archive, component_a, strict_component=False) | ||
269 | 235 | |||
270 | 236 | def test_cannot_upload_to_disabled_archive(self): | ||
271 | 237 | spn = self.factory.makeSourcePackageName() | ||
272 | 238 | archive = self.factory.makeArchive() | ||
273 | 239 | removeSecurityProxy(archive).disable() | ||
274 | 240 | component = self.factory.makeComponent() | ||
275 | 241 | self.assertCannotUpload(u"%s is disabled." % (archive.displayname), | ||
276 | 242 | archive.owner, spn, archive, component) | ||
277 | 243 | 0 | ||
278 | === modified file 'lib/lp/buildmaster/interfaces/packagebuild.py' | |||
279 | --- lib/lp/buildmaster/interfaces/packagebuild.py 2010-06-14 08:11:33 +0000 | |||
280 | +++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-08-04 22:02:48 +0000 | |||
281 | @@ -106,7 +106,7 @@ | |||
282 | 106 | stored. | 106 | stored. |
283 | 107 | """ | 107 | """ |
284 | 108 | 108 | ||
286 | 109 | def getLogFromSlave(): | 109 | def getLogFromSlave(build): |
287 | 110 | """Get last buildlog from slave. """ | 110 | """Get last buildlog from slave. """ |
288 | 111 | 111 | ||
289 | 112 | def getUploadLogContent(root, leaf): | 112 | def getUploadLogContent(root, leaf): |
290 | @@ -120,7 +120,7 @@ | |||
291 | 120 | def estimateDuration(): | 120 | def estimateDuration(): |
292 | 121 | """Estimate the build duration.""" | 121 | """Estimate the build duration.""" |
293 | 122 | 122 | ||
295 | 123 | def storeBuildInfo(librarian, slave_status): | 123 | def storeBuildInfo(build, librarian, slave_status): |
296 | 124 | """Store available information for the build job. | 124 | """Store available information for the build job. |
297 | 125 | 125 | ||
298 | 126 | Derived classes can override this as needed, and call it from | 126 | Derived classes can override this as needed, and call it from |
299 | 127 | 127 | ||
300 | === modified file 'lib/lp/soyuz/model/archive.py' | |||
301 | --- lib/lp/soyuz/model/archive.py 2010-08-03 14:59:22 +0000 | |||
302 | +++ lib/lp/soyuz/model/archive.py 2010-08-04 22:02:48 +0000 | |||
303 | @@ -336,9 +336,9 @@ | |||
304 | 336 | def archive_url(self): | 336 | def archive_url(self): |
305 | 337 | """See `IArchive`.""" | 337 | """See `IArchive`.""" |
306 | 338 | archive_postfixes = { | 338 | archive_postfixes = { |
310 | 339 | ArchivePurpose.PRIMARY : '', | 339 | ArchivePurpose.PRIMARY: '', |
311 | 340 | ArchivePurpose.PARTNER : '-partner', | 340 | ArchivePurpose.PARTNER: '-partner', |
312 | 341 | ArchivePurpose.DEBUG : '-debug', | 341 | ArchivePurpose.DEBUG: '-debug', |
313 | 342 | } | 342 | } |
314 | 343 | 343 | ||
315 | 344 | if self.is_ppa: | 344 | if self.is_ppa: |
316 | @@ -568,7 +568,7 @@ | |||
317 | 568 | # the result is empty, so instead: | 568 | # the result is empty, so instead: |
318 | 569 | return sum(result.values(LibraryFileContent.filesize)) | 569 | return sum(result.values(LibraryFileContent.filesize)) |
319 | 570 | 570 | ||
321 | 571 | def _getBinaryPublishingBaseClauses ( | 571 | def _getBinaryPublishingBaseClauses( |
322 | 572 | self, name=None, version=None, status=None, distroarchseries=None, | 572 | self, name=None, version=None, status=None, distroarchseries=None, |
323 | 573 | pocket=None, exact_match=False): | 573 | pocket=None, exact_match=False): |
324 | 574 | """Base clauses and clauseTables for binary publishing queries. | 574 | """Base clauses and clauseTables for binary publishing queries. |
325 | @@ -648,7 +648,7 @@ | |||
326 | 648 | distroarchseries=distroarchseries, exact_match=exact_match) | 648 | distroarchseries=distroarchseries, exact_match=exact_match) |
327 | 649 | 649 | ||
328 | 650 | all_binaries = BinaryPackagePublishingHistory.select( | 650 | all_binaries = BinaryPackagePublishingHistory.select( |
330 | 651 | ' AND '.join(clauses) , clauseTables=clauseTables, | 651 | ' AND '.join(clauses), clauseTables=clauseTables, |
331 | 652 | orderBy=orderBy) | 652 | orderBy=orderBy) |
332 | 653 | 653 | ||
333 | 654 | return all_binaries | 654 | return all_binaries |
334 | @@ -720,7 +720,7 @@ | |||
335 | 720 | BinaryPackagePublishingHistory.binarypackagereleaseID == | 720 | BinaryPackagePublishingHistory.binarypackagereleaseID == |
336 | 721 | BinaryPackageFile.binarypackagereleaseID, | 721 | BinaryPackageFile.binarypackagereleaseID, |
337 | 722 | BinaryPackageFile.libraryfileID == LibraryFileAlias.id, | 722 | BinaryPackageFile.libraryfileID == LibraryFileAlias.id, |
339 | 723 | LibraryFileAlias.contentID == LibraryFileContent.id | 723 | LibraryFileAlias.contentID == LibraryFileContent.id, |
340 | 724 | ] | 724 | ] |
341 | 725 | 725 | ||
342 | 726 | # Exclude DDEBs from the repository size, they are not published | 726 | # Exclude DDEBs from the repository size, they are not published |
343 | @@ -750,10 +750,10 @@ | |||
344 | 750 | def allowUpdatesToReleasePocket(self): | 750 | def allowUpdatesToReleasePocket(self): |
345 | 751 | """See `IArchive`.""" | 751 | """See `IArchive`.""" |
346 | 752 | purposeToPermissionMap = { | 752 | purposeToPermissionMap = { |
351 | 753 | ArchivePurpose.COPY : True, | 753 | ArchivePurpose.COPY: True, |
352 | 754 | ArchivePurpose.PARTNER : True, | 754 | ArchivePurpose.PARTNER: True, |
353 | 755 | ArchivePurpose.PPA : True, | 755 | ArchivePurpose.PPA: True, |
354 | 756 | ArchivePurpose.PRIMARY : False, | 756 | ArchivePurpose.PRIMARY: False, |
355 | 757 | } | 757 | } |
356 | 758 | 758 | ||
357 | 759 | try: | 759 | try: |
358 | @@ -775,6 +775,7 @@ | |||
359 | 775 | # gets fixed we should probably change it to a normal list and | 775 | # gets fixed we should probably change it to a normal list and |
360 | 776 | # benefit of the FTI rank for ordering. | 776 | # benefit of the FTI rank for ordering. |
361 | 777 | cache_contents = set() | 777 | cache_contents = set() |
362 | 778 | |||
363 | 778 | def add_cache_content(content): | 779 | def add_cache_content(content): |
364 | 779 | """Sanitise and add contents to the cache.""" | 780 | """Sanitise and add contents to the cache.""" |
365 | 780 | content = clean_text.sub(' ', content) | 781 | content = clean_text.sub(' ', content) |
366 | @@ -914,7 +915,7 @@ | |||
367 | 914 | 915 | ||
368 | 915 | find_spec = ( | 916 | find_spec = ( |
369 | 916 | BuildFarmJob.status, | 917 | BuildFarmJob.status, |
371 | 917 | Count(BinaryPackageBuild.id) | 918 | Count(BinaryPackageBuild.id), |
372 | 918 | ) | 919 | ) |
373 | 919 | result = store.using( | 920 | result = store.using( |
374 | 920 | BinaryPackageBuild, PackageBuild, BuildFarmJob).find( | 921 | BinaryPackageBuild, PackageBuild, BuildFarmJob).find( |
375 | @@ -922,8 +923,7 @@ | |||
376 | 922 | BinaryPackageBuild.package_build == PackageBuild.id, | 923 | BinaryPackageBuild.package_build == PackageBuild.id, |
377 | 923 | PackageBuild.archive == self, | 924 | PackageBuild.archive == self, |
378 | 924 | PackageBuild.build_farm_job == BuildFarmJob.id, | 925 | PackageBuild.build_farm_job == BuildFarmJob.id, |
381 | 925 | *extra_exprs | 926 | *extra_exprs).group_by(BuildFarmJob.status).order_by( |
380 | 926 | ).group_by(BuildFarmJob.status).order_by( | ||
382 | 927 | BuildFarmJob.status) | 927 | BuildFarmJob.status) |
383 | 928 | 928 | ||
384 | 929 | # Create a map for each count summary to a number of buildstates: | 929 | # Create a map for each count summary to a number of buildstates: |
385 | @@ -955,7 +955,7 @@ | |||
386 | 955 | BuildStatus.BUILDING, | 955 | BuildStatus.BUILDING, |
387 | 956 | BuildStatus.FULLYBUILT, | 956 | BuildStatus.FULLYBUILT, |
388 | 957 | BuildStatus.SUPERSEDED, | 957 | BuildStatus.SUPERSEDED, |
390 | 958 | ] | 958 | ], |
391 | 959 | } | 959 | } |
392 | 960 | 960 | ||
393 | 961 | # If we were asked to include builds with the state NEEDSBUILD, | 961 | # If we were asked to include builds with the state NEEDSBUILD, |
394 | @@ -1097,7 +1097,11 @@ | |||
395 | 1097 | return None | 1097 | return None |
396 | 1098 | 1098 | ||
397 | 1099 | if not self.getComponentsForUploader(person): | 1099 | if not self.getComponentsForUploader(person): |
399 | 1100 | if not self.getPackagesetsForUploader(person): | 1100 | # XXX: JamesWestby 2010-08-01 bug=612351: We have to use |
400 | 1101 | # is_empty() as we don't get an SQLObjectResultSet back, and | ||
401 | 1102 | # so __nonzero__ isn't defined on it, and a straight bool | ||
402 | 1103 | # check wouldn't do the right thing. | ||
403 | 1104 | if self.getPackagesetsForUploader(person).is_empty(): | ||
404 | 1101 | return NoRightsForArchive() | 1105 | return NoRightsForArchive() |
405 | 1102 | else: | 1106 | else: |
406 | 1103 | return InsufficientUploadRights() | 1107 | return InsufficientUploadRights() |
407 | @@ -1668,7 +1672,6 @@ | |||
408 | 1668 | 1672 | ||
409 | 1669 | return default_name_by_purpose[purpose] | 1673 | return default_name_by_purpose[purpose] |
410 | 1670 | 1674 | ||
411 | 1671 | |||
412 | 1672 | def getByDistroPurpose(self, distribution, purpose, name=None): | 1675 | def getByDistroPurpose(self, distribution, purpose, name=None): |
413 | 1673 | """See `IArchiveSet`.""" | 1676 | """See `IArchiveSet`.""" |
414 | 1674 | if purpose == ArchivePurpose.PPA: | 1677 | if purpose == ArchivePurpose.PPA: |
415 | @@ -1777,7 +1780,6 @@ | |||
416 | 1777 | 1780 | ||
417 | 1778 | return new_archive | 1781 | return new_archive |
418 | 1779 | 1782 | ||
419 | 1780 | |||
420 | 1781 | def __iter__(self): | 1783 | def __iter__(self): |
421 | 1782 | """See `IArchiveSet`.""" | 1784 | """See `IArchiveSet`.""" |
422 | 1783 | return iter(Archive.select()) | 1785 | return iter(Archive.select()) |
423 | 1784 | 1786 | ||
424 | === modified file 'lib/lp/soyuz/model/buildpackagejob.py' | |||
425 | --- lib/lp/soyuz/model/buildpackagejob.py 2010-06-10 12:18:10 +0000 | |||
426 | +++ lib/lp/soyuz/model/buildpackagejob.py 2010-08-04 22:02:48 +0000 | |||
427 | @@ -115,9 +115,8 @@ | |||
428 | 115 | score += score_pocket | 115 | score += score_pocket |
429 | 116 | 116 | ||
430 | 117 | # Calculates the component-related part of the score. | 117 | # Calculates the component-related part of the score. |
434 | 118 | score_component = score_componentname[ | 118 | score += score_componentname.get( |
435 | 119 | self.build.current_component.name] | 119 | self.build.current_component.name, 0) |
433 | 120 | score += score_component | ||
436 | 121 | 120 | ||
437 | 122 | # Calculates the build queue time component of the score. | 121 | # Calculates the build queue time component of the score. |
438 | 123 | right_now = datetime.now(pytz.timezone('UTC')) | 122 | right_now = datetime.now(pytz.timezone('UTC')) |
439 | 124 | 123 | ||
440 | === modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt' | |||
441 | --- lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-07-27 12:33:02 +0000 | |||
442 | +++ lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-08-04 22:02:48 +0000 | |||
443 | @@ -377,8 +377,8 @@ | |||
444 | 377 | >>> print(response) | 377 | >>> print(response) |
445 | 378 | HTTP/1.1 403 Forbidden | 378 | HTTP/1.1 403 Forbidden |
446 | 379 | ... | 379 | ... |
449 | 380 | InsufficientUploadRights: The signer of this package is lacking the upload rights for the source package, component or package set in question. | 380 | NoRightsForArchive: The signer of this package has no upload rights to |
450 | 381 | 381 | this distribution's primary archive. Did you mean to upload to a PPA? | |
451 | 382 | 382 | ||
452 | 383 | 383 | ||
453 | 384 | Only the archive owners can add or remove component-uploaders. | 384 | Only the archive owners can add or remove component-uploaders. |
454 | 385 | 385 | ||
455 | === modified file 'lib/lp/soyuz/tests/test_archive.py' | |||
456 | --- lib/lp/soyuz/tests/test_archive.py 2010-08-03 19:10:42 +0000 | |||
457 | +++ lib/lp/soyuz/tests/test_archive.py 2010-08-04 22:02:48 +0000 | |||
458 | @@ -1,9 +1,11 @@ | |||
459 | 1 | # Copyright 2009-2010 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2010 Canonical Ltd. This software is licensed under the |
460 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
461 | 3 | 3 | ||
462 | 4 | from __future__ import with_statement | ||
463 | 5 | |||
464 | 4 | """Test Archive features.""" | 6 | """Test Archive features.""" |
465 | 5 | 7 | ||
467 | 6 | from datetime import date, timedelta | 8 | from datetime import date |
468 | 7 | 9 | ||
469 | 8 | import transaction | 10 | import transaction |
470 | 9 | 11 | ||
471 | @@ -12,31 +14,35 @@ | |||
472 | 12 | from zope.security.proxy import removeSecurityProxy | 14 | from zope.security.proxy import removeSecurityProxy |
473 | 13 | 15 | ||
474 | 14 | from canonical.database.sqlbase import sqlvalues | 16 | from canonical.database.sqlbase import sqlvalues |
475 | 17 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities | ||
476 | 15 | from canonical.launchpad.webapp.interfaces import ( | 18 | from canonical.launchpad.webapp.interfaces import ( |
477 | 16 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) | 19 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) |
478 | 17 | from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer | 20 | from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer |
479 | 18 | 21 | ||
480 | 19 | from lp.buildmaster.interfaces.buildbase import BuildStatus | 22 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
481 | 20 | from lp.registry.interfaces.distribution import IDistributionSet | ||
482 | 21 | from lp.registry.interfaces.person import IPersonSet | ||
483 | 22 | from lp.registry.interfaces.pocket import PackagePublishingPocket | 23 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
484 | 24 | from lp.registry.interfaces.series import SeriesStatus | ||
485 | 23 | from lp.services.job.interfaces.job import JobStatus | 25 | from lp.services.job.interfaces.job import JobStatus |
489 | 24 | from lp.soyuz.interfaces.archive import (IArchiveSet, ArchivePurpose, | 26 | from lp.soyuz.interfaces.archive import ( |
490 | 25 | ArchiveStatus, CannotRestrictArchitectures, CannotSwitchPrivacy, | 27 | ArchiveDisabled, ArchivePurpose, ArchiveStatus, |
491 | 26 | InvalidPocketForPartnerArchive, InvalidPocketForPPA) | 28 | CannotRestrictArchitectures, CannotSwitchPrivacy, CannotUploadToPocket, |
492 | 29 | CannotUploadToPPA, IArchiveSet, InsufficientUploadRights, | ||
493 | 30 | InvalidPocketForPartnerArchive, InvalidPocketForPPA, NoRightsForArchive, | ||
494 | 31 | NoRightsForComponent) | ||
495 | 27 | from lp.services.worlddata.interfaces.country import ICountrySet | 32 | from lp.services.worlddata.interfaces.country import ICountrySet |
496 | 28 | from lp.soyuz.interfaces.archivearch import IArchiveArchSet | 33 | from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
497 | 34 | from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet | ||
498 | 29 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet | 35 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
499 | 30 | from lp.soyuz.interfaces.binarypackagerelease import ( | 36 | from lp.soyuz.interfaces.binarypackagerelease import ( |
500 | 31 | BinaryPackageFileType, BinaryPackageFormat) | 37 | BinaryPackageFileType, BinaryPackageFormat) |
501 | 32 | from lp.soyuz.interfaces.component import IComponentSet | 38 | from lp.soyuz.interfaces.component import IComponentSet |
502 | 33 | from lp.soyuz.interfaces.processor import IProcessorFamilySet | 39 | from lp.soyuz.interfaces.processor import IProcessorFamilySet |
503 | 34 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus | 40 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
504 | 35 | from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild | ||
505 | 36 | from lp.soyuz.model.binarypackagerelease import ( | 41 | from lp.soyuz.model.binarypackagerelease import ( |
506 | 37 | BinaryPackageReleaseDownloadCount) | 42 | BinaryPackageReleaseDownloadCount) |
507 | 38 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher | 43 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
509 | 39 | from lp.testing import login, login_person, TestCaseWithFactory | 44 | from lp.testing import ( |
510 | 45 | login, login_person, person_logged_in, TestCaseWithFactory) | ||
511 | 40 | 46 | ||
512 | 41 | 47 | ||
513 | 42 | class TestGetPublicationsInArchive(TestCaseWithFactory): | 48 | class TestGetPublicationsInArchive(TestCaseWithFactory): |
514 | @@ -207,247 +213,128 @@ | |||
515 | 207 | class TestSeriesWithSources(TestCaseWithFactory): | 213 | class TestSeriesWithSources(TestCaseWithFactory): |
516 | 208 | """Create some sources in different series.""" | 214 | """Create some sources in different series.""" |
517 | 209 | 215 | ||
550 | 210 | layer = LaunchpadZopelessLayer | 216 | layer = DatabaseFunctionalLayer |
519 | 211 | |||
520 | 212 | def setUp(self): | ||
521 | 213 | super(TestSeriesWithSources, self).setUp() | ||
522 | 214 | self.publisher = SoyuzTestPublisher() | ||
523 | 215 | self.publisher.prepareBreezyAutotest() | ||
524 | 216 | |||
525 | 217 | # Create three sources for the two different distroseries. | ||
526 | 218 | breezy_autotest = self.publisher.distroseries | ||
527 | 219 | ubuntu_test = breezy_autotest.distribution | ||
528 | 220 | self.series = [breezy_autotest] | ||
529 | 221 | self.series.append(self.factory.makeDistroRelease( | ||
530 | 222 | distribution=ubuntu_test, name="foo-series", version='1.0')) | ||
531 | 223 | |||
532 | 224 | self.sources = [] | ||
533 | 225 | gedit_src_hist = self.publisher.getPubSource( | ||
534 | 226 | sourcename="gedit", status=PackagePublishingStatus.PUBLISHED) | ||
535 | 227 | self.sources.append(gedit_src_hist) | ||
536 | 228 | |||
537 | 229 | firefox_src_hist = self.publisher.getPubSource( | ||
538 | 230 | sourcename="firefox", status=PackagePublishingStatus.PUBLISHED, | ||
539 | 231 | distroseries=self.series[1]) | ||
540 | 232 | self.sources.append(firefox_src_hist) | ||
541 | 233 | |||
542 | 234 | gtg_src_hist = self.publisher.getPubSource( | ||
543 | 235 | sourcename="getting-things-gnome", | ||
544 | 236 | status=PackagePublishingStatus.PUBLISHED, | ||
545 | 237 | distroseries=self.series[1]) | ||
546 | 238 | self.sources.append(gtg_src_hist) | ||
547 | 239 | |||
548 | 240 | # Shortcuts for test readability. | ||
549 | 241 | self.archive = self.series[0].main_archive | ||
551 | 242 | 217 | ||
552 | 243 | def test_series_with_sources_returns_all_series(self): | 218 | def test_series_with_sources_returns_all_series(self): |
553 | 244 | # Calling series_with_sources returns all series with publishings. | 219 | # Calling series_with_sources returns all series with publishings. |
560 | 245 | series = self.archive.series_with_sources | 220 | distribution = self.factory.makeDistribution() |
561 | 246 | series_names = [s.displayname for s in series] | 221 | archive = self.factory.makeArchive(distribution=distribution) |
562 | 247 | 222 | series_with_no_sources = self.factory.makeDistroSeries( | |
563 | 248 | self.assertContentEqual( | 223 | distribution=distribution, version="0.5") |
564 | 249 | [u'Breezy Badger Autotest', u'Foo-series'], | 224 | series_with_sources1 = self.factory.makeDistroSeries( |
565 | 250 | series_names) | 225 | distribution=distribution, version="1") |
566 | 226 | self.factory.makeSourcePackagePublishingHistory( | ||
567 | 227 | distroseries=series_with_sources1, archive=archive, | ||
568 | 228 | status=PackagePublishingStatus.PUBLISHED) | ||
569 | 229 | series_with_sources2 = self.factory.makeDistroSeries( | ||
570 | 230 | distribution=distribution, version="2") | ||
571 | 231 | self.factory.makeSourcePackagePublishingHistory( | ||
572 | 232 | distroseries=series_with_sources2, archive=archive, | ||
573 | 233 | status=PackagePublishingStatus.PENDING) | ||
574 | 234 | self.assertEqual( | ||
575 | 235 | [series_with_sources2, series_with_sources1], | ||
576 | 236 | archive.series_with_sources) | ||
577 | 251 | 237 | ||
578 | 252 | def test_series_with_sources_ignore_non_published_records(self): | 238 | def test_series_with_sources_ignore_non_published_records(self): |
579 | 253 | # If all publishings in a series are deleted or superseded | 239 | # If all publishings in a series are deleted or superseded |
580 | 254 | # the series will not be returned. | 240 | # the series will not be returned. |
588 | 255 | self.sources[0].status = ( | 241 | series = self.factory.makeDistroSeries() |
589 | 256 | PackagePublishingStatus.DELETED) | 242 | archive = self.factory.makeArchive(distribution=series.distribution) |
590 | 257 | 243 | self.factory.makeSourcePackagePublishingHistory( | |
591 | 258 | series = self.archive.series_with_sources | 244 | distroseries=series, archive=archive, |
592 | 259 | series_names = [s.displayname for s in series] | 245 | status=PackagePublishingStatus.DELETED) |
593 | 260 | 246 | self.assertEqual([], archive.series_with_sources) | |
587 | 261 | self.assertContentEqual([u'Foo-series'], series_names) | ||
594 | 262 | 247 | ||
595 | 263 | def test_series_with_sources_ordered_by_version(self): | 248 | def test_series_with_sources_ordered_by_version(self): |
596 | 264 | # The returned series are ordered by the distroseries version. | 249 | # The returned series are ordered by the distroseries version. |
613 | 265 | series = self.archive.series_with_sources | 250 | distribution = self.factory.makeDistribution() |
614 | 266 | versions = [s.version for s in series] | 251 | archive = self.factory.makeArchive(distribution=distribution) |
615 | 267 | 252 | series1 = self.factory.makeDistroSeries( | |
616 | 268 | # Latest version should be first | 253 | version="1", distribution=distribution) |
617 | 269 | self.assertEqual( | 254 | series2 = self.factory.makeDistroSeries( |
618 | 270 | [u'6.6.6', u'1.0'], versions, | 255 | version="2", distribution=distribution) |
619 | 271 | "The latest version was not first.") | 256 | self.factory.makeSourcePackagePublishingHistory( |
620 | 272 | 257 | distroseries=series1, archive=archive, | |
621 | 273 | # Update the version of breezyautotest and ensure that the | 258 | status=PackagePublishingStatus.PUBLISHED) |
622 | 274 | # latest version is still first. | 259 | self.factory.makeSourcePackagePublishingHistory( |
623 | 275 | self.series[0].version = u'0.5' | 260 | distroseries=series2, archive=archive, |
624 | 276 | series = self.archive.series_with_sources | 261 | status=PackagePublishingStatus.PUBLISHED) |
625 | 277 | versions = [s.version for s in series] | 262 | self.assertEqual([series2, series1], archive.series_with_sources) |
626 | 278 | self.assertEqual( | 263 | # Change the version such that they should order differently |
627 | 279 | [u'1.0', u'0.5'], versions, | 264 | removeSecurityProxy(series2).version = "0.5" |
628 | 280 | "The latest version was not first.") | 265 | # ... and check that they do |
629 | 266 | self.assertEqual([series1, series2], archive.series_with_sources) | ||
630 | 281 | 267 | ||
631 | 282 | 268 | ||
632 | 283 | class TestGetSourcePackageReleases(TestCaseWithFactory): | 269 | class TestGetSourcePackageReleases(TestCaseWithFactory): |
633 | 284 | 270 | ||
659 | 285 | layer = LaunchpadZopelessLayer | 271 | layer = DatabaseFunctionalLayer |
660 | 286 | 272 | ||
661 | 287 | def setUp(self): | 273 | def createArchiveWithBuilds(self, statuses): |
662 | 288 | super(TestGetSourcePackageReleases, self).setUp() | 274 | archive = self.factory.makeArchive() |
663 | 289 | self.publisher = SoyuzTestPublisher() | 275 | sprs = [] |
664 | 290 | self.publisher.prepareBreezyAutotest() | 276 | for status in statuses: |
665 | 291 | 277 | sourcepackagerelease = self.factory.makeSourcePackageRelease() | |
666 | 292 | # Create an archive with some published binaries. | 278 | self.factory.makeBinaryPackageBuild( |
667 | 293 | self.archive = self.factory.makeArchive() | 279 | source_package_release=sourcepackagerelease, |
668 | 294 | binaries_foo = self.publisher.getPubBinaries( | 280 | archive=archive, status=status) |
669 | 295 | archive=self.archive, binaryname="foo-bin") | 281 | sprs.append(sourcepackagerelease) |
670 | 296 | binaries_bar = self.publisher.getPubBinaries( | 282 | unlinked_spr = self.factory.makeSourcePackageRelease() |
671 | 297 | archive=self.archive, binaryname="bar-bin") | 283 | return archive, sprs |
647 | 298 | |||
648 | 299 | # Collect the builds for reference. | ||
649 | 300 | self.builds_foo = [ | ||
650 | 301 | binary.binarypackagerelease.build for binary in binaries_foo] | ||
651 | 302 | self.builds_bar = [ | ||
652 | 303 | binary.binarypackagerelease.build for binary in binaries_bar] | ||
653 | 304 | |||
654 | 305 | # Collect the source package releases for reference. | ||
655 | 306 | self.sourcepackagereleases = [ | ||
656 | 307 | self.builds_foo[0].source_package_release, | ||
657 | 308 | self.builds_bar[0].source_package_release, | ||
658 | 309 | ] | ||
672 | 310 | 284 | ||
673 | 311 | def test_getSourcePackageReleases_with_no_params(self): | 285 | def test_getSourcePackageReleases_with_no_params(self): |
674 | 312 | # With no params all source package releases are returned. | 286 | # With no params all source package releases are returned. |
678 | 313 | sprs = self.archive.getSourcePackageReleases() | 287 | archive, sprs = self.createArchiveWithBuilds( |
679 | 314 | 288 | [BuildStatus.NEEDSBUILD, BuildStatus.FULLYBUILT]) | |
680 | 315 | self.assertContentEqual(self.sourcepackagereleases, sprs) | 289 | self.assertContentEqual( |
681 | 290 | sprs, archive.getSourcePackageReleases()) | ||
682 | 316 | 291 | ||
683 | 317 | def test_getSourcePackageReleases_with_buildstatus(self): | 292 | def test_getSourcePackageReleases_with_buildstatus(self): |
684 | 318 | # Results are filtered by the specified buildstatus. | 293 | # Results are filtered by the specified buildstatus. |
696 | 319 | 294 | archive, sprs = self.createArchiveWithBuilds( | |
697 | 320 | # Set the builds for one of the sprs to needs build. | 295 | [BuildStatus.NEEDSBUILD, BuildStatus.FULLYBUILT]) |
698 | 321 | for build in self.builds_foo: | 296 | self.assertContentEqual( |
699 | 322 | removeSecurityProxy(build).status = BuildStatus.NEEDSBUILD | 297 | [sprs[0]], archive.getSourcePackageReleases( |
700 | 323 | 298 | build_status=BuildStatus.NEEDSBUILD)) | |
690 | 324 | result = self.archive.getSourcePackageReleases( | ||
691 | 325 | build_status=BuildStatus.NEEDSBUILD) | ||
692 | 326 | |||
693 | 327 | self.failUnlessEqual(1, result.count()) | ||
694 | 328 | self.failUnlessEqual( | ||
695 | 329 | self.sourcepackagereleases[0], result[0]) | ||
701 | 330 | 299 | ||
702 | 331 | 300 | ||
703 | 332 | class TestCorrespondingDebugArchive(TestCaseWithFactory): | 301 | class TestCorrespondingDebugArchive(TestCaseWithFactory): |
704 | 333 | 302 | ||
726 | 334 | layer = LaunchpadZopelessLayer | 303 | layer = DatabaseFunctionalLayer |
706 | 335 | |||
707 | 336 | def setUp(self): | ||
708 | 337 | super(TestCorrespondingDebugArchive, self).setUp() | ||
709 | 338 | |||
710 | 339 | self.ubuntutest = getUtility(IDistributionSet)['ubuntutest'] | ||
711 | 340 | |||
712 | 341 | # Create a debug archive, as there isn't one in the sample data. | ||
713 | 342 | self.debug_archive = getUtility(IArchiveSet).new( | ||
714 | 343 | purpose=ArchivePurpose.DEBUG, | ||
715 | 344 | distribution=self.ubuntutest, | ||
716 | 345 | owner=self.ubuntutest.owner) | ||
717 | 346 | |||
718 | 347 | # Retrieve sample data archives of each type. | ||
719 | 348 | self.primary_archive = getUtility(IArchiveSet).getByDistroPurpose( | ||
720 | 349 | self.ubuntutest, ArchivePurpose.PRIMARY) | ||
721 | 350 | self.partner_archive = getUtility(IArchiveSet).getByDistroPurpose( | ||
722 | 351 | self.ubuntutest, ArchivePurpose.PARTNER) | ||
723 | 352 | self.copy_archive = getUtility(IArchiveSet).getByDistroPurpose( | ||
724 | 353 | self.ubuntutest, ArchivePurpose.PARTNER) | ||
725 | 354 | self.ppa = getUtility(IPersonSet).getByName('cprov').archive | ||
727 | 355 | 304 | ||
728 | 356 | def testPrimaryDebugArchiveIsDebug(self): | 305 | def testPrimaryDebugArchiveIsDebug(self): |
731 | 357 | self.assertEquals( | 306 | distribution = self.factory.makeDistribution() |
732 | 358 | self.primary_archive.debug_archive, self.debug_archive) | 307 | primary = self.factory.makeArchive( |
733 | 308 | distribution=distribution, purpose=ArchivePurpose.PRIMARY) | ||
734 | 309 | debug = self.factory.makeArchive( | ||
735 | 310 | distribution=distribution, purpose=ArchivePurpose.DEBUG) | ||
736 | 311 | self.assertEquals(primary.debug_archive, debug) | ||
737 | 359 | 312 | ||
738 | 360 | def testPartnerDebugArchiveIsSelf(self): | 313 | def testPartnerDebugArchiveIsSelf(self): |
741 | 361 | self.assertEquals( | 314 | partner = self.factory.makeArchive(purpose=ArchivePurpose.PARTNER) |
742 | 362 | self.partner_archive.debug_archive, self.partner_archive) | 315 | self.assertEquals(partner.debug_archive, partner) |
743 | 363 | 316 | ||
744 | 364 | def testCopyDebugArchiveIsSelf(self): | 317 | def testCopyDebugArchiveIsSelf(self): |
747 | 365 | self.assertEquals( | 318 | copy = self.factory.makeArchive(purpose=ArchivePurpose.COPY) |
748 | 366 | self.copy_archive.debug_archive, self.copy_archive) | 319 | self.assertEquals(copy.debug_archive, copy) |
749 | 367 | 320 | ||
750 | 368 | def testDebugDebugArchiveIsSelf(self): | 321 | def testDebugDebugArchiveIsSelf(self): |
753 | 369 | self.assertEquals( | 322 | debug = self.factory.makeArchive(purpose=ArchivePurpose.DEBUG) |
754 | 370 | self.debug_archive.debug_archive, self.debug_archive) | 323 | self.assertEquals(debug.debug_archive, debug) |
755 | 371 | 324 | ||
756 | 372 | def testPPADebugArchiveIsSelf(self): | 325 | def testPPADebugArchiveIsSelf(self): |
758 | 373 | self.assertEquals(self.ppa.debug_archive, self.ppa) | 326 | ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA) |
759 | 327 | self.assertEquals(ppa.debug_archive, ppa) | ||
760 | 374 | 328 | ||
761 | 375 | def testMissingPrimaryDebugArchiveIsNone(self): | 329 | def testMissingPrimaryDebugArchiveIsNone(self): |
767 | 376 | # Turn the DEBUG archive into a COPY archive to hide it. | 330 | primary = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) |
768 | 377 | removeSecurityProxy(self.debug_archive).purpose = ArchivePurpose.COPY | 331 | self.assertIs(primary.debug_archive, None) |
764 | 378 | |||
765 | 379 | self.assertIs( | ||
766 | 380 | self.primary_archive.debug_archive, None) | ||
769 | 381 | 332 | ||
770 | 382 | 333 | ||
771 | 383 | class TestArchiveEnableDisable(TestCaseWithFactory): | 334 | class TestArchiveEnableDisable(TestCaseWithFactory): |
772 | 384 | """Test the enable and disable methods of Archive.""" | 335 | """Test the enable and disable methods of Archive.""" |
773 | 385 | 336 | ||
839 | 386 | layer = LaunchpadZopelessLayer | 337 | layer = DatabaseFunctionalLayer |
775 | 387 | |||
776 | 388 | def setUp(self): | ||
777 | 389 | #XXX: rockstar - 12 Jan 2010 - Bug #506255 - Tidy up these tests! | ||
778 | 390 | super(TestArchiveEnableDisable, self).setUp() | ||
779 | 391 | |||
780 | 392 | self.publisher = SoyuzTestPublisher() | ||
781 | 393 | self.publisher.prepareBreezyAutotest() | ||
782 | 394 | |||
783 | 395 | self.ubuntutest = getUtility(IDistributionSet)['ubuntutest'] | ||
784 | 396 | self.archive = getUtility(IArchiveSet).getByDistroPurpose( | ||
785 | 397 | self.ubuntutest, ArchivePurpose.PRIMARY) | ||
786 | 398 | |||
787 | 399 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) | ||
788 | 400 | sample_data = store.find(BinaryPackageBuild) | ||
789 | 401 | for build in sample_data: | ||
790 | 402 | build.buildstate = BuildStatus.FULLYBUILT | ||
791 | 403 | store.flush() | ||
792 | 404 | |||
793 | 405 | # We test builds that target a primary archive. | ||
794 | 406 | self.builds = [] | ||
795 | 407 | self.builds.extend( | ||
796 | 408 | self.publisher.getPubSource( | ||
797 | 409 | sourcename="gedit", status=PackagePublishingStatus.PUBLISHED, | ||
798 | 410 | archive=self.archive).createMissingBuilds()) | ||
799 | 411 | self.builds.extend( | ||
800 | 412 | self.publisher.getPubSource( | ||
801 | 413 | sourcename="firefox", | ||
802 | 414 | status=PackagePublishingStatus.PUBLISHED, | ||
803 | 415 | archive=self.archive).createMissingBuilds()) | ||
804 | 416 | self.builds.extend( | ||
805 | 417 | self.publisher.getPubSource( | ||
806 | 418 | sourcename="apg", status=PackagePublishingStatus.PUBLISHED, | ||
807 | 419 | archive=self.archive).createMissingBuilds()) | ||
808 | 420 | self.builds.extend( | ||
809 | 421 | self.publisher.getPubSource( | ||
810 | 422 | sourcename="vim", status=PackagePublishingStatus.PUBLISHED, | ||
811 | 423 | archive=self.archive).createMissingBuilds()) | ||
812 | 424 | self.builds.extend( | ||
813 | 425 | self.publisher.getPubSource( | ||
814 | 426 | sourcename="gcc", status=PackagePublishingStatus.PUBLISHED, | ||
815 | 427 | archive=self.archive).createMissingBuilds()) | ||
816 | 428 | self.builds.extend( | ||
817 | 429 | self.publisher.getPubSource( | ||
818 | 430 | sourcename="bison", status=PackagePublishingStatus.PUBLISHED, | ||
819 | 431 | archive=self.archive).createMissingBuilds()) | ||
820 | 432 | self.builds.extend( | ||
821 | 433 | self.publisher.getPubSource( | ||
822 | 434 | sourcename="flex", status=PackagePublishingStatus.PUBLISHED, | ||
823 | 435 | archive=self.archive).createMissingBuilds()) | ||
824 | 436 | self.builds.extend( | ||
825 | 437 | self.publisher.getPubSource( | ||
826 | 438 | sourcename="postgres", | ||
827 | 439 | status=PackagePublishingStatus.PUBLISHED, | ||
828 | 440 | archive=self.archive).createMissingBuilds()) | ||
829 | 441 | # Set up the builds for test. | ||
830 | 442 | score = 1000 | ||
831 | 443 | duration = 0 | ||
832 | 444 | for build in self.builds: | ||
833 | 445 | score += 1 | ||
834 | 446 | duration += 60 | ||
835 | 447 | bq = build.buildqueue_record | ||
836 | 448 | bq.lastscore = score | ||
837 | 449 | removeSecurityProxy(bq).estimated_duration = timedelta( | ||
838 | 450 | seconds=duration) | ||
840 | 451 | 338 | ||
841 | 452 | def _getBuildJobsByStatus(self, archive, status): | 339 | def _getBuildJobsByStatus(self, archive, status): |
842 | 453 | # Return the count for archive build jobs with the given status. | 340 | # Return the count for archive build jobs with the given status. |
843 | @@ -474,92 +361,95 @@ | |||
844 | 474 | # status. | 361 | # status. |
845 | 475 | self.assertEqual(self._getBuildJobsByStatus(archive, status), 0) | 362 | self.assertEqual(self._getBuildJobsByStatus(archive, status), 0) |
846 | 476 | 363 | ||
848 | 477 | def assertHasBuildJobsWithStatus(self, archive, status): | 364 | def assertHasBuildJobsWithStatus(self, archive, status, count): |
849 | 478 | # Check that that there are jobs attached to this archive that have | 365 | # Check that that there are jobs attached to this archive that have |
850 | 479 | # the specified status. | 366 | # the specified status. |
852 | 480 | self.assertEqual(self._getBuildJobsByStatus(archive, status), 8) | 367 | self.assertEqual(self._getBuildJobsByStatus(archive, status), count) |
853 | 481 | 368 | ||
854 | 482 | def test_enableArchive(self): | 369 | def test_enableArchive(self): |
855 | 483 | # Enabling an archive should set all the Archive's suspended builds to | 370 | # Enabling an archive should set all the Archive's suspended builds to |
856 | 484 | # WAITING. | 371 | # WAITING. |
864 | 485 | 372 | archive = self.factory.makeArchive(enabled=True) | |
865 | 486 | # Disable the archive, because it's currently enabled. | 373 | self.factory.makeBinaryPackageBuild( |
866 | 487 | self.archive.disable() | 374 | archive=archive, status=BuildStatus.NEEDSBUILD) |
867 | 488 | self.assertHasBuildJobsWithStatus(self.archive, JobStatus.SUSPENDED) | 375 | # disable the archive, as it is currently enabled |
868 | 489 | self.archive.enable() | 376 | removeSecurityProxy(archive).disable() |
869 | 490 | self.assertNoBuildJobsHaveStatus(self.archive, JobStatus.SUSPENDED) | 377 | self.assertHasBuildJobsWithStatus(archive, JobStatus.SUSPENDED, 1) |
870 | 491 | self.assertTrue(self.archive.enabled) | 378 | removeSecurityProxy(archive).enable() |
871 | 379 | self.assertNoBuildJobsHaveStatus(archive, JobStatus.SUSPENDED) | ||
872 | 380 | self.assertTrue(archive.enabled) | ||
873 | 492 | 381 | ||
874 | 493 | def test_enableArchiveAlreadyEnabled(self): | 382 | def test_enableArchiveAlreadyEnabled(self): |
875 | 494 | # Enabling an already enabled Archive should raise an AssertionError. | 383 | # Enabling an already enabled Archive should raise an AssertionError. |
877 | 495 | self.assertRaises(AssertionError, self.archive.enable) | 384 | archive = self.factory.makeArchive(enabled=True) |
878 | 385 | self.assertRaises(AssertionError, removeSecurityProxy(archive).enable) | ||
879 | 496 | 386 | ||
880 | 497 | def test_disableArchive(self): | 387 | def test_disableArchive(self): |
881 | 498 | # Disabling an archive should set all the Archive's pending bulds to | 388 | # Disabling an archive should set all the Archive's pending bulds to |
882 | 499 | # SUSPENDED. | 389 | # SUSPENDED. |
887 | 500 | self.assertHasBuildJobsWithStatus(self.archive, JobStatus.WAITING) | 390 | archive = self.factory.makeArchive(enabled=True) |
888 | 501 | self.archive.disable() | 391 | self.factory.makeBinaryPackageBuild( |
889 | 502 | self.assertNoBuildJobsHaveStatus(self.archive, JobStatus.WAITING) | 392 | archive=archive, status=BuildStatus.NEEDSBUILD) |
890 | 503 | self.assertFalse(self.archive.enabled) | 393 | self.assertHasBuildJobsWithStatus(archive, JobStatus.WAITING, 1) |
891 | 394 | removeSecurityProxy(archive).disable() | ||
892 | 395 | self.assertNoBuildJobsHaveStatus(archive, JobStatus.WAITING) | ||
893 | 396 | self.assertFalse(archive.enabled) | ||
894 | 504 | 397 | ||
895 | 505 | def test_disableArchiveAlreadyDisabled(self): | 398 | def test_disableArchiveAlreadyDisabled(self): |
896 | 506 | # Disabling an already disabled Archive should raise an | 399 | # Disabling an already disabled Archive should raise an |
897 | 507 | # AssertionError. | 400 | # AssertionError. |
900 | 508 | self.archive.disable() | 401 | archive = self.factory.makeArchive(enabled=False) |
901 | 509 | self.assertRaises(AssertionError, self.archive.disable) | 402 | self.assertRaises( |
902 | 403 | AssertionError, removeSecurityProxy(archive).disable) | ||
903 | 510 | 404 | ||
904 | 511 | 405 | ||
905 | 512 | class TestCollectLatestPublishedSources(TestCaseWithFactory): | 406 | class TestCollectLatestPublishedSources(TestCaseWithFactory): |
906 | 513 | """Ensure that the private helper method works as expected.""" | 407 | """Ensure that the private helper method works as expected.""" |
907 | 514 | 408 | ||
933 | 515 | layer = LaunchpadZopelessLayer | 409 | layer = DatabaseFunctionalLayer |
934 | 516 | 410 | ||
935 | 517 | def setUp(self): | 411 | def makePublishedSources(self, archive, statuses, versions, names): |
936 | 518 | """Setup an archive with relevant publications.""" | 412 | for status, version, name in zip(statuses, versions, names): |
937 | 519 | super(TestCollectLatestPublishedSources, self).setUp() | 413 | self.factory.makeSourcePackagePublishingHistory( |
938 | 520 | self.publisher = SoyuzTestPublisher() | 414 | sourcepackagename=name, archive=archive, |
939 | 521 | self.publisher.prepareBreezyAutotest() | 415 | version=version, status=status) |
915 | 522 | |||
916 | 523 | # Create an archive with some published sources. We'll store | ||
917 | 524 | # a reference to the naked archive so that we can call | ||
918 | 525 | # the private method which is not defined on the interface. | ||
919 | 526 | self.archive = self.factory.makeArchive() | ||
920 | 527 | self.naked_archive = removeSecurityProxy(self.archive) | ||
921 | 528 | |||
922 | 529 | self.pub_1 = self.publisher.getPubSource( | ||
923 | 530 | version='0.5.11~ppa1', archive=self.archive, sourcename="foo", | ||
924 | 531 | status=PackagePublishingStatus.PUBLISHED) | ||
925 | 532 | |||
926 | 533 | self.pub_2 = self.publisher.getPubSource( | ||
927 | 534 | version='0.5.11~ppa2', archive=self.archive, sourcename="foo", | ||
928 | 535 | status=PackagePublishingStatus.PUBLISHED) | ||
929 | 536 | |||
930 | 537 | self.pub_3 = self.publisher.getPubSource( | ||
931 | 538 | version='0.9', archive=self.archive, sourcename="bar", | ||
932 | 539 | status=PackagePublishingStatus.PUBLISHED) | ||
940 | 540 | 416 | ||
941 | 541 | def test_collectLatestPublishedSources_returns_latest(self): | 417 | def test_collectLatestPublishedSources_returns_latest(self): |
944 | 542 | pubs = self.naked_archive._collectLatestPublishedSources( | 418 | sourcepackagename = self.factory.makeSourcePackageName(name="foo") |
945 | 543 | self.archive, ["foo"]) | 419 | other_spn = self.factory.makeSourcePackageName(name="bar") |
946 | 420 | archive = self.factory.makeArchive() | ||
947 | 421 | self.makePublishedSources(archive, | ||
948 | 422 | [PackagePublishingStatus.PUBLISHED]*3, | ||
949 | 423 | ["1.0", "1.1", "2.0"], | ||
950 | 424 | [sourcepackagename, sourcepackagename, other_spn]) | ||
951 | 425 | pubs = removeSecurityProxy(archive)._collectLatestPublishedSources( | ||
952 | 426 | archive, ["foo"]) | ||
953 | 544 | self.assertEqual(1, len(pubs)) | 427 | self.assertEqual(1, len(pubs)) |
955 | 545 | self.assertEqual('0.5.11~ppa2', pubs[0].source_package_version) | 428 | self.assertEqual('1.1', pubs[0].source_package_version) |
956 | 546 | 429 | ||
957 | 547 | def test_collectLatestPublishedSources_returns_published_only(self): | 430 | def test_collectLatestPublishedSources_returns_published_only(self): |
958 | 548 | # Set the status of the latest pub to DELETED and ensure that it | 431 | # Set the status of the latest pub to DELETED and ensure that it |
959 | 549 | # is not returned. | 432 | # is not returned. |
964 | 550 | self.pub_2.status = PackagePublishingStatus.DELETED | 433 | sourcepackagename = self.factory.makeSourcePackageName(name="foo") |
965 | 551 | 434 | other_spn = self.factory.makeSourcePackageName(name="bar") | |
966 | 552 | pubs = self.naked_archive._collectLatestPublishedSources( | 435 | archive = self.factory.makeArchive() |
967 | 553 | self.archive, ["foo"]) | 436 | self.makePublishedSources(archive, |
968 | 437 | [PackagePublishingStatus.PUBLISHED, | ||
969 | 438 | PackagePublishingStatus.DELETED, | ||
970 | 439 | PackagePublishingStatus.PUBLISHED], | ||
971 | 440 | ["1.0", "1.1", "2.0"], | ||
972 | 441 | [sourcepackagename, sourcepackagename, other_spn]) | ||
973 | 442 | pubs = removeSecurityProxy(archive)._collectLatestPublishedSources( | ||
974 | 443 | archive, ["foo"]) | ||
975 | 554 | self.assertEqual(1, len(pubs)) | 444 | self.assertEqual(1, len(pubs)) |
977 | 555 | self.assertEqual('0.5.11~ppa1', pubs[0].source_package_version) | 445 | self.assertEqual('1.0', pubs[0].source_package_version) |
978 | 556 | 446 | ||
979 | 557 | 447 | ||
980 | 558 | class TestArchiveCanUpload(TestCaseWithFactory): | 448 | class TestArchiveCanUpload(TestCaseWithFactory): |
981 | 559 | """Test the various methods that verify whether uploads are allowed to | 449 | """Test the various methods that verify whether uploads are allowed to |
982 | 560 | happen.""" | 450 | happen.""" |
983 | 561 | 451 | ||
985 | 562 | layer = LaunchpadZopelessLayer | 452 | layer = DatabaseFunctionalLayer |
986 | 563 | 453 | ||
987 | 564 | def test_checkArchivePermission_by_PPA_owner(self): | 454 | def test_checkArchivePermission_by_PPA_owner(self): |
988 | 565 | # Uploading to a PPA should be allowed for a user that is the owner | 455 | # Uploading to a PPA should be allowed for a user that is the owner |
989 | @@ -572,50 +462,356 @@ | |||
990 | 572 | 462 | ||
991 | 573 | def test_checkArchivePermission_distro_archive(self): | 463 | def test_checkArchivePermission_distro_archive(self): |
992 | 574 | # Regular users can not upload to ubuntu | 464 | # Regular users can not upload to ubuntu |
996 | 575 | ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | 465 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) |
994 | 576 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY, | ||
995 | 577 | distribution=ubuntu) | ||
997 | 578 | main = getUtility(IComponentSet)["main"] | 466 | main = getUtility(IComponentSet)["main"] |
998 | 579 | # A regular user doesn't have access | 467 | # A regular user doesn't have access |
1000 | 580 | somebody = self.factory.makePerson(name="somebody") | 468 | somebody = self.factory.makePerson() |
1001 | 581 | self.assertEquals(False, | 469 | self.assertEquals(False, |
1002 | 582 | archive.checkArchivePermission(somebody, main)) | 470 | archive.checkArchivePermission(somebody, main)) |
1003 | 583 | # An ubuntu core developer does have access | 471 | # An ubuntu core developer does have access |
1006 | 584 | kamion = getUtility(IPersonSet).getByName('kamion') | 472 | coredev = self.factory.makePerson() |
1007 | 585 | self.assertEquals(True, archive.checkArchivePermission(kamion, main)) | 473 | with person_logged_in(archive.owner): |
1008 | 474 | archive.newComponentUploader(coredev, main.name) | ||
1009 | 475 | self.assertEquals(True, archive.checkArchivePermission(coredev, main)) | ||
1010 | 586 | 476 | ||
1011 | 587 | def test_checkArchivePermission_ppa(self): | 477 | def test_checkArchivePermission_ppa(self): |
1014 | 588 | ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | 478 | owner = self.factory.makePerson() |
1013 | 589 | owner = self.factory.makePerson(name="eigenaar") | ||
1015 | 590 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA, | 479 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA, |
1016 | 591 | distribution=ubuntu, | ||
1017 | 592 | owner=owner) | 480 | owner=owner) |
1019 | 593 | somebody = self.factory.makePerson(name="somebody") | 481 | somebody = self.factory.makePerson() |
1020 | 594 | # The owner has access | 482 | # The owner has access |
1021 | 595 | self.assertEquals(True, archive.checkArchivePermission(owner)) | 483 | self.assertEquals(True, archive.checkArchivePermission(owner)) |
1022 | 596 | # Somebody unrelated does not | 484 | # Somebody unrelated does not |
1023 | 597 | self.assertEquals(False, archive.checkArchivePermission(somebody)) | 485 | self.assertEquals(False, archive.checkArchivePermission(somebody)) |
1024 | 598 | 486 | ||
1025 | 487 | def makeArchiveAndActiveDistroSeries(self, purpose=None): | ||
1026 | 488 | if purpose is None: | ||
1027 | 489 | purpose = ArchivePurpose.PRIMARY | ||
1028 | 490 | archive = self.factory.makeArchive(purpose=purpose) | ||
1029 | 491 | distroseries = self.factory.makeDistroSeries( | ||
1030 | 492 | distribution=archive.distribution, | ||
1031 | 493 | status=SeriesStatus.DEVELOPMENT) | ||
1032 | 494 | return archive, distroseries | ||
1033 | 495 | |||
1034 | 496 | def makePersonWithComponentPermission(self, archive): | ||
1035 | 497 | person = self.factory.makePerson() | ||
1036 | 498 | component = self.factory.makeComponent() | ||
1037 | 499 | removeSecurityProxy(archive).newComponentUploader( | ||
1038 | 500 | person, component) | ||
1039 | 501 | return person, component | ||
1040 | 502 | |||
1041 | 503 | def checkUpload(self, archive, person, sourcepackagename, | ||
1042 | 504 | distroseries=None, component=None, | ||
1043 | 505 | pocket=None, strict_component=False): | ||
1044 | 506 | if distroseries is None: | ||
1045 | 507 | distroseries = self.factory.makeDistroSeries() | ||
1046 | 508 | if component is None: | ||
1047 | 509 | component = self.factory.makeComponent() | ||
1048 | 510 | if pocket is None: | ||
1049 | 511 | pocket = PackagePublishingPocket.RELEASE | ||
1050 | 512 | return archive.checkUpload( | ||
1051 | 513 | person, distroseries, sourcepackagename, component, pocket, | ||
1052 | 514 | strict_component=strict_component) | ||
1053 | 515 | |||
1054 | 516 | def assertCanUpload(self, archive, person, sourcepackagename, | ||
1055 | 517 | distroseries=None, component=None, | ||
1056 | 518 | pocket=None, strict_component=False): | ||
1057 | 519 | """Assert an upload to 'archive' will be accepted.""" | ||
1058 | 520 | self.assertIs( | ||
1059 | 521 | None, | ||
1060 | 522 | self.checkUpload( | ||
1061 | 523 | archive, person, sourcepackagename, | ||
1062 | 524 | distroseries=distroseries, component=component, | ||
1063 | 525 | pocket=pocket, strict_component=strict_component)) | ||
1064 | 526 | |||
1065 | 527 | def assertCannotUpload(self, reason, archive, person, sourcepackagename, | ||
1066 | 528 | distroseries=None, component=None, pocket=None, | ||
1067 | 529 | strict_component=False): | ||
1068 | 530 | """Assert that upload to 'archive' will be rejected. | ||
1069 | 531 | |||
1070 | 532 | :param reason: The expected reason for not being able to upload. A | ||
1071 | 533 | class. | ||
1072 | 534 | """ | ||
1073 | 535 | self.assertIsInstance( | ||
1074 | 536 | self.checkUpload( | ||
1075 | 537 | archive, person, sourcepackagename, | ||
1076 | 538 | distroseries=distroseries, component=component, | ||
1077 | 539 | pocket=pocket, strict_component=strict_component), | ||
1078 | 540 | reason | ||
1079 | 541 | ) | ||
1080 | 542 | |||
1081 | 599 | def test_checkUpload_partner_invalid_pocket(self): | 543 | def test_checkUpload_partner_invalid_pocket(self): |
1082 | 600 | # Partner archives only have release and proposed pockets | 544 | # Partner archives only have release and proposed pockets |
1090 | 601 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PARTNER) | 545 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( |
1091 | 602 | self.assertIsInstance(archive.checkUpload(self.factory.makePerson(), | 546 | purpose=ArchivePurpose.PARTNER) |
1092 | 603 | self.factory.makeDistroSeries(), | 547 | self.assertCannotUpload( |
1093 | 604 | self.factory.makeSourcePackageName(), | 548 | InvalidPocketForPartnerArchive, archive, |
1094 | 605 | self.factory.makeComponent(), | 549 | self.factory.makePerson(), self.factory.makeSourcePackageName(), |
1095 | 606 | PackagePublishingPocket.UPDATES), | 550 | pocket=PackagePublishingPocket.UPDATES, |
1096 | 607 | InvalidPocketForPartnerArchive) | 551 | distroseries=distroseries) |
1097 | 608 | 552 | ||
1098 | 609 | def test_checkUpload_ppa_invalid_pocket(self): | 553 | def test_checkUpload_ppa_invalid_pocket(self): |
1099 | 610 | # PPA archives only have release pockets | 554 | # PPA archives only have release pockets |
1108 | 611 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA) | 555 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( |
1109 | 612 | self.assertIsInstance(archive.checkUpload(self.factory.makePerson(), | 556 | purpose=ArchivePurpose.PPA) |
1110 | 613 | self.factory.makeDistroSeries(), | 557 | self.assertCannotUpload( |
1111 | 614 | self.factory.makeSourcePackageName(), | 558 | InvalidPocketForPPA, archive, |
1112 | 615 | self.factory.makeComponent(), | 559 | self.factory.makePerson(), self.factory.makeSourcePackageName(), |
1113 | 616 | PackagePublishingPocket.PROPOSED), | 560 | pocket=PackagePublishingPocket.PROPOSED, |
1114 | 617 | InvalidPocketForPPA) | 561 | distroseries=distroseries) |
1115 | 618 | # XXX: JRV 20100511: IArchive.canUploadSuiteSourcePackage needs tests | 562 | |
1116 | 563 | def test_checkUpload_invalid_pocket_for_series_state(self): | ||
1117 | 564 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1118 | 565 | purpose=ArchivePurpose.PRIMARY) | ||
1119 | 566 | self.assertCannotUpload( | ||
1120 | 567 | CannotUploadToPocket, archive, | ||
1121 | 568 | self.factory.makePerson(), self.factory.makeSourcePackageName(), | ||
1122 | 569 | pocket=PackagePublishingPocket.PROPOSED, | ||
1123 | 570 | distroseries=distroseries) | ||
1124 | 571 | |||
1125 | 572 | def test_checkUpload_disabled_archive(self): | ||
1126 | 573 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1127 | 574 | purpose=ArchivePurpose.PRIMARY) | ||
1128 | 575 | removeSecurityProxy(archive).disable() | ||
1129 | 576 | self.assertCannotUpload( | ||
1130 | 577 | ArchiveDisabled, archive, self.factory.makePerson(), | ||
1131 | 578 | self.factory.makeSourcePackageName(), | ||
1132 | 579 | distroseries=distroseries) | ||
1133 | 580 | |||
1134 | 581 | def test_checkUpload_ppa_owner(self): | ||
1135 | 582 | person = self.factory.makePerson() | ||
1136 | 583 | archive = self.factory.makeArchive( | ||
1137 | 584 | purpose=ArchivePurpose.PPA, owner=person) | ||
1138 | 585 | self.assertCanUpload( | ||
1139 | 586 | archive, person, self.factory.makeSourcePackageName()) | ||
1140 | 587 | |||
1141 | 588 | def test_checkUpload_ppa_with_permission(self): | ||
1142 | 589 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA) | ||
1143 | 590 | person = self.factory.makePerson() | ||
1144 | 591 | removeSecurityProxy(archive).newComponentUploader(person, "main") | ||
1145 | 592 | # component is ignored | ||
1146 | 593 | self.assertCanUpload( | ||
1147 | 594 | archive, person, self.factory.makeSourcePackageName(), | ||
1148 | 595 | component=self.factory.makeComponent(name="universe")) | ||
1149 | 596 | |||
1150 | 597 | def test_checkUpload_ppa_with_no_permission(self): | ||
1151 | 598 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA) | ||
1152 | 599 | person = self.factory.makePerson() | ||
1153 | 600 | self.assertCannotUpload( | ||
1154 | 601 | CannotUploadToPPA, archive, person, | ||
1155 | 602 | self.factory.makeSourcePackageName()) | ||
1156 | 603 | |||
1157 | 604 | def test_owner_can_upload_to_ppa_no_sourcepackage(self): | ||
1158 | 605 | # The owner can upload to PPAs even if the source package doesn't | ||
1159 | 606 | # exist yet. | ||
1160 | 607 | team = self.factory.makeTeam() | ||
1161 | 608 | archive = self.factory.makeArchive( | ||
1162 | 609 | purpose=ArchivePurpose.PPA, owner=team) | ||
1163 | 610 | person = self.factory.makePerson() | ||
1164 | 611 | removeSecurityProxy(team).addMember(person, team.teamowner) | ||
1165 | 612 | self.assertCanUpload(archive, person, None) | ||
1166 | 613 | |||
1167 | 614 | def test_can_upload_to_ppa_for_old_series(self): | ||
1168 | 615 | # You can upload whatever you want to a PPA, regardless of the upload | ||
1169 | 616 | # policy. | ||
1170 | 617 | person = self.factory.makePerson() | ||
1171 | 618 | archive = self.factory.makeArchive( | ||
1172 | 619 | purpose=ArchivePurpose.PPA, owner=person) | ||
1173 | 620 | spn = self.factory.makeSourcePackageName() | ||
1174 | 621 | distroseries = self.factory.makeDistroSeries( | ||
1175 | 622 | status=SeriesStatus.CURRENT) | ||
1176 | 623 | self.assertCanUpload( | ||
1177 | 624 | archive, person, spn, distroseries=distroseries) | ||
1178 | 625 | |||
1179 | 626 | def test_checkUpload_copy_archive_no_permission(self): | ||
1180 | 627 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1181 | 628 | purpose=ArchivePurpose.COPY) | ||
1182 | 629 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1183 | 630 | person = self.factory.makePerson() | ||
1184 | 631 | removeSecurityProxy(archive).newPackageUploader( | ||
1185 | 632 | person, sourcepackagename) | ||
1186 | 633 | self.assertCannotUpload( | ||
1187 | 634 | NoRightsForArchive, archive, person, sourcepackagename, | ||
1188 | 635 | distroseries=distroseries) | ||
1189 | 636 | |||
1190 | 637 | def test_checkUpload_package_permission(self): | ||
1191 | 638 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1192 | 639 | purpose=ArchivePurpose.PRIMARY) | ||
1193 | 640 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1194 | 641 | person = self.factory.makePerson() | ||
1195 | 642 | removeSecurityProxy(archive).newPackageUploader( | ||
1196 | 643 | person, sourcepackagename) | ||
1197 | 644 | self.assertCanUpload( | ||
1198 | 645 | archive, person, sourcepackagename, distroseries=distroseries) | ||
1199 | 646 | |||
1200 | 647 | def make_person_with_packageset_permission(self, archive, distroseries, | ||
1201 | 648 | packages=()): | ||
1202 | 649 | packageset = self.factory.makePackageset( | ||
1203 | 650 | distroseries=distroseries, packages=packages) | ||
1204 | 651 | person = self.factory.makePerson() | ||
1205 | 652 | techboard = getUtility(ILaunchpadCelebrities).ubuntu_techboard | ||
1206 | 653 | with person_logged_in(techboard): | ||
1207 | 654 | archive.newPackagesetUploader(person, packageset) | ||
1208 | 655 | return person, packageset | ||
1209 | 656 | |||
1210 | 657 | def test_checkUpload_packageset_permission(self): | ||
1211 | 658 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1212 | 659 | purpose=ArchivePurpose.PRIMARY) | ||
1213 | 660 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1214 | 661 | person, packageset = self.make_person_with_packageset_permission( | ||
1215 | 662 | archive, distroseries, packages=[sourcepackagename]) | ||
1216 | 663 | self.assertCanUpload( | ||
1217 | 664 | archive, person, sourcepackagename, distroseries=distroseries) | ||
1218 | 665 | |||
1219 | 666 | def test_checkUpload_packageset_wrong_distroseries(self): | ||
1220 | 667 | # A person with rights to upload to the package set in distro | ||
1221 | 668 | # series K may not upload with these same rights to a different | ||
1222 | 669 | # distro series L. | ||
1223 | 670 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1224 | 671 | purpose=ArchivePurpose.PRIMARY) | ||
1225 | 672 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1226 | 673 | person, packageset = self.make_person_with_packageset_permission( | ||
1227 | 674 | archive, distroseries, packages=[sourcepackagename]) | ||
1228 | 675 | other_distroseries = self.factory.makeDistroSeries() | ||
1229 | 676 | self.assertCannotUpload( | ||
1230 | 677 | InsufficientUploadRights, archive, person, sourcepackagename, | ||
1231 | 678 | distroseries=other_distroseries) | ||
1232 | 679 | |||
1233 | 680 | def test_checkUpload_component_permission(self): | ||
1234 | 681 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1235 | 682 | purpose=ArchivePurpose.PRIMARY) | ||
1236 | 683 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1237 | 684 | person, component = self.makePersonWithComponentPermission( | ||
1238 | 685 | archive) | ||
1239 | 686 | self.assertCanUpload( | ||
1240 | 687 | archive, person, sourcepackagename, distroseries=distroseries, | ||
1241 | 688 | component=component) | ||
1242 | 689 | |||
1243 | 690 | def test_checkUpload_no_permissions(self): | ||
1244 | 691 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1245 | 692 | purpose=ArchivePurpose.PRIMARY) | ||
1246 | 693 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1247 | 694 | person = self.factory.makePerson() | ||
1248 | 695 | self.assertCannotUpload( | ||
1249 | 696 | NoRightsForArchive, archive, person, sourcepackagename, | ||
1250 | 697 | distroseries=distroseries) | ||
1251 | 698 | |||
1252 | 699 | def test_checkUpload_insufficient_permissions(self): | ||
1253 | 700 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1254 | 701 | purpose=ArchivePurpose.PRIMARY) | ||
1255 | 702 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1256 | 703 | person, packageset = self.make_person_with_packageset_permission( | ||
1257 | 704 | archive, distroseries) | ||
1258 | 705 | self.assertCannotUpload( | ||
1259 | 706 | InsufficientUploadRights, archive, person, sourcepackagename, | ||
1260 | 707 | distroseries=distroseries) | ||
1261 | 708 | |||
1262 | 709 | def test_checkUpload_without_strict_component(self): | ||
1263 | 710 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1264 | 711 | purpose=ArchivePurpose.PRIMARY) | ||
1265 | 712 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1266 | 713 | person, component = self.makePersonWithComponentPermission( | ||
1267 | 714 | archive) | ||
1268 | 715 | other_component = self.factory.makeComponent() | ||
1269 | 716 | self.assertCanUpload( | ||
1270 | 717 | archive, person, sourcepackagename, distroseries=distroseries, | ||
1271 | 718 | component=other_component, strict_component=False) | ||
1272 | 719 | |||
1273 | 720 | def test_checkUpload_with_strict_component(self): | ||
1274 | 721 | archive, distroseries = self.makeArchiveAndActiveDistroSeries( | ||
1275 | 722 | purpose=ArchivePurpose.PRIMARY) | ||
1276 | 723 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1277 | 724 | person, component = self.makePersonWithComponentPermission( | ||
1278 | 725 | archive) | ||
1279 | 726 | other_component = self.factory.makeComponent() | ||
1280 | 727 | self.assertCannotUpload( | ||
1281 | 728 | NoRightsForComponent, archive, person, sourcepackagename, | ||
1282 | 729 | distroseries=distroseries, component=other_component, | ||
1283 | 730 | strict_component=True) | ||
1284 | 731 | |||
1285 | 732 | def test_checkUpload_component_rights_no_package(self): | ||
1286 | 733 | # A person allowed to upload to a particular component of an archive | ||
1287 | 734 | # can upload basically whatever they want to that component, even if | ||
1288 | 735 | # the package doesn't exist yet. | ||
1289 | 736 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
1290 | 737 | person, component = self.makePersonWithComponentPermission( | ||
1291 | 738 | archive) | ||
1292 | 739 | self.assertCanUpload(archive, person, None, component=component) | ||
1293 | 740 | |||
1294 | 741 | def makePackageToUpload(self, distroseries): | ||
1295 | 742 | sourcepackagename = self.factory.makeSourcePackageName() | ||
1296 | 743 | suitesourcepackage = self.factory.makeSuiteSourcePackage( | ||
1297 | 744 | pocket=PackagePublishingPocket.RELEASE, | ||
1298 | 745 | sourcepackagename=sourcepackagename, | ||
1299 | 746 | distroseries=distroseries) | ||
1300 | 747 | return suitesourcepackage | ||
1301 | 748 | |||
1302 | 749 | def test_canUploadSuiteSourcePackage_invalid_pocket(self): | ||
1303 | 750 | # Test that canUploadSuiteSourcePackage calls checkUpload for | ||
1304 | 751 | # the pocket checks. | ||
1305 | 752 | person = self.factory.makePerson() | ||
1306 | 753 | archive = self.factory.makeArchive( | ||
1307 | 754 | purpose=ArchivePurpose.PPA, owner=person) | ||
1308 | 755 | suitesourcepackage = self.factory.makeSuiteSourcePackage( | ||
1309 | 756 | pocket=PackagePublishingPocket.PROPOSED) | ||
1310 | 757 | self.assertEqual( | ||
1311 | 758 | False, | ||
1312 | 759 | archive.canUploadSuiteSourcePackage(person, suitesourcepackage)) | ||
1313 | 760 | |||
1314 | 761 | def test_canUploadSuiteSourcePackage_no_permission(self): | ||
1315 | 762 | # Test that canUploadSuiteSourcePackage calls verifyUpload for | ||
1316 | 763 | # the permission checks. | ||
1317 | 764 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA) | ||
1318 | 765 | suitesourcepackage = self.factory.makeSuiteSourcePackage( | ||
1319 | 766 | pocket=PackagePublishingPocket.RELEASE) | ||
1320 | 767 | person = self.factory.makePerson() | ||
1321 | 768 | self.assertEqual( | ||
1322 | 769 | False, | ||
1323 | 770 | archive.canUploadSuiteSourcePackage(person, suitesourcepackage)) | ||
1324 | 771 | |||
1325 | 772 | def test_canUploadSuiteSourcePackage_package_permission(self): | ||
1326 | 773 | # Test that a package permission is enough to upload a new | ||
1327 | 774 | # package. | ||
1328 | 775 | archive, distroseries = self.makeArchiveAndActiveDistroSeries() | ||
1329 | 776 | suitesourcepackage = self.makePackageToUpload(distroseries) | ||
1330 | 777 | person = self.factory.makePerson() | ||
1331 | 778 | removeSecurityProxy(archive).newPackageUploader( | ||
1332 | 779 | person, suitesourcepackage.sourcepackagename) | ||
1333 | 780 | self.assertEqual( | ||
1334 | 781 | True, | ||
1335 | 782 | archive.canUploadSuiteSourcePackage(person, suitesourcepackage)) | ||
1336 | 783 | |||
1337 | 784 | def test_canUploadSuiteSourcePackage_component_permission(self): | ||
1338 | 785 | # Test that component upload permission is enough to be | ||
1339 | 786 | # allowed to upload a new package. | ||
1340 | 787 | archive, distroseries = self.makeArchiveAndActiveDistroSeries() | ||
1341 | 788 | suitesourcepackage = self.makePackageToUpload(distroseries) | ||
1342 | 789 | person = self.factory.makePerson() | ||
1343 | 790 | removeSecurityProxy(archive).newComponentUploader(person, "universe") | ||
1344 | 791 | self.assertEqual( | ||
1345 | 792 | True, | ||
1346 | 793 | archive.canUploadSuiteSourcePackage(person, suitesourcepackage)) | ||
1347 | 794 | |||
1348 | 795 | def test_canUploadSuiteSourcePackage_strict_component(self): | ||
1349 | 796 | # Test that canUploadSuiteSourcePackage uses strict component | ||
1350 | 797 | # checking. | ||
1351 | 798 | archive, distroseries = self.makeArchiveAndActiveDistroSeries() | ||
1352 | 799 | suitesourcepackage = self.makePackageToUpload(distroseries) | ||
1353 | 800 | main_component = self.factory.makeComponent(name="main") | ||
1354 | 801 | self.factory.makeSourcePackagePublishingHistory( | ||
1355 | 802 | archive=archive, distroseries=distroseries, | ||
1356 | 803 | sourcepackagename=suitesourcepackage.sourcepackagename, | ||
1357 | 804 | status=PackagePublishingStatus.PUBLISHED, | ||
1358 | 805 | pocket=PackagePublishingPocket.RELEASE, | ||
1359 | 806 | component=main_component) | ||
1360 | 807 | person = self.factory.makePerson() | ||
1361 | 808 | removeSecurityProxy(archive).newComponentUploader(person, "universe") | ||
1362 | 809 | # This time the user can't upload as there has been a | ||
1363 | 810 | # publication and they don't have permission for the component | ||
1364 | 811 | # the package is published in. | ||
1365 | 812 | self.assertEqual( | ||
1366 | 813 | False, | ||
1367 | 814 | archive.canUploadSuiteSourcePackage(person, suitesourcepackage)) | ||
1368 | 619 | 815 | ||
1369 | 620 | 816 | ||
1370 | 621 | class TestUpdatePackageDownloadCount(TestCaseWithFactory): | 817 | class TestUpdatePackageDownloadCount(TestCaseWithFactory): |
1371 | @@ -1216,3 +1412,29 @@ | |||
1372 | 1216 | component=getUtility(IComponentSet)['universe']) | 1412 | component=getUtility(IComponentSet)['universe']) |
1373 | 1217 | self.assertDep('i386', 'foo-main', [main_bins[0]]) | 1413 | self.assertDep('i386', 'foo-main', [main_bins[0]]) |
1374 | 1218 | self.assertDep('i386', 'foo-universe', [universe_bins[0]]) | 1414 | self.assertDep('i386', 'foo-universe', [universe_bins[0]]) |
1375 | 1415 | |||
1376 | 1416 | |||
1377 | 1417 | class TestComponents(TestCaseWithFactory): | ||
1378 | 1418 | |||
1379 | 1419 | layer = DatabaseFunctionalLayer | ||
1380 | 1420 | |||
1381 | 1421 | def test_no_components_for_arbitrary_person(self): | ||
1382 | 1422 | # By default, a person cannot upload to any component of an archive. | ||
1383 | 1423 | archive = self.factory.makeArchive() | ||
1384 | 1424 | person = self.factory.makePerson() | ||
1385 | 1425 | self.assertEqual(set(), | ||
1386 | 1426 | set(archive.getComponentsForUploader(person))) | ||
1387 | 1427 | |||
1388 | 1428 | def test_components_for_person_with_permissions(self): | ||
1389 | 1429 | # If a person has been explicitly granted upload permissions to a | ||
1390 | 1430 | # particular component, then those components are included in | ||
1391 | 1431 | # IArchive.getComponentsForUploader. | ||
1392 | 1432 | archive = self.factory.makeArchive() | ||
1393 | 1433 | component = self.factory.makeComponent() | ||
1394 | 1434 | person = self.factory.makePerson() | ||
1395 | 1435 | # Only admins or techboard members can add permissions normally. That | ||
1396 | 1436 | # restriction isn't relevant to this test. | ||
1397 | 1437 | ap_set = removeSecurityProxy(getUtility(IArchivePermissionSet)) | ||
1398 | 1438 | ap = ap_set.newComponentUploader(archive, person, component) | ||
1399 | 1439 | self.assertEqual(set([ap]), | ||
1400 | 1440 | set(archive.getComponentsForUploader(person))) | ||
1401 | 1219 | 1441 | ||
1402 | === modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py' | |||
1403 | --- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-13 19:36:56 +0000 | |||
1404 | +++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-08-04 22:02:48 +0000 | |||
1405 | @@ -10,7 +10,7 @@ | |||
1406 | 10 | 10 | ||
1407 | 11 | from canonical.launchpad.webapp.interfaces import ( | 11 | from canonical.launchpad.webapp.interfaces import ( |
1408 | 12 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) | 12 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) |
1410 | 13 | from canonical.testing import LaunchpadZopelessLayer | 13 | from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer |
1411 | 14 | 14 | ||
1412 | 15 | from lp.buildmaster.interfaces.buildbase import BuildStatus | 15 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
1413 | 16 | from lp.buildmaster.interfaces.builder import IBuilderSet | 16 | from lp.buildmaster.interfaces.builder import IBuilderSet |
1414 | @@ -244,3 +244,22 @@ | |||
1415 | 244 | build_package_job.jobStarted() | 244 | build_package_job.jobStarted() |
1416 | 245 | self.failUnlessEqual( | 245 | self.failUnlessEqual( |
1417 | 246 | BuildStatus.BUILDING, build_package_job.build.status) | 246 | BuildStatus.BUILDING, build_package_job.build.status) |
1418 | 247 | |||
1419 | 248 | |||
1420 | 249 | class TestBuildPackageJobScore(TestCaseWithFactory): | ||
1421 | 250 | |||
1422 | 251 | layer = DatabaseFunctionalLayer | ||
1423 | 252 | |||
1424 | 253 | def test_score_unusual_component(self): | ||
1425 | 254 | unusual_component = self.factory.makeComponent(name="unusual") | ||
1426 | 255 | source_package_release = self.factory.makeSourcePackageRelease() | ||
1427 | 256 | self.factory.makeSourcePackagePublishingHistory( | ||
1428 | 257 | sourcepackagerelease=source_package_release, | ||
1429 | 258 | component=unusual_component, | ||
1430 | 259 | archive=source_package_release.upload_archive, | ||
1431 | 260 | distroseries=source_package_release.upload_distroseries) | ||
1432 | 261 | build = self.factory.makeBinaryPackageBuild( | ||
1433 | 262 | source_package_release=source_package_release) | ||
1434 | 263 | job = build.buildqueue_record.specific_job | ||
1435 | 264 | # For now just test that it doesn't raise an Exception | ||
1436 | 265 | job.score() | ||
1437 | 247 | 266 | ||
1438 | === modified file 'lib/lp/testing/factory.py' | |||
1439 | --- lib/lp/testing/factory.py 2010-08-04 00:41:14 +0000 | |||
1440 | +++ lib/lp/testing/factory.py 2010-08-04 22:02:48 +0000 | |||
1441 | @@ -2363,7 +2363,8 @@ | |||
1442 | 2363 | libraryfile=library_file, filetype=filetype)) | 2363 | libraryfile=library_file, filetype=filetype)) |
1443 | 2364 | 2364 | ||
1444 | 2365 | def makeBinaryPackageBuild(self, source_package_release=None, | 2365 | def makeBinaryPackageBuild(self, source_package_release=None, |
1446 | 2366 | distroarchseries=None, archive=None, builder=None): | 2366 | distroarchseries=None, archive=None, builder=None, |
1447 | 2367 | status=None): | ||
1448 | 2367 | """Create a BinaryPackageBuild. | 2368 | """Create a BinaryPackageBuild. |
1449 | 2368 | 2369 | ||
1450 | 2369 | If archive is not supplied, the source_package_release is used | 2370 | If archive is not supplied, the source_package_release is used |
1451 | @@ -2373,6 +2374,7 @@ | |||
1452 | 2373 | :param distroarchseries: The DistroArchSeries to use. | 2374 | :param distroarchseries: The DistroArchSeries to use. |
1453 | 2374 | :param archive: The Archive to use. | 2375 | :param archive: The Archive to use. |
1454 | 2375 | :param builder: An optional builder to assign. | 2376 | :param builder: An optional builder to assign. |
1455 | 2377 | :param status: The BuildStatus for the build. | ||
1456 | 2376 | """ | 2378 | """ |
1457 | 2377 | if archive is None: | 2379 | if archive is None: |
1458 | 2378 | if source_package_release is None: | 2380 | if source_package_release is None: |
1459 | @@ -2383,16 +2385,21 @@ | |||
1460 | 2383 | multiverse = self.makeComponent(name='multiverse') | 2385 | multiverse = self.makeComponent(name='multiverse') |
1461 | 2384 | source_package_release = self.makeSourcePackageRelease( | 2386 | source_package_release = self.makeSourcePackageRelease( |
1462 | 2385 | archive, component=multiverse) | 2387 | archive, component=multiverse) |
1463 | 2388 | self.makeSourcePackagePublishingHistory( | ||
1464 | 2389 | distroseries=source_package_release.upload_distroseries, | ||
1465 | 2390 | archive=archive, sourcepackagerelease=source_package_release) | ||
1466 | 2386 | processor = self.makeProcessor() | 2391 | processor = self.makeProcessor() |
1467 | 2387 | if distroarchseries is None: | 2392 | if distroarchseries is None: |
1468 | 2388 | distroarchseries = self.makeDistroArchSeries( | 2393 | distroarchseries = self.makeDistroArchSeries( |
1469 | 2389 | distroseries=source_package_release.upload_distroseries, | 2394 | distroseries=source_package_release.upload_distroseries, |
1470 | 2390 | processorfamily=processor.family) | 2395 | processorfamily=processor.family) |
1471 | 2396 | if status is None: | ||
1472 | 2397 | status = BuildStatus.NEEDSBUILD | ||
1473 | 2391 | binary_package_build = getUtility(IBinaryPackageBuildSet).new( | 2398 | binary_package_build = getUtility(IBinaryPackageBuildSet).new( |
1474 | 2392 | source_package_release=source_package_release, | 2399 | source_package_release=source_package_release, |
1475 | 2393 | processor=processor, | 2400 | processor=processor, |
1476 | 2394 | distro_arch_series=distroarchseries, | 2401 | distro_arch_series=distroarchseries, |
1478 | 2395 | status=BuildStatus.NEEDSBUILD, | 2402 | status=status, |
1479 | 2396 | archive=archive, | 2403 | archive=archive, |
1480 | 2397 | pocket=PackagePublishingPocket.RELEASE, | 2404 | pocket=PackagePublishingPocket.RELEASE, |
1481 | 2398 | date_created=self.getUniqueDate()) | 2405 | date_created=self.getUniqueDate()) |
1482 | @@ -2611,7 +2618,8 @@ | |||
1483 | 2611 | isinstance(sourcepackagename, basestring)): | 2618 | isinstance(sourcepackagename, basestring)): |
1484 | 2612 | sourcepackagename = self.getOrMakeSourcePackageName( | 2619 | sourcepackagename = self.getOrMakeSourcePackageName( |
1485 | 2613 | sourcepackagename) | 2620 | sourcepackagename) |
1487 | 2614 | return SuiteSourcePackage(distroseries, pocket, sourcepackagename) | 2621 | return ProxyFactory( |
1488 | 2622 | SuiteSourcePackage(distroseries, pocket, sourcepackagename)) | ||
1489 | 2615 | 2623 | ||
1490 | 2616 | def makeDistributionSourcePackage(self, sourcepackagename=None, | 2624 | def makeDistributionSourcePackage(self, sourcepackagename=None, |
1491 | 2617 | distribution=None): | 2625 | distribution=None): |
1492 | 2618 | 2626 | ||
1493 | === modified file 'lib/lp/testing/tests/test_factory.py' | |||
1494 | --- lib/lp/testing/tests/test_factory.py 2010-08-02 19:52:59 +0000 | |||
1495 | +++ lib/lp/testing/tests/test_factory.py 2010-08-04 22:02:48 +0000 | |||
1496 | @@ -15,9 +15,12 @@ | |||
1497 | 15 | from canonical.launchpad.webapp.interfaces import ILaunchBag | 15 | from canonical.launchpad.webapp.interfaces import ILaunchBag |
1498 | 16 | from canonical.testing.layers import ( | 16 | from canonical.testing.layers import ( |
1499 | 17 | DatabaseFunctionalLayer, LaunchpadZopelessLayer) | 17 | DatabaseFunctionalLayer, LaunchpadZopelessLayer) |
1500 | 18 | from lp.buildmaster.interfaces.buildbase import BuildStatus | ||
1501 | 18 | from lp.code.enums import CodeImportReviewStatus | 19 | from lp.code.enums import CodeImportReviewStatus |
1502 | 19 | from lp.registry.interfaces.sourcepackage import SourcePackageFileType | 20 | from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
1503 | 21 | from lp.registry.interfaces.suitesourcepackage import ISuiteSourcePackage | ||
1504 | 20 | from lp.services.worlddata.interfaces.language import ILanguage | 22 | from lp.services.worlddata.interfaces.language import ILanguage |
1505 | 23 | from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuild | ||
1506 | 21 | from lp.soyuz.interfaces.binarypackagerelease import ( | 24 | from lp.soyuz.interfaces.binarypackagerelease import ( |
1507 | 22 | BinaryPackageFileType, IBinaryPackageRelease) | 25 | BinaryPackageFileType, IBinaryPackageRelease) |
1508 | 23 | from lp.soyuz.interfaces.files import ( | 26 | from lp.soyuz.interfaces.files import ( |
1509 | @@ -42,6 +45,32 @@ | |||
1510 | 42 | self.assertIsNot(None, person) | 45 | self.assertIsNot(None, person) |
1511 | 43 | self.assertEqual(person, current_person) | 46 | self.assertEqual(person, current_person) |
1512 | 44 | 47 | ||
1513 | 48 | # makeBinaryPackageBuild | ||
1514 | 49 | def test_makeBinaryPackageBuild_returns_IBinaryPackageBuild(self): | ||
1515 | 50 | bpb = self.factory.makeBinaryPackageBuild() | ||
1516 | 51 | self.assertThat( | ||
1517 | 52 | removeSecurityProxy(bpb), Provides(IBinaryPackageBuild)) | ||
1518 | 53 | |||
1519 | 54 | def test_makeBinaryPackageBuild_returns_proxy(self): | ||
1520 | 55 | bpb = self.factory.makeBinaryPackageBuild() | ||
1521 | 56 | self.assertThat(bpb, IsProxied()) | ||
1522 | 57 | |||
1523 | 58 | def test_makeBinaryPackageBuild_created_SPR_is_published(self): | ||
1524 | 59 | # It is expected that every build references an SPR that is | ||
1525 | 60 | # published in the target archive. Check that a created | ||
1526 | 61 | # SPR is also published. | ||
1527 | 62 | bpb = self.factory.makeBinaryPackageBuild() | ||
1528 | 63 | self.assertIn( | ||
1529 | 64 | bpb.archive, bpb.source_package_release.published_archives) | ||
1530 | 65 | |||
1531 | 66 | def test_makeBinaryPackageBuild_uses_status(self): | ||
1532 | 67 | bpb = self.factory.makeBinaryPackageBuild( | ||
1533 | 68 | status=BuildStatus.NEEDSBUILD) | ||
1534 | 69 | self.assertEqual(BuildStatus.NEEDSBUILD, bpb.status) | ||
1535 | 70 | bpb = self.factory.makeBinaryPackageBuild( | ||
1536 | 71 | status=BuildStatus.FULLYBUILT) | ||
1537 | 72 | self.assertEqual(BuildStatus.FULLYBUILT, bpb.status) | ||
1538 | 73 | |||
1539 | 45 | # makeBinaryPackagePublishingHistory | 74 | # makeBinaryPackagePublishingHistory |
1540 | 46 | def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self): | 75 | def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self): |
1541 | 47 | bpph = self.factory.makeBinaryPackagePublishingHistory() | 76 | bpph = self.factory.makeBinaryPackagePublishingHistory() |
1542 | @@ -170,6 +199,11 @@ | |||
1543 | 170 | scheduleddeletiondate=scheduleddeletiondate) | 199 | scheduleddeletiondate=scheduleddeletiondate) |
1544 | 171 | self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate) | 200 | self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate) |
1545 | 172 | 201 | ||
1546 | 202 | # makeSuiteSourcePackage | ||
1547 | 203 | def test_makeSuiteSourcePackage_returns_ISuiteSourcePackage(self): | ||
1548 | 204 | ssp = self.factory.makeSuiteSourcePackage() | ||
1549 | 205 | self.assertThat(ssp, ProvidesAndIsProxied(ISuiteSourcePackage)) | ||
1550 | 206 | |||
1551 | 173 | 207 | ||
1552 | 174 | class TestFactoryWithLibrarian(TestCaseWithFactory): | 208 | class TestFactoryWithLibrarian(TestCaseWithFactory): |
1553 | 175 | 209 |
On Sun, Aug 1, 2010 at 9:55 PM, James Westby <email address hidden> wrote: reviewers) her.setup_ breezy_ autotest( )).
> James Westby has proposed merging lp:~james-w/launchpad/no-more-sampledata-1 into lp:launchpad/devel with lp:~james-w/launchpad/no-more-sampledata-0 as a prerequisite.
>
> Requested reviews:
> Launchpad code reviewers (launchpad-
>
>
> Hi,
>
> Here's some more cleanup of test_archive to remove reliance on
> sampledata (or at least SoyuzTestPublis
>
> There are a couple of fixes here too, one for bug 612351, and one
> where the build scoring code assumed it new the complete list of
> components, but they are stored in the db, not in an enum or similar.
>
Sweet, thanks.
I've got a few trivial suggestions, and would like to see some tests
for the changes made to the factory. Other than that, looks good.
I look forward to hearing back from you.
jml
> === modified file 'lib/lp/ soyuz/model/ buildpackagejob .py' soyuz/model/ buildpackagejob .py 2010-06-10 12:18:10 +0000 soyuz/model/ buildpackagejob .py 2010-08-01 20:54:49 +0000 name[ current_ component. name] current_ component. name in score_component name: name[ current_ component. name]
> --- lib/lp/
> +++ lib/lp/
> @@ -115,9 +115,10 @@
> score += score_pocket
>
> # Calculates the component-related part of the score.
> - score_component = score_component
> - self.build.
> - score += score_component
> + if self.build.
> + score_component = score_component
> + self.build.
> + score += score_component
>
FWIW, this can also be written as: name.get( self.build. current_ component. name, 0)
score_component =
score_component
score += score_component
Which I *think* might be a little faster. Whether it's clearer or not
is subjective. Your call as to whether you make the change.
> # Calculates the build queue time component of the score. now(pytz. timezone( 'UTC')) soyuz/tests/ test_archive. py' soyuz/tests/ test_archive. py 2010-08-01 20:54:47 +0000 soyuz/tests/ test_archive. py 2010-08-01 20:54:49 +0000 database. sqlbase import sqlvalues launchpad. interfaces. launchpad import ILaunchpadCeleb rities launchpad. webapp. interfaces import ( nalLayer, LaunchpadZopele ssLayer interfaces. buildbase import BuildStatus interfaces. distribution import IDistributionSet interfaces. person import IPersonSet interfaces. pocket import PackagePubli...
> right_now = datetime.
>
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -1,9 +1,11 @@
> # Copyright 2009-2010 Canonical Ltd. This software is licensed under the
> # GNU Affero General Public License version 3 (see the file LICENSE).
>
> +from __future__ import with_statement
> +
> """Test Archive features."""
>
> -from datetime import date, timedelta
> +from datetime import date
>
> import transaction
>
> @@ -12,18 +14,21 @@
> from zope.security.proxy import removeSecurityProxy
>
> from canonical.
> +from canonical.
> from canonical.
> IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
> from canonical.testing import DatabaseFunctio
>
> from lp.buildmaster.
> -from lp.registry.
> -from lp.registry.
> from lp.registry.