Merge lp:~james-w/launchpad/no-more-sampledata-1 into lp:launchpad

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
Reviewer Review Type Date Requested Status
Jonathan Lange (community) Approve
Review via email: mp+31493@code.launchpad.net

Description of the change

Hi,

Here's some more cleanup of test_archive to remove reliance on
sampledata (or at least SoyuzTestPublisher.setup_breezy_autotest()).

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 :
Download full text (46.1 KiB)

On Sun, Aug 1, 2010 at 9:55 PM, James Westby <email address hidden> wrote:
> 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-reviewers)
>
>
> Hi,
>
> Here's some more cleanup of test_archive to remove reliance on
> sampledata (or at least SoyuzTestPublisher.setup_breezy_autotest()).
>
> 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'
> --- lib/lp/soyuz/model/buildpackagejob.py       2010-06-10 12:18:10 +0000
> +++ lib/lp/soyuz/model/buildpackagejob.py       2010-08-01 20:54:49 +0000
> @@ -115,9 +115,10 @@
>             score += score_pocket
>
>             # Calculates the component-related part of the score.
> -            score_component = score_componentname[
> -                self.build.current_component.name]
> -            score += score_component
> +            if self.build.current_component.name in score_componentname:
> +                score_component = score_componentname[
> +                    self.build.current_component.name]
> +                score += score_component
>

FWIW, this can also be written as:
  score_component =
score_componentname.get(self.build.current_component.name, 0)
  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.
>             right_now = datetime.now(pytz.timezone('UTC'))
>
> === modified file 'lib/lp/soyuz/tests/test_archive.py'
> --- lib/lp/soyuz/tests/test_archive.py  2010-08-01 20:54:47 +0000
> +++ lib/lp/soyuz/tests/test_archive.py  2010-08-01 20:54:49 +0000
> @@ -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.database.sqlbase import sqlvalues
> +from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
>  from canonical.launchpad.webapp.interfaces import (
>     IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
>  from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer
>
>  from lp.buildmaster.interfaces.buildbase import BuildStatus
> -from lp.registry.interfaces.distribution import IDistributionSet
> -from lp.registry.interfaces.person import IPersonSet
>  from lp.registry.interfaces.pocket import PackagePubli...

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

Revision history for this message
Jonathan Lange (jml) wrote :

Perfect. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/archiveuploader/tests/nascentupload-packageset.txt'
--- lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-05-11 14:09:44 +0000
+++ lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-08-04 22:02:48 +0000
@@ -39,8 +39,8 @@
39 >>> bar_failed.is_rejected39 >>> bar_failed.is_rejected
40 True40 True
41 >>> print bar_failed.rejection_message41 >>> print bar_failed.rejection_message
42 The signer of this package is lacking the upload rights for the source42 The signer of this package has no upload rights to this distribution's
43 package, component or package set in question.43 primary archive. Did you mean to upload to a PPA?
4444
4545
46We can grant selective, package set based upload permissions to the user46We can grant selective, package set based upload permissions to the user
4747
=== modified file 'lib/lp/archiveuploader/tests/nascentupload.txt'
--- lib/lp/archiveuploader/tests/nascentupload.txt 2010-07-24 09:12:37 +0000
+++ lib/lp/archiveuploader/tests/nascentupload.txt 2010-08-04 22:02:48 +0000
@@ -879,8 +879,8 @@
879 >>> bar_failed.is_rejected879 >>> bar_failed.is_rejected
880 True880 True
881 >>> print bar_failed.rejection_message881 >>> print bar_failed.rejection_message
882 The signer of this package is lacking the upload rights for the source882 The signer of this package has no upload rights to this distribution's
883 package, component or package set in question.883 primary archive. Did you mean to upload to a PPA?
884884
885Even in a rejected upload using 'insecure' policy, the DSC signing key885Even in a rejected upload using 'insecure' policy, the DSC signing key
886and the changesfile sigining key are stored in NascentUpload instance886and the changesfile sigining key are stored in NascentUpload instance
887887
=== removed file 'lib/lp/archiveuploader/tests/test_permission.py'
--- lib/lp/archiveuploader/tests/test_permission.py 2010-07-18 00:26:33 +0000
+++ lib/lp/archiveuploader/tests/test_permission.py 1970-01-01 00:00:00 +0000
@@ -1,242 +0,0 @@
1# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Tests for the permissions for uploading to an archive."""
5
6__metaclass__ = type
7
8from zope.component import getUtility
9from zope.security.proxy import removeSecurityProxy
10
11from canonical.testing import DatabaseFunctionalLayer
12
13from lp.registry.interfaces.series import SeriesStatus
14from lp.registry.interfaces.pocket import PackagePublishingPocket
15from lp.soyuz.interfaces.archive import ArchivePurpose
16from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
17from lp.testing import TestCaseWithFactory
18
19
20class TestComponents(TestCaseWithFactory):
21
22 layer = DatabaseFunctionalLayer
23
24 def test_no_components_for_arbitrary_person(self):
25 # By default, a person cannot upload to any component of an archive.
26 archive = self.factory.makeArchive()
27 person = self.factory.makePerson()
28 self.assertEqual(set(),
29 set(archive.getComponentsForUploader(person)))
30
31 def test_components_for_person_with_permissions(self):
32 # If a person has been explicitly granted upload permissions to a
33 # particular component, then those components are included in
34 # IArchive.getComponentsForUploader.
35 archive = self.factory.makeArchive()
36 component = self.factory.makeComponent()
37 person = self.factory.makePerson()
38 # Only admins or techboard members can add permissions normally. That
39 # restriction isn't relevant to this test.
40 ap_set = removeSecurityProxy(getUtility(IArchivePermissionSet))
41 ap = ap_set.newComponentUploader(archive, person, component)
42 self.assertEqual(set([ap]),
43 set(archive.getComponentsForUploader(person)))
44
45
46class TestPermission(TestCaseWithFactory):
47
48 layer = DatabaseFunctionalLayer
49
50 def setUp(self):
51 TestCaseWithFactory.setUp(self)
52 permission_set = getUtility(IArchivePermissionSet)
53 # Only admins or techboard members can add permissions normally. That
54 # restriction isn't relevant to these tests.
55 self.permission_set = removeSecurityProxy(permission_set)
56
57 def assertCanUpload(self, person, spn, archive, component,
58 strict_component=True, distroseries=None):
59 """Assert that 'person' can upload 'spn' to 'archive'."""
60 # For now, just check that doesn't raise an exception.
61 if distroseries is None:
62 distroseries = self.factory.makeDistroSeries(
63 distribution=archive.distribution)
64 pocket = PackagePublishingPocket.RELEASE
65 self.assertIs(
66 None,
67 archive.checkUpload(
68 person, distroseries, spn, component, pocket,
69 strict_component))
70
71 def assertCannotUpload(self, reason, person, spn, archive, component,
72 distroseries=None):
73 """Assert that 'person' cannot upload to the archive.
74
75 :param reason: The expected reason for not being able to upload. A
76 string.
77 :param person: The person trying to upload.
78 :param spn: The `ISourcePackageName` being uploaded to. None if the
79 package does not yet exist.
80 :param archive: The `IArchive` being uploaded to.
81 :param component: The IComponent to which the package belongs.
82 :param distroseries: The upload's target distro series.
83 """
84 if distroseries is None:
85 distroseries = self.factory.makeDistroSeries()
86 pocket = PackagePublishingPocket.RELEASE
87 exception = archive.checkUpload(
88 person, distroseries, spn, component, pocket)
89 self.assertEqual(reason, str(exception))
90
91 def test_random_person_cannot_upload_to_ppa(self):
92 # Arbitrary people cannot upload to a PPA.
93 person = self.factory.makePerson()
94 ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
95 spn = self.factory.makeSourcePackageName()
96 self.assertCannotUpload(
97 'Signer has no upload rights to this PPA.',
98 person, spn, ppa, None)
99
100 def test_owner_can_upload_to_ppa(self):
101 # If the archive is a PPA, and you own it, then you can upload pretty
102 # much anything to it.
103 team = self.factory.makeTeam()
104 ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA, owner=team)
105 person = self.factory.makePerson()
106 removeSecurityProxy(team).addMember(person, team.teamowner)
107 spn = self.factory.makeSourcePackageName()
108 self.assertCanUpload(person, spn, ppa, None)
109
110 def test_owner_can_upload_to_ppa_no_sourcepackage(self):
111 # The owner can upload to PPAs even if the source package doesn't
112 # exist yet.
113 team = self.factory.makeTeam()
114 ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA, owner=team)
115 person = self.factory.makePerson()
116 removeSecurityProxy(team).addMember(person, team.teamowner)
117 self.assertCanUpload(person, None, ppa, None)
118
119 def test_can_upload_to_ppa_for_old_series(self):
120 # You can upload whatever you want to a PPA, regardless of the upload
121 # policy.
122 person = self.factory.makePerson()
123 ppa = self.factory.makeArchive(
124 purpose=ArchivePurpose.PPA, owner=person)
125 spn = self.factory.makeSourcePackageName()
126 distroseries = self.factory.makeDistroSeries(
127 status=SeriesStatus.CURRENT)
128 self.assertCanUpload(
129 person, spn, ppa, None, distroseries=distroseries)
130
131 def test_arbitrary_person_cannot_upload_to_primary_archive(self):
132 # By default, you can't upload to the primary archive.
133 person = self.factory.makePerson()
134 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
135 spn = self.factory.makeSourcePackageName()
136 self.assertCannotUpload(
137 ("The signer of this package is lacking the upload rights for "
138 "the source package, component or package set in question."),
139 person, spn, archive, None)
140
141 def test_package_specific_rights(self):
142 # A person can be granted specific rights for uploading a package,
143 # based only on the source package name. If they have these rights,
144 # they can upload to the package.
145 person = self.factory.makePerson()
146 spn = self.factory.makeSourcePackageName()
147 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
148 # We can't use a PPA, because they have a different logic for
149 # permissions. We can't create an arbitrary archive, because there's
150 # only one primary archive per distro.
151 self.permission_set.newPackageUploader(archive, person, spn)
152 self.assertCanUpload(person, spn, archive, None)
153
154 def test_packageset_specific_rights(self):
155 # A person with rights to upload to the package set can upload the
156 # package set to the archive.
157 person = self.factory.makePerson()
158 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
159 spn = self.factory.makeSourcePackageName()
160 distroseries = self.factory.makeDistroSeries()
161 package_set = self.factory.makePackageset(
162 packages=[spn], distroseries=distroseries)
163 self.permission_set.newPackagesetUploader(
164 archive, person, package_set)
165 self.assertCanUpload(
166 person, spn, archive, None, distroseries=distroseries)
167
168 def test_packageset_wrong_distroseries(self):
169 # A person with rights to upload to the package set in distro
170 # series K may not upload with these same rights to a different
171 # distro series L.
172 distroseries_K = self.factory.makeDistroRelease()
173 distroseries_L = self.factory.makeDistroRelease()
174 person = self.factory.makePerson()
175 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
176 spn = self.factory.makeSourcePackageName()
177 package_set = self.factory.makePackageset(
178 packages=[spn], distroseries=distroseries_K)
179 self.permission_set.newPackagesetUploader(
180 archive, person, package_set)
181 self.assertCanUpload(
182 person, spn, archive, None, distroseries=distroseries_K)
183 self.assertCannotUpload(
184 ("The signer of this package is lacking the upload rights for "
185 "the source package, component or package set in question."),
186 person, spn, archive, None, distroseries=distroseries_L)
187
188 def test_component_rights(self):
189 # A person allowed to upload to a particular component of an archive
190 # can upload basically whatever they want to that component.
191 person = self.factory.makePerson()
192 spn = self.factory.makeSourcePackageName()
193 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
194 component = self.factory.makeComponent()
195 self.permission_set.newComponentUploader(archive, person, component)
196 self.assertCanUpload(person, spn, archive, component)
197
198 def test_incorrect_component_rights(self):
199 # Even if a person has upload rights for a particular component in an
200 # archive, it doesn't mean they have upload rights for everything in
201 # that archive.
202 person = self.factory.makePerson()
203 spn = self.factory.makeSourcePackageName()
204 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
205 permitted_component = self.factory.makeComponent()
206 forbidden_component = self.factory.makeComponent()
207 self.permission_set.newComponentUploader(
208 archive, person, permitted_component)
209 self.assertCannotUpload(
210 u"Signer is not permitted to upload to the component '%s'." % (
211 forbidden_component.name),
212 person, spn, archive, forbidden_component)
213
214 def test_component_rights_no_package(self):
215 # A person allowed to upload to a particular component of an archive
216 # can upload basically whatever they want to that component, even if
217 # the package doesn't exist yet.
218 person = self.factory.makePerson()
219 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
220 component = self.factory.makeComponent()
221 self.permission_set.newComponentUploader(archive, person, component)
222 self.assertCanUpload(person, None, archive, component)
223
224 def test_non_strict_component_rights(self):
225 # If we aren't testing strict component access, then we only need to
226 # have access to an arbitrary component.
227 person = self.factory.makePerson()
228 spn = self.factory.makeSourcePackageName()
229 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
230 component_a = self.factory.makeComponent()
231 component_b = self.factory.makeComponent()
232 self.permission_set.newComponentUploader(archive, person, component_b)
233 self.assertCanUpload(
234 person, spn, archive, component_a, strict_component=False)
235
236 def test_cannot_upload_to_disabled_archive(self):
237 spn = self.factory.makeSourcePackageName()
238 archive = self.factory.makeArchive()
239 removeSecurityProxy(archive).disable()
240 component = self.factory.makeComponent()
241 self.assertCannotUpload(u"%s is disabled." % (archive.displayname),
242 archive.owner, spn, archive, component)
2430
=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-06-14 08:11:33 +0000
+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-08-04 22:02:48 +0000
@@ -106,7 +106,7 @@
106 stored.106 stored.
107 """107 """
108108
109 def getLogFromSlave():109 def getLogFromSlave(build):
110 """Get last buildlog from slave. """110 """Get last buildlog from slave. """
111111
112 def getUploadLogContent(root, leaf):112 def getUploadLogContent(root, leaf):
@@ -120,7 +120,7 @@
120 def estimateDuration():120 def estimateDuration():
121 """Estimate the build duration."""121 """Estimate the build duration."""
122122
123 def storeBuildInfo(librarian, slave_status):123 def storeBuildInfo(build, librarian, slave_status):
124 """Store available information for the build job.124 """Store available information for the build job.
125125
126 Derived classes can override this as needed, and call it from126 Derived classes can override this as needed, and call it from
127127
=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py 2010-08-03 14:59:22 +0000
+++ lib/lp/soyuz/model/archive.py 2010-08-04 22:02:48 +0000
@@ -336,9 +336,9 @@
336 def archive_url(self):336 def archive_url(self):
337 """See `IArchive`."""337 """See `IArchive`."""
338 archive_postfixes = {338 archive_postfixes = {
339 ArchivePurpose.PRIMARY : '',339 ArchivePurpose.PRIMARY: '',
340 ArchivePurpose.PARTNER : '-partner',340 ArchivePurpose.PARTNER: '-partner',
341 ArchivePurpose.DEBUG : '-debug',341 ArchivePurpose.DEBUG: '-debug',
342 }342 }
343343
344 if self.is_ppa:344 if self.is_ppa:
@@ -568,7 +568,7 @@
568 # the result is empty, so instead:568 # the result is empty, so instead:
569 return sum(result.values(LibraryFileContent.filesize))569 return sum(result.values(LibraryFileContent.filesize))
570570
571 def _getBinaryPublishingBaseClauses (571 def _getBinaryPublishingBaseClauses(
572 self, name=None, version=None, status=None, distroarchseries=None,572 self, name=None, version=None, status=None, distroarchseries=None,
573 pocket=None, exact_match=False):573 pocket=None, exact_match=False):
574 """Base clauses and clauseTables for binary publishing queries.574 """Base clauses and clauseTables for binary publishing queries.
@@ -648,7 +648,7 @@
648 distroarchseries=distroarchseries, exact_match=exact_match)648 distroarchseries=distroarchseries, exact_match=exact_match)
649649
650 all_binaries = BinaryPackagePublishingHistory.select(650 all_binaries = BinaryPackagePublishingHistory.select(
651 ' AND '.join(clauses) , clauseTables=clauseTables,651 ' AND '.join(clauses), clauseTables=clauseTables,
652 orderBy=orderBy)652 orderBy=orderBy)
653653
654 return all_binaries654 return all_binaries
@@ -720,7 +720,7 @@
720 BinaryPackagePublishingHistory.binarypackagereleaseID ==720 BinaryPackagePublishingHistory.binarypackagereleaseID ==
721 BinaryPackageFile.binarypackagereleaseID,721 BinaryPackageFile.binarypackagereleaseID,
722 BinaryPackageFile.libraryfileID == LibraryFileAlias.id,722 BinaryPackageFile.libraryfileID == LibraryFileAlias.id,
723 LibraryFileAlias.contentID == LibraryFileContent.id723 LibraryFileAlias.contentID == LibraryFileContent.id,
724 ]724 ]
725725
726 # Exclude DDEBs from the repository size, they are not published726 # Exclude DDEBs from the repository size, they are not published
@@ -750,10 +750,10 @@
750 def allowUpdatesToReleasePocket(self):750 def allowUpdatesToReleasePocket(self):
751 """See `IArchive`."""751 """See `IArchive`."""
752 purposeToPermissionMap = {752 purposeToPermissionMap = {
753 ArchivePurpose.COPY : True,753 ArchivePurpose.COPY: True,
754 ArchivePurpose.PARTNER : True,754 ArchivePurpose.PARTNER: True,
755 ArchivePurpose.PPA : True,755 ArchivePurpose.PPA: True,
756 ArchivePurpose.PRIMARY : False,756 ArchivePurpose.PRIMARY: False,
757 }757 }
758758
759 try:759 try:
@@ -775,6 +775,7 @@
775 # gets fixed we should probably change it to a normal list and775 # gets fixed we should probably change it to a normal list and
776 # benefit of the FTI rank for ordering.776 # benefit of the FTI rank for ordering.
777 cache_contents = set()777 cache_contents = set()
778
778 def add_cache_content(content):779 def add_cache_content(content):
779 """Sanitise and add contents to the cache."""780 """Sanitise and add contents to the cache."""
780 content = clean_text.sub(' ', content)781 content = clean_text.sub(' ', content)
@@ -914,7 +915,7 @@
914915
915 find_spec = (916 find_spec = (
916 BuildFarmJob.status,917 BuildFarmJob.status,
917 Count(BinaryPackageBuild.id)918 Count(BinaryPackageBuild.id),
918 )919 )
919 result = store.using(920 result = store.using(
920 BinaryPackageBuild, PackageBuild, BuildFarmJob).find(921 BinaryPackageBuild, PackageBuild, BuildFarmJob).find(
@@ -922,8 +923,7 @@
922 BinaryPackageBuild.package_build == PackageBuild.id,923 BinaryPackageBuild.package_build == PackageBuild.id,
923 PackageBuild.archive == self,924 PackageBuild.archive == self,
924 PackageBuild.build_farm_job == BuildFarmJob.id,925 PackageBuild.build_farm_job == BuildFarmJob.id,
925 *extra_exprs926 *extra_exprs).group_by(BuildFarmJob.status).order_by(
926 ).group_by(BuildFarmJob.status).order_by(
927 BuildFarmJob.status)927 BuildFarmJob.status)
928928
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:
@@ -955,7 +955,7 @@
955 BuildStatus.BUILDING,955 BuildStatus.BUILDING,
956 BuildStatus.FULLYBUILT,956 BuildStatus.FULLYBUILT,
957 BuildStatus.SUPERSEDED,957 BuildStatus.SUPERSEDED,
958 ]958 ],
959 }959 }
960960
961 # If we were asked to include builds with the state NEEDSBUILD,961 # If we were asked to include builds with the state NEEDSBUILD,
@@ -1097,7 +1097,11 @@
1097 return None1097 return None
10981098
1099 if not self.getComponentsForUploader(person):1099 if not self.getComponentsForUploader(person):
1100 if not self.getPackagesetsForUploader(person):1100 # XXX: JamesWestby 2010-08-01 bug=612351: We have to use
1101 # is_empty() as we don't get an SQLObjectResultSet back, and
1102 # so __nonzero__ isn't defined on it, and a straight bool
1103 # check wouldn't do the right thing.
1104 if self.getPackagesetsForUploader(person).is_empty():
1101 return NoRightsForArchive()1105 return NoRightsForArchive()
1102 else:1106 else:
1103 return InsufficientUploadRights()1107 return InsufficientUploadRights()
@@ -1668,7 +1672,6 @@
16681672
1669 return default_name_by_purpose[purpose]1673 return default_name_by_purpose[purpose]
16701674
1671
1672 def getByDistroPurpose(self, distribution, purpose, name=None):1675 def getByDistroPurpose(self, distribution, purpose, name=None):
1673 """See `IArchiveSet`."""1676 """See `IArchiveSet`."""
1674 if purpose == ArchivePurpose.PPA:1677 if purpose == ArchivePurpose.PPA:
@@ -1777,7 +1780,6 @@
17771780
1778 return new_archive1781 return new_archive
17791782
1780
1781 def __iter__(self):1783 def __iter__(self):
1782 """See `IArchiveSet`."""1784 """See `IArchiveSet`."""
1783 return iter(Archive.select())1785 return iter(Archive.select())
17841786
=== modified file 'lib/lp/soyuz/model/buildpackagejob.py'
--- lib/lp/soyuz/model/buildpackagejob.py 2010-06-10 12:18:10 +0000
+++ lib/lp/soyuz/model/buildpackagejob.py 2010-08-04 22:02:48 +0000
@@ -115,9 +115,8 @@
115 score += score_pocket115 score += score_pocket
116116
117 # Calculates the component-related part of the score.117 # Calculates the component-related part of the score.
118 score_component = score_componentname[118 score += score_componentname.get(
119 self.build.current_component.name]119 self.build.current_component.name, 0)
120 score += score_component
121120
122 # Calculates the build queue time component of the score.121 # Calculates the build queue time component of the score.
123 right_now = datetime.now(pytz.timezone('UTC'))122 right_now = datetime.now(pytz.timezone('UTC'))
124123
=== modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt'
--- lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-07-27 12:33:02 +0000
+++ lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-08-04 22:02:48 +0000
@@ -377,8 +377,8 @@
377 >>> print(response)377 >>> print(response)
378 HTTP/1.1 403 Forbidden378 HTTP/1.1 403 Forbidden
379 ...379 ...
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
381381 this distribution's primary archive. Did you mean to upload to a PPA?
382382
383383
384Only the archive owners can add or remove component-uploaders.384Only the archive owners can add or remove component-uploaders.
385385
=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py 2010-08-03 19:10:42 +0000
+++ lib/lp/soyuz/tests/test_archive.py 2010-08-04 22:02:48 +0000
@@ -1,9 +1,11 @@
1# Copyright 2009-2010 Canonical Ltd. This software is licensed under the1# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from __future__ import with_statement
5
4"""Test Archive features."""6"""Test Archive features."""
57
6from datetime import date, timedelta8from datetime import date
79
8import transaction10import transaction
911
@@ -12,31 +14,35 @@
12from zope.security.proxy import removeSecurityProxy14from zope.security.proxy import removeSecurityProxy
1315
14from canonical.database.sqlbase import sqlvalues16from canonical.database.sqlbase import sqlvalues
17from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
15from canonical.launchpad.webapp.interfaces import (18from canonical.launchpad.webapp.interfaces import (
16 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)19 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
17from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer20from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer
1821
19from lp.buildmaster.interfaces.buildbase import BuildStatus22from lp.buildmaster.interfaces.buildbase import BuildStatus
20from lp.registry.interfaces.distribution import IDistributionSet
21from lp.registry.interfaces.person import IPersonSet
22from lp.registry.interfaces.pocket import PackagePublishingPocket23from lp.registry.interfaces.pocket import PackagePublishingPocket
24from lp.registry.interfaces.series import SeriesStatus
23from lp.services.job.interfaces.job import JobStatus25from lp.services.job.interfaces.job import JobStatus
24from lp.soyuz.interfaces.archive import (IArchiveSet, ArchivePurpose,26from lp.soyuz.interfaces.archive import (
25 ArchiveStatus, CannotRestrictArchitectures, CannotSwitchPrivacy,27 ArchiveDisabled, ArchivePurpose, ArchiveStatus,
26 InvalidPocketForPartnerArchive, InvalidPocketForPPA)28 CannotRestrictArchitectures, CannotSwitchPrivacy, CannotUploadToPocket,
29 CannotUploadToPPA, IArchiveSet, InsufficientUploadRights,
30 InvalidPocketForPartnerArchive, InvalidPocketForPPA, NoRightsForArchive,
31 NoRightsForComponent)
27from lp.services.worlddata.interfaces.country import ICountrySet32from lp.services.worlddata.interfaces.country import ICountrySet
28from lp.soyuz.interfaces.archivearch import IArchiveArchSet33from lp.soyuz.interfaces.archivearch import IArchiveArchSet
34from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
29from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet35from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
30from lp.soyuz.interfaces.binarypackagerelease import (36from lp.soyuz.interfaces.binarypackagerelease import (
31 BinaryPackageFileType, BinaryPackageFormat)37 BinaryPackageFileType, BinaryPackageFormat)
32from lp.soyuz.interfaces.component import IComponentSet38from lp.soyuz.interfaces.component import IComponentSet
33from lp.soyuz.interfaces.processor import IProcessorFamilySet39from lp.soyuz.interfaces.processor import IProcessorFamilySet
34from lp.soyuz.interfaces.publishing import PackagePublishingStatus40from lp.soyuz.interfaces.publishing import PackagePublishingStatus
35from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
36from lp.soyuz.model.binarypackagerelease import (41from lp.soyuz.model.binarypackagerelease import (
37 BinaryPackageReleaseDownloadCount)42 BinaryPackageReleaseDownloadCount)
38from lp.soyuz.tests.test_publishing import SoyuzTestPublisher43from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
39from lp.testing import login, login_person, TestCaseWithFactory44from lp.testing import (
45 login, login_person, person_logged_in, TestCaseWithFactory)
4046
4147
42class TestGetPublicationsInArchive(TestCaseWithFactory):48class TestGetPublicationsInArchive(TestCaseWithFactory):
@@ -207,247 +213,128 @@
207class TestSeriesWithSources(TestCaseWithFactory):213class TestSeriesWithSources(TestCaseWithFactory):
208 """Create some sources in different series."""214 """Create some sources in different series."""
209215
210 layer = LaunchpadZopelessLayer216 layer = DatabaseFunctionalLayer
211
212 def setUp(self):
213 super(TestSeriesWithSources, self).setUp()
214 self.publisher = SoyuzTestPublisher()
215 self.publisher.prepareBreezyAutotest()
216
217 # Create three sources for the two different distroseries.
218 breezy_autotest = self.publisher.distroseries
219 ubuntu_test = breezy_autotest.distribution
220 self.series = [breezy_autotest]
221 self.series.append(self.factory.makeDistroRelease(
222 distribution=ubuntu_test, name="foo-series", version='1.0'))
223
224 self.sources = []
225 gedit_src_hist = self.publisher.getPubSource(
226 sourcename="gedit", status=PackagePublishingStatus.PUBLISHED)
227 self.sources.append(gedit_src_hist)
228
229 firefox_src_hist = self.publisher.getPubSource(
230 sourcename="firefox", status=PackagePublishingStatus.PUBLISHED,
231 distroseries=self.series[1])
232 self.sources.append(firefox_src_hist)
233
234 gtg_src_hist = self.publisher.getPubSource(
235 sourcename="getting-things-gnome",
236 status=PackagePublishingStatus.PUBLISHED,
237 distroseries=self.series[1])
238 self.sources.append(gtg_src_hist)
239
240 # Shortcuts for test readability.
241 self.archive = self.series[0].main_archive
242217
243 def test_series_with_sources_returns_all_series(self):218 def test_series_with_sources_returns_all_series(self):
244 # Calling series_with_sources returns all series with publishings.219 # Calling series_with_sources returns all series with publishings.
245 series = self.archive.series_with_sources220 distribution = self.factory.makeDistribution()
246 series_names = [s.displayname for s in series]221 archive = self.factory.makeArchive(distribution=distribution)
247222 series_with_no_sources = self.factory.makeDistroSeries(
248 self.assertContentEqual(223 distribution=distribution, version="0.5")
249 [u'Breezy Badger Autotest', u'Foo-series'],224 series_with_sources1 = self.factory.makeDistroSeries(
250 series_names)225 distribution=distribution, version="1")
226 self.factory.makeSourcePackagePublishingHistory(
227 distroseries=series_with_sources1, archive=archive,
228 status=PackagePublishingStatus.PUBLISHED)
229 series_with_sources2 = self.factory.makeDistroSeries(
230 distribution=distribution, version="2")
231 self.factory.makeSourcePackagePublishingHistory(
232 distroseries=series_with_sources2, archive=archive,
233 status=PackagePublishingStatus.PENDING)
234 self.assertEqual(
235 [series_with_sources2, series_with_sources1],
236 archive.series_with_sources)
251237
252 def test_series_with_sources_ignore_non_published_records(self):238 def test_series_with_sources_ignore_non_published_records(self):
253 # If all publishings in a series are deleted or superseded239 # If all publishings in a series are deleted or superseded
254 # the series will not be returned.240 # the series will not be returned.
255 self.sources[0].status = (241 series = self.factory.makeDistroSeries()
256 PackagePublishingStatus.DELETED)242 archive = self.factory.makeArchive(distribution=series.distribution)
257243 self.factory.makeSourcePackagePublishingHistory(
258 series = self.archive.series_with_sources244 distroseries=series, archive=archive,
259 series_names = [s.displayname for s in series]245 status=PackagePublishingStatus.DELETED)
260246 self.assertEqual([], archive.series_with_sources)
261 self.assertContentEqual([u'Foo-series'], series_names)
262247
263 def test_series_with_sources_ordered_by_version(self):248 def test_series_with_sources_ordered_by_version(self):
264 # The returned series are ordered by the distroseries version.249 # The returned series are ordered by the distroseries version.
265 series = self.archive.series_with_sources250 distribution = self.factory.makeDistribution()
266 versions = [s.version for s in series]251 archive = self.factory.makeArchive(distribution=distribution)
267252 series1 = self.factory.makeDistroSeries(
268 # Latest version should be first253 version="1", distribution=distribution)
269 self.assertEqual(254 series2 = self.factory.makeDistroSeries(
270 [u'6.6.6', u'1.0'], versions,255 version="2", distribution=distribution)
271 "The latest version was not first.")256 self.factory.makeSourcePackagePublishingHistory(
272257 distroseries=series1, archive=archive,
273 # Update the version of breezyautotest and ensure that the258 status=PackagePublishingStatus.PUBLISHED)
274 # latest version is still first.259 self.factory.makeSourcePackagePublishingHistory(
275 self.series[0].version = u'0.5'260 distroseries=series2, archive=archive,
276 series = self.archive.series_with_sources261 status=PackagePublishingStatus.PUBLISHED)
277 versions = [s.version for s in series]262 self.assertEqual([series2, series1], archive.series_with_sources)
278 self.assertEqual(263 # Change the version such that they should order differently
279 [u'1.0', u'0.5'], versions,264 removeSecurityProxy(series2).version = "0.5"
280 "The latest version was not first.")265 # ... and check that they do
266 self.assertEqual([series1, series2], archive.series_with_sources)
281267
282268
283class TestGetSourcePackageReleases(TestCaseWithFactory):269class TestGetSourcePackageReleases(TestCaseWithFactory):
284270
285 layer = LaunchpadZopelessLayer271 layer = DatabaseFunctionalLayer
286272
287 def setUp(self):273 def createArchiveWithBuilds(self, statuses):
288 super(TestGetSourcePackageReleases, self).setUp()274 archive = self.factory.makeArchive()
289 self.publisher = SoyuzTestPublisher()275 sprs = []
290 self.publisher.prepareBreezyAutotest()276 for status in statuses:
291277 sourcepackagerelease = self.factory.makeSourcePackageRelease()
292 # Create an archive with some published binaries.278 self.factory.makeBinaryPackageBuild(
293 self.archive = self.factory.makeArchive()279 source_package_release=sourcepackagerelease,
294 binaries_foo = self.publisher.getPubBinaries(280 archive=archive, status=status)
295 archive=self.archive, binaryname="foo-bin")281 sprs.append(sourcepackagerelease)
296 binaries_bar = self.publisher.getPubBinaries(282 unlinked_spr = self.factory.makeSourcePackageRelease()
297 archive=self.archive, binaryname="bar-bin")283 return archive, sprs
298
299 # Collect the builds for reference.
300 self.builds_foo = [
301 binary.binarypackagerelease.build for binary in binaries_foo]
302 self.builds_bar = [
303 binary.binarypackagerelease.build for binary in binaries_bar]
304
305 # Collect the source package releases for reference.
306 self.sourcepackagereleases = [
307 self.builds_foo[0].source_package_release,
308 self.builds_bar[0].source_package_release,
309 ]
310284
311 def test_getSourcePackageReleases_with_no_params(self):285 def test_getSourcePackageReleases_with_no_params(self):
312 # With no params all source package releases are returned.286 # With no params all source package releases are returned.
313 sprs = self.archive.getSourcePackageReleases()287 archive, sprs = self.createArchiveWithBuilds(
314288 [BuildStatus.NEEDSBUILD, BuildStatus.FULLYBUILT])
315 self.assertContentEqual(self.sourcepackagereleases, sprs)289 self.assertContentEqual(
290 sprs, archive.getSourcePackageReleases())
316291
317 def test_getSourcePackageReleases_with_buildstatus(self):292 def test_getSourcePackageReleases_with_buildstatus(self):
318 # Results are filtered by the specified buildstatus.293 # Results are filtered by the specified buildstatus.
319294 archive, sprs = self.createArchiveWithBuilds(
320 # Set the builds for one of the sprs to needs build.295 [BuildStatus.NEEDSBUILD, BuildStatus.FULLYBUILT])
321 for build in self.builds_foo:296 self.assertContentEqual(
322 removeSecurityProxy(build).status = BuildStatus.NEEDSBUILD297 [sprs[0]], archive.getSourcePackageReleases(
323298 build_status=BuildStatus.NEEDSBUILD))
324 result = self.archive.getSourcePackageReleases(
325 build_status=BuildStatus.NEEDSBUILD)
326
327 self.failUnlessEqual(1, result.count())
328 self.failUnlessEqual(
329 self.sourcepackagereleases[0], result[0])
330299
331300
332class TestCorrespondingDebugArchive(TestCaseWithFactory):301class TestCorrespondingDebugArchive(TestCaseWithFactory):
333302
334 layer = LaunchpadZopelessLayer303 layer = DatabaseFunctionalLayer
335
336 def setUp(self):
337 super(TestCorrespondingDebugArchive, self).setUp()
338
339 self.ubuntutest = getUtility(IDistributionSet)['ubuntutest']
340
341 # Create a debug archive, as there isn't one in the sample data.
342 self.debug_archive = getUtility(IArchiveSet).new(
343 purpose=ArchivePurpose.DEBUG,
344 distribution=self.ubuntutest,
345 owner=self.ubuntutest.owner)
346
347 # Retrieve sample data archives of each type.
348 self.primary_archive = getUtility(IArchiveSet).getByDistroPurpose(
349 self.ubuntutest, ArchivePurpose.PRIMARY)
350 self.partner_archive = getUtility(IArchiveSet).getByDistroPurpose(
351 self.ubuntutest, ArchivePurpose.PARTNER)
352 self.copy_archive = getUtility(IArchiveSet).getByDistroPurpose(
353 self.ubuntutest, ArchivePurpose.PARTNER)
354 self.ppa = getUtility(IPersonSet).getByName('cprov').archive
355304
356 def testPrimaryDebugArchiveIsDebug(self):305 def testPrimaryDebugArchiveIsDebug(self):
357 self.assertEquals(306 distribution = self.factory.makeDistribution()
358 self.primary_archive.debug_archive, self.debug_archive)307 primary = self.factory.makeArchive(
308 distribution=distribution, purpose=ArchivePurpose.PRIMARY)
309 debug = self.factory.makeArchive(
310 distribution=distribution, purpose=ArchivePurpose.DEBUG)
311 self.assertEquals(primary.debug_archive, debug)
359312
360 def testPartnerDebugArchiveIsSelf(self):313 def testPartnerDebugArchiveIsSelf(self):
361 self.assertEquals(314 partner = self.factory.makeArchive(purpose=ArchivePurpose.PARTNER)
362 self.partner_archive.debug_archive, self.partner_archive)315 self.assertEquals(partner.debug_archive, partner)
363316
364 def testCopyDebugArchiveIsSelf(self):317 def testCopyDebugArchiveIsSelf(self):
365 self.assertEquals(318 copy = self.factory.makeArchive(purpose=ArchivePurpose.COPY)
366 self.copy_archive.debug_archive, self.copy_archive)319 self.assertEquals(copy.debug_archive, copy)
367320
368 def testDebugDebugArchiveIsSelf(self):321 def testDebugDebugArchiveIsSelf(self):
369 self.assertEquals(322 debug = self.factory.makeArchive(purpose=ArchivePurpose.DEBUG)
370 self.debug_archive.debug_archive, self.debug_archive)323 self.assertEquals(debug.debug_archive, debug)
371324
372 def testPPADebugArchiveIsSelf(self):325 def testPPADebugArchiveIsSelf(self):
373 self.assertEquals(self.ppa.debug_archive, self.ppa)326 ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
327 self.assertEquals(ppa.debug_archive, ppa)
374328
375 def testMissingPrimaryDebugArchiveIsNone(self):329 def testMissingPrimaryDebugArchiveIsNone(self):
376 # Turn the DEBUG archive into a COPY archive to hide it.330 primary = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
377 removeSecurityProxy(self.debug_archive).purpose = ArchivePurpose.COPY331 self.assertIs(primary.debug_archive, None)
378
379 self.assertIs(
380 self.primary_archive.debug_archive, None)
381332
382333
383class TestArchiveEnableDisable(TestCaseWithFactory):334class TestArchiveEnableDisable(TestCaseWithFactory):
384 """Test the enable and disable methods of Archive."""335 """Test the enable and disable methods of Archive."""
385336
386 layer = LaunchpadZopelessLayer337 layer = DatabaseFunctionalLayer
387
388 def setUp(self):
389 #XXX: rockstar - 12 Jan 2010 - Bug #506255 - Tidy up these tests!
390 super(TestArchiveEnableDisable, self).setUp()
391
392 self.publisher = SoyuzTestPublisher()
393 self.publisher.prepareBreezyAutotest()
394
395 self.ubuntutest = getUtility(IDistributionSet)['ubuntutest']
396 self.archive = getUtility(IArchiveSet).getByDistroPurpose(
397 self.ubuntutest, ArchivePurpose.PRIMARY)
398
399 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
400 sample_data = store.find(BinaryPackageBuild)
401 for build in sample_data:
402 build.buildstate = BuildStatus.FULLYBUILT
403 store.flush()
404
405 # We test builds that target a primary archive.
406 self.builds = []
407 self.builds.extend(
408 self.publisher.getPubSource(
409 sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
410 archive=self.archive).createMissingBuilds())
411 self.builds.extend(
412 self.publisher.getPubSource(
413 sourcename="firefox",
414 status=PackagePublishingStatus.PUBLISHED,
415 archive=self.archive).createMissingBuilds())
416 self.builds.extend(
417 self.publisher.getPubSource(
418 sourcename="apg", status=PackagePublishingStatus.PUBLISHED,
419 archive=self.archive).createMissingBuilds())
420 self.builds.extend(
421 self.publisher.getPubSource(
422 sourcename="vim", status=PackagePublishingStatus.PUBLISHED,
423 archive=self.archive).createMissingBuilds())
424 self.builds.extend(
425 self.publisher.getPubSource(
426 sourcename="gcc", status=PackagePublishingStatus.PUBLISHED,
427 archive=self.archive).createMissingBuilds())
428 self.builds.extend(
429 self.publisher.getPubSource(
430 sourcename="bison", status=PackagePublishingStatus.PUBLISHED,
431 archive=self.archive).createMissingBuilds())
432 self.builds.extend(
433 self.publisher.getPubSource(
434 sourcename="flex", status=PackagePublishingStatus.PUBLISHED,
435 archive=self.archive).createMissingBuilds())
436 self.builds.extend(
437 self.publisher.getPubSource(
438 sourcename="postgres",
439 status=PackagePublishingStatus.PUBLISHED,
440 archive=self.archive).createMissingBuilds())
441 # Set up the builds for test.
442 score = 1000
443 duration = 0
444 for build in self.builds:
445 score += 1
446 duration += 60
447 bq = build.buildqueue_record
448 bq.lastscore = score
449 removeSecurityProxy(bq).estimated_duration = timedelta(
450 seconds=duration)
451338
452 def _getBuildJobsByStatus(self, archive, status):339 def _getBuildJobsByStatus(self, archive, status):
453 # Return the count for archive build jobs with the given status.340 # Return the count for archive build jobs with the given status.
@@ -474,92 +361,95 @@
474 # status.361 # status.
475 self.assertEqual(self._getBuildJobsByStatus(archive, status), 0)362 self.assertEqual(self._getBuildJobsByStatus(archive, status), 0)
476363
477 def assertHasBuildJobsWithStatus(self, archive, status):364 def assertHasBuildJobsWithStatus(self, archive, status, count):
478 # Check that that there are jobs attached to this archive that have365 # Check that that there are jobs attached to this archive that have
479 # the specified status.366 # the specified status.
480 self.assertEqual(self._getBuildJobsByStatus(archive, status), 8)367 self.assertEqual(self._getBuildJobsByStatus(archive, status), count)
481368
482 def test_enableArchive(self):369 def test_enableArchive(self):
483 # Enabling an archive should set all the Archive's suspended builds to370 # Enabling an archive should set all the Archive's suspended builds to
484 # WAITING.371 # WAITING.
485372 archive = self.factory.makeArchive(enabled=True)
486 # Disable the archive, because it's currently enabled.373 self.factory.makeBinaryPackageBuild(
487 self.archive.disable()374 archive=archive, status=BuildStatus.NEEDSBUILD)
488 self.assertHasBuildJobsWithStatus(self.archive, JobStatus.SUSPENDED)375 # disable the archive, as it is currently enabled
489 self.archive.enable()376 removeSecurityProxy(archive).disable()
490 self.assertNoBuildJobsHaveStatus(self.archive, JobStatus.SUSPENDED)377 self.assertHasBuildJobsWithStatus(archive, JobStatus.SUSPENDED, 1)
491 self.assertTrue(self.archive.enabled)378 removeSecurityProxy(archive).enable()
379 self.assertNoBuildJobsHaveStatus(archive, JobStatus.SUSPENDED)
380 self.assertTrue(archive.enabled)
492381
493 def test_enableArchiveAlreadyEnabled(self):382 def test_enableArchiveAlreadyEnabled(self):
494 # Enabling an already enabled Archive should raise an AssertionError.383 # Enabling an already enabled Archive should raise an AssertionError.
495 self.assertRaises(AssertionError, self.archive.enable)384 archive = self.factory.makeArchive(enabled=True)
385 self.assertRaises(AssertionError, removeSecurityProxy(archive).enable)
496386
497 def test_disableArchive(self):387 def test_disableArchive(self):
498 # Disabling an archive should set all the Archive's pending bulds to388 # Disabling an archive should set all the Archive's pending bulds to
499 # SUSPENDED.389 # SUSPENDED.
500 self.assertHasBuildJobsWithStatus(self.archive, JobStatus.WAITING)390 archive = self.factory.makeArchive(enabled=True)
501 self.archive.disable()391 self.factory.makeBinaryPackageBuild(
502 self.assertNoBuildJobsHaveStatus(self.archive, JobStatus.WAITING)392 archive=archive, status=BuildStatus.NEEDSBUILD)
503 self.assertFalse(self.archive.enabled)393 self.assertHasBuildJobsWithStatus(archive, JobStatus.WAITING, 1)
394 removeSecurityProxy(archive).disable()
395 self.assertNoBuildJobsHaveStatus(archive, JobStatus.WAITING)
396 self.assertFalse(archive.enabled)
504397
505 def test_disableArchiveAlreadyDisabled(self):398 def test_disableArchiveAlreadyDisabled(self):
506 # Disabling an already disabled Archive should raise an399 # Disabling an already disabled Archive should raise an
507 # AssertionError.400 # AssertionError.
508 self.archive.disable()401 archive = self.factory.makeArchive(enabled=False)
509 self.assertRaises(AssertionError, self.archive.disable)402 self.assertRaises(
403 AssertionError, removeSecurityProxy(archive).disable)
510404
511405
512class TestCollectLatestPublishedSources(TestCaseWithFactory):406class TestCollectLatestPublishedSources(TestCaseWithFactory):
513 """Ensure that the private helper method works as expected."""407 """Ensure that the private helper method works as expected."""
514408
515 layer = LaunchpadZopelessLayer409 layer = DatabaseFunctionalLayer
516410
517 def setUp(self):411 def makePublishedSources(self, archive, statuses, versions, names):
518 """Setup an archive with relevant publications."""412 for status, version, name in zip(statuses, versions, names):
519 super(TestCollectLatestPublishedSources, self).setUp()413 self.factory.makeSourcePackagePublishingHistory(
520 self.publisher = SoyuzTestPublisher()414 sourcepackagename=name, archive=archive,
521 self.publisher.prepareBreezyAutotest()415 version=version, status=status)
522
523 # Create an archive with some published sources. We'll store
524 # a reference to the naked archive so that we can call
525 # the private method which is not defined on the interface.
526 self.archive = self.factory.makeArchive()
527 self.naked_archive = removeSecurityProxy(self.archive)
528
529 self.pub_1 = self.publisher.getPubSource(
530 version='0.5.11~ppa1', archive=self.archive, sourcename="foo",
531 status=PackagePublishingStatus.PUBLISHED)
532
533 self.pub_2 = self.publisher.getPubSource(
534 version='0.5.11~ppa2', archive=self.archive, sourcename="foo",
535 status=PackagePublishingStatus.PUBLISHED)
536
537 self.pub_3 = self.publisher.getPubSource(
538 version='0.9', archive=self.archive, sourcename="bar",
539 status=PackagePublishingStatus.PUBLISHED)
540416
541 def test_collectLatestPublishedSources_returns_latest(self):417 def test_collectLatestPublishedSources_returns_latest(self):
542 pubs = self.naked_archive._collectLatestPublishedSources(418 sourcepackagename = self.factory.makeSourcePackageName(name="foo")
543 self.archive, ["foo"])419 other_spn = self.factory.makeSourcePackageName(name="bar")
420 archive = self.factory.makeArchive()
421 self.makePublishedSources(archive,
422 [PackagePublishingStatus.PUBLISHED]*3,
423 ["1.0", "1.1", "2.0"],
424 [sourcepackagename, sourcepackagename, other_spn])
425 pubs = removeSecurityProxy(archive)._collectLatestPublishedSources(
426 archive, ["foo"])
544 self.assertEqual(1, len(pubs))427 self.assertEqual(1, len(pubs))
545 self.assertEqual('0.5.11~ppa2', pubs[0].source_package_version)428 self.assertEqual('1.1', pubs[0].source_package_version)
546429
547 def test_collectLatestPublishedSources_returns_published_only(self):430 def test_collectLatestPublishedSources_returns_published_only(self):
548 # Set the status of the latest pub to DELETED and ensure that it431 # Set the status of the latest pub to DELETED and ensure that it
549 # is not returned.432 # is not returned.
550 self.pub_2.status = PackagePublishingStatus.DELETED433 sourcepackagename = self.factory.makeSourcePackageName(name="foo")
551434 other_spn = self.factory.makeSourcePackageName(name="bar")
552 pubs = self.naked_archive._collectLatestPublishedSources(435 archive = self.factory.makeArchive()
553 self.archive, ["foo"])436 self.makePublishedSources(archive,
437 [PackagePublishingStatus.PUBLISHED,
438 PackagePublishingStatus.DELETED,
439 PackagePublishingStatus.PUBLISHED],
440 ["1.0", "1.1", "2.0"],
441 [sourcepackagename, sourcepackagename, other_spn])
442 pubs = removeSecurityProxy(archive)._collectLatestPublishedSources(
443 archive, ["foo"])
554 self.assertEqual(1, len(pubs))444 self.assertEqual(1, len(pubs))
555 self.assertEqual('0.5.11~ppa1', pubs[0].source_package_version)445 self.assertEqual('1.0', pubs[0].source_package_version)
556446
557447
558class TestArchiveCanUpload(TestCaseWithFactory):448class TestArchiveCanUpload(TestCaseWithFactory):
559 """Test the various methods that verify whether uploads are allowed to449 """Test the various methods that verify whether uploads are allowed to
560 happen."""450 happen."""
561451
562 layer = LaunchpadZopelessLayer452 layer = DatabaseFunctionalLayer
563453
564 def test_checkArchivePermission_by_PPA_owner(self):454 def test_checkArchivePermission_by_PPA_owner(self):
565 # Uploading to a PPA should be allowed for a user that is the owner455 # Uploading to a PPA should be allowed for a user that is the owner
@@ -572,50 +462,356 @@
572462
573 def test_checkArchivePermission_distro_archive(self):463 def test_checkArchivePermission_distro_archive(self):
574 # Regular users can not upload to ubuntu464 # Regular users can not upload to ubuntu
575 ubuntu = getUtility(IDistributionSet).getByName('ubuntu')465 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
576 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY,
577 distribution=ubuntu)
578 main = getUtility(IComponentSet)["main"]466 main = getUtility(IComponentSet)["main"]
579 # A regular user doesn't have access467 # A regular user doesn't have access
580 somebody = self.factory.makePerson(name="somebody")468 somebody = self.factory.makePerson()
581 self.assertEquals(False,469 self.assertEquals(False,
582 archive.checkArchivePermission(somebody, main))470 archive.checkArchivePermission(somebody, main))
583 # An ubuntu core developer does have access471 # An ubuntu core developer does have access
584 kamion = getUtility(IPersonSet).getByName('kamion')472 coredev = self.factory.makePerson()
585 self.assertEquals(True, archive.checkArchivePermission(kamion, main))473 with person_logged_in(archive.owner):
474 archive.newComponentUploader(coredev, main.name)
475 self.assertEquals(True, archive.checkArchivePermission(coredev, main))
586476
587 def test_checkArchivePermission_ppa(self):477 def test_checkArchivePermission_ppa(self):
588 ubuntu = getUtility(IDistributionSet).getByName('ubuntu')478 owner = self.factory.makePerson()
589 owner = self.factory.makePerson(name="eigenaar")
590 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA,479 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA,
591 distribution=ubuntu,
592 owner=owner)480 owner=owner)
593 somebody = self.factory.makePerson(name="somebody")481 somebody = self.factory.makePerson()
594 # The owner has access482 # The owner has access
595 self.assertEquals(True, archive.checkArchivePermission(owner))483 self.assertEquals(True, archive.checkArchivePermission(owner))
596 # Somebody unrelated does not484 # Somebody unrelated does not
597 self.assertEquals(False, archive.checkArchivePermission(somebody))485 self.assertEquals(False, archive.checkArchivePermission(somebody))
598486
487 def makeArchiveAndActiveDistroSeries(self, purpose=None):
488 if purpose is None:
489 purpose = ArchivePurpose.PRIMARY
490 archive = self.factory.makeArchive(purpose=purpose)
491 distroseries = self.factory.makeDistroSeries(
492 distribution=archive.distribution,
493 status=SeriesStatus.DEVELOPMENT)
494 return archive, distroseries
495
496 def makePersonWithComponentPermission(self, archive):
497 person = self.factory.makePerson()
498 component = self.factory.makeComponent()
499 removeSecurityProxy(archive).newComponentUploader(
500 person, component)
501 return person, component
502
503 def checkUpload(self, archive, person, sourcepackagename,
504 distroseries=None, component=None,
505 pocket=None, strict_component=False):
506 if distroseries is None:
507 distroseries = self.factory.makeDistroSeries()
508 if component is None:
509 component = self.factory.makeComponent()
510 if pocket is None:
511 pocket = PackagePublishingPocket.RELEASE
512 return archive.checkUpload(
513 person, distroseries, sourcepackagename, component, pocket,
514 strict_component=strict_component)
515
516 def assertCanUpload(self, archive, person, sourcepackagename,
517 distroseries=None, component=None,
518 pocket=None, strict_component=False):
519 """Assert an upload to 'archive' will be accepted."""
520 self.assertIs(
521 None,
522 self.checkUpload(
523 archive, person, sourcepackagename,
524 distroseries=distroseries, component=component,
525 pocket=pocket, strict_component=strict_component))
526
527 def assertCannotUpload(self, reason, archive, person, sourcepackagename,
528 distroseries=None, component=None, pocket=None,
529 strict_component=False):
530 """Assert that upload to 'archive' will be rejected.
531
532 :param reason: The expected reason for not being able to upload. A
533 class.
534 """
535 self.assertIsInstance(
536 self.checkUpload(
537 archive, person, sourcepackagename,
538 distroseries=distroseries, component=component,
539 pocket=pocket, strict_component=strict_component),
540 reason
541 )
542
599 def test_checkUpload_partner_invalid_pocket(self):543 def test_checkUpload_partner_invalid_pocket(self):
600 # Partner archives only have release and proposed pockets544 # Partner archives only have release and proposed pockets
601 archive = self.factory.makeArchive(purpose=ArchivePurpose.PARTNER)545 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
602 self.assertIsInstance(archive.checkUpload(self.factory.makePerson(),546 purpose=ArchivePurpose.PARTNER)
603 self.factory.makeDistroSeries(),547 self.assertCannotUpload(
604 self.factory.makeSourcePackageName(),548 InvalidPocketForPartnerArchive, archive,
605 self.factory.makeComponent(),549 self.factory.makePerson(), self.factory.makeSourcePackageName(),
606 PackagePublishingPocket.UPDATES),550 pocket=PackagePublishingPocket.UPDATES,
607 InvalidPocketForPartnerArchive)551 distroseries=distroseries)
608552
609 def test_checkUpload_ppa_invalid_pocket(self):553 def test_checkUpload_ppa_invalid_pocket(self):
610 # PPA archives only have release pockets554 # PPA archives only have release pockets
611 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)555 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
612 self.assertIsInstance(archive.checkUpload(self.factory.makePerson(),556 purpose=ArchivePurpose.PPA)
613 self.factory.makeDistroSeries(),557 self.assertCannotUpload(
614 self.factory.makeSourcePackageName(),558 InvalidPocketForPPA, archive,
615 self.factory.makeComponent(),559 self.factory.makePerson(), self.factory.makeSourcePackageName(),
616 PackagePublishingPocket.PROPOSED),560 pocket=PackagePublishingPocket.PROPOSED,
617 InvalidPocketForPPA)561 distroseries=distroseries)
618 # XXX: JRV 20100511: IArchive.canUploadSuiteSourcePackage needs tests562
563 def test_checkUpload_invalid_pocket_for_series_state(self):
564 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
565 purpose=ArchivePurpose.PRIMARY)
566 self.assertCannotUpload(
567 CannotUploadToPocket, archive,
568 self.factory.makePerson(), self.factory.makeSourcePackageName(),
569 pocket=PackagePublishingPocket.PROPOSED,
570 distroseries=distroseries)
571
572 def test_checkUpload_disabled_archive(self):
573 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
574 purpose=ArchivePurpose.PRIMARY)
575 removeSecurityProxy(archive).disable()
576 self.assertCannotUpload(
577 ArchiveDisabled, archive, self.factory.makePerson(),
578 self.factory.makeSourcePackageName(),
579 distroseries=distroseries)
580
581 def test_checkUpload_ppa_owner(self):
582 person = self.factory.makePerson()
583 archive = self.factory.makeArchive(
584 purpose=ArchivePurpose.PPA, owner=person)
585 self.assertCanUpload(
586 archive, person, self.factory.makeSourcePackageName())
587
588 def test_checkUpload_ppa_with_permission(self):
589 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
590 person = self.factory.makePerson()
591 removeSecurityProxy(archive).newComponentUploader(person, "main")
592 # component is ignored
593 self.assertCanUpload(
594 archive, person, self.factory.makeSourcePackageName(),
595 component=self.factory.makeComponent(name="universe"))
596
597 def test_checkUpload_ppa_with_no_permission(self):
598 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
599 person = self.factory.makePerson()
600 self.assertCannotUpload(
601 CannotUploadToPPA, archive, person,
602 self.factory.makeSourcePackageName())
603
604 def test_owner_can_upload_to_ppa_no_sourcepackage(self):
605 # The owner can upload to PPAs even if the source package doesn't
606 # exist yet.
607 team = self.factory.makeTeam()
608 archive = self.factory.makeArchive(
609 purpose=ArchivePurpose.PPA, owner=team)
610 person = self.factory.makePerson()
611 removeSecurityProxy(team).addMember(person, team.teamowner)
612 self.assertCanUpload(archive, person, None)
613
614 def test_can_upload_to_ppa_for_old_series(self):
615 # You can upload whatever you want to a PPA, regardless of the upload
616 # policy.
617 person = self.factory.makePerson()
618 archive = self.factory.makeArchive(
619 purpose=ArchivePurpose.PPA, owner=person)
620 spn = self.factory.makeSourcePackageName()
621 distroseries = self.factory.makeDistroSeries(
622 status=SeriesStatus.CURRENT)
623 self.assertCanUpload(
624 archive, person, spn, distroseries=distroseries)
625
626 def test_checkUpload_copy_archive_no_permission(self):
627 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
628 purpose=ArchivePurpose.COPY)
629 sourcepackagename = self.factory.makeSourcePackageName()
630 person = self.factory.makePerson()
631 removeSecurityProxy(archive).newPackageUploader(
632 person, sourcepackagename)
633 self.assertCannotUpload(
634 NoRightsForArchive, archive, person, sourcepackagename,
635 distroseries=distroseries)
636
637 def test_checkUpload_package_permission(self):
638 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
639 purpose=ArchivePurpose.PRIMARY)
640 sourcepackagename = self.factory.makeSourcePackageName()
641 person = self.factory.makePerson()
642 removeSecurityProxy(archive).newPackageUploader(
643 person, sourcepackagename)
644 self.assertCanUpload(
645 archive, person, sourcepackagename, distroseries=distroseries)
646
647 def make_person_with_packageset_permission(self, archive, distroseries,
648 packages=()):
649 packageset = self.factory.makePackageset(
650 distroseries=distroseries, packages=packages)
651 person = self.factory.makePerson()
652 techboard = getUtility(ILaunchpadCelebrities).ubuntu_techboard
653 with person_logged_in(techboard):
654 archive.newPackagesetUploader(person, packageset)
655 return person, packageset
656
657 def test_checkUpload_packageset_permission(self):
658 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
659 purpose=ArchivePurpose.PRIMARY)
660 sourcepackagename = self.factory.makeSourcePackageName()
661 person, packageset = self.make_person_with_packageset_permission(
662 archive, distroseries, packages=[sourcepackagename])
663 self.assertCanUpload(
664 archive, person, sourcepackagename, distroseries=distroseries)
665
666 def test_checkUpload_packageset_wrong_distroseries(self):
667 # A person with rights to upload to the package set in distro
668 # series K may not upload with these same rights to a different
669 # distro series L.
670 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
671 purpose=ArchivePurpose.PRIMARY)
672 sourcepackagename = self.factory.makeSourcePackageName()
673 person, packageset = self.make_person_with_packageset_permission(
674 archive, distroseries, packages=[sourcepackagename])
675 other_distroseries = self.factory.makeDistroSeries()
676 self.assertCannotUpload(
677 InsufficientUploadRights, archive, person, sourcepackagename,
678 distroseries=other_distroseries)
679
680 def test_checkUpload_component_permission(self):
681 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
682 purpose=ArchivePurpose.PRIMARY)
683 sourcepackagename = self.factory.makeSourcePackageName()
684 person, component = self.makePersonWithComponentPermission(
685 archive)
686 self.assertCanUpload(
687 archive, person, sourcepackagename, distroseries=distroseries,
688 component=component)
689
690 def test_checkUpload_no_permissions(self):
691 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
692 purpose=ArchivePurpose.PRIMARY)
693 sourcepackagename = self.factory.makeSourcePackageName()
694 person = self.factory.makePerson()
695 self.assertCannotUpload(
696 NoRightsForArchive, archive, person, sourcepackagename,
697 distroseries=distroseries)
698
699 def test_checkUpload_insufficient_permissions(self):
700 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
701 purpose=ArchivePurpose.PRIMARY)
702 sourcepackagename = self.factory.makeSourcePackageName()
703 person, packageset = self.make_person_with_packageset_permission(
704 archive, distroseries)
705 self.assertCannotUpload(
706 InsufficientUploadRights, archive, person, sourcepackagename,
707 distroseries=distroseries)
708
709 def test_checkUpload_without_strict_component(self):
710 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
711 purpose=ArchivePurpose.PRIMARY)
712 sourcepackagename = self.factory.makeSourcePackageName()
713 person, component = self.makePersonWithComponentPermission(
714 archive)
715 other_component = self.factory.makeComponent()
716 self.assertCanUpload(
717 archive, person, sourcepackagename, distroseries=distroseries,
718 component=other_component, strict_component=False)
719
720 def test_checkUpload_with_strict_component(self):
721 archive, distroseries = self.makeArchiveAndActiveDistroSeries(
722 purpose=ArchivePurpose.PRIMARY)
723 sourcepackagename = self.factory.makeSourcePackageName()
724 person, component = self.makePersonWithComponentPermission(
725 archive)
726 other_component = self.factory.makeComponent()
727 self.assertCannotUpload(
728 NoRightsForComponent, archive, person, sourcepackagename,
729 distroseries=distroseries, component=other_component,
730 strict_component=True)
731
732 def test_checkUpload_component_rights_no_package(self):
733 # A person allowed to upload to a particular component of an archive
734 # can upload basically whatever they want to that component, even if
735 # the package doesn't exist yet.
736 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
737 person, component = self.makePersonWithComponentPermission(
738 archive)
739 self.assertCanUpload(archive, person, None, component=component)
740
741 def makePackageToUpload(self, distroseries):
742 sourcepackagename = self.factory.makeSourcePackageName()
743 suitesourcepackage = self.factory.makeSuiteSourcePackage(
744 pocket=PackagePublishingPocket.RELEASE,
745 sourcepackagename=sourcepackagename,
746 distroseries=distroseries)
747 return suitesourcepackage
748
749 def test_canUploadSuiteSourcePackage_invalid_pocket(self):
750 # Test that canUploadSuiteSourcePackage calls checkUpload for
751 # the pocket checks.
752 person = self.factory.makePerson()
753 archive = self.factory.makeArchive(
754 purpose=ArchivePurpose.PPA, owner=person)
755 suitesourcepackage = self.factory.makeSuiteSourcePackage(
756 pocket=PackagePublishingPocket.PROPOSED)
757 self.assertEqual(
758 False,
759 archive.canUploadSuiteSourcePackage(person, suitesourcepackage))
760
761 def test_canUploadSuiteSourcePackage_no_permission(self):
762 # Test that canUploadSuiteSourcePackage calls verifyUpload for
763 # the permission checks.
764 archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
765 suitesourcepackage = self.factory.makeSuiteSourcePackage(
766 pocket=PackagePublishingPocket.RELEASE)
767 person = self.factory.makePerson()
768 self.assertEqual(
769 False,
770 archive.canUploadSuiteSourcePackage(person, suitesourcepackage))
771
772 def test_canUploadSuiteSourcePackage_package_permission(self):
773 # Test that a package permission is enough to upload a new
774 # package.
775 archive, distroseries = self.makeArchiveAndActiveDistroSeries()
776 suitesourcepackage = self.makePackageToUpload(distroseries)
777 person = self.factory.makePerson()
778 removeSecurityProxy(archive).newPackageUploader(
779 person, suitesourcepackage.sourcepackagename)
780 self.assertEqual(
781 True,
782 archive.canUploadSuiteSourcePackage(person, suitesourcepackage))
783
784 def test_canUploadSuiteSourcePackage_component_permission(self):
785 # Test that component upload permission is enough to be
786 # allowed to upload a new package.
787 archive, distroseries = self.makeArchiveAndActiveDistroSeries()
788 suitesourcepackage = self.makePackageToUpload(distroseries)
789 person = self.factory.makePerson()
790 removeSecurityProxy(archive).newComponentUploader(person, "universe")
791 self.assertEqual(
792 True,
793 archive.canUploadSuiteSourcePackage(person, suitesourcepackage))
794
795 def test_canUploadSuiteSourcePackage_strict_component(self):
796 # Test that canUploadSuiteSourcePackage uses strict component
797 # checking.
798 archive, distroseries = self.makeArchiveAndActiveDistroSeries()
799 suitesourcepackage = self.makePackageToUpload(distroseries)
800 main_component = self.factory.makeComponent(name="main")
801 self.factory.makeSourcePackagePublishingHistory(
802 archive=archive, distroseries=distroseries,
803 sourcepackagename=suitesourcepackage.sourcepackagename,
804 status=PackagePublishingStatus.PUBLISHED,
805 pocket=PackagePublishingPocket.RELEASE,
806 component=main_component)
807 person = self.factory.makePerson()
808 removeSecurityProxy(archive).newComponentUploader(person, "universe")
809 # This time the user can't upload as there has been a
810 # publication and they don't have permission for the component
811 # the package is published in.
812 self.assertEqual(
813 False,
814 archive.canUploadSuiteSourcePackage(person, suitesourcepackage))
619815
620816
621class TestUpdatePackageDownloadCount(TestCaseWithFactory):817class TestUpdatePackageDownloadCount(TestCaseWithFactory):
@@ -1216,3 +1412,29 @@
1216 component=getUtility(IComponentSet)['universe'])1412 component=getUtility(IComponentSet)['universe'])
1217 self.assertDep('i386', 'foo-main', [main_bins[0]])1413 self.assertDep('i386', 'foo-main', [main_bins[0]])
1218 self.assertDep('i386', 'foo-universe', [universe_bins[0]])1414 self.assertDep('i386', 'foo-universe', [universe_bins[0]])
1415
1416
1417class TestComponents(TestCaseWithFactory):
1418
1419 layer = DatabaseFunctionalLayer
1420
1421 def test_no_components_for_arbitrary_person(self):
1422 # By default, a person cannot upload to any component of an archive.
1423 archive = self.factory.makeArchive()
1424 person = self.factory.makePerson()
1425 self.assertEqual(set(),
1426 set(archive.getComponentsForUploader(person)))
1427
1428 def test_components_for_person_with_permissions(self):
1429 # If a person has been explicitly granted upload permissions to a
1430 # particular component, then those components are included in
1431 # IArchive.getComponentsForUploader.
1432 archive = self.factory.makeArchive()
1433 component = self.factory.makeComponent()
1434 person = self.factory.makePerson()
1435 # Only admins or techboard members can add permissions normally. That
1436 # restriction isn't relevant to this test.
1437 ap_set = removeSecurityProxy(getUtility(IArchivePermissionSet))
1438 ap = ap_set.newComponentUploader(archive, person, component)
1439 self.assertEqual(set([ap]),
1440 set(archive.getComponentsForUploader(person)))
12191441
=== modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py'
--- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-13 19:36:56 +0000
+++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-08-04 22:02:48 +0000
@@ -10,7 +10,7 @@
1010
11from canonical.launchpad.webapp.interfaces import (11from canonical.launchpad.webapp.interfaces import (
12 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)12 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
13from canonical.testing import LaunchpadZopelessLayer13from canonical.testing import DatabaseFunctionalLayer, LaunchpadZopelessLayer
1414
15from lp.buildmaster.interfaces.buildbase import BuildStatus15from lp.buildmaster.interfaces.buildbase import BuildStatus
16from lp.buildmaster.interfaces.builder import IBuilderSet16from lp.buildmaster.interfaces.builder import IBuilderSet
@@ -244,3 +244,22 @@
244 build_package_job.jobStarted()244 build_package_job.jobStarted()
245 self.failUnlessEqual(245 self.failUnlessEqual(
246 BuildStatus.BUILDING, build_package_job.build.status)246 BuildStatus.BUILDING, build_package_job.build.status)
247
248
249class TestBuildPackageJobScore(TestCaseWithFactory):
250
251 layer = DatabaseFunctionalLayer
252
253 def test_score_unusual_component(self):
254 unusual_component = self.factory.makeComponent(name="unusual")
255 source_package_release = self.factory.makeSourcePackageRelease()
256 self.factory.makeSourcePackagePublishingHistory(
257 sourcepackagerelease=source_package_release,
258 component=unusual_component,
259 archive=source_package_release.upload_archive,
260 distroseries=source_package_release.upload_distroseries)
261 build = self.factory.makeBinaryPackageBuild(
262 source_package_release=source_package_release)
263 job = build.buildqueue_record.specific_job
264 # For now just test that it doesn't raise an Exception
265 job.score()
247266
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-08-04 00:41:14 +0000
+++ lib/lp/testing/factory.py 2010-08-04 22:02:48 +0000
@@ -2363,7 +2363,8 @@
2363 libraryfile=library_file, filetype=filetype))2363 libraryfile=library_file, filetype=filetype))
23642364
2365 def makeBinaryPackageBuild(self, source_package_release=None,2365 def makeBinaryPackageBuild(self, source_package_release=None,
2366 distroarchseries=None, archive=None, builder=None):2366 distroarchseries=None, archive=None, builder=None,
2367 status=None):
2367 """Create a BinaryPackageBuild.2368 """Create a BinaryPackageBuild.
23682369
2369 If archive is not supplied, the source_package_release is used2370 If archive is not supplied, the source_package_release is used
@@ -2373,6 +2374,7 @@
2373 :param distroarchseries: The DistroArchSeries to use.2374 :param distroarchseries: The DistroArchSeries to use.
2374 :param archive: The Archive to use.2375 :param archive: The Archive to use.
2375 :param builder: An optional builder to assign.2376 :param builder: An optional builder to assign.
2377 :param status: The BuildStatus for the build.
2376 """2378 """
2377 if archive is None:2379 if archive is None:
2378 if source_package_release is None:2380 if source_package_release is None:
@@ -2383,16 +2385,21 @@
2383 multiverse = self.makeComponent(name='multiverse')2385 multiverse = self.makeComponent(name='multiverse')
2384 source_package_release = self.makeSourcePackageRelease(2386 source_package_release = self.makeSourcePackageRelease(
2385 archive, component=multiverse)2387 archive, component=multiverse)
2388 self.makeSourcePackagePublishingHistory(
2389 distroseries=source_package_release.upload_distroseries,
2390 archive=archive, sourcepackagerelease=source_package_release)
2386 processor = self.makeProcessor()2391 processor = self.makeProcessor()
2387 if distroarchseries is None:2392 if distroarchseries is None:
2388 distroarchseries = self.makeDistroArchSeries(2393 distroarchseries = self.makeDistroArchSeries(
2389 distroseries=source_package_release.upload_distroseries,2394 distroseries=source_package_release.upload_distroseries,
2390 processorfamily=processor.family)2395 processorfamily=processor.family)
2396 if status is None:
2397 status = BuildStatus.NEEDSBUILD
2391 binary_package_build = getUtility(IBinaryPackageBuildSet).new(2398 binary_package_build = getUtility(IBinaryPackageBuildSet).new(
2392 source_package_release=source_package_release,2399 source_package_release=source_package_release,
2393 processor=processor,2400 processor=processor,
2394 distro_arch_series=distroarchseries,2401 distro_arch_series=distroarchseries,
2395 status=BuildStatus.NEEDSBUILD,2402 status=status,
2396 archive=archive,2403 archive=archive,
2397 pocket=PackagePublishingPocket.RELEASE,2404 pocket=PackagePublishingPocket.RELEASE,
2398 date_created=self.getUniqueDate())2405 date_created=self.getUniqueDate())
@@ -2611,7 +2618,8 @@
2611 isinstance(sourcepackagename, basestring)):2618 isinstance(sourcepackagename, basestring)):
2612 sourcepackagename = self.getOrMakeSourcePackageName(2619 sourcepackagename = self.getOrMakeSourcePackageName(
2613 sourcepackagename)2620 sourcepackagename)
2614 return SuiteSourcePackage(distroseries, pocket, sourcepackagename)2621 return ProxyFactory(
2622 SuiteSourcePackage(distroseries, pocket, sourcepackagename))
26152623
2616 def makeDistributionSourcePackage(self, sourcepackagename=None,2624 def makeDistributionSourcePackage(self, sourcepackagename=None,
2617 distribution=None):2625 distribution=None):
26182626
=== modified file 'lib/lp/testing/tests/test_factory.py'
--- lib/lp/testing/tests/test_factory.py 2010-08-02 19:52:59 +0000
+++ lib/lp/testing/tests/test_factory.py 2010-08-04 22:02:48 +0000
@@ -15,9 +15,12 @@
15from canonical.launchpad.webapp.interfaces import ILaunchBag15from canonical.launchpad.webapp.interfaces import ILaunchBag
16from canonical.testing.layers import (16from canonical.testing.layers import (
17 DatabaseFunctionalLayer, LaunchpadZopelessLayer)17 DatabaseFunctionalLayer, LaunchpadZopelessLayer)
18from lp.buildmaster.interfaces.buildbase import BuildStatus
18from lp.code.enums import CodeImportReviewStatus19from lp.code.enums import CodeImportReviewStatus
19from lp.registry.interfaces.sourcepackage import SourcePackageFileType20from lp.registry.interfaces.sourcepackage import SourcePackageFileType
21from lp.registry.interfaces.suitesourcepackage import ISuiteSourcePackage
20from lp.services.worlddata.interfaces.language import ILanguage22from lp.services.worlddata.interfaces.language import ILanguage
23from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuild
21from lp.soyuz.interfaces.binarypackagerelease import (24from lp.soyuz.interfaces.binarypackagerelease import (
22 BinaryPackageFileType, IBinaryPackageRelease)25 BinaryPackageFileType, IBinaryPackageRelease)
23from lp.soyuz.interfaces.files import (26from lp.soyuz.interfaces.files import (
@@ -42,6 +45,32 @@
42 self.assertIsNot(None, person)45 self.assertIsNot(None, person)
43 self.assertEqual(person, current_person)46 self.assertEqual(person, current_person)
4447
48 # makeBinaryPackageBuild
49 def test_makeBinaryPackageBuild_returns_IBinaryPackageBuild(self):
50 bpb = self.factory.makeBinaryPackageBuild()
51 self.assertThat(
52 removeSecurityProxy(bpb), Provides(IBinaryPackageBuild))
53
54 def test_makeBinaryPackageBuild_returns_proxy(self):
55 bpb = self.factory.makeBinaryPackageBuild()
56 self.assertThat(bpb, IsProxied())
57
58 def test_makeBinaryPackageBuild_created_SPR_is_published(self):
59 # It is expected that every build references an SPR that is
60 # published in the target archive. Check that a created
61 # SPR is also published.
62 bpb = self.factory.makeBinaryPackageBuild()
63 self.assertIn(
64 bpb.archive, bpb.source_package_release.published_archives)
65
66 def test_makeBinaryPackageBuild_uses_status(self):
67 bpb = self.factory.makeBinaryPackageBuild(
68 status=BuildStatus.NEEDSBUILD)
69 self.assertEqual(BuildStatus.NEEDSBUILD, bpb.status)
70 bpb = self.factory.makeBinaryPackageBuild(
71 status=BuildStatus.FULLYBUILT)
72 self.assertEqual(BuildStatus.FULLYBUILT, bpb.status)
73
45 # makeBinaryPackagePublishingHistory74 # makeBinaryPackagePublishingHistory
46 def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self):75 def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self):
47 bpph = self.factory.makeBinaryPackagePublishingHistory()76 bpph = self.factory.makeBinaryPackagePublishingHistory()
@@ -170,6 +199,11 @@
170 scheduleddeletiondate=scheduleddeletiondate)199 scheduleddeletiondate=scheduleddeletiondate)
171 self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate)200 self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate)
172201
202 # makeSuiteSourcePackage
203 def test_makeSuiteSourcePackage_returns_ISuiteSourcePackage(self):
204 ssp = self.factory.makeSuiteSourcePackage()
205 self.assertThat(ssp, ProvidesAndIsProxied(ISuiteSourcePackage))
206
173207
174class TestFactoryWithLibrarian(TestCaseWithFactory):208class TestFactoryWithLibrarian(TestCaseWithFactory):
175209