Merge lp:~julian-edwards/launchpad/arch-all-domination-bug-34086 into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 14169
Proposed branch: lp:~julian-edwards/launchpad/arch-all-domination-bug-34086
Merge into: lp:launchpad
Diff against target: 528 lines (+346/-60)
4 files modified
lib/lp/archivepublisher/domination.py (+52/-30)
lib/lp/archivepublisher/tests/test_dominator.py (+133/-30)
lib/lp/soyuz/model/publishing.py (+55/-0)
lib/lp/soyuz/tests/test_publishing.py (+106/-0)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/arch-all-domination-bug-34086
Reviewer Review Type Date Requested Status
William Grant (community) code Approve
Review via email: mp+79675@code.launchpad.net

Commit message

[r=wgrant][bug=34086] Prevent superseding of arch-indep binaries until all binaries from the same source are all also superseded.

Description of the change

Fix problems discovered in the previous branch that was backed out where arch-indep and arch-specific binaries flip.

Since the last branch is being re-applied the diff is large. The actual changes are here: http://pastebin.ubuntu.com/711881/

To post a comment you must log in.
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
=== modified file 'lib/lp/archivepublisher/domination.py'
--- lib/lp/archivepublisher/domination.py 2011-10-18 02:09:38 +0000
+++ lib/lp/archivepublisher/domination.py 2011-10-18 12:00:30 +0000
@@ -153,6 +153,7 @@
153 class.153 class.
154 """154 """
155 def __init__(self, is_source=True):155 def __init__(self, is_source=True):
156 self.is_source = is_source
156 if is_source:157 if is_source:
157 self.traits = SourcePublicationTraits158 self.traits = SourcePublicationTraits
158 else:159 else:
@@ -204,6 +205,27 @@
204 self.logger = logger205 self.logger = logger
205 self.archive = archive206 self.archive = archive
206207
208 def _checkArchIndep(self, publication):
209 """Return True if the binary publication can be superseded.
210
211 If the publication is an arch-indep binary, we can only supersede
212 it if all the binaries from the same source are also superseded,
213 else those binaries may become uninstallable.
214 See bug 34086.
215 """
216 binary = publication.binarypackagerelease
217 if not binary.architecturespecific:
218 # getOtherPublicationsForSameSource returns PENDING in
219 # addition to PUBLISHED binaries, and we rely on this since
220 # they must also block domination.
221 others = publication.getOtherPublicationsForSameSource()
222 if others.any():
223 # Don't dominate this arch:all binary as there are
224 # other arch-specific binaries from the same build
225 # that are still active.
226 return False
227 return True
228
207 def dominatePackage(self, publications, live_versions, generalization):229 def dominatePackage(self, publications, live_versions, generalization):
208 """Dominate publications for a single package.230 """Dominate publications for a single package.
209231
@@ -260,7 +282,9 @@
260 pub.supersede(current_dominant, logger=self.logger)282 pub.supersede(current_dominant, logger=self.logger)
261 self.logger.debug2(283 self.logger.debug2(
262 "Superseding older publication for version %s.", version)284 "Superseding older publication for version %s.", version)
263 elif version in live_versions:285 elif (version in live_versions or
286 (not generalization.is_source and
287 not self._checkArchIndep(pub))):
264 # This publication stays active; if any publications288 # This publication stays active; if any publications
265 # that follow right after this are to be superseded,289 # that follow right after this are to be superseded,
266 # this is the release that they are superseded by.290 # this is the release that they are superseded by.
@@ -298,6 +322,7 @@
298 # one, this dominatePackage call will never result in a322 # one, this dominatePackage call will never result in a
299 # deletion.323 # deletion.
300 latest_version = generalization.getPackageVersion(publications[0])324 latest_version = generalization.getPackageVersion(publications[0])
325 self.logger.debug2("Dominating %s" % name)
301 self.dominatePackage(326 self.dominatePackage(
302 publications, [latest_version], generalization)327 publications, [latest_version], generalization)
303328
@@ -359,27 +384,6 @@
359384
360 self.logger.debug("Beginning superseded processing...")385 self.logger.debug("Beginning superseded processing...")
361386
362 # XXX: dsilvers 2005-09-22 bug=55030:
363 # Need to make binaries go in groups but for now this'll do.
364 # An example of the concrete problem here is:
365 # - Upload foo-1.0, which builds foo and foo-common (arch all).
366 # - Upload foo-1.1, ditto.
367 # - foo-common-1.1 is built (along with the i386 binary for foo)
368 # - foo-common-1.0 is superseded
369 # Foo is now uninstallable on any architectures which don't yet
370 # have a build of foo-1.1, as the foo-common for foo-1.0 is gone.
371
372 # Essentially we ideally don't want to lose superseded binaries
373 # unless the entire group is ready to be made pending removal.
374 # In this instance a group is defined as all the binaries from a
375 # given build. This assumes we've copied the arch_all binaries
376 # from whichever build provided them into each arch-specific build
377 # which we publish. If instead we simply publish the arch-all
378 # binaries from another build then instead we should scan up from
379 # the binary to its source, and then back from the source to each
380 # binary published in *this* distroarchseries for that source.
381 # if the binaries as a group (in that definition) are all superseded
382 # then we can consider them eligible for removal.
383 for pub_record in binary_records:387 for pub_record in binary_records:
384 binpkg_release = pub_record.binarypackagerelease388 binpkg_release = pub_record.binarypackagerelease
385 self.logger.debug(389 self.logger.debug(
@@ -450,19 +454,19 @@
450 generalization = GeneralizedPublication(is_source=False)454 generalization = GeneralizedPublication(is_source=False)
451455
452 for distroarchseries in distroseries.architectures:456 for distroarchseries in distroseries.architectures:
453 self.logger.debug(457 self.logger.info(
454 "Performing domination across %s/%s (%s)",458 "Performing domination across %s/%s (%s)",
455 distroseries.name, pocket.title,459 distroseries.name, pocket.title,
456 distroarchseries.architecturetag)460 distroarchseries.architecturetag)
457461
458 bpph_location_clauses = And(462 bpph_location_clauses = [
459 BinaryPackagePublishingHistory.status ==463 BinaryPackagePublishingHistory.status ==
460 PackagePublishingStatus.PUBLISHED,464 PackagePublishingStatus.PUBLISHED,
461 BinaryPackagePublishingHistory.distroarchseries ==465 BinaryPackagePublishingHistory.distroarchseries ==
462 distroarchseries,466 distroarchseries,
463 BinaryPackagePublishingHistory.archive == self.archive,467 BinaryPackagePublishingHistory.archive == self.archive,
464 BinaryPackagePublishingHistory.pocket == pocket,468 BinaryPackagePublishingHistory.pocket == pocket,
465 )469 ]
466 candidate_binary_names = Select(470 candidate_binary_names = Select(
467 BinaryPackageName.id,471 BinaryPackageName.id,
468 And(472 And(
@@ -474,7 +478,7 @@
474 ),478 ),
475 group_by=BinaryPackageName.id,479 group_by=BinaryPackageName.id,
476 having=Count(BinaryPackagePublishingHistory.id) > 1)480 having=Count(BinaryPackagePublishingHistory.id) > 1)
477 binaries = IStore(BinaryPackagePublishingHistory).find(481 main_clauses = [
478 BinaryPackagePublishingHistory,482 BinaryPackagePublishingHistory,
479 BinaryPackageRelease.id ==483 BinaryPackageRelease.id ==
480 BinaryPackagePublishingHistory.binarypackagereleaseID,484 BinaryPackagePublishingHistory.binarypackagereleaseID,
@@ -482,10 +486,28 @@
482 candidate_binary_names),486 candidate_binary_names),
483 BinaryPackageRelease.binpackageformat !=487 BinaryPackageRelease.binpackageformat !=
484 BinaryPackageFormat.DDEB,488 BinaryPackageFormat.DDEB,
485 bpph_location_clauses)489 ]
486 self.logger.debug("Dominating binaries...")490 main_clauses.extend(bpph_location_clauses)
487 self._dominatePublications(491
488 self._sortPackages(binaries, generalization), generalization)492 def do_domination(pass2_msg=""):
493 msg = "binaries..." + pass2_msg
494 self.logger.info("Finding %s" % msg)
495 bins = IStore(
496 BinaryPackagePublishingHistory).find(*main_clauses)
497 self.logger.info("Dominating %s" % msg)
498 sorted_packages = self._sortPackages(bins, generalization)
499 self._dominatePublications(sorted_packages, generalization)
500
501 do_domination()
502
503 # We need to make a second pass to cover the cases where:
504 # * arch-specific binaries were not all dominated before arch-all
505 # ones that depend on them
506 # * An arch-all turned into an arch-specific, or vice-versa
507 # * A package is completely schizophrenic and changes all of
508 # its binaries between arch-all and arch-any (apparently
509 # occurs sometimes!)
510 do_domination("(2nd pass)")
489511
490 def _composeActiveSourcePubsCondition(self, distroseries, pocket):512 def _composeActiveSourcePubsCondition(self, distroseries, pocket):
491 """Compose ORM condition for restricting relevant source pubs."""513 """Compose ORM condition for restricting relevant source pubs."""
492514
=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
--- lib/lp/archivepublisher/tests/test_dominator.py 2011-10-18 02:20:28 +0000
+++ lib/lp/archivepublisher/tests/test_dominator.py 2011-10-18 12:00:30 +0000
@@ -23,7 +23,9 @@
23from lp.registry.interfaces.pocket import PackagePublishingPocket23from lp.registry.interfaces.pocket import PackagePublishingPocket
24from lp.registry.interfaces.series import SeriesStatus24from lp.registry.interfaces.series import SeriesStatus
25from lp.services.log.logger import DevNullLogger25from lp.services.log.logger import DevNullLogger
26from lp.soyuz.enums import PackagePublishingStatus26from lp.soyuz.enums import (
27 PackagePublishingStatus,
28 )
27from lp.soyuz.interfaces.publishing import ISourcePackagePublishingHistory29from lp.soyuz.interfaces.publishing import ISourcePackagePublishingHistory
28from lp.soyuz.tests.test_publishing import TestNativePublishingBase30from lp.soyuz.tests.test_publishing import TestNativePublishingBase
29from lp.testing import (31from lp.testing import (
@@ -169,6 +171,136 @@
169 dominator._dominatePublications,171 dominator._dominatePublications,
170 pubs, GeneralizedPublication(True))172 pubs, GeneralizedPublication(True))
171173
174 def test_archall_domination(self):
175 # Arch-all binaries should not be dominated when a new source
176 # version builds an updated arch-all binary, because slower builds
177 # of other architectures will leave the previous version
178 # uninstallable if they depend on the arch-all binary.
179 # See https://bugs.launchpad.net/launchpad/+bug/34086
180
181 # Set up a source, "foo" which builds "foo-bin" and foo-common
182 # (which is arch-all).
183 foo_10_src = self.getPubSource(
184 sourcename="foo", version="1.0", architecturehintlist="i386",
185 status=PackagePublishingStatus.PUBLISHED)
186 [foo_10_i386_bin] = self.getPubBinaries(
187 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
188 architecturespecific=True, version="1.0", pub_source=foo_10_src)
189 [build] = foo_10_src.getBuilds()
190 bpr = self.factory.makeBinaryPackageRelease(
191 binarypackagename="foo-common", version="1.0", build=build,
192 architecturespecific=False)
193 foo_10_all_bins = self.publishBinaryInArchive(
194 bpr, self.ubuntutest.main_archive, pocket=foo_10_src.pocket,
195 status=PackagePublishingStatus.PUBLISHED)
196
197 # Now, make version 1.1 of foo and add a foo-common but not foo-bin
198 # (imagine that it's not finished building yet).
199 foo_11_src = self.getPubSource(
200 sourcename="foo", version="1.1", architecturehintlist="all",
201 status=PackagePublishingStatus.PUBLISHED)
202 foo_11_all_bins = self.getPubBinaries(
203 binaryname="foo-common", status=PackagePublishingStatus.PUBLISHED,
204 architecturespecific=False, version="1.1", pub_source=foo_11_src)
205
206 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
207 dominator.judgeAndDominate(
208 foo_10_src.distroseries, foo_10_src.pocket)
209
210 # The source will be superseded.
211 self.checkPublication(foo_10_src, PackagePublishingStatus.SUPERSEDED)
212 # The arch-specific has no dominant, so it's still published
213 self.checkPublication(
214 foo_10_i386_bin, PackagePublishingStatus.PUBLISHED)
215 # The arch-indep has a dominant but must not be superseded yet
216 # since the arch-specific is still published.
217 self.checkPublications(
218 foo_10_all_bins, PackagePublishingStatus.PUBLISHED)
219
220 # Now creating a newer foo-bin should see those last two
221 # publications superseded.
222 [build2] = foo_11_src.getBuilds()
223 foo_11_bin = self.factory.makeBinaryPackageRelease(
224 binarypackagename="foo-bin", version="1.1", build=build2,
225 architecturespecific=True)
226 self.publishBinaryInArchive(
227 foo_11_bin, self.ubuntutest.main_archive,
228 pocket=foo_10_src.pocket,
229 status=PackagePublishingStatus.PUBLISHED)
230 dominator.judgeAndDominate(
231 foo_10_src.distroseries, foo_10_src.pocket)
232 self.checkPublication(
233 foo_10_i386_bin, PackagePublishingStatus.SUPERSEDED)
234 self.checkPublications(
235 foo_10_all_bins, PackagePublishingStatus.SUPERSEDED)
236
237 def test_any_superseded_by_all(self):
238 # Set up a source, foo, which builds an architecture-dependent
239 # binary, foo-bin.
240 foo_10_src = self.getPubSource(
241 sourcename="foo", version="1.0", architecturehintlist="i386",
242 status=PackagePublishingStatus.PUBLISHED)
243 [foo_10_i386_bin] = self.getPubBinaries(
244 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
245 architecturespecific=True, version="1.0", pub_source=foo_10_src)
246
247 # Now, make version 1.1 of foo, where foo-bin is now
248 # architecture-independent.
249 foo_11_src = self.getPubSource(
250 sourcename="foo", version="1.1", architecturehintlist="all",
251 status=PackagePublishingStatus.PUBLISHED)
252 [foo_10_all_bin, foo_10_all_bin_2] = self.getPubBinaries(
253 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
254 architecturespecific=False, version="1.1", pub_source=foo_11_src)
255
256 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
257 dominator.judgeAndDominate(
258 foo_10_src.distroseries, foo_10_src.pocket)
259
260 # The source will be superseded.
261 self.checkPublication(foo_10_src, PackagePublishingStatus.SUPERSEDED)
262 # The arch-specific is superseded by the new arch-indep.
263 self.checkPublication(
264 foo_10_i386_bin, PackagePublishingStatus.SUPERSEDED)
265
266 def test_schitzoid_package(self):
267 # Test domination of a source that produces an arch-indep and an
268 # arch-all, that then switches both on the next version to the
269 # other arch type.
270 foo_10_src = self.getPubSource(
271 sourcename="foo", version="1.0", architecturehintlist="i386",
272 status=PackagePublishingStatus.PUBLISHED)
273 [foo_10_i386_bin] = self.getPubBinaries(
274 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
275 architecturespecific=True, version="1.0", pub_source=foo_10_src)
276 [build] = foo_10_src.getBuilds()
277 bpr = self.factory.makeBinaryPackageRelease(
278 binarypackagename="foo-common", version="1.0", build=build,
279 architecturespecific=False)
280 foo_10_all_bins = self.publishBinaryInArchive(
281 bpr, self.ubuntutest.main_archive, pocket=foo_10_src.pocket,
282 status=PackagePublishingStatus.PUBLISHED)
283
284 foo_11_src = self.getPubSource(
285 sourcename="foo", version="1.1", architecturehintlist="i386",
286 status=PackagePublishingStatus.PUBLISHED)
287 [foo_11_i386_bin] = self.getPubBinaries(
288 binaryname="foo-common", status=PackagePublishingStatus.PUBLISHED,
289 architecturespecific=True, version="1.1", pub_source=foo_11_src)
290 [build] = foo_11_src.getBuilds()
291 bpr = self.factory.makeBinaryPackageRelease(
292 binarypackagename="foo-bin", version="1.1", build=build,
293 architecturespecific=False)
294 foo_11_all_bins = self.publishBinaryInArchive(
295 bpr, self.ubuntutest.main_archive, pocket=foo_11_src.pocket,
296 status=PackagePublishingStatus.PUBLISHED)
297
298 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
299 dominator.judgeAndDominate(foo_10_src.distroseries, foo_10_src.pocket)
300
301 self.checkPublications(foo_10_all_bins + [foo_10_i386_bin],
302 PackagePublishingStatus.SUPERSEDED)
303
172304
173class TestDomination(TestNativePublishingBase):305class TestDomination(TestNativePublishingBase):
174 """Test overall domination procedure."""306 """Test overall domination procedure."""
@@ -223,35 +355,6 @@
223 self.ubuntutest['breezy-autotest'].status = (355 self.ubuntutest['breezy-autotest'].status = (
224 SeriesStatus.OBSOLETE)356 SeriesStatus.OBSOLETE)
225357
226 def test_any_superseded_by_all(self):
227 # Set up a source, foo, which builds an architecture-dependent
228 # binary, foo-bin.
229 foo_10_src = self.getPubSource(
230 sourcename="foo", version="1.0", architecturehintlist="i386",
231 status=PackagePublishingStatus.PUBLISHED)
232 [foo_10_i386_bin] = self.getPubBinaries(
233 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
234 architecturespecific=True, version="1.0", pub_source=foo_10_src)
235
236 # Now, make version 1.1 of foo, where foo-bin is now
237 # architecture-independent.
238 foo_11_src = self.getPubSource(
239 sourcename="foo", version="1.1", architecturehintlist="all",
240 status=PackagePublishingStatus.PUBLISHED)
241 [foo_10_all_bin, foo_10_all_bin_2] = self.getPubBinaries(
242 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
243 architecturespecific=False, version="1.1", pub_source=foo_11_src)
244
245 dominator = Dominator(self.logger, self.ubuntutest.main_archive)
246 dominator.judgeAndDominate(
247 foo_10_src.distroseries, foo_10_src.pocket)
248
249 # The source will be superseded.
250 self.checkPublication(foo_10_src, PackagePublishingStatus.SUPERSEDED)
251 # The arch-specific is superseded by the new arch-indep.
252 self.checkPublication(
253 foo_10_i386_bin, PackagePublishingStatus.SUPERSEDED)
254
255358
256def make_spphs_for_versions(factory, versions):359def make_spphs_for_versions(factory, versions):
257 """Create publication records for each of `versions`.360 """Create publication records for each of `versions`.
258361
=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py 2011-10-18 02:09:38 +0000
+++ lib/lp/soyuz/model/publishing.py 2011-10-18 12:00:30 +0000
@@ -33,6 +33,7 @@
33 Desc,33 Desc,
34 LeftJoin,34 LeftJoin,
35 Or,35 Or,
36 Select,
36 Sum,37 Sum,
37 )38 )
38from storm.store import Store39from storm.store import Store
@@ -1118,6 +1119,60 @@
1118 section=self.section,1119 section=self.section,
1119 priority=self.priority)1120 priority=self.priority)
11201121
1122 def getOtherPublicationsForSameSource(self, include_archindep=False):
1123 """Return all the other published or pending binaries for this
1124 source.
1125
1126 For example if source package foo builds:
1127 foo - i386
1128 foo - amd64
1129 foo-common - arch-all (published in i386 and amd64)
1130 then if this publication is the arch-all amd64, return foo(i386),
1131 foo(amd64). If include_archindep is True then also return
1132 foo-common (i386)
1133
1134 :param include_archindep: If True, return architecture independent
1135 publications too. Defaults to False.
1136
1137 :return: an iterable of `BinaryPackagePublishingHistory`
1138 """
1139 # Avoid circular wotsits.
1140 from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
1141 from lp.soyuz.model.distroarchseries import DistroArchSeries
1142 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
1143 source_select = Select(
1144 SourcePackageRelease.id,
1145 And(
1146 BinaryPackageBuild.source_package_release_id ==
1147 SourcePackageRelease.id,
1148 BinaryPackageRelease.build == BinaryPackageBuild.id,
1149 self.binarypackagereleaseID == BinaryPackageRelease.id,
1150 ))
1151 pubs = [
1152 BinaryPackageBuild.source_package_release_id ==
1153 SourcePackageRelease.id,
1154 SourcePackageRelease.id.is_in(source_select),
1155 BinaryPackageRelease.build == BinaryPackageBuild.id,
1156 BinaryPackagePublishingHistory.binarypackagereleaseID ==
1157 BinaryPackageRelease.id,
1158 BinaryPackagePublishingHistory.archiveID == self.archive.id,
1159 BinaryPackagePublishingHistory.distroarchseriesID ==
1160 DistroArchSeries.id,
1161 DistroArchSeries.distroseriesID == self.distroseries.id,
1162 BinaryPackagePublishingHistory.pocket == self.pocket,
1163 BinaryPackagePublishingHistory.status.is_in(
1164 active_publishing_status),
1165 BinaryPackagePublishingHistory.id != self.id
1166 ]
1167
1168 if not include_archindep:
1169 pubs.append(BinaryPackageRelease.architecturespecific == True)
1170
1171 return IMasterStore(BinaryPackagePublishingHistory).find(
1172 BinaryPackagePublishingHistory,
1173 *pubs
1174 )
1175
1121 def supersede(self, dominant=None, logger=None):1176 def supersede(self, dominant=None, logger=None):
1122 """See `IBinaryPackagePublishingHistory`."""1177 """See `IBinaryPackagePublishingHistory`."""
1123 # At this point only PUBLISHED (ancient versions) or PENDING (1178 # At this point only PUBLISHED (ancient versions) or PENDING (
11241179
=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
--- lib/lp/soyuz/tests/test_publishing.py 2011-10-18 02:09:38 +0000
+++ lib/lp/soyuz/tests/test_publishing.py 2011-10-18 12:00:30 +0000
@@ -1471,6 +1471,112 @@
1471 self.assertEquals(spph.ancestor.displayname, ancestor.displayname)1471 self.assertEquals(spph.ancestor.displayname, ancestor.displayname)
14721472
14731473
1474class TestGetOtherPublicationsForSameSource(TestNativePublishingBase):
1475 """Test parts of the BinaryPackagePublishingHistory model.
1476
1477 See also lib/lp/soyuz/doc/publishing.txt
1478 """
1479
1480 layer = LaunchpadZopelessLayer
1481
1482 def _makeMixedSingleBuildPackage(self, version="1.0"):
1483 # Set up a source with a build that generated four binaries,
1484 # two of them an arch-all.
1485 foo_src_pub = self.getPubSource(
1486 sourcename="foo", version=version, architecturehintlist="i386",
1487 status=PackagePublishingStatus.PUBLISHED)
1488 [foo_bin_pub] = self.getPubBinaries(
1489 binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED,
1490 architecturespecific=True, version=version,
1491 pub_source=foo_src_pub)
1492 # Now need to grab the build for the source so we can add
1493 # more binaries to it.
1494 [build] = foo_src_pub.getBuilds()
1495 foo_one_common = self.factory.makeBinaryPackageRelease(
1496 binarypackagename="foo-one-common", version=version, build=build,
1497 architecturespecific=False)
1498 foo_one_common_pubs = self.publishBinaryInArchive(
1499 foo_one_common, self.ubuntutest.main_archive,
1500 pocket=foo_src_pub.pocket,
1501 status=PackagePublishingStatus.PUBLISHED)
1502 foo_two_common = self.factory.makeBinaryPackageRelease(
1503 binarypackagename="foo-two-common", version=version, build=build,
1504 architecturespecific=False)
1505 foo_two_common_pubs = self.publishBinaryInArchive(
1506 foo_two_common, self.ubuntutest.main_archive,
1507 pocket=foo_src_pub.pocket,
1508 status=PackagePublishingStatus.PUBLISHED)
1509 foo_three = self.factory.makeBinaryPackageRelease(
1510 binarypackagename="foo-three", version=version, build=build,
1511 architecturespecific=True)
1512 [foo_three_pub] = self.publishBinaryInArchive(
1513 foo_three, self.ubuntutest.main_archive,
1514 pocket=foo_src_pub.pocket,
1515 status=PackagePublishingStatus.PUBLISHED)
1516 # So now we have source foo, which has arch specific binaries
1517 # foo-bin and foo-three, and arch:all binaries foo-one-common and
1518 # foo-two-common. The latter two will have multiple publications,
1519 # one for each DAS in the series.
1520 return (
1521 foo_src_pub, foo_bin_pub, foo_one_common_pubs,
1522 foo_two_common_pubs, foo_three_pub)
1523
1524 def test_getOtherPublicationsForSameSource(self):
1525 # By default getOtherPublicationsForSameSource should return all
1526 # of the other binaries built by the same source as the passed
1527 # binary publication, except the arch-indep ones.
1528 (foo_src_pub, foo_bin_pub, foo_one_common_pubs, foo_two_common_pubs,
1529 foo_three_pub) = self._makeMixedSingleBuildPackage()
1530
1531 foo_one_common_pub = foo_one_common_pubs[0]
1532 others = foo_one_common_pub.getOtherPublicationsForSameSource()
1533 others = list(others)
1534
1535 self.assertContentEqual([foo_three_pub, foo_bin_pub], others)
1536
1537 def test_getOtherPublicationsForSameSource_include_archindep(self):
1538 # Check that the arch-indep binaries are returned if requested.
1539 (foo_src_pub, foo_bin_pub, foo_one_common_pubs, foo_two_common_pubs,
1540 foo_three_pub) = self._makeMixedSingleBuildPackage()
1541
1542 foo_one_common_pub = foo_one_common_pubs[0]
1543 others = foo_one_common_pub.getOtherPublicationsForSameSource(
1544 include_archindep=True)
1545 others = list(others)
1546
1547 # We expect all publications created above to be returned,
1548 # except the one we use to call the method on.
1549 expected = [foo_three_pub, foo_bin_pub]
1550 expected.extend(foo_one_common_pubs[1:])
1551 expected.extend(foo_two_common_pubs)
1552 self.assertContentEqual(expected, others)
1553
1554 def test_getOtherPublicationsForSameSource_inactive(self):
1555 # Check that inactive publications are not returned.
1556 (foo_src_pub, foo_bin_pub, foo_one_common_pubs, foo_two_common_pubs,
1557 foo_three_pub) = self._makeMixedSingleBuildPackage()
1558 foo_bin_pub.status = PackagePublishingStatus.SUPERSEDED
1559 foo_three_pub.status = PackagePublishingStatus.SUPERSEDED
1560 foo_one_common_pub = foo_one_common_pubs[0]
1561 others = foo_one_common_pub.getOtherPublicationsForSameSource()
1562 others = list(others)
1563
1564 self.assertEqual(0, len(others))
1565
1566 def test_getOtherPublicationsForSameSource_multiple_versions(self):
1567 # Check that publications for only the same version as the
1568 # context binary publication are returned.
1569 (foo_src_pub, foo_bin_pub, foo_one_common_pubs, foo_two_common_pubs,
1570 foo_three_pub) = self._makeMixedSingleBuildPackage(version="1.0")
1571 self._makeMixedSingleBuildPackage(version="1.1")
1572
1573 foo_one_common_pub = foo_one_common_pubs[0]
1574 others = foo_one_common_pub.getOtherPublicationsForSameSource()
1575 others = list(others)
1576
1577 self.assertContentEqual([foo_three_pub, foo_bin_pub], others)
1578
1579
1474class TestGetBuiltBinaries(TestNativePublishingBase):1580class TestGetBuiltBinaries(TestNativePublishingBase):
1475 """Test SourcePackagePublishingHistory.getBuiltBinaries() works."""1581 """Test SourcePackagePublishingHistory.getBuiltBinaries() works."""
14761582