Merge ~cjwatson/launchpad:fix-dominate-sources-with-channel into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 38c2e117ab40a980961217405f7ea6b4dcdf8b8a
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:fix-dominate-sources-with-channel
Merge into: launchpad:master
Diff against target: 116 lines (+75/-5)
2 files modified
lib/lp/archivepublisher/domination.py (+5/-2)
lib/lp/archivepublisher/tests/test_dominator.py (+70/-3)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+427776@code.launchpad.net

Commit message

Fix domination of source publications with channels

Description of the change

We need to explicitly pass a `jsonb` operand to `IsDistinctFrom`, as otherwise it miscompiles to the nonsensical `channel IS DISTINCT FROM track IS DISTINCT FROM risk IS DISTINCT FROM branch` rather than `channel IS DISTINCT FROM CAST('[track, risk, branch]' AS jsonb)`.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

Good to know for future usages of `IsDistinctFrom` with json blobs.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/archivepublisher/domination.py b/lib/lp/archivepublisher/domination.py
2index 7ee9b5e..d705f81 100644
3--- a/lib/lp/archivepublisher/domination.py
4+++ b/lib/lp/archivepublisher/domination.py
5@@ -50,6 +50,7 @@ it is performed for each suite using:
6
7 __all__ = ["Dominator"]
8
9+import json
10 from collections import defaultdict
11 from datetime import timedelta
12 from functools import cmp_to_key
13@@ -57,7 +58,7 @@ from itertools import filterfalse
14 from operator import attrgetter, itemgetter
15
16 import apt_pkg
17-from storm.expr import And, Count, Desc, Not, Select
18+from storm.expr import And, Cast, Count, Desc, Not, Select
19 from zope.component import getUtility
20
21 from lp.registry.model.sourcepackagename import SourcePackageName
22@@ -594,7 +595,9 @@ class Dominator:
23 Not(
24 IsDistinctFrom(
25 BinaryPackagePublishingHistory._channel,
26- pub_record._channel,
27+ Cast(json.dumps(pub_record._channel), "jsonb")
28+ if pub_record._channel is not None
29+ else None,
30 )
31 ),
32 )
33diff --git a/lib/lp/archivepublisher/tests/test_dominator.py b/lib/lp/archivepublisher/tests/test_dominator.py
34index acff7b4..e689f3c 100644
35--- a/lib/lp/archivepublisher/tests/test_dominator.py
36+++ b/lib/lp/archivepublisher/tests/test_dominator.py
37@@ -517,9 +517,76 @@ class TestDominator(TestNativePublishingBase):
38 for pub in overrides_2:
39 self.assertEqual(PackagePublishingStatus.PUBLISHED, pub.status)
40
41- def test_dominate_by_channel(self):
42- # Publications only dominate other publications in the same channel.
43- # (Currently only tested for binary publications.)
44+ def test_dominate_sources_by_channel(self):
45+ # Source publications only dominate other publications in the same
46+ # channel.
47+ with lp_dbuser():
48+ archive = self.factory.makeArchive()
49+ distroseries = self.factory.makeDistroSeries(
50+ distribution=archive.distribution
51+ )
52+ das = self.factory.makeDistroArchSeries(distroseries=distroseries)
53+ repository = self.factory.makeGitRepository(
54+ target=self.factory.makeDistributionSourcePackage(
55+ distribution=archive.distribution
56+ )
57+ )
58+ ci_builds = [
59+ self.factory.makeCIBuild(
60+ git_repository=repository, distro_arch_series=das
61+ )
62+ for _ in range(3)
63+ ]
64+ spn = self.factory.makeSourcePackageName()
65+ sprs = [
66+ ci_build.createSourcePackageRelease(
67+ distroseries=distroseries,
68+ sourcepackagename=spn,
69+ version=version,
70+ creator=ci_build.git_repository.owner,
71+ archive=archive,
72+ )
73+ for version, ci_build in zip(("1.0", "1.1", "1.2"), ci_builds)
74+ ]
75+ stable_spphs = [
76+ self.factory.makeSourcePackagePublishingHistory(
77+ distroseries=distroseries,
78+ archive=archive,
79+ sourcepackagerelease=spr,
80+ pocket=PackagePublishingPocket.RELEASE,
81+ status=PackagePublishingStatus.PUBLISHED,
82+ channel="stable",
83+ )
84+ for spr in sprs[:2]
85+ ]
86+ candidate_spph = self.factory.makeSourcePackagePublishingHistory(
87+ distroseries=distroseries,
88+ archive=archive,
89+ sourcepackagerelease=sprs[2],
90+ pocket=PackagePublishingPocket.RELEASE,
91+ status=PackagePublishingStatus.PUBLISHED,
92+ channel="candidate",
93+ )
94+
95+ dominator = Dominator(self.logger, archive)
96+ dominator.judgeAndDominate(
97+ distroseries, PackagePublishingPocket.RELEASE
98+ )
99+
100+ # The older of the two stable publications is superseded, while the
101+ # current stable publication and the candidate publication are left
102+ # alone.
103+ self.checkPublication(
104+ stable_spphs[0], PackagePublishingStatus.SUPERSEDED
105+ )
106+ self.checkPublications(
107+ (stable_spphs[1], candidate_spph),
108+ PackagePublishingStatus.PUBLISHED,
109+ )
110+
111+ def test_dominate_binaries_by_channel(self):
112+ # Binary publications only dominate other publications in the same
113+ # channel.
114 with lp_dbuser():
115 archive = self.factory.makeArchive()
116 distroseries = self.factory.makeDistroSeries(

Subscribers

People subscribed via source and target branches

to status/vote changes: