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

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 16064
Proposed branch: lp:~wgrant/launchpad/bug-1058310
Merge into: lp:launchpad
Diff against target: 202 lines (+57/-67)
2 files modified
lib/lp/soyuz/model/buildpackagejob.py (+16/-42)
lib/lp/soyuz/tests/test_buildpackagejob.py (+41/-25)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-1058310
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+127414@code.launchpad.net

Commit message

Rework BinaryPackageBuild scoring: language packs now use the archive base score, packageset scores no longer apply to PPAs, and age-based scoring is gone.

Description of the change

This branch reworks BinaryPackageBuild scoring a little.

Language packs now get the base archive score, rather than always 0 (for the primary archive and public PPAs they'll still be 0, but those in private PPAs and copy archives will now be correctly scored up and down respectively).

Packageset-based score adjustments no longer apply to PPAs, just primary/partner/copy. It's possible we'll also want to adjust copy archives later, but it's not critical either way for now.

I also took the opportunity to eliminate age-based scoring. It's counter-intuitive, the tiebreaker is id (a rather good proxy for age) anyway, and we don't run queue-builder any more so the score is never calculated except at age=0.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) :
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/soyuz/model/buildpackagejob.py'
2--- lib/lp/soyuz/model/buildpackagejob.py 2012-07-20 08:29:06 +0000
3+++ lib/lp/soyuz/model/buildpackagejob.py 2012-10-02 04:50:25 +0000
4@@ -7,9 +7,6 @@
5 ]
6
7
8-from datetime import datetime
9-
10-import pytz
11 from storm.locals import (
12 Int,
13 Reference,
14@@ -76,25 +73,22 @@
15
16 def score(self):
17 """See `IBuildPackageJob`."""
18- # Define a table we'll use to calculate the score based on the time
19- # in the build queue. The table is a sorted list of (upper time
20- # limit in seconds, score) tuples.
21- queue_time_scores = [
22- (14400, 100),
23- (7200, 50),
24- (3600, 20),
25- (1800, 15),
26- (900, 10),
27- (300, 5),
28- ]
29-
30- # Please note: the score for language packs is to be zero because
31- # they unduly delay the building of packages in the main component
32- # otherwise.
33+ score = 0
34+
35+ # Private builds get uber score.
36+ if self.build.archive.private:
37+ score += PRIVATE_ARCHIVE_SCORE_BONUS
38+
39+ if self.build.archive.is_copy:
40+ score -= COPY_ARCHIVE_SCORE_PENALTY
41+
42+ score += self.build.archive.relative_build_score
43+
44+ # Language packs don't get any of the usual package-specific
45+ # score bumps, as they unduly delay the building of packages in
46+ # the main component otherwise.
47 if self.build.source_package_release.section.name == 'translations':
48- return 0
49-
50- score = 0
51+ return score
52
53 # Calculates the urgency-related part of the score.
54 score += SCORE_BY_URGENCY[self.build.source_package_release.urgency]
55@@ -110,29 +104,9 @@
56 package_sets = getUtility(IPackagesetSet).setsIncludingSource(
57 self.build.source_package_release.name,
58 distroseries=self.build.distro_series)
59- if not package_sets.is_empty():
60+ if not self.build.archive.is_ppa and not package_sets.is_empty():
61 score += package_sets.max(Packageset.relative_build_score)
62
63- # Calculates the build queue time component of the score.
64- right_now = datetime.now(pytz.timezone('UTC'))
65- eta = right_now - self.job.date_created
66- for limit, dep_score in queue_time_scores:
67- if eta.seconds > limit:
68- score += dep_score
69- break
70-
71- # Private builds get uber score.
72- if self.build.archive.private:
73- score += PRIVATE_ARCHIVE_SCORE_BONUS
74-
75- if self.build.archive.is_copy:
76- score -= COPY_ARCHIVE_SCORE_PENALTY
77-
78- # Lastly, apply the archive score delta. This is to boost
79- # or retard build scores for any build in a particular
80- # archive.
81- score += self.build.archive.relative_build_score
82-
83 return score
84
85 def getLogFileName(self):
86
87=== modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py'
88--- lib/lp/soyuz/tests/test_buildpackagejob.py 2012-09-28 06:25:44 +0000
89+++ lib/lp/soyuz/tests/test_buildpackagejob.py 2012-10-02 04:50:25 +0000
90@@ -246,23 +246,20 @@
91 layer = DatabaseFunctionalLayer
92
93 def makeBuildJob(self, purpose=None, private=False, component="main",
94- urgency="high", pocket="RELEASE", age=None):
95+ urgency="high", pocket="RELEASE", section_name=None):
96 if purpose is not None or private:
97 archive = self.factory.makeArchive(
98 purpose=purpose, private=private)
99 else:
100 archive = None
101 spph = self.factory.makeSourcePackagePublishingHistory(
102- archive=archive, component=component, urgency=urgency)
103+ archive=archive, component=component, urgency=urgency,
104+ section_name=section_name)
105 naked_spph = removeSecurityProxy(spph) # needed for private archives
106 build = self.factory.makeBinaryPackageBuild(
107 source_package_release=naked_spph.sourcepackagerelease,
108 pocket=pocket)
109- job = removeSecurityProxy(build).makeJob()
110- if age is not None:
111- removeSecurityProxy(job).job.date_created = (
112- datetime.now(pytz.timezone("UTC")) - timedelta(seconds=age))
113- return job
114+ return removeSecurityProxy(build).makeJob()
115
116 # The defaults for pocket, component, and urgency here match those in
117 # makeBuildJob.
118@@ -320,32 +317,29 @@
119 job, "RELEASE", "main", "high", PRIVATE_ARCHIVE_SCORE_BONUS)
120
121 def test_main_release_low_recent_score(self):
122- # Builds created less than five minutes ago get no bonus.
123- job = self.makeBuildJob(component="main", urgency="low", age=290)
124+ # 1500 (RELEASE) + 1000 (main) + 5 (low) = 2505.
125+ job = self.makeBuildJob(component="main", urgency="low")
126 self.assertCorrectScore(job, "RELEASE", "main", "low")
127
128 def test_universe_release_high_five_minutes_score(self):
129- # 1500 (RELEASE) + 250 (universe) + 15 (high) + 5 (>300s) = 1770.
130- job = self.makeBuildJob(component="universe", urgency="high", age=310)
131- self.assertCorrectScore(job, "RELEASE", "universe", "high", 5)
132+ # 1500 (RELEASE) + 250 (universe) + 15 (high) = 1765.
133+ job = self.makeBuildJob(component="universe", urgency="high")
134+ self.assertCorrectScore(job, "RELEASE", "universe", "high")
135
136 def test_multiverse_release_medium_fifteen_minutes_score(self):
137- # 1500 (RELEASE) + 0 (multiverse) + 10 (medium) + 10 (>900s) = 1520.
138- job = self.makeBuildJob(
139- component="multiverse", urgency="medium", age=1000)
140- self.assertCorrectScore(job, "RELEASE", "multiverse", "medium", 10)
141+ # 1500 (RELEASE) + 0 (multiverse) + 10 (medium) = 1510.
142+ job = self.makeBuildJob(component="multiverse", urgency="medium")
143+ self.assertCorrectScore(job, "RELEASE", "multiverse", "medium")
144
145 def test_main_release_emergency_thirty_minutes_score(self):
146- # 1500 (RELEASE) + 1000 (main) + 20 (emergency) + 15 (>1800s) = 2535.
147- job = self.makeBuildJob(
148- component="main", urgency="emergency", age=1801)
149- self.assertCorrectScore(job, "RELEASE", "main", "emergency", 15)
150+ # 1500 (RELEASE) + 1000 (main) + 20 (emergency) = 2520.
151+ job = self.makeBuildJob(component="main", urgency="emergency")
152+ self.assertCorrectScore(job, "RELEASE", "main", "emergency")
153
154 def test_restricted_release_low_one_hour_score(self):
155- # 1500 (RELEASE) + 750 (restricted) + 5 (low) + 20 (>3600s) = 2275.
156- job = self.makeBuildJob(
157- component="restricted", urgency="low", age=4000)
158- self.assertCorrectScore(job, "RELEASE", "restricted", "low", 20)
159+ # 1500 (RELEASE) + 750 (restricted) + 5 (low) = 2255.
160+ job = self.makeBuildJob(component="restricted", urgency="low")
161+ self.assertCorrectScore(job, "RELEASE", "restricted", "low")
162
163 def test_backports_score(self):
164 # BACKPORTS is the lowest-priority pocket.
165@@ -374,7 +368,10 @@
166 self.assertCorrectScore(job, "SECURITY")
167
168 def test_score_packageset(self):
169- job = self.makeBuildJob(component="main", urgency="low")
170+ # Package sets alter the score of official packages for their
171+ # series.
172+ job = self.makeBuildJob(
173+ component="main", urgency="low", purpose=ArchivePurpose.PRIMARY)
174 packageset = self.factory.makePackageset(
175 distroseries=job.build.distro_series)
176 removeSecurityProxy(packageset).add(
177@@ -382,6 +379,25 @@
178 removeSecurityProxy(packageset).relative_build_score = 100
179 self.assertCorrectScore(job, "RELEASE", "main", "low", 100)
180
181+ def test_score_packageset_in_ppa(self):
182+ # Package set score boosts don't affect PPA packages.
183+ job = self.makeBuildJob(
184+ component="main", urgency="low", purpose=ArchivePurpose.PPA)
185+ packageset = self.factory.makePackageset(
186+ distroseries=job.build.distro_series)
187+ removeSecurityProxy(packageset).add(
188+ [job.build.source_package_release.sourcepackagename])
189+ removeSecurityProxy(packageset).relative_build_score = 100
190+ self.assertCorrectScore(job, "RELEASE", "main", "low", 0)
191+
192+ def test_translations_score(self):
193+ # Language packs (the translations section) don't get any
194+ # package-specific score bumps. They always have the archive's
195+ # base score.
196+ job = self.makeBuildJob(section_name='translations')
197+ removeSecurityProxy(job.build.archive).relative_build_score = 666
198+ self.assertEqual(666, job.score())
199+
200 def assertScoreReadableByAnyone(self, obj):
201 """An object's build score is readable by anyone."""
202 with person_logged_in(obj.owner):