Merge lp:~wallyworld/launchpad/recent-recipe-build-query into lp:launchpad

Proposed by Ian Booth
Status: Merged
Merged at revision: 12072
Proposed branch: lp:~wallyworld/launchpad/recent-recipe-build-query
Merge into: lp:launchpad
Diff against target: 264 lines (+75/-62)
5 files modified
lib/lp/code/browser/tests/test_recipebuildslisting.py (+4/-4)
lib/lp/code/configure.zcml (+1/-1)
lib/lp/code/model/recipebuild.py (+9/-9)
lib/lp/code/templates/daily-builds-listing.pt (+3/-3)
lib/lp/testing/factory.py (+58/-45)
To merge this branch: bzr merge lp:~wallyworld/launchpad/recent-recipe-build-query
Reviewer Review Type Date Requested Status
Tim Penhey (community) Approve
Review via email: mp+43608@code.launchpad.net

Commit message

[r=thumper][ui=none][bug=690035] Rework the query used to load the most recently completed daily recipe builds.

Description of the change

= Summary =

Quick fix to correct the query used to load most recently completed source package recipes.

= Implementation =

The Storm find query was modified to produce the correct joins and group by the correct columns. The SourcePackageRecipeBuild in the group by was replaced with SourcePackageRecipe. Tweaks also to the page template and RecipeBuildRecord named tuple to reference the changed data attribute.

= Tests =

The makeRecipeBuildRecords factory method was fixed to create recipe build records with the correct daily build archive set and enhanced to create build records which should not be displayed. These extra records have daily build set to False and/or build status set to "needs build".

bin/test -vvt test_recipebuildslisting

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/code/configure.zcml
  lib/lp/code/browser/tests/test_recipebuildslisting.py
  lib/lp/code/model/recipebuild.py
  lib/lp/code/templates/daily-builds-listing.pt
  lib/lp/testing/factory.py

./lib/lp/code/model/recipebuild.py
     152: E302 expected 2 blank lines, found 1

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/browser/tests/test_recipebuildslisting.py'
2--- lib/lp/code/browser/tests/test_recipebuildslisting.py 2010-12-13 21:20:03 +0000
3+++ lib/lp/code/browser/tests/test_recipebuildslisting.py 2010-12-14 05:59:55 +0000
4@@ -48,14 +48,14 @@
5 layer = DatabaseFunctionalLayer
6
7 def _extract_view_text(self, recipe_build_record):
8- naked_recipebuild = removeSecurityProxy(
9- recipe_build_record.recipebuild)
10+ naked_archive = removeSecurityProxy(
11+ recipe_build_record.archive)
12 naked_distribution = removeSecurityProxy(
13- naked_recipebuild.distribution)
14+ naked_archive.distribution)
15 text = '\n'.join(str(item) for item in (
16 naked_distribution.displayname,
17 recipe_build_record.sourcepackagename.name,
18- naked_recipebuild.recipe.name,
19+ recipe_build_record.recipe.name,
20 recipe_build_record.recipeowner.displayname,
21 recipe_build_record.archive.displayname,
22 recipe_build_record.most_recent_build_time.strftime(
23
24=== modified file 'lib/lp/code/configure.zcml'
25--- lib/lp/code/configure.zcml 2010-11-26 03:16:53 +0000
26+++ lib/lp/code/configure.zcml 2010-12-14 05:59:55 +0000
27@@ -1012,7 +1012,7 @@
28 </securedutility>
29
30 <class class="lp.code.model.recipebuild.RecipeBuildRecord">
31- <allow attributes="sourcepackagename recipeowner recipebuild archive
32+ <allow attributes="sourcepackagename recipeowner recipe archive
33 most_recent_build_time distro_source_package"/>
34 </class>
35
36
37=== modified file 'lib/lp/code/model/recipebuild.py'
38--- lib/lp/code/model/recipebuild.py 2010-12-01 23:42:55 +0000
39+++ lib/lp/code/model/recipebuild.py 2010-12-14 05:59:55 +0000
40@@ -48,7 +48,7 @@
41
42 class RecipeBuildRecord(namedtuple(
43 'RecipeBuildRecord',
44- """sourcepackagename, recipeowner, archive, recipebuild,
45+ """sourcepackagename, recipeowner, archive, recipe,
46 most_recent_build_time""")):
47 # We need to implement our own equality check since __eq__ is broken on
48 # SourcePackageRecipe. It's broken there because __eq__ is broken,
49@@ -56,7 +56,7 @@
50 def __eq__(self, other):
51 return (self.sourcepackagename == other.sourcepackagename
52 and self.recipeowner == other.recipeowner
53- and self.recipebuild.recipe.name == other.recipebuild.recipe.name
54+ and self.recipe.name == other.recipe.name
55 and self.archive == other.archive
56 and self.most_recent_build_time == other.most_recent_build_time)
57
58@@ -64,13 +64,13 @@
59 return (
60 hash(self.sourcepackagename.name) ^
61 hash(self.recipeowner.name) ^
62- hash(self.recipebuild.recipe.name) ^
63+ hash(self.recipe.name) ^
64 hash(self.archive.name) ^
65 hash(self.most_recent_build_time))
66
67 @property
68 def distro_source_package(self):
69- return self.recipebuild.distribution.getSourcePackage(
70+ return self.archive.distribution.getSourcePackage(
71 self.sourcepackagename)
72
73
74@@ -104,7 +104,7 @@
75 BinaryPackageBuild.package_build_id),
76 Join(Archive,
77 Archive.id ==
78- PackageBuild.archive_id),
79+ SourcePackageRecipe.daily_build_archive_id),
80 Join(BuildFarmJob,
81 BuildFarmJob.id ==
82 PackageBuild.build_farm_job_id),
83@@ -119,7 +119,7 @@
84 result_set = store.using(*tables).find(
85 (SourcePackageName,
86 Person,
87- SourcePackageRecipeBuild,
88+ SourcePackageRecipe,
89 Archive,
90 Max(BuildFarmJob.date_finished),
91 ),
92@@ -127,7 +127,7 @@
93 ).group_by(
94 SourcePackageName,
95 Person,
96- SourcePackageRecipeBuild,
97+ SourcePackageRecipe,
98 Archive,
99 ).order_by(
100 SourcePackageName.name,
101@@ -136,11 +136,11 @@
102 )
103
104 def _makeRecipeBuildRecord(values):
105- (sourcepackagename, recipeowner, recipebuild, archive,
106+ (sourcepackagename, recipeowner, recipe, archive,
107 date_finished) = values
108 return RecipeBuildRecord(
109 sourcepackagename, recipeowner,
110- archive, recipebuild,
111+ archive, recipe,
112 date_finished)
113
114 return RecipeBuildRecordResultSet(
115
116=== modified file 'lib/lp/code/templates/daily-builds-listing.pt'
117--- lib/lp/code/templates/daily-builds-listing.pt 2010-11-26 03:14:03 +0000
118+++ lib/lp/code/templates/daily-builds-listing.pt 2010-12-14 05:59:55 +0000
119@@ -69,14 +69,14 @@
120 <tbody>
121 <tr tal:repeat="dailybuild dailybuilds">
122 <td>
123- <a tal:replace="structure dailybuild/recipebuild/distribution/fmt:link">distribution</a>
124+ <a tal:replace="structure dailybuild/archive/distribution/fmt:link">distribution</a>
125 <a tal:attributes="href dailybuild/distro_source_package/fmt:url"
126 tal:content="dailybuild/sourcepackagename/name">source package name</a>
127 </td>
128
129 <td>
130- <a href="recipe" tal:attributes="href dailybuild/recipebuild/recipe/fmt:url">
131- <span tal:replace="dailybuild/recipebuild/recipe/name">
132+ <a href="recipe" tal:attributes="href dailybuild/recipe/fmt:url">
133+ <span tal:replace="dailybuild/recipe/name">
134 recipe
135 </span>
136 </a>
137
138=== modified file 'lib/lp/testing/factory.py'
139--- lib/lp/testing/factory.py 2010-12-14 02:02:38 +0000
140+++ lib/lp/testing/factory.py 2010-12-14 05:59:55 +0000
141@@ -2295,7 +2295,10 @@
142
143 A RecipeBuildRecord is a named tuple. Some records will be created
144 with archive of type ArchivePurpose.PRIMARY, others with type
145- ArchivePurpose.PPA.
146+ ArchivePurpose.PPA. Some build records with be created with a build
147+ status of fully built and some will be created with the daily build
148+ option set to True and False. Only those records with daily build set
149+ to True and build status to fully built are returned.
150 :param num_recent_records: the number of records within the specified
151 time window.
152 :param num_records_outside_epoch: the number of records outside the
153@@ -2308,12 +2311,6 @@
154 sourcepackage = self.makeSourcePackage(
155 sourcepackagename=sourcepackagename,
156 distroseries=distroseries)
157- recipeowner = self.makePerson()
158- recipe = self.makeSourcePackageRecipe(
159- build_daily=True,
160- owner=recipeowner,
161- name="Recipe_"+sourcepackagename.name,
162- distroseries=distroseries)
163
164 records = []
165 records_outside_epoch = []
166@@ -2323,44 +2320,60 @@
167 purpose = ArchivePurpose.PPA
168 else:
169 purpose = ArchivePurpose.PRIMARY
170- archive = self.makeArchive(purpose=purpose)
171- sprb = self.makeSourcePackageRecipeBuild(
172- requester=recipeowner,
173- recipe=recipe,
174- archive=archive,
175- sourcepackage=sourcepackage,
176- distroseries=distroseries)
177- spr = self.makeSourcePackageRelease(
178- source_package_recipe_build=sprb,
179- archive=archive,
180- sourcepackagename=sourcepackagename,
181- distroseries=distroseries)
182- binary_build = self.makeBinaryPackageBuild(
183- source_package_release=spr)
184- naked_build = removeSecurityProxy(binary_build)
185- naked_build.queueBuild()
186- naked_build.status = BuildStatus.FULLYBUILT
187-
188- from random import randrange
189- offset = randrange(0, epoch_days)
190- now = datetime.now(UTC)
191- if x >= num_recent_records:
192- offset = epoch_days + 1 + offset
193- naked_build.date_finished = (
194- now - timedelta(days=offset))
195- naked_build.date_started = (
196- naked_build.date_finished - timedelta(minutes=5))
197- rbr = RecipeBuildRecord(
198- removeSecurityProxy(sourcepackagename),
199- removeSecurityProxy(recipeowner),
200- removeSecurityProxy(archive),
201- removeSecurityProxy(sprb),
202- naked_build.date_finished.replace(tzinfo=None))
203-
204- if x < num_recent_records:
205- records.append(rbr)
206- else:
207- records_outside_epoch.append(rbr)
208+ archive = self.makeArchive(
209+ purpose=purpose, distribution=distroseries.distribution)
210+ # Make some daily and non-daily recipe builds.
211+ for daily in (True, False):
212+ recipeowner = self.makePerson()
213+ recipe = self.makeSourcePackageRecipe(
214+ build_daily=daily,
215+ owner=recipeowner,
216+ name="Recipe_%s_%d" % (sourcepackagename.name, x),
217+ daily_build_archive=archive,
218+ distroseries=distroseries)
219+ sprb = self.makeSourcePackageRecipeBuild(
220+ requester=recipeowner,
221+ recipe=recipe,
222+ sourcepackage=sourcepackage,
223+ distroseries=distroseries)
224+ spr = self.makeSourcePackageRelease(
225+ source_package_recipe_build=sprb,
226+ sourcepackagename=sourcepackagename,
227+ distroseries=distroseries)
228+
229+ # Make some complete and incomplete builds.
230+ for build_status in (
231+ BuildStatus.FULLYBUILT,
232+ BuildStatus.NEEDSBUILD,
233+ ):
234+ binary_build = self.makeBinaryPackageBuild(
235+ source_package_release=spr)
236+ naked_build = removeSecurityProxy(binary_build)
237+ naked_build.queueBuild()
238+ naked_build.status = build_status
239+
240+ from random import randrange
241+ offset = randrange(0, epoch_days)
242+ now = datetime.now(UTC)
243+ if x >= num_recent_records:
244+ offset = epoch_days + 1 + offset
245+ naked_build.date_finished = (
246+ now - timedelta(days=offset))
247+ naked_build.date_started = (
248+ naked_build.date_finished - timedelta(minutes=5))
249+ rbr = RecipeBuildRecord(
250+ removeSecurityProxy(sourcepackagename),
251+ removeSecurityProxy(recipeowner),
252+ removeSecurityProxy(archive),
253+ removeSecurityProxy(recipe),
254+ naked_build.date_finished.replace(tzinfo=None))
255+
256+ # Only return fully completed daily builds.
257+ if daily and build_status == BuildStatus.FULLYBUILT:
258+ if x < num_recent_records:
259+ records.append(rbr)
260+ else:
261+ records_outside_epoch.append(rbr)
262 # We need to explicitly commit because if don't, the records don't
263 # appear in the slave datastore.
264 transaction.commit()