Merge ~pelpsi/launchpad:alphabetical-sort-orderd-unhelpful-codenames into launchpad:master

Proposed by Simone Pelosi
Status: Merged
Approved by: Simone Pelosi
Approved revision: 18a42c72f7f15854ec0d7024abe210226e633ec5
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~pelpsi/launchpad:alphabetical-sort-orderd-unhelpful-codenames
Merge into: launchpad:master
Diff against target: 93 lines (+50/-3)
3 files modified
lib/lp/registry/interfaces/product.py (+2/-1)
lib/lp/registry/model/product.py (+9/-2)
lib/lp/registry/tests/test_product.py (+39/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+439077@code.launchpad.net

Commit message

Current alphabetical sort order for Ubuntu codenames is unhelpful

translation sorted by distroseries.version instead of (distroseries.name, package.name)

LP: #1923378

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote (last edit ):

Have you noticed that Colin suggested to replace `p.distroseries.name` with `Version(p.distroseries.version)` in the related bug in a comment?

If you plan to do otherwise, what are your reasons?

Also, while it seem daunting to find corresponding tests, there are a couple of strategies I use.

First, as you modify something in `product.py`, it is highly likely that there are unit tests in a `test_product.py` near the same location of the former file.

You are modifying the `translatable_packages` property, so the first I would do is search for that name in the above test file. If that does not show up, I would look where `translatable_packages` is used and then look for the corresponding tests.

Also, sometimes we do have doctests, which are a bit harder to find.

Running the whole test suite to find the correct tests is usually off limits except for the most severe changesets, as it takes so long ( 6 hours on my laptop, though mine seems to be on the slower end ).

tl/dr Although we do not measure test coverage, we seem to have a pretty high coverage. Please have a look whether you could create a test, and in case you need help, please do not hesitate to reach out.

Revision history for this message
Colin Watson (cjwatson) wrote :

I don't think it was right to remove the source package name from the sort keys here. Can you explain your thinking there? My inclination would be to put it back, because there's nothing technically to prevent the same upstream product being packaged in more than one source package (it happens in practice sometimes due to renames), and we should make the sort order be deterministic in that case.

It should be straightforward to add some test coverage for this, so I'd definitely like to see that before landing this (if nothing else because it will be some practice with the test suite). An untested sketch of the setup part of a unit test might look something like this (probably in `lp.registry.tests.test_product.TestProduct`):

    productseries = self.factory.makeProductSeries()
    zesty = self.factory.makeUbuntuDistroSeries(version="17.04", name="zesty")
    artful = self.factory.makeUbuntuDistroSeries(version="17.10", name="artful")
    spns = [self.factory.makeSourcePackageName("package-%d" % i) for i in range(2)]
    for distroseries in zesty, artful:
        for spn in spns:
            self.factory.makePackagingLink(productseries=productseries, sourcepackagename=spn, distroseries=distroseries)
            self.factory.makePOTemplate(distroseries=distroseries, sourcepackagename=spn)

(Normally I prefer to use entirely synthetic data in tests, but in this case the real Ubuntu "zesty" and "artful" series make a good illustration of the problem we're trying to avoid.)

You'd then want to assert that `productseries.product.translatable_packages` is in the right order, which in this case would be `(artful, spns[0]), (artful, spns[1]), (zesty, spns[0]), (zesty, spns[1])`.

review: Needs Fixing
Revision history for this message
Colin Watson (cjwatson) wrote :

(And I agree with Jürgen that this should wrap `Version()` around the series version, so that it compares using version semantics rather than purely lexicographically.)

18a42c7... by Simone Pelosi

Added a test case for translated packages order and fixed the sorting order

Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/interfaces/product.py b/lib/lp/registry/interfaces/product.py
2index a27236b..e28f68c 100644
3--- a/lib/lp/registry/interfaces/product.py
4+++ b/lib/lp/registry/interfaces/product.py
5@@ -920,7 +920,8 @@ class IProductView(
6
7 translatable_packages = Attribute(
8 "A list of the source packages for this product that can be "
9- "translated sorted by distroseries.name and sourcepackage.name."
10+ "translated sorted by distroseries.version (descending order) "
11+ "and package.name (ascending order)."
12 )
13
14 translatable_series = Attribute(
15diff --git a/lib/lp/registry/model/product.py b/lib/lp/registry/model/product.py
16index f7c3b99..8faf3cf 100644
17--- a/lib/lp/registry/model/product.py
18+++ b/lib/lp/registry/model/product.py
19@@ -57,6 +57,7 @@ from lp.app.errors import NotFoundError, ServiceUsageForbidden
20 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
21 from lp.app.interfaces.services import IService
22 from lp.app.model.launchpad import InformationTypeMixin
23+from lp.archivepublisher.debversion import Version
24 from lp.blueprints.enums import SpecificationFilter
25 from lp.blueprints.model.specification import (
26 SPECIFICATION_POLICY_ALLOWED_TYPES,
27@@ -1270,8 +1271,14 @@ class Product(
28 if package.has_current_translation_templates
29 }
30
31- # Sort packages by distroseries.name and package.name
32- return sorted(packages, key=lambda p: (p.distroseries.name, p.name))
33+ # Sort packages by distroseries.version (descending order)
34+ # and package.name (ascending order)
35+ sorted_by_names = sorted(packages, key=lambda p: p.name)
36+ return sorted(
37+ sorted_by_names,
38+ key=lambda p: Version(p.distroseries.version),
39+ reverse=True,
40+ )
41
42 @property
43 def translatable_series(self):
44diff --git a/lib/lp/registry/tests/test_product.py b/lib/lp/registry/tests/test_product.py
45index 6f28d7b..5401861 100644
46--- a/lib/lp/registry/tests/test_product.py
47+++ b/lib/lp/registry/tests/test_product.py
48@@ -256,6 +256,45 @@ class TestProduct(TestCaseWithFactory):
49 [series.name for series in product.getVersionSortedSeries()],
50 )
51
52+ def test_translatable_packages_order(self):
53+ # The product translatable packages should be ordered
54+ # by Version(distroseries.version) and package.name in
55+ # descending order.
56+ productseries = self.factory.makeProductSeries()
57+ zesty = self.factory.makeUbuntuDistroSeries(
58+ version="17.04", name="zesty"
59+ )
60+ artful = self.factory.makeUbuntuDistroSeries(
61+ version="17.10", name="artful"
62+ )
63+ spns = [
64+ self.factory.makeSourcePackageName("package-%d" % i)
65+ for i in range(2)
66+ ]
67+
68+ for distroseries in zesty, artful:
69+ for spn in spns:
70+ self.factory.makePackagingLink(
71+ productseries=productseries,
72+ sourcepackagename=spn,
73+ distroseries=distroseries,
74+ )
75+ self.factory.makePOTemplate(
76+ distroseries=distroseries, sourcepackagename=spn
77+ )
78+ self.assertEqual(
79+ [
80+ ("artful", "package-0"),
81+ ("artful", "package-1"),
82+ ("zesty", "package-0"),
83+ ("zesty", "package-1"),
84+ ],
85+ [
86+ (p.distroseries.name, p.name)
87+ for p in productseries.product.translatable_packages
88+ ],
89+ )
90+
91 def test_getVersionSortedSeries_with_specific_statuses(self):
92 # The obsolete series should be included in the results if
93 # statuses=[SeriesStatus.OBSOLETE]. The development focus will

Subscribers

People subscribed via source and target branches

to status/vote changes: