Merge lp:~cjwatson/launchpad/recipe-build-ordering into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18587
Proposed branch: lp:~cjwatson/launchpad/recipe-build-ordering
Merge into: lp:launchpad
Diff against target: 70 lines (+23/-6)
2 files modified
lib/lp/code/model/sourcepackagerecipe.py (+9/-6)
lib/lp/code/model/tests/test_sourcepackagerecipe.py (+14/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad/recipe-build-ordering
Reviewer Review Type Date Requested Status
William Grant code Approve
Vincent Ladeuil (community) hug Approve
Review via email: mp+340534@code.launchpad.net

Commit message

Sort cancelled-before-starting recipe builds to the end of the build history.

Description of the change

These queries will be a little slower until the corresponding database branch lands, but they do well enough with other indexes that we don't need to coordinate that too carefully.

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

And the world is a better place...
Thanks ;)

Revision history for this message
Vincent Ladeuil (vila) :
review: Approve (hug)
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/model/sourcepackagerecipe.py'
2--- lib/lp/code/model/sourcepackagerecipe.py 2016-10-14 16:16:18 +0000
3+++ lib/lp/code/model/sourcepackagerecipe.py 2018-03-02 18:02:05 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
6+# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """Implementation of the `SourcePackageRecipe` content type."""
10@@ -67,7 +67,10 @@
11 IMasterStore,
12 IStore,
13 )
14-from lp.services.database.stormexpr import Greatest
15+from lp.services.database.stormexpr import (
16+ Greatest,
17+ NullsLast,
18+ )
19 from lp.services.propertycache import (
20 cachedproperty,
21 get_property_cache,
22@@ -330,9 +333,9 @@
23 def builds(self):
24 """See `ISourcePackageRecipe`."""
25 order_by = (
26- Desc(Greatest(
27+ NullsLast(Desc(Greatest(
28 SourcePackageRecipeBuild.date_started,
29- SourcePackageRecipeBuild.date_finished)),
30+ SourcePackageRecipeBuild.date_finished))),
31 Desc(SourcePackageRecipeBuild.date_created),
32 Desc(SourcePackageRecipeBuild.id))
33 return self._getBuilds(None, order_by)
34@@ -343,9 +346,9 @@
35 filter_term = (
36 SourcePackageRecipeBuild.status != BuildStatus.NEEDSBUILD)
37 order_by = (
38- Desc(Greatest(
39+ NullsLast(Desc(Greatest(
40 SourcePackageRecipeBuild.date_started,
41- SourcePackageRecipeBuild.date_finished)),
42+ SourcePackageRecipeBuild.date_finished))),
43 Desc(SourcePackageRecipeBuild.id))
44 return self._getBuilds(filter_term, order_by)
45
46
47=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py'
48--- lib/lp/code/model/tests/test_sourcepackagerecipe.py 2017-10-04 01:53:48 +0000
49+++ lib/lp/code/model/tests/test_sourcepackagerecipe.py 2018-03-02 18:02:05 +0000
50@@ -765,6 +765,20 @@
51 self.assertEqual([build], list(recipe.completed_builds))
52 self.assertEqual([], list(recipe.pending_builds))
53
54+ def test_getBuilds_cancelled_never_started_last(self):
55+ # A cancelled build that was never even started sorts to the end.
56+ recipe = self.makeSourcePackageRecipe()
57+ fullybuilt = self.factory.makeSourcePackageRecipeBuild(recipe=recipe)
58+ instacancelled = self.factory.makeSourcePackageRecipeBuild(
59+ recipe=recipe)
60+ fullybuilt.updateStatus(BuildStatus.BUILDING)
61+ fullybuilt.updateStatus(BuildStatus.CANCELLED)
62+ instacancelled.updateStatus(BuildStatus.CANCELLED)
63+ self.assertEqual([fullybuilt, instacancelled], list(recipe.builds))
64+ self.assertEqual(
65+ [fullybuilt, instacancelled], list(recipe.completed_builds))
66+ self.assertEqual([], list(recipe.pending_builds))
67+
68 def test_setRecipeText_private_base_branch(self):
69 source_package_recipe = self.makeSourcePackageRecipe()
70 with person_logged_in(source_package_recipe.owner):