Merge lp:~stevenk/launchpad/queue-recipes-better into lp:launchpad
- queue-recipes-better
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Robert Collins | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 12298 | ||||
Proposed branch: | lp:~stevenk/launchpad/queue-recipes-better | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
316 lines (+128/-43) 4 files modified
lib/lp/code/model/sourcepackagerecipe.py (+30/-13) lib/lp/code/model/sourcepackagerecipebuild.py (+7/-4) lib/lp/code/model/tests/test_sourcepackagerecipe.py (+16/-0) lib/lp/code/model/tests/test_sourcepackagerecipebuild.py (+75/-26) |
||||
To merge this branch: | bzr merge lp:~stevenk/launchpad/queue-recipes-better | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code* | Approve | |
Robert Collins (community) | Approve | ||
Review via email: mp+47358@code.launchpad.net |
Commit message
[r=lifeless,
Description of the change
Change findStaleDailyB
Steve Kowalik (stevenk) wrote : | # |
The point of this branch is to foster work to getting the request_
Robert Collins (lifeless) wrote : | # |
On Tue, Jan 25, 2011 at 6:43 PM, Steve Kowalik <email address hidden> wrote:
> The point of this branch is to foster work to getting the request_
That implies that we'll be considering builds which are not
interesting to build, which is inefficient. I don't think this is a
useful step towards where you want to get. Better to only iterate
recipes which are interesting to build on a given run - which won't
need any of the changes of this patch, and will be sufficient in and
of itself.
Seperately, remember than changing something takes time - a 24 hour
interval isn't 24 hours, its really 24 hours - the time we take to do
stuff - otherwise folk will get built one day, not the next, and so
on.
-Rob
William Grant (wgrant) wrote : | # |
Thanks for this change, Steve. However, findStaleDailyB
A few other largely stylistic comments:
- requestBuild should use Archive.
- The join is unreadable; could you please fix up the indentation?
- Why use a RightJoin instead of a LeftJoin? There is not a single other RightJoin callsite in the tree.
- There is some trailing whitespace in findStaleDailyB
Robert Collins (lifeless) wrote : | # |
Mentor review.
I think this is fine to land with a few small tweaks.
William: meta on the review - we try not to escalate the work done in a branch except to avoid regressions; in particular the defects about series and archive are already present in the tree; they are neutral as far as this branch is concerned. I agree that they are defects, but not new to the branch and so deferrable. When possible suggest actual fixes with diffs/something to copy and paste in. Lastly some of the prose could be improved - comments in particular can bitrot so its worth making sure they really are clear.
As for the right join, thats because this is appropriate; we have a really weird one-object,
Steven: I agree about the join indentation. How about this:
+ joins = RightJoin(
+ Join(
+ Join(SourcePack
+ PackageBuild.id == SourcePackageRe
+ BuildFarmJob,
+ And(BuildFarmJob.id == PackageBuild.
+ BuildFarmJob.
+ SourcePackageRe
+ SourcePackageRe
200 + # makeDailyBuilds() won't create a build if the recipe isn't stale.
->
200 + # only stale builds cause makeDailyBuilds() to make new builds
William Grant (wgrant) wrote : | # |
The defects are new, since requesting a single build did not previously unset is_stale.
Robert Collins (lifeless) wrote : | # |
On Mon, Jan 31, 2011 at 4:13 PM, William Grant <email address hidden> wrote:
> The defects are new, since requesting a single build did not previously unset is_stale.
Good catch, we do need to fix them - sorry that I misunderstood.
William Grant (wgrant) wrote : | # |
I'd personally prefer it to be indented like http://
Preview Diff
1 | === modified file 'lib/lp/code/model/sourcepackagerecipe.py' | |||
2 | --- lib/lp/code/model/sourcepackagerecipe.py 2011-01-14 05:46:14 +0000 | |||
3 | +++ lib/lp/code/model/sourcepackagerecipe.py 2011-02-01 01:40:41 +0000 | |||
4 | @@ -11,7 +11,17 @@ | |||
5 | 11 | 'SourcePackageRecipe', | 11 | 'SourcePackageRecipe', |
6 | 12 | ] | 12 | ] |
7 | 13 | 13 | ||
8 | 14 | from datetime import ( | ||
9 | 15 | datetime, | ||
10 | 16 | timedelta, | ||
11 | 17 | ) | ||
12 | 14 | from lazr.delegates import delegates | 18 | from lazr.delegates import delegates |
13 | 19 | from pytz import utc | ||
14 | 20 | from storm.expr import ( | ||
15 | 21 | And, | ||
16 | 22 | Join, | ||
17 | 23 | RightJoin, | ||
18 | 24 | ) | ||
19 | 15 | from storm.locals import ( | 25 | from storm.locals import ( |
20 | 16 | Bool, | 26 | Bool, |
21 | 17 | Desc, | 27 | Desc, |
22 | @@ -56,7 +66,6 @@ | |||
23 | 56 | from lp.registry.interfaces.distroseries import IDistroSeriesSet | 66 | from lp.registry.interfaces.distroseries import IDistroSeriesSet |
24 | 57 | from lp.registry.model.distroseries import DistroSeries | 67 | from lp.registry.model.distroseries import DistroSeries |
25 | 58 | from lp.soyuz.interfaces.archive import IArchiveSet | 68 | from lp.soyuz.interfaces.archive import IArchiveSet |
26 | 59 | from lp.soyuz.interfaces.component import IComponentSet | ||
27 | 60 | 69 | ||
28 | 61 | 70 | ||
29 | 62 | def get_buildable_distroseries_set(user): | 71 | def get_buildable_distroseries_set(user): |
30 | @@ -178,8 +187,22 @@ | |||
31 | 178 | 187 | ||
32 | 179 | @classmethod | 188 | @classmethod |
33 | 180 | def findStaleDailyBuilds(cls): | 189 | def findStaleDailyBuilds(cls): |
36 | 181 | store = IStore(cls) | 190 | one_day_ago = datetime.now(utc) - timedelta(hours=23, minutes=50) |
37 | 182 | return store.find(cls, cls.is_stale == True, cls.build_daily == True) | 191 | joins = RightJoin( |
38 | 192 | Join( | ||
39 | 193 | Join(SourcePackageRecipeBuild, PackageBuild, | ||
40 | 194 | PackageBuild.id == | ||
41 | 195 | SourcePackageRecipeBuild.package_build_id), | ||
42 | 196 | BuildFarmJob, | ||
43 | 197 | And(BuildFarmJob.id == PackageBuild.build_farm_job_id, | ||
44 | 198 | BuildFarmJob.date_created > one_day_ago)), | ||
45 | 199 | SourcePackageRecipe, | ||
46 | 200 | And(SourcePackageRecipeBuild.recipe == SourcePackageRecipe.id, | ||
47 | 201 | SourcePackageRecipe.daily_build_archive_id == | ||
48 | 202 | PackageBuild.archive_id)) | ||
49 | 203 | return IStore(cls).using(joins).find( | ||
50 | 204 | cls, cls.is_stale == True, cls.build_daily == True, | ||
51 | 205 | BuildFarmJob.date_created == None).config(distinct=True) | ||
52 | 183 | 206 | ||
53 | 184 | @staticmethod | 207 | @staticmethod |
54 | 185 | def exists(owner, name): | 208 | def exists(owner, name): |
55 | @@ -216,14 +239,14 @@ | |||
56 | 216 | raise ValueError('Source package recipe builds disabled.') | 239 | raise ValueError('Source package recipe builds disabled.') |
57 | 217 | if not archive.is_ppa: | 240 | if not archive.is_ppa: |
58 | 218 | raise NonPPABuildRequest | 241 | raise NonPPABuildRequest |
59 | 219 | component = getUtility(IComponentSet)["multiverse"] | ||
60 | 220 | 242 | ||
61 | 221 | buildable_distros = get_buildable_distroseries_set(archive.owner) | 243 | buildable_distros = get_buildable_distroseries_set(archive.owner) |
62 | 222 | if distroseries not in buildable_distros: | 244 | if distroseries not in buildable_distros: |
63 | 223 | raise BuildNotAllowedForDistro(self, distroseries) | 245 | raise BuildNotAllowedForDistro(self, distroseries) |
64 | 224 | 246 | ||
65 | 225 | reject_reason = archive.checkUpload( | 247 | reject_reason = archive.checkUpload( |
67 | 226 | requester, self.distroseries, None, component, pocket) | 248 | requester, self.distroseries, None, archive.default_component, |
68 | 249 | pocket) | ||
69 | 227 | if reject_reason is not None: | 250 | if reject_reason is not None: |
70 | 228 | raise reject_reason | 251 | raise reject_reason |
71 | 229 | if self.isOverQuota(requester, distroseries): | 252 | if self.isOverQuota(requester, distroseries): |
72 | @@ -271,14 +294,8 @@ | |||
73 | 271 | 294 | ||
74 | 272 | def getLastBuild(self): | 295 | def getLastBuild(self): |
75 | 273 | """See `ISourcePackageRecipeBuild`.""" | 296 | """See `ISourcePackageRecipeBuild`.""" |
84 | 274 | store = Store.of(self) | 297 | return self._getBuilds( |
85 | 275 | result = store.find( | 298 | True, Desc(BuildFarmJob.date_finished)).first() |
78 | 276 | (SourcePackageRecipeBuild), | ||
79 | 277 | SourcePackageRecipeBuild.recipe == self, | ||
80 | 278 | SourcePackageRecipeBuild.package_build_id == PackageBuild.id, | ||
81 | 279 | PackageBuild.build_farm_job_id == BuildFarmJob.id) | ||
82 | 280 | result.order_by(Desc(BuildFarmJob.date_finished)) | ||
83 | 281 | return result.first() | ||
86 | 282 | 299 | ||
87 | 283 | def getMedianBuildDuration(self): | 300 | def getMedianBuildDuration(self): |
88 | 284 | """Return the median duration of builds of this recipe.""" | 301 | """Return the median duration of builds of this recipe.""" |
89 | 285 | 302 | ||
90 | === modified file 'lib/lp/code/model/sourcepackagerecipebuild.py' | |||
91 | --- lib/lp/code/model/sourcepackagerecipebuild.py 2011-01-20 22:01:29 +0000 | |||
92 | +++ lib/lp/code/model/sourcepackagerecipebuild.py 2011-02-01 01:40:41 +0000 | |||
93 | @@ -10,7 +10,10 @@ | |||
94 | 10 | 'SourcePackageRecipeBuild', | 10 | 'SourcePackageRecipeBuild', |
95 | 11 | ] | 11 | ] |
96 | 12 | 12 | ||
98 | 13 | import datetime | 13 | from datetime import ( |
99 | 14 | datetime, | ||
100 | 15 | timedelta, | ||
101 | 16 | ) | ||
102 | 14 | import logging | 17 | import logging |
103 | 15 | import sys | 18 | import sys |
104 | 16 | 19 | ||
105 | @@ -259,9 +262,9 @@ | |||
106 | 259 | def getRecentBuilds(cls, requester, recipe, distroseries, _now=None): | 262 | def getRecentBuilds(cls, requester, recipe, distroseries, _now=None): |
107 | 260 | from lp.buildmaster.model.buildfarmjob import BuildFarmJob | 263 | from lp.buildmaster.model.buildfarmjob import BuildFarmJob |
108 | 261 | if _now is None: | 264 | if _now is None: |
110 | 262 | _now = datetime.datetime.now(utc) | 265 | _now = datetime.now(utc) |
111 | 263 | store = IMasterStore(SourcePackageRecipeBuild) | 266 | store = IMasterStore(SourcePackageRecipeBuild) |
113 | 264 | old_threshold = _now - datetime.timedelta(days=1) | 267 | old_threshold = _now - timedelta(days=1) |
114 | 265 | return store.find(cls, cls.distroseries_id == distroseries.id, | 268 | return store.find(cls, cls.distroseries_id == distroseries.id, |
115 | 266 | cls.requester_id == requester.id, cls.recipe_id == recipe.id, | 269 | cls.requester_id == requester.id, cls.recipe_id == recipe.id, |
116 | 267 | BuildFarmJob.date_created > old_threshold, | 270 | BuildFarmJob.date_created > old_threshold, |
117 | @@ -282,7 +285,7 @@ | |||
118 | 282 | median = self.recipe.getMedianBuildDuration() | 285 | median = self.recipe.getMedianBuildDuration() |
119 | 283 | if median is not None: | 286 | if median is not None: |
120 | 284 | return median | 287 | return median |
122 | 285 | return datetime.timedelta(minutes=10) | 288 | return timedelta(minutes=10) |
123 | 286 | 289 | ||
124 | 287 | def verifySuccessfulUpload(self): | 290 | def verifySuccessfulUpload(self): |
125 | 288 | return self.source_package_release is not None | 291 | return self.source_package_release is not None |
126 | 289 | 292 | ||
127 | === modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py' | |||
128 | --- lib/lp/code/model/tests/test_sourcepackagerecipe.py 2011-01-13 03:53:53 +0000 | |||
129 | +++ lib/lp/code/model/tests/test_sourcepackagerecipe.py 2011-02-01 01:40:41 +0000 | |||
130 | @@ -561,6 +561,22 @@ | |||
131 | 561 | self.assertContentEqual([stale_daily], | 561 | self.assertContentEqual([stale_daily], |
132 | 562 | SourcePackageRecipe.findStaleDailyBuilds()) | 562 | SourcePackageRecipe.findStaleDailyBuilds()) |
133 | 563 | 563 | ||
134 | 564 | def test_findStaleDailyBuildsDistinct(self): | ||
135 | 565 | # If a recipe has 2 builds due to 2 distroseries, it only returns | ||
136 | 566 | # one recipe. | ||
137 | 567 | recipe = self.factory.makeSourcePackageRecipe( | ||
138 | 568 | build_daily=True, is_stale=True) | ||
139 | 569 | hoary = self.factory.makeSourcePackageRecipeDistroseries("hoary") | ||
140 | 570 | recipe.distroseries.add(hoary) | ||
141 | 571 | for series in recipe.distroseries: | ||
142 | 572 | build = recipe.requestBuild( | ||
143 | 573 | recipe.daily_build_archive, recipe.owner, | ||
144 | 574 | series, PackagePublishingPocket.RELEASE) | ||
145 | 575 | removeSecurityProxy(build).date_created = ( | ||
146 | 576 | datetime.now(UTC) - timedelta(hours=24, seconds=1)) | ||
147 | 577 | stale_recipes = SourcePackageRecipe.findStaleDailyBuilds() | ||
148 | 578 | self.assertEqual([recipe], list(stale_recipes)) | ||
149 | 579 | |||
150 | 564 | def test_getMedianBuildDuration(self): | 580 | def test_getMedianBuildDuration(self): |
151 | 565 | 581 | ||
152 | 566 | def set_duration(build, minutes): | 582 | def set_duration(build, minutes): |
153 | 567 | 583 | ||
154 | === modified file 'lib/lp/code/model/tests/test_sourcepackagerecipebuild.py' | |||
155 | --- lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2011-01-20 22:01:29 +0000 | |||
156 | +++ lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2011-02-01 01:40:41 +0000 | |||
157 | @@ -5,9 +5,12 @@ | |||
158 | 5 | 5 | ||
159 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
160 | 7 | 7 | ||
162 | 8 | import datetime | 8 | from datetime import ( |
163 | 9 | datetime, | ||
164 | 10 | timedelta, | ||
165 | 11 | ) | ||
166 | 12 | from pytz import utc | ||
167 | 9 | import re | 13 | import re |
168 | 10 | import unittest | ||
169 | 11 | 14 | ||
170 | 12 | from storm.locals import Store | 15 | from storm.locals import Store |
171 | 13 | import transaction | 16 | import transaction |
172 | @@ -177,16 +180,13 @@ | |||
173 | 177 | # If there are no successful builds, estimate 10 minutes. | 180 | # If there are no successful builds, estimate 10 minutes. |
174 | 178 | spb = self.makeSourcePackageRecipeBuild() | 181 | spb = self.makeSourcePackageRecipeBuild() |
175 | 179 | cur_date = self.factory.getUniqueDate() | 182 | cur_date = self.factory.getUniqueDate() |
178 | 180 | self.assertEqual( | 183 | self.assertEqual(timedelta(minutes=10), spb.estimateDuration()) |
177 | 181 | datetime.timedelta(minutes=10), spb.estimateDuration()) | ||
179 | 182 | for minutes in [20, 5, 1]: | 184 | for minutes in [20, 5, 1]: |
180 | 183 | build = removeSecurityProxy( | 185 | build = removeSecurityProxy( |
181 | 184 | self.factory.makeSourcePackageRecipeBuild(recipe=spb.recipe)) | 186 | self.factory.makeSourcePackageRecipeBuild(recipe=spb.recipe)) |
182 | 185 | build.date_started = cur_date | 187 | build.date_started = cur_date |
187 | 186 | build.date_finished = ( | 188 | build.date_finished = cur_date + timedelta(minutes=minutes) |
188 | 187 | cur_date + datetime.timedelta(minutes=minutes)) | 189 | self.assertEqual(timedelta(minutes=5), spb.estimateDuration()) |
185 | 188 | self.assertEqual( | ||
186 | 189 | datetime.timedelta(minutes=5), spb.estimateDuration()) | ||
189 | 190 | 190 | ||
190 | 191 | def test_getFileByName(self): | 191 | def test_getFileByName(self): |
191 | 192 | """getFileByName returns the logs when requested by name.""" | 192 | """getFileByName returns the logs when requested by name.""" |
192 | @@ -269,20 +269,74 @@ | |||
193 | 269 | SourcePackageRecipeBuild.makeDailyBuilds()[0] | 269 | SourcePackageRecipeBuild.makeDailyBuilds()[0] |
194 | 270 | self.assertFalse(recipe.is_stale) | 270 | self.assertFalse(recipe.is_stale) |
195 | 271 | 271 | ||
198 | 272 | def test_makeDailyBuilds_skips_pending(self): | 272 | def test_makeDailyBuilds_skips_if_built_in_last_24_hours(self): |
199 | 273 | """When creating daily builds, skip ones that are already pending.""" | 273 | # We won't create a build during makeDailyBuilds() if the recipe |
200 | 274 | # has been built in the last 24 hours. | ||
201 | 274 | recipe = self.factory.makeSourcePackageRecipe( | 275 | recipe = self.factory.makeSourcePackageRecipe( |
202 | 275 | build_daily=True, is_stale=True) | 276 | build_daily=True, is_stale=True) |
203 | 276 | first_distroseries = list(recipe.distroseries)[0] | ||
204 | 277 | recipe.requestBuild( | 277 | recipe.requestBuild( |
206 | 278 | recipe.daily_build_archive, recipe.owner, first_distroseries, | 278 | recipe.daily_build_archive, recipe.owner, |
207 | 279 | list(recipe.distroseries)[0], PackagePublishingPocket.RELEASE) | ||
208 | 280 | daily_builds = SourcePackageRecipeBuild.makeDailyBuilds() | ||
209 | 281 | self.assertEqual([], daily_builds) | ||
210 | 282 | |||
211 | 283 | def test_makeDailyBuilds_skips_non_stale_builds(self): | ||
212 | 284 | # If the recipe isn't stale, makeDailyBuilds() won't create a build. | ||
213 | 285 | self.factory.makeSourcePackageRecipe( | ||
214 | 286 | build_daily=True, is_stale=False) | ||
215 | 287 | daily_builds = SourcePackageRecipeBuild.makeDailyBuilds() | ||
216 | 288 | self.assertEqual([], daily_builds) | ||
217 | 289 | |||
218 | 290 | def test_makeDailyBuilds_with_an_older_build(self): | ||
219 | 291 | # If a previous build is more than 24 hours old, and the recipe is | ||
220 | 292 | # stale, we'll fire another off. | ||
221 | 293 | recipe = self.factory.makeSourcePackageRecipe( | ||
222 | 294 | build_daily=True, is_stale=True) | ||
223 | 295 | build = recipe.requestBuild( | ||
224 | 296 | recipe.daily_build_archive, recipe.owner, | ||
225 | 297 | list(recipe.distroseries)[0], PackagePublishingPocket.RELEASE) | ||
226 | 298 | nb = removeSecurityProxy(build) | ||
227 | 299 | nb.date_created = datetime.now(utc) - timedelta(hours=24, seconds=1) | ||
228 | 300 | # The build also needs to be completed | ||
229 | 301 | nb.status = BuildStatus.FULLYBUILT | ||
230 | 302 | daily_builds = SourcePackageRecipeBuild.makeDailyBuilds() | ||
231 | 303 | self.assertEquals(1, len(daily_builds)) | ||
232 | 304 | actual_title = [b.title for b in daily_builds] | ||
233 | 305 | self.assertEquals([build.title], actual_title) | ||
234 | 306 | |||
235 | 307 | def test_makeDailyBuilds_with_an_older_and_newer_build(self): | ||
236 | 308 | # If a recipe has been built twice, and the most recent build is | ||
237 | 309 | # within 24 hours, makeDailyBuilds() won't create a build. | ||
238 | 310 | recipe = self.factory.makeSourcePackageRecipe( | ||
239 | 311 | build_daily=True, is_stale=True) | ||
240 | 312 | for timediff in (timedelta(hours=24, seconds=1), timedelta(hours=8)): | ||
241 | 313 | build = recipe.requestBuild( | ||
242 | 314 | recipe.daily_build_archive, recipe.owner, | ||
243 | 315 | list(recipe.distroseries)[0], | ||
244 | 316 | PackagePublishingPocket.RELEASE) | ||
245 | 317 | nb = removeSecurityProxy(build) | ||
246 | 318 | nb.date_created = datetime.now(utc) - timediff | ||
247 | 319 | # The build also needs to be completed | ||
248 | 320 | nb.status = BuildStatus.FULLYBUILT | ||
249 | 321 | daily_builds = SourcePackageRecipeBuild.makeDailyBuilds() | ||
250 | 322 | self.assertEquals([], list(daily_builds)) | ||
251 | 323 | |||
252 | 324 | def test_makeDailyBuilds_with_new_build_different_archive(self): | ||
253 | 325 | # If a recipe has been built into an archive that isn't the | ||
254 | 326 | # daily_build_archive, we will create a build. | ||
255 | 327 | recipe = self.factory.makeSourcePackageRecipe( | ||
256 | 328 | build_daily=True, is_stale=True) | ||
257 | 329 | archive = self.factory.makeArchive(owner=recipe.owner) | ||
258 | 330 | build = recipe.requestBuild( | ||
259 | 331 | archive, recipe.owner, list(recipe.distroseries)[0], | ||
260 | 279 | PackagePublishingPocket.RELEASE) | 332 | PackagePublishingPocket.RELEASE) |
267 | 280 | second_distroseries = \ | 333 | nb = removeSecurityProxy(build) |
268 | 281 | self.factory.makeSourcePackageRecipeDistroseries("hoary") | 334 | nb.date_created = datetime.now(utc) - timedelta(hours=8) |
269 | 282 | recipe.distroseries.add(second_distroseries) | 335 | # The build also needs to be completed |
270 | 283 | builds = SourcePackageRecipeBuild.makeDailyBuilds() | 336 | nb.status = BuildStatus.FULLYBUILT |
271 | 284 | self.assertEqual( | 337 | daily_builds = SourcePackageRecipeBuild.makeDailyBuilds() |
272 | 285 | [second_distroseries], [build.distroseries for build in builds]) | 338 | actual_title = [b.title for b in daily_builds] |
273 | 339 | self.assertEquals([build.title], actual_title) | ||
274 | 286 | 340 | ||
275 | 287 | def test_getRecentBuilds(self): | 341 | def test_getRecentBuilds(self): |
276 | 288 | """Recent builds match the same person, series and receipe. | 342 | """Recent builds match the same person, series and receipe. |
277 | @@ -306,12 +360,12 @@ | |||
278 | 306 | return SourcePackageRecipeBuild.getRecentBuilds( | 360 | return SourcePackageRecipeBuild.getRecentBuilds( |
279 | 307 | requester, recipe, series, _now=now) | 361 | requester, recipe, series, _now=now) |
280 | 308 | self.assertContentEqual([], get_recent()) | 362 | self.assertContentEqual([], get_recent()) |
282 | 309 | yesterday = now - datetime.timedelta(days=1) | 363 | yesterday = now - timedelta(days=1) |
283 | 310 | recent_build = self.factory.makeSourcePackageRecipeBuild( | 364 | recent_build = self.factory.makeSourcePackageRecipeBuild( |
284 | 311 | recipe=recipe, distroseries=series, requester=requester, | 365 | recipe=recipe, distroseries=series, requester=requester, |
285 | 312 | date_created=yesterday) | 366 | date_created=yesterday) |
286 | 313 | self.assertContentEqual([], get_recent()) | 367 | self.assertContentEqual([], get_recent()) |
288 | 314 | a_second = datetime.timedelta(seconds=1) | 368 | a_second = timedelta(seconds=1) |
289 | 315 | removeSecurityProxy(recent_build).date_created += a_second | 369 | removeSecurityProxy(recent_build).date_created += a_second |
290 | 316 | self.assertContentEqual([recent_build], get_recent()) | 370 | self.assertContentEqual([recent_build], get_recent()) |
291 | 317 | 371 | ||
292 | @@ -363,7 +417,6 @@ | |||
293 | 363 | # getSpecificJob returns the SourcePackageRecipeBuild | 417 | # getSpecificJob returns the SourcePackageRecipeBuild |
294 | 364 | sprb = self.makeSourcePackageRecipeBuild() | 418 | sprb = self.makeSourcePackageRecipeBuild() |
295 | 365 | Store.of(sprb).flush() | 419 | Store.of(sprb).flush() |
296 | 366 | build = sprb.build_farm_job | ||
297 | 367 | job = sprb.build_farm_job.getSpecificJob() | 420 | job = sprb.build_farm_job.getSpecificJob() |
298 | 368 | self.assertEqual(sprb, job) | 421 | self.assertEqual(sprb, job) |
299 | 369 | 422 | ||
300 | @@ -443,7 +496,7 @@ | |||
301 | 443 | build = self.factory.makeSourcePackageRecipeBuild( | 496 | build = self.factory.makeSourcePackageRecipeBuild( |
302 | 444 | distroseries=distroseries, | 497 | distroseries=distroseries, |
303 | 445 | status=BuildStatus.FULLYBUILT, | 498 | status=BuildStatus.FULLYBUILT, |
305 | 446 | duration=datetime.timedelta(minutes=5)) | 499 | duration=timedelta(minutes=5)) |
306 | 447 | build.queueBuild(build) | 500 | build.queueBuild(build) |
307 | 448 | return build | 501 | return build |
308 | 449 | 502 | ||
309 | @@ -456,7 +509,3 @@ | |||
310 | 456 | class TestHandleStatusForSPRBuild( | 509 | class TestHandleStatusForSPRBuild( |
311 | 457 | MakeSPRecipeBuildMixin, TestHandleStatusMixin, TrialTestCase): | 510 | MakeSPRecipeBuildMixin, TestHandleStatusMixin, TrialTestCase): |
312 | 458 | """IPackageBuild.handleStatus works with SPRecipe builds.""" | 511 | """IPackageBuild.handleStatus works with SPRecipe builds.""" |
313 | 459 | |||
314 | 460 | |||
315 | 461 | def test_suite(): | ||
316 | 462 | return unittest.TestLoader().loadTestsFromName(__name__) |
So, whats this intended to achieve? As I read it it will result in builds building once every two days. That seems undesirable and confusing.