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
=== modified file 'lib/lp/archivepublisher/domination.py'
--- lib/lp/archivepublisher/domination.py 2010-07-11 13:58:56 +0000
+++ lib/lp/archivepublisher/domination.py 2010-07-26 12:04:48 +0000
@@ -66,6 +66,7 @@
66 clear_current_connection_cache)66 clear_current_connection_cache)
6767
68from canonical.launchpad.interfaces import PackagePublishingStatus68from canonical.launchpad.interfaces import PackagePublishingStatus
69from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
6970
7071
71def clear_cache():72def clear_cache():
@@ -310,10 +311,12 @@
310 AND binarypackagepublishinghistory.status = %s AND311 AND binarypackagepublishinghistory.status = %s AND
311 binarypackagepublishinghistory.binarypackagerelease =312 binarypackagepublishinghistory.binarypackagerelease =
312 binarypackagerelease.id313 binarypackagerelease.id
314 AND binarypackagerelease.binpackageformat != %s
313 AND binarypackagerelease.binarypackagename IN (315 AND binarypackagerelease.binarypackagename IN (
314 SELECT name FROM PubDomHelper WHERE count > 1)"""316 SELECT name FROM PubDomHelper WHERE count > 1)"""
315 % sqlvalues(distroarchseries, self.archive,317 % sqlvalues(distroarchseries, self.archive,
316 pocket, PackagePublishingStatus.PUBLISHED),318 pocket, PackagePublishingStatus.PUBLISHED,
319 BinaryPackageFormat.DDEB),
317 clauseTables=['BinaryPackageRelease'])320 clauseTables=['BinaryPackageRelease'])
318321
319 self.debug("Dominating binaries...")322 self.debug("Dominating binaries...")
320323
=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
--- lib/lp/archivepublisher/tests/test_dominator.py 2010-07-22 11:59:40 +0000
+++ lib/lp/archivepublisher/tests/test_dominator.py 2010-07-26 12:04:48 +0000
@@ -18,13 +18,14 @@
18class TestDominator(TestNativePublishingBase):18class TestDominator(TestNativePublishingBase):
19 """Test Dominator class."""19 """Test Dominator class."""
2020
21 def createSourceAndBinaries(self, version):21 def createSourceAndBinaries(self, version, with_debug=False,
22 archive=None):
22 """Create a source and binaries with the given version."""23 """Create a source and binaries with the given version."""
23 source = self.getPubSource(24 source = self.getPubSource(
24 version=version,25 version=version, archive=archive,
25 status=PackagePublishingStatus.PUBLISHED)26 status=PackagePublishingStatus.PUBLISHED)
26 binaries = self.getPubBinaries(27 binaries = self.getPubBinaries(
27 pub_source=source,28 pub_source=source, with_debug=with_debug,
28 status=PackagePublishingStatus.PUBLISHED)29 status=PackagePublishingStatus.PUBLISHED)
29 return (source, binaries)30 return (source, binaries)
3031
@@ -107,6 +108,36 @@
107 [foo_10_source] + foo_10_binaries,108 [foo_10_source] + foo_10_binaries,
108 PackagePublishingStatus.SUPERSEDED)109 PackagePublishingStatus.SUPERSEDED)
109110
111 def testJudgeAndDominateWithDDEBs(self):
112 """Verify that judgeAndDominate ignores DDEBs correctly.
113
114 DDEBs are superseded by their corresponding DEB publications, so they
115 are forbidden from superseding publications (an attempt would result
116 in an AssertionError), and shouldn't be directly considered for
117 superseding either.
118 """
119 ppa = self.factory.makeArchive()
120 foo_10_source, foo_10_binaries = self.createSourceAndBinaries(
121 '1.0', with_debug=True, archive=ppa)
122 foo_11_source, foo_11_binaries = self.createSourceAndBinaries(
123 '1.1', with_debug=True, archive=ppa)
124 foo_12_source, foo_12_binaries = self.createSourceAndBinaries(
125 '1.2', with_debug=True, archive=ppa)
126
127 dominator = Dominator(self.logger, ppa)
128 dominator.judgeAndDominate(
129 foo_10_source.distroseries, foo_10_source.pocket, self.config)
130
131 self.checkPublications(
132 [foo_12_source] + foo_12_binaries,
133 PackagePublishingStatus.PUBLISHED)
134 self.checkPublications(
135 [foo_11_source] + foo_11_binaries,
136 PackagePublishingStatus.SUPERSEDED)
137 self.checkPublications(
138 [foo_10_source] + foo_10_binaries,
139 PackagePublishingStatus.SUPERSEDED)
140
110 def testEmptyDomination(self):141 def testEmptyDomination(self):
111 """Domination asserts for not empty input list."""142 """Domination asserts for not empty input list."""
112 dominator = Dominator(self.logger, self.ubuntutest.main_archive)143 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
113144
=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py 2010-07-21 14:14:54 +0000
+++ lib/lp/soyuz/model/publishing.py 2010-07-26 12:04:48 +0000
@@ -50,6 +50,7 @@
50from lp.registry.interfaces.person import validate_public_person50from lp.registry.interfaces.person import validate_public_person
51from lp.registry.interfaces.pocket import PackagePublishingPocket51from lp.registry.interfaces.pocket import PackagePublishingPocket
52from lp.services.worlddata.model.country import Country52from lp.services.worlddata.model.country import Country
53from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
53from lp.soyuz.model.binarypackagename import BinaryPackageName54from lp.soyuz.model.binarypackagename import BinaryPackageName
54from lp.soyuz.model.binarypackagerelease import (BinaryPackageRelease,55from lp.soyuz.model.binarypackagerelease import (BinaryPackageRelease,
55 BinaryPackageReleaseDownloadCount)56 BinaryPackageReleaseDownloadCount)
@@ -975,6 +976,26 @@
975 section=self.section,976 section=self.section,
976 priority=self.priority)977 priority=self.priority)
977978
979 def _getCorrespondingDDEBPublications(self):
980 """Return remaining publications of the corresponding DDEB.
981
982 Only considers binary publications in the corresponding debug
983 archive with the same distroarchseries, pocket, component, section
984 and priority.
985 """
986 return IMasterStore(BinaryPackagePublishingHistory).find(
987 BinaryPackagePublishingHistory,
988 BinaryPackagePublishingHistory.status.is_in(
989 [PUBLISHED, PENDING]),
990 BinaryPackagePublishingHistory.distroarchseries ==
991 self.distroarchseries,
992 binarypackagerelease=self.binarypackagerelease.debug_package,
993 archive=self.archive.debug_archive,
994 pocket=self.pocket,
995 component=self.component,
996 section=self.section,
997 priority=self.priority)
998
978 def supersede(self, dominant=None, logger=None):999 def supersede(self, dominant=None, logger=None):
979 """See `IBinaryPackagePublishingHistory`."""1000 """See `IBinaryPackagePublishingHistory`."""
980 # At this point only PUBLISHED (ancient versions) or PENDING (1001 # At this point only PUBLISHED (ancient versions) or PENDING (
@@ -993,6 +1014,16 @@
993 super(BinaryPackagePublishingHistory, self).supersede()1014 super(BinaryPackagePublishingHistory, self).supersede()
9941015
995 if dominant is not None:1016 if dominant is not None:
1017 # DDEBs cannot themselves be dominant; they are always dominated
1018 # by their corresponding DEB. Any attempt to dominate with a
1019 # dominant DDEB is a bug.
1020 assert (
1021 dominant.binarypackagerelease.binpackageformat !=
1022 BinaryPackageFormat.DDEB), (
1023 "Should not dominate with %s (%s); DDEBs cannot dominate" % (
1024 dominant.binarypackagerelease.title,
1025 dominant.distroarchseries.architecturetag))
1026
996 dominant_build = dominant.binarypackagerelease.build1027 dominant_build = dominant.binarypackagerelease.build
997 distroarchseries = dominant_build.distro_arch_series1028 distroarchseries = dominant_build.distro_arch_series
998 if logger is not None:1029 if logger is not None:
@@ -1010,7 +1041,10 @@
1010 # between releases.1041 # between releases.
1011 self.supersededby = dominant_build1042 self.supersededby = dominant_build
10121043
1013 # If this is architecture-independet, all publications with the same1044 for dominated in self._getCorrespondingDDEBPublications():
1045 dominated.supersede(dominant, logger)
1046
1047 # If this is architecture-independent, all publications with the same
1014 # context and overrides should be dominated simultaneously.1048 # context and overrides should be dominated simultaneously.
1015 if not self.binarypackagerelease.architecturespecific:1049 if not self.binarypackagerelease.architecturespecific:
1016 for dominated in self._getOtherPublications():1050 for dominated in self._getOtherPublications():
10171051
=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
--- lib/lp/soyuz/tests/test_publishing.py 2010-07-23 12:19:26 +0000
+++ lib/lp/soyuz/tests/test_publishing.py 2010-07-26 12:04:48 +0000
@@ -32,7 +32,7 @@
32from lp.soyuz.model.processor import ProcessorFamily32from lp.soyuz.model.processor import ProcessorFamily
33from lp.soyuz.model.publishing import (33from lp.soyuz.model.publishing import (
34 SourcePackagePublishingHistory, BinaryPackagePublishingHistory)34 SourcePackagePublishingHistory, BinaryPackagePublishingHistory)
35from lp.soyuz.interfaces.archive import ArchivePurpose35from lp.soyuz.interfaces.archive import ArchivePurpose, IArchiveSet
36from lp.soyuz.interfaces.archivearch import IArchiveArchSet36from lp.soyuz.interfaces.archivearch import IArchiveArchSet
37from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet37from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
38from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat38from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
@@ -275,7 +275,8 @@
275 version='666',275 version='666',
276 architecturespecific=False,276 architecturespecific=False,
277 builder=None,277 builder=None,
278 component='main'):278 component='main',
279 with_debug=False):
279 """Return a list of binary publishing records."""280 """Return a list of binary publishing records."""
280 if distroseries is None:281 if distroseries is None:
281 distroseries = self.distroseries282 distroseries = self.distroseries
@@ -302,11 +303,25 @@
302 published_binaries = []303 published_binaries = []
303 for build in builds:304 for build in builds:
304 build.builder = builder305 build.builder = builder
306 pub_binaries = []
307 if with_debug:
308 binarypackagerelease_ddeb = self.uploadBinaryForBuild(
309 build, binaryname + '-dbgsym', filecontent, summary,
310 description, shlibdep, depends, recommends, suggests,
311 conflicts, replaces, provides, pre_depends, enhances,
312 breaks, BinaryPackageFormat.DDEB)
313 pub_binaries += self.publishBinaryInArchive(
314 binarypackagerelease_ddeb, archive.debug_archive, status,
315 pocket, scheduleddeletiondate, dateremoved)
316 else:
317 binarypackagerelease_ddeb = None
318
305 binarypackagerelease = self.uploadBinaryForBuild(319 binarypackagerelease = self.uploadBinaryForBuild(
306 build, binaryname, filecontent, summary, description,320 build, binaryname, filecontent, summary, description,
307 shlibdep, depends, recommends, suggests, conflicts, replaces,321 shlibdep, depends, recommends, suggests, conflicts, replaces,
308 provides, pre_depends, enhances, breaks, format)322 provides, pre_depends, enhances, breaks, format,
309 pub_binaries = self.publishBinaryInArchive(323 binarypackagerelease_ddeb)
324 pub_binaries += self.publishBinaryInArchive(
310 binarypackagerelease, archive, status, pocket,325 binarypackagerelease, archive, status, pocket,
311 scheduleddeletiondate, dateremoved)326 scheduleddeletiondate, dateremoved)
312 published_binaries.extend(pub_binaries)327 published_binaries.extend(pub_binaries)
@@ -1144,6 +1159,48 @@
1144 self.checkSuperseded([bin], super_bin)1159 self.checkSuperseded([bin], super_bin)
1145 self.assertEquals(super_date, bin.datesuperseded)1160 self.assertEquals(super_date, bin.datesuperseded)
11461161
1162 def testSupersedesCorrespondingDDEB(self):
1163 """Check that supersede() takes with it any corresponding DDEB.
1164
1165 DDEB publications should be superseded when their corresponding DEB
1166 is.
1167 """
1168 getUtility(IArchiveSet).new(
1169 purpose=ArchivePurpose.DEBUG, owner=self.ubuntutest.owner,
1170 distribution=self.ubuntutest)
1171
1172 # Each of these will return (i386 deb, i386 ddeb, hppa deb,
1173 # hppa ddeb).
1174 bins = self.getPubBinaries(
1175 architecturespecific=True, with_debug=True)
1176 super_bins = self.getPubBinaries(
1177 architecturespecific=True, with_debug=True)
1178
1179 bins[0].supersede(super_bins[0])
1180 self.checkSuperseded(bins[:2], super_bins[0])
1181 self.checkPublications(bins[2:], PackagePublishingStatus.PENDING)
1182 self.checkPublications(super_bins, PackagePublishingStatus.PENDING)
1183
1184 bins[2].supersede(super_bins[2])
1185 self.checkSuperseded(bins[:2], super_bins[0])
1186 self.checkSuperseded(bins[2:], super_bins[2])
1187 self.checkPublications(super_bins, PackagePublishingStatus.PENDING)
1188
1189 def testDDEBsCannotSupersede(self):
1190 """Check that DDEBs cannot supersede other publications.
1191
1192 Since DDEBs are superseded when their DEBs are, there's no need to
1193 for them supersede anything themselves. Any such attempt is an error.
1194 """
1195 getUtility(IArchiveSet).new(
1196 purpose=ArchivePurpose.DEBUG, owner=self.ubuntutest.owner,
1197 distribution=self.ubuntutest)
1198
1199 # This will return (i386 deb, i386 ddeb, hppa deb, hppa ddeb).
1200 bins = self.getPubBinaries(
1201 architecturespecific=True, with_debug=True)
1202 self.assertRaises(AssertionError, bins[0].supersede, bins[1])
1203
11471204
1148class TestBinaryGetOtherPublications(TestNativePublishingBase):1205class TestBinaryGetOtherPublications(TestNativePublishingBase):
1149 """Test BinaryPackagePublishingHistory._getOtherPublications() works."""1206 """Test BinaryPackagePublishingHistory._getOtherPublications() works."""

Subscribers

People subscribed via source and target branches

to status/vote changes: