Merge lp:~cjwatson/launchpad/remove-recipe-quota into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 17468
Proposed branch: lp:~cjwatson/launchpad/remove-recipe-quota
Merge into: lp:launchpad
Diff against target: 333 lines (+3/-161)
9 files modified
lib/lp/code/browser/sourcepackagerecipe.py (+1/-11)
lib/lp/code/browser/tests/test_sourcepackagerecipe.py (+1/-35)
lib/lp/code/errors.py (+0/-11)
lib/lp/code/interfaces/sourcepackagerecipe.py (+0/-7)
lib/lp/code/interfaces/webservice.py (+0/-2)
lib/lp/code/model/sourcepackagerecipe.py (+0/-8)
lib/lp/code/model/sourcepackagerecipebuild.py (+1/-14)
lib/lp/code/model/tests/test_sourcepackagerecipe.py (+0/-39)
lib/lp/code/model/tests/test_sourcepackagerecipebuild.py (+0/-34)
To merge this branch: bzr merge lp:~cjwatson/launchpad/remove-recipe-quota
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+257845@code.launchpad.net

Commit message

Remove the hardcoded five-a-day recipe build quota.

Description of the change

Remove the hardcoded five-a-day recipe build quota. It's an occasional support burden and is generally more trouble than it's worth now that the PPA build farm is much more capable. We have other ways to deal with abuse if that becomes necessary.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/browser/sourcepackagerecipe.py'
2--- lib/lp/code/browser/sourcepackagerecipe.py 2014-11-16 09:49:59 +0000
3+++ lib/lp/code/browser/sourcepackagerecipe.py 2015-04-30 02:20:23 +0000
4@@ -89,7 +89,6 @@
5 BuildAlreadyPending,
6 NoSuchBranch,
7 PrivateBranchRecipe,
8- TooManyBuilds,
9 TooNewRecipeFormat,
10 )
11 from lp.code.interfaces.branchtarget import IBranchTarget
12@@ -390,15 +389,6 @@
13 "You need to specify at least one distro series for which "
14 "to build.")
15 return
16- over_quota_distroseries = []
17- for distroseries in data['distroseries']:
18- if self.context.isOverQuota(self.user, distroseries):
19- over_quota_distroseries.append(str(distroseries))
20- if len(over_quota_distroseries) > 0:
21- self.setFieldError(
22- 'distroseries',
23- "You have exceeded today's quota for %s." %
24- ', '.join(over_quota_distroseries))
25
26 def requestBuild(self, data):
27 """User action for requesting a number of builds.
28@@ -527,7 +517,7 @@
29 recipe = self.context
30 try:
31 builds = recipe.performDailyBuild()
32- except (TooManyBuilds, ArchiveDisabled) as e:
33+ except ArchiveDisabled as e:
34 self.request.response.addErrorNotification(str(e))
35 self.next_url = canonical_url(recipe)
36 return
37
38=== modified file 'lib/lp/code/browser/tests/test_sourcepackagerecipe.py'
39--- lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2015-04-20 09:48:57 +0000
40+++ lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2015-04-30 02:20:23 +0000
41@@ -1384,24 +1384,6 @@
42 set([2505]),
43 set(build.buildqueue_record.lastscore for build in builds))
44
45- def test_request_daily_builds_action_over_quota(self):
46- recipe = self.factory.makeSourcePackageRecipe(
47- owner=self.chef, daily_build_archive=self.ppa,
48- name=u'julia', is_stale=True, build_daily=True)
49- # Create some previous builds.
50- series = list(recipe.distroseries)[0]
51- for x in xrange(5):
52- build = recipe.requestBuild(
53- self.ppa, self.chef, series, PackagePublishingPocket.RELEASE)
54- build.updateStatus(BuildStatus.FULLYBUILT)
55- harness = LaunchpadFormHarness(
56- recipe, SourcePackageRecipeRequestDailyBuildView)
57- harness.submit('build', {})
58- self.assertEqual(
59- "You have exceeded your quota for recipe chef/julia "
60- "for distroseries ubuntu warty",
61- harness.view.request.notifications[0].message)
62-
63 def test_request_daily_builds_disabled_archive(self):
64 # Requesting a daily build from a disabled archive is a user error.
65 recipe = self.factory.makeSourcePackageRecipe(
66@@ -1509,24 +1491,8 @@
67 self.factory.makePerson(), supports_virtualized=True)
68 return woody
69
70- def test_request_build_rejects_over_quota(self):
71- """Over-quota build requests cause validation failures."""
72- woody = self._makeWoodyDistroSeries()
73- recipe = self.makeRecipe()
74- for x in range(5):
75- build = recipe.requestBuild(
76- self.ppa, self.chef, woody, PackagePublishingPocket.RELEASE)
77- build.updateStatus(BuildStatus.FULLYBUILT)
78-
79- browser = self.getViewBrowser(recipe, '+request-builds')
80- browser.getControl('Woody').click()
81- browser.getControl('Request builds').click()
82- self.assertIn(
83- html_escape("You have exceeded today's quota for ubuntu woody."),
84- extract_text(find_main_content(browser.contents)))
85-
86 def test_request_builds_rejects_duplicate(self):
87- """Over-quota build requests cause validation failures."""
88+ """Duplicate build requests cause validation failures."""
89 woody = self._makeWoodyDistroSeries()
90 recipe = self.makeRecipe()
91 recipe.requestBuild(
92
93=== modified file 'lib/lp/code/errors.py'
94--- lib/lp/code/errors.py 2015-04-29 12:55:48 +0000
95+++ lib/lp/code/errors.py 2015-04-30 02:20:23 +0000
96@@ -46,7 +46,6 @@
97 'PrivateBranchRecipe',
98 'ReviewNotPending',
99 'StaleLastMirrored',
100- 'TooManyBuilds',
101 'TooNewRecipeFormat',
102 'UnknownBranchTypeError',
103 'UpdatePreviewDiffNotReady',
104@@ -465,16 +464,6 @@
105 Exception.__init__(self, msg)
106
107
108-class TooManyBuilds(RecipeBuildException):
109- """A build was requested that exceeded the quota."""
110-
111- def __init__(self, recipe, distroseries):
112- RecipeBuildException.__init__(
113- self, recipe, distroseries,
114- 'You have exceeded your quota for recipe %(recipe)s for'
115- ' distroseries %(distroseries)s')
116-
117-
118 class BuildAlreadyPending(RecipeBuildException):
119 """A build was requested when an identical build was already pending."""
120
121
122=== modified file 'lib/lp/code/interfaces/sourcepackagerecipe.py'
123--- lib/lp/code/interfaces/sourcepackagerecipe.py 2014-07-09 03:08:57 +0000
124+++ lib/lp/code/interfaces/sourcepackagerecipe.py 2015-04-30 02:20:23 +0000
125@@ -135,13 +135,6 @@
126 title=_("The the most recent build of this recipe."),
127 readonly=True))
128
129- def isOverQuota(requester, distroseries):
130- """True if the recipe/requester/distroseries combo is >= quota.
131-
132- :param requester: The Person requesting a build.
133- :param distroseries: The distroseries to build for.
134- """
135-
136 @call_with(requester=REQUEST_USER)
137 @operation_parameters(
138 archive=Reference(schema=IArchive),
139
140=== modified file 'lib/lp/code/interfaces/webservice.py'
141--- lib/lp/code/interfaces/webservice.py 2015-04-19 12:56:32 +0000
142+++ lib/lp/code/interfaces/webservice.py 2015-04-30 02:20:23 +0000
143@@ -33,7 +33,6 @@
144 'IPreviewDiff',
145 'ISourcePackageRecipe',
146 'ISourcePackageRecipeBuild',
147- 'TooManyBuilds',
148 ]
149
150 # The exceptions are imported so that they can produce the special
151@@ -46,7 +45,6 @@
152 BuildAlreadyPending,
153 CodeImportAlreadyRunning,
154 CodeImportNotInReviewedState,
155- TooManyBuilds,
156 )
157 from lp.code.interfaces.branch import (
158 IBranch,
159
160=== modified file 'lib/lp/code/model/sourcepackagerecipe.py'
161--- lib/lp/code/model/sourcepackagerecipe.py 2015-02-24 13:46:46 +0000
162+++ lib/lp/code/model/sourcepackagerecipe.py 2015-04-30 02:20:23 +0000
163@@ -40,7 +40,6 @@
164 from lp.code.errors import (
165 BuildAlreadyPending,
166 BuildNotAllowedForDistro,
167- TooManyBuilds,
168 )
169 from lp.code.interfaces.sourcepackagerecipe import (
170 ISourcePackageRecipe,
171@@ -254,11 +253,6 @@
172 store.remove(self._recipe_data)
173 store.remove(self)
174
175- def isOverQuota(self, requester, distroseries):
176- """See `ISourcePackageRecipe`."""
177- return SourcePackageRecipeBuild.getRecentBuilds(
178- requester, self, distroseries).count() >= 5
179-
180 def containsUnbuildableSeries(self, archive):
181 buildable_distros = set(
182 BuildableDistroSeries.findSeries(archive.owner))
183@@ -280,8 +274,6 @@
184 pocket)
185 if reject_reason is not None:
186 raise reject_reason
187- if self.isOverQuota(requester, distroseries):
188- raise TooManyBuilds(self, distroseries)
189 pending = IStore(self).find(SourcePackageRecipeBuild,
190 SourcePackageRecipeBuild.recipe_id == self.id,
191 SourcePackageRecipeBuild.distroseries_id == distroseries.id,
192
193=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
194--- lib/lp/code/model/sourcepackagerecipebuild.py 2013-11-28 05:13:37 +0000
195+++ lib/lp/code/model/sourcepackagerecipebuild.py 2015-04-30 02:20:23 +0000
196@@ -8,10 +8,7 @@
197 'SourcePackageRecipeBuild',
198 ]
199
200-from datetime import (
201- datetime,
202- timedelta,
203- )
204+from datetime import timedelta
205 import logging
206
207 from psycopg2 import ProgrammingError
208@@ -318,16 +315,6 @@
209 bfj.id for bfj in build_farm_jobs))
210 return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)
211
212- @classmethod
213- def getRecentBuilds(cls, requester, recipe, distroseries, _now=None):
214- if _now is None:
215- _now = datetime.now(pytz.UTC)
216- store = IMasterStore(SourcePackageRecipeBuild)
217- old_threshold = _now - timedelta(days=1)
218- return store.find(cls, cls.distroseries_id == distroseries.id,
219- cls.requester_id == requester.id, cls.recipe_id == recipe.id,
220- cls.date_created > old_threshold)
221-
222 def estimateDuration(self):
223 """See `IPackageBuild`."""
224 median = self.recipe.getMedianBuildDuration()
225
226=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py'
227--- lib/lp/code/model/tests/test_sourcepackagerecipe.py 2014-09-01 03:45:08 +0000
228+++ lib/lp/code/model/tests/test_sourcepackagerecipe.py 2015-04-30 02:20:23 +0000
229@@ -32,7 +32,6 @@
230 from lp.code.errors import (
231 BuildAlreadyPending,
232 PrivateBranchRecipe,
233- TooManyBuilds,
234 TooNewRecipeFormat,
235 )
236 from lp.code.interfaces.sourcepackagerecipe import (
237@@ -406,24 +405,6 @@
238 queue_record.score()
239 self.assertEqual(2705, queue_record.lastscore)
240
241- def test_requestBuildRejectsOverQuota(self):
242- """Build requests that exceed quota raise an exception."""
243- requester = self.factory.makePerson(name='requester')
244- recipe = self.factory.makeSourcePackageRecipe(
245- name=u'myrecipe', owner=requester)
246- series = list(recipe.distroseries)[0]
247- archive = self.factory.makeArchive(owner=requester)
248-
249- def request_build():
250- build = recipe.requestBuild(archive, requester, series,
251- PackagePublishingPocket.RELEASE)
252- build.updateStatus(BuildStatus.FULLYBUILT)
253- [request_build() for num in range(5)]
254- e = self.assertRaises(TooManyBuilds, request_build)
255- self.assertIn(
256- 'You have exceeded your quota for recipe requester/myrecipe',
257- str(e))
258-
259 def test_requestBuildRejectRepeats(self):
260 """Reject build requests that are identical to pending builds."""
261 recipe = self.factory.makeSourcePackageRecipe()
262@@ -1120,26 +1101,6 @@
263 self.assertIn(
264 'An identical build of this recipe is already pending.', str(e))
265
266- def test_requestBuildRejectOverQuota(self):
267- """Build requests are rejected if they exceed quota."""
268- person = self.factory.makePerson()
269- archives = [self.factory.makeArchive(owner=person) for x in range(6)]
270- distroseries = self.factory.makeSourcePackageRecipeDistroseries()
271-
272- recipe, user, launchpad = self.makeRecipe(person)
273- distroseries = ws_object(launchpad, distroseries)
274- for archive in archives[:-1]:
275- archive = ws_object(launchpad, archive)
276- recipe.requestBuild(
277- archive=archive, distroseries=distroseries,
278- pocket=PackagePublishingPocket.RELEASE.title)
279-
280- archive = ws_object(launchpad, archives[-1])
281- e = self.assertRaises(Exception, recipe.requestBuild,
282- archive=archive, distroseries=distroseries,
283- pocket=PackagePublishingPocket.RELEASE.title)
284- self.assertIn('You have exceeded your quota', str(e))
285-
286 def test_requestBuildRejectUnsupportedDistroSeries(self):
287 """Build requests are rejected if they have a bad distroseries."""
288 person = self.factory.makePerson()
289
290=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipebuild.py'
291--- lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2015-04-20 09:48:57 +0000
292+++ lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2015-04-30 02:20:23 +0000
293@@ -406,40 +406,6 @@
294 "DEBUG - cannot build against Warty (4.10).",
295 logger.getLogBuffer())
296
297- def test_getRecentBuilds(self):
298- """Recent builds match the same person, series and receipe.
299-
300- Builds do not match if they are older than 24 hours, or have a
301- different requester, series or recipe.
302- """
303- requester = self.factory.makePerson()
304- recipe = self.factory.makeSourcePackageRecipe()
305- series = self.factory.makeDistroSeries()
306- removeSecurityProxy(series).nominatedarchindep = (
307- self.factory.makeDistroArchSeries(distroseries=series))
308- now = self.factory.getUniqueDate()
309- build = self.factory.makeSourcePackageRecipeBuild(recipe=recipe,
310- requester=requester)
311- self.factory.makeSourcePackageRecipeBuild(
312- recipe=recipe, distroseries=series)
313- self.factory.makeSourcePackageRecipeBuild(
314- requester=requester, distroseries=series)
315-
316- def get_recent():
317- Store.of(build).flush()
318- return SourcePackageRecipeBuild.getRecentBuilds(
319- requester, recipe, series, _now=now)
320- self.assertContentEqual([], get_recent())
321- yesterday = now - timedelta(days=1)
322- self.factory.makeSourcePackageRecipeBuild(
323- recipe=recipe, distroseries=series, requester=requester,
324- date_created=yesterday)
325- self.assertContentEqual([], get_recent())
326- more_recent_build = self.factory.makeSourcePackageRecipeBuild(
327- recipe=recipe, distroseries=series, requester=requester,
328- date_created=yesterday + timedelta(seconds=1))
329- self.assertContentEqual([more_recent_build], get_recent())
330-
331 def test_destroySelf(self):
332 # ISourcePackageRecipeBuild should make sure to remove jobs and build
333 # queue entries and then invalidate itself.