Merge lp:~wgrant/launchpad/ddeb-domination into lp:launchpad/db-devel

Proposed by William Grant
Status: Merged
Approved by: Māris Fogels
Approved revision: no longer in the source branch.
Merged at revision: 9581
Proposed branch: lp:~wgrant/launchpad/ddeb-domination
Merge into: lp:launchpad/db-devel
Diff against target: 252 lines (+134/-9)
4 files modified
lib/lp/archivepublisher/domination.py (+4/-1)
lib/lp/archivepublisher/tests/test_dominator.py (+34/-3)
lib/lp/soyuz/model/publishing.py (+35/-1)
lib/lp/soyuz/tests/test_publishing.py (+61/-4)
To merge this branch: bzr merge lp:~wgrant/launchpad/ddeb-domination
Reviewer Review Type Date Requested Status
Māris Fogels (community) code Approve
Review via email: mp+30928@code.launchpad.net

Commit message

Binary publications now supersede their corresponding debug publications when they are themselves superseded.

Description of the change

This branch alters binary domination to fix bug #604425.

DDEBs need to be as unintrusive as possible -- people shouldn't have to change how they deal with archive administration. To help with this, DDEB publications should be superseded as soon as their DEB is. This will, for example, eliminate the need for archive admins to manually NBS them out if they stop being built.

This is implemented much the same as atomic arch-indep domination: BinaryPackagePublishingHistory.supersede locates corresponding DDEB publications with the same overrides, and supersedes them.

Because of this change, it's no longer important for DDEBs to supersede each other (their DEBs will handle it all). I've filtered them out of the Dominator query, and added an assertion to confirm that no DDEB ever accidentally supersedes something else.

To post a comment you must log in.
Revision history for this message
Māris Fogels (mars) wrote :

Hi William,

This is a very good change! At first I was caught thinking testJudgeAndDominateWithDDEBs() needed refactoring, but was pleasantly surprised to find that you fully tested both DDEB policies in the test_publishing module. I guess testJudgeAndDominate is just checking that the components are integrated correctly.

The only other question is about _getCorrespondingDDEBPublications(): can it use the ISlaveStore instead of the IMasterStore? Check lib/canonical/launchpad/doc/db-policy.txt for the difference.

Otherwise this looks good to me: r=mars

Maris

review: Approve (code)
Revision history for this message
William Grant (wgrant) wrote :

Hi Māris,

On Tue, 2010-07-27 at 20:26 +0000, Māris Fogels wrote:
> Review: Approve code
> Hi William,

Thanks for the review.

> This is a very good change! At first I was caught thinking
> testJudgeAndDominateWithDDEBs() needed refactoring, but was pleasantly
> surprised to find that you fully tested both DDEB policies in the
> test_publishing module. I guess testJudgeAndDominate is just checking
> that the components are integrated correctly.

Right. I refactored the related code in earlier branches to make this
style of testing possible. I think it worked pretty well.

> The only other question is about _getCorrespondingDDEBPublications():
> can it use the ISlaveStore instead of the IMasterStore? Check
> lib/canonical/launchpad/doc/db-policy.txt for the difference.

This is the sort of thing where it's absolutely critical that we have
up-to-the-second data. Using the slave store would be dangerous.

> Otherwise this looks good to me: r=mars

Thanks!

Revision history for this message
Robert Collins (lifeless) wrote :

there is a typo - 'independet'.

-Rob

Revision history for this message
William Grant (wgrant) wrote :

Robert:

145 - # If this is architecture-independet, all publications with the same
        ^ It's already fixed!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/archivepublisher/domination.py'
2--- lib/lp/archivepublisher/domination.py 2010-07-11 13:58:56 +0000
3+++ lib/lp/archivepublisher/domination.py 2010-07-26 12:04:48 +0000
4@@ -66,6 +66,7 @@
5 clear_current_connection_cache)
6
7 from canonical.launchpad.interfaces import PackagePublishingStatus
8+from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
9
10
11 def clear_cache():
12@@ -310,10 +311,12 @@
13 AND binarypackagepublishinghistory.status = %s AND
14 binarypackagepublishinghistory.binarypackagerelease =
15 binarypackagerelease.id
16+ AND binarypackagerelease.binpackageformat != %s
17 AND binarypackagerelease.binarypackagename IN (
18 SELECT name FROM PubDomHelper WHERE count > 1)"""
19 % sqlvalues(distroarchseries, self.archive,
20- pocket, PackagePublishingStatus.PUBLISHED),
21+ pocket, PackagePublishingStatus.PUBLISHED,
22+ BinaryPackageFormat.DDEB),
23 clauseTables=['BinaryPackageRelease'])
24
25 self.debug("Dominating binaries...")
26
27=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
28--- lib/lp/archivepublisher/tests/test_dominator.py 2010-07-22 11:59:40 +0000
29+++ lib/lp/archivepublisher/tests/test_dominator.py 2010-07-26 12:04:48 +0000
30@@ -18,13 +18,14 @@
31 class TestDominator(TestNativePublishingBase):
32 """Test Dominator class."""
33
34- def createSourceAndBinaries(self, version):
35+ def createSourceAndBinaries(self, version, with_debug=False,
36+ archive=None):
37 """Create a source and binaries with the given version."""
38 source = self.getPubSource(
39- version=version,
40+ version=version, archive=archive,
41 status=PackagePublishingStatus.PUBLISHED)
42 binaries = self.getPubBinaries(
43- pub_source=source,
44+ pub_source=source, with_debug=with_debug,
45 status=PackagePublishingStatus.PUBLISHED)
46 return (source, binaries)
47
48@@ -107,6 +108,36 @@
49 [foo_10_source] + foo_10_binaries,
50 PackagePublishingStatus.SUPERSEDED)
51
52+ def testJudgeAndDominateWithDDEBs(self):
53+ """Verify that judgeAndDominate ignores DDEBs correctly.
54+
55+ DDEBs are superseded by their corresponding DEB publications, so they
56+ are forbidden from superseding publications (an attempt would result
57+ in an AssertionError), and shouldn't be directly considered for
58+ superseding either.
59+ """
60+ ppa = self.factory.makeArchive()
61+ foo_10_source, foo_10_binaries = self.createSourceAndBinaries(
62+ '1.0', with_debug=True, archive=ppa)
63+ foo_11_source, foo_11_binaries = self.createSourceAndBinaries(
64+ '1.1', with_debug=True, archive=ppa)
65+ foo_12_source, foo_12_binaries = self.createSourceAndBinaries(
66+ '1.2', with_debug=True, archive=ppa)
67+
68+ dominator = Dominator(self.logger, ppa)
69+ dominator.judgeAndDominate(
70+ foo_10_source.distroseries, foo_10_source.pocket, self.config)
71+
72+ self.checkPublications(
73+ [foo_12_source] + foo_12_binaries,
74+ PackagePublishingStatus.PUBLISHED)
75+ self.checkPublications(
76+ [foo_11_source] + foo_11_binaries,
77+ PackagePublishingStatus.SUPERSEDED)
78+ self.checkPublications(
79+ [foo_10_source] + foo_10_binaries,
80+ PackagePublishingStatus.SUPERSEDED)
81+
82 def testEmptyDomination(self):
83 """Domination asserts for not empty input list."""
84 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
85
86=== modified file 'lib/lp/soyuz/model/publishing.py'
87--- lib/lp/soyuz/model/publishing.py 2010-07-21 14:14:54 +0000
88+++ lib/lp/soyuz/model/publishing.py 2010-07-26 12:04:48 +0000
89@@ -50,6 +50,7 @@
90 from lp.registry.interfaces.person import validate_public_person
91 from lp.registry.interfaces.pocket import PackagePublishingPocket
92 from lp.services.worlddata.model.country import Country
93+from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
94 from lp.soyuz.model.binarypackagename import BinaryPackageName
95 from lp.soyuz.model.binarypackagerelease import (BinaryPackageRelease,
96 BinaryPackageReleaseDownloadCount)
97@@ -975,6 +976,26 @@
98 section=self.section,
99 priority=self.priority)
100
101+ def _getCorrespondingDDEBPublications(self):
102+ """Return remaining publications of the corresponding DDEB.
103+
104+ Only considers binary publications in the corresponding debug
105+ archive with the same distroarchseries, pocket, component, section
106+ and priority.
107+ """
108+ return IMasterStore(BinaryPackagePublishingHistory).find(
109+ BinaryPackagePublishingHistory,
110+ BinaryPackagePublishingHistory.status.is_in(
111+ [PUBLISHED, PENDING]),
112+ BinaryPackagePublishingHistory.distroarchseries ==
113+ self.distroarchseries,
114+ binarypackagerelease=self.binarypackagerelease.debug_package,
115+ archive=self.archive.debug_archive,
116+ pocket=self.pocket,
117+ component=self.component,
118+ section=self.section,
119+ priority=self.priority)
120+
121 def supersede(self, dominant=None, logger=None):
122 """See `IBinaryPackagePublishingHistory`."""
123 # At this point only PUBLISHED (ancient versions) or PENDING (
124@@ -993,6 +1014,16 @@
125 super(BinaryPackagePublishingHistory, self).supersede()
126
127 if dominant is not None:
128+ # DDEBs cannot themselves be dominant; they are always dominated
129+ # by their corresponding DEB. Any attempt to dominate with a
130+ # dominant DDEB is a bug.
131+ assert (
132+ dominant.binarypackagerelease.binpackageformat !=
133+ BinaryPackageFormat.DDEB), (
134+ "Should not dominate with %s (%s); DDEBs cannot dominate" % (
135+ dominant.binarypackagerelease.title,
136+ dominant.distroarchseries.architecturetag))
137+
138 dominant_build = dominant.binarypackagerelease.build
139 distroarchseries = dominant_build.distro_arch_series
140 if logger is not None:
141@@ -1010,7 +1041,10 @@
142 # between releases.
143 self.supersededby = dominant_build
144
145- # If this is architecture-independet, all publications with the same
146+ for dominated in self._getCorrespondingDDEBPublications():
147+ dominated.supersede(dominant, logger)
148+
149+ # If this is architecture-independent, all publications with the same
150 # context and overrides should be dominated simultaneously.
151 if not self.binarypackagerelease.architecturespecific:
152 for dominated in self._getOtherPublications():
153
154=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
155--- lib/lp/soyuz/tests/test_publishing.py 2010-07-23 12:19:26 +0000
156+++ lib/lp/soyuz/tests/test_publishing.py 2010-07-26 12:04:48 +0000
157@@ -32,7 +32,7 @@
158 from lp.soyuz.model.processor import ProcessorFamily
159 from lp.soyuz.model.publishing import (
160 SourcePackagePublishingHistory, BinaryPackagePublishingHistory)
161-from lp.soyuz.interfaces.archive import ArchivePurpose
162+from lp.soyuz.interfaces.archive import ArchivePurpose, IArchiveSet
163 from lp.soyuz.interfaces.archivearch import IArchiveArchSet
164 from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
165 from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
166@@ -275,7 +275,8 @@
167 version='666',
168 architecturespecific=False,
169 builder=None,
170- component='main'):
171+ component='main',
172+ with_debug=False):
173 """Return a list of binary publishing records."""
174 if distroseries is None:
175 distroseries = self.distroseries
176@@ -302,11 +303,25 @@
177 published_binaries = []
178 for build in builds:
179 build.builder = builder
180+ pub_binaries = []
181+ if with_debug:
182+ binarypackagerelease_ddeb = self.uploadBinaryForBuild(
183+ build, binaryname + '-dbgsym', filecontent, summary,
184+ description, shlibdep, depends, recommends, suggests,
185+ conflicts, replaces, provides, pre_depends, enhances,
186+ breaks, BinaryPackageFormat.DDEB)
187+ pub_binaries += self.publishBinaryInArchive(
188+ binarypackagerelease_ddeb, archive.debug_archive, status,
189+ pocket, scheduleddeletiondate, dateremoved)
190+ else:
191+ binarypackagerelease_ddeb = None
192+
193 binarypackagerelease = self.uploadBinaryForBuild(
194 build, binaryname, filecontent, summary, description,
195 shlibdep, depends, recommends, suggests, conflicts, replaces,
196- provides, pre_depends, enhances, breaks, format)
197- pub_binaries = self.publishBinaryInArchive(
198+ provides, pre_depends, enhances, breaks, format,
199+ binarypackagerelease_ddeb)
200+ pub_binaries += self.publishBinaryInArchive(
201 binarypackagerelease, archive, status, pocket,
202 scheduleddeletiondate, dateremoved)
203 published_binaries.extend(pub_binaries)
204@@ -1144,6 +1159,48 @@
205 self.checkSuperseded([bin], super_bin)
206 self.assertEquals(super_date, bin.datesuperseded)
207
208+ def testSupersedesCorrespondingDDEB(self):
209+ """Check that supersede() takes with it any corresponding DDEB.
210+
211+ DDEB publications should be superseded when their corresponding DEB
212+ is.
213+ """
214+ getUtility(IArchiveSet).new(
215+ purpose=ArchivePurpose.DEBUG, owner=self.ubuntutest.owner,
216+ distribution=self.ubuntutest)
217+
218+ # Each of these will return (i386 deb, i386 ddeb, hppa deb,
219+ # hppa ddeb).
220+ bins = self.getPubBinaries(
221+ architecturespecific=True, with_debug=True)
222+ super_bins = self.getPubBinaries(
223+ architecturespecific=True, with_debug=True)
224+
225+ bins[0].supersede(super_bins[0])
226+ self.checkSuperseded(bins[:2], super_bins[0])
227+ self.checkPublications(bins[2:], PackagePublishingStatus.PENDING)
228+ self.checkPublications(super_bins, PackagePublishingStatus.PENDING)
229+
230+ bins[2].supersede(super_bins[2])
231+ self.checkSuperseded(bins[:2], super_bins[0])
232+ self.checkSuperseded(bins[2:], super_bins[2])
233+ self.checkPublications(super_bins, PackagePublishingStatus.PENDING)
234+
235+ def testDDEBsCannotSupersede(self):
236+ """Check that DDEBs cannot supersede other publications.
237+
238+ Since DDEBs are superseded when their DEBs are, there's no need to
239+ for them supersede anything themselves. Any such attempt is an error.
240+ """
241+ getUtility(IArchiveSet).new(
242+ purpose=ArchivePurpose.DEBUG, owner=self.ubuntutest.owner,
243+ distribution=self.ubuntutest)
244+
245+ # This will return (i386 deb, i386 ddeb, hppa deb, hppa ddeb).
246+ bins = self.getPubBinaries(
247+ architecturespecific=True, with_debug=True)
248+ self.assertRaises(AssertionError, bins[0].supersede, bins[1])
249+
250
251 class TestBinaryGetOtherPublications(TestNativePublishingBase):
252 """Test BinaryPackagePublishingHistory._getOtherPublications() works."""

Subscribers

People subscribed via source and target branches

to status/vote changes: