← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/simplify-getRelevantToSourceAndArchive into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/simplify-getRelevantToSourceAndArchive into lp:launchpad.

Commit message:
BinaryPackageBuildSet.getRelevantToSourceAndLocation is replaced by a much simpler findBuiltOrPublishedBySourceAndArchive. Only successful builds are interesting, the series is uninteresting, and there's always at most one per archtag.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/simplify-getRelevantToSourceAndArchive/+merge/240805

BinaryPackageBuildSet.getRelevantToSourceAndLocation is replaced by a much simpler findBuiltOrPublishedBySourceAndArchive.

The horrifying complexity arose over the 9 year history of the method (originally SourcePackageRelease.getBuildByArch), persisting through ArchiveRework and NativeSourceSyncing which both fundamentally changed its functionality. SPR.getBuildByArch's purpose is now served by two new methods: a tiny BPBS.getBySourceAndLocation which looks any build up by its natural key (SourcePackageRelease, Archive, DistroArchSeries), and a little-used BPBS.findBuiltOrPublishedBySourceAndArchive which finds all successfully builds that either built in or were copied into the archive, split by architecturetag.

findBuiltOrPublishedBySourceAndArchive is much simpler and faster than the old getBuildByArch, as its callsites only care about successful builds, and the series is irrelevant to filtering.
-- 
https://code.launchpad.net/~wgrant/launchpad/simplify-getRelevantToSourceAndArchive/+merge/240805
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/simplify-getRelevantToSourceAndArchive into lp:launchpad.
=== removed file 'lib/lp/soyuz/doc/sourcepackagerelease-build-lookup.txt'
--- lib/lp/soyuz/doc/sourcepackagerelease-build-lookup.txt	2014-11-05 09:09:21 +0000
+++ lib/lp/soyuz/doc/sourcepackagerelease-build-lookup.txt	1970-01-01 00:00:00 +0000
@@ -1,349 +0,0 @@
-     DOCTESTS SUCK! PLEASE DO NOT ADD TO THIS DOCTEST, SEE
-     lib/lp/soyuz/tests/test_sourcepackagerelease.py instead and consider
-     migrating tests from here to there.
-
-
-= Creating & Looking for Build records =
-
-IBinaryPackageBuildSet can create and look up build records.
-
-It provides a 'getRelevantToSourceAndLocation' method which allows the
-application to lookup for BinaryPackageBuild records for
-SourcePackageRelease in a given DistroArchSeries and Archive.
-
-To demonstrate this we need to define some variables.
-
-    >>> from zope.component import getUtility
-    >>> from lp.registry.interfaces.distribution import IDistributionSet
-    >>> from lp.services.librarian.interfaces import ILibraryFileAliasSet
-    >>> from lp.soyuz.interfaces.binarypackagebuild import (
-    ...     IBinaryPackageBuildSet)
-
-    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
-    >>> hoary = ubuntu.getSeries('hoary')
-
-Retrieve hoary/i386 and hoary/hppa `DistroArchSeries.
-
-    >>> hoary_i386 = hoary['i386']
-    >>> hoary_hppa = hoary['hppa']
-
-    >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1]
-    >>> trash = hoary_i386.addOrUpdateChroot(fake_chroot)
-    >>> trash = hoary_hppa.addOrUpdateChroot(fake_chroot)
-
-    >>> from lp.registry.interfaces.person import IPersonSet
-    >>> cprov = getUtility(IPersonSet).getByName('cprov')
-
-    >>> from lp.registry.interfaces.pocket import (
-    ...    PackagePublishingPocket)
-    >>> pocket_release = PackagePublishingPocket.RELEASE
-
-The base method BinaryPackageBuildSet.new() is able to create a build to
-a given distro_arch_series, pocket and archive.
-
-Build.status, by default is set to NEEDSBUILD, but you can
-optionally provide another status.
-
-    >>> hoary_evo_source = hoary.getSourcePackage('evolution')
-    >>> evo_release = hoary_evo_source['1.0'].sourcepackagerelease
-
-    >>> from lp.buildmaster.enums import BuildStatus
-    >>> evo_build_i386 = getUtility(IBinaryPackageBuildSet).new(
-    ...     evo_release, ubuntu.main_archive, hoary_i386, pocket_release,
-    ...     status=BuildStatus.FULLYBUILT)
-
-    >>> print evo_build_i386.status.name
-    FULLYBUILT
-
-    >>> evo_build_i386.distro_arch_series.architecturetag
-    u'i386'
-
-    >>> print evo_build_i386.archive.displayname
-    Primary Archive for Ubuntu Linux
-
-The build record can be retrieved on hoary/i386 architecture.
-
-    >>> bpbs = getUtility(IBinaryPackageBuildSet)
-    >>> test_build_i386 = bpbs.getRelevantToSourceAndLocation(
-    ...     evo_release, ubuntu.main_archive, hoary_i386)
-    >>> test_build_i386 == evo_build_i386
-    True
-
-However a hoary/hppa build is not available.
-
-    >>> test_build_hppa = bpbs.getRelevantToSourceAndLocation(
-    ...     evo_release, ubuntu.main_archive, hoary_hppa)
-    >>> print test_build_hppa
-    None
-
-
-== Sources inherited during distroseries initialization ==
-
-We will copy the evolution source to ubuntu/breezy-autotest as if it
-was inherited in the initialization.
-
-    >>> breezy_autotest = ubuntu.getSeries('breezy-autotest')
-    >>> breezy_autotest_i386 = breezy_autotest['i386']
-
-    >>> print breezy_autotest.previous_series.title
-    The Hoary Hedgehog Release
-
-    >>> evo_pub = hoary.getPublishedSources('evolution', version='1.0')[0]
-    >>> copied_pub = evo_pub.copyTo(
-    ...     breezy_autotest, pocket_release, breezy_autotest.main_archive)
-
-    >>> breezy_autotest_evo_source = breezy_autotest.getSourcePackage(
-    ...     'evolution')
-    >>> breezy_autotest_evo_release = breezy_autotest_evo_source['1.0']
-    >>> evo_release == breezy_autotest_evo_release.sourcepackagerelease
-    True
-
-Since evolution source was already built on ubuntu/hoary/i386, the
-parent series, it should be found by a build lookup happening on
-ubuntu/breezy-autotest/i386.
-
-In practical terms it means that another build is not necessary in
-this context.
-
-    >>> breezy_autotest_build = bpbs.getRelevantToSourceAndLocation(
-    ...     evo_release, ubuntu.main_archive, breezy_autotest_i386)
-    >>> print breezy_autotest_build.title
-    i386 build of evolution 1.0 in ubuntu hoary RELEASE
-
-
-== Sources with architecture-independent and specific binaries ==
-
-Even if the source package builds an architecture-independent package,
-no Build record will be returned by getRelevantToSourceAndLocation() if
-arch-specific binary packages were not built (see bug #65712 for further
-information).
-
-In order to be independent of the sampledata we will use the
-SoyuzTestPublisher helper to create fake but complete publication for
-this test.
-
-    >>> from lp.soyuz.enums import (
-    ...    PackagePublishingStatus)
-    >>> from lp.soyuz.tests.test_publishing import (
-    ...     SoyuzTestPublisher)
-
-    >>> test_publisher = SoyuzTestPublisher()
-
-    >>> name16 = getUtility(IPersonSet).getByName('name16')
-    >>> test_publisher.person = name16
-
-Let's create and publish a source which produces an
-architecture-independent binary.
-
-    >>> foo_pub_src = test_publisher.getPubSource(
-    ...     version="1.0", architecturehintlist='all',
-    ...     distroseries=hoary, archive=ubuntu.main_archive,
-    ...     status=PackagePublishingStatus.PUBLISHED)
-
-    >>> foo_pub_binaries = test_publisher.getPubBinaries(
-    ...     distroseries=hoary, pub_source=foo_pub_src,
-    ...     status=PackagePublishingStatus.PUBLISHED)
-
-The build record for foo in hoary/i386 was created.
-
-    >>> test_build_i386 = bpbs.getRelevantToSourceAndLocation(
-    ...     foo_pub_src.sourcepackagerelease, ubuntu.main_archive, hoary_i386)
-    >>> print test_build_i386.title
-    i386 build of foo 1.0 in ubuntu hoary RELEASE
-
-And despite of having a architecture-independent binary published in
-hoary hppa, the build lookup in this architecture returns None, i.e,
-the build doesn't exist.
-
-    >>> for pub in foo_pub_binaries:
-    ...     print pub.displayname
-    foo-bin 1.0 in hoary i386
-    foo-bin 1.0 in hoary hppa
-
-    >>> test_build_hppa = bpbs.getRelevantToSourceAndLocation(
-    ...     foo_pub_src.sourcepackagerelease, ubuntu.main_archive, hoary_hppa)
-    >>> print test_build_hppa
-    None
-
-
-== Sources copied from PRIMARY to PPAs ==
-
-Sources published (uploaded or copied) to the PPA do not share builds
-with the distribution main archive (PRIMARY/PARTNER). They should have
-a build record representing the building context for the specific PPA
-where they are published.
-
-Let's start by copying a PRIMARY archive source to Celso's PPA.
-
-    >>> copy = evo_pub.copyTo(hoary, pocket_release, cprov.archive)
-
-No suitable build will be found for it.
-
-    >>> test_build_i386_ppa = bpbs.getRelevantToSourceAndLocation(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_i386)
-    >>> print test_build_i386_ppa
-    None
-
-Then we can create a build record representing the intent to build
-the copied source using the current PPA context. The PPA build context
-is a merge between the PRIMARY archive context and the differences
-introduced by the PPA itself, like new package or new dependency
-versions, so the resulted binary will be influenced by the PPA
-contents at the time it was built.
-
-    >>> evo_build_i386_ppa = getUtility(IBinaryPackageBuildSet).new(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_i386,
-    ...     pocket_release)
-
-    >>> evo_build_i386_ppa.status.name
-    'NEEDSBUILD'
-
-    >>> print evo_build_i386_ppa.archive.displayname
-    PPA for Celso Providelo
-
-The copied source build lookup in the PPA returns the build created in
-the PPA context, not the PRIMARY archive one.
-
-    >>> test_build_i386_ppa = bpbs.getRelevantToSourceAndLocation(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_i386)
-    >>> test_build_i386_ppa == evo_build_i386_ppa
-    True
-
-As expected, the hoary/hppa build is still missing in both archives.
-
-    >>> test_build_hppa_ppa = bpbs.getRelevantToSourceAndLocation(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_hppa)
-    >>> print test_build_hppa_ppa
-    None
-
-When we create a hoary/hppa build in the PPA context, it will continue
-to be missing in the PRIMARY archive context.
-
-    >>> evo_build_hppa_ppa = getUtility(IBinaryPackageBuildSet).new(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_hppa,
-    ...     pocket_release)
-
-    >>> test_build_hppa_ppa = bpbs.getRelevantToSourceAndLocation(
-    ...     copy.sourcepackagerelease, cprov.archive, hoary_hppa)
-    >>> print test_build_hppa_ppa.title
-    hppa build of evolution 1.0 in ubuntu hoary RELEASE
-
-    >>> test_build_hppa = bpbs.getRelevantToSourceAndLocation(
-    ...     evo_release, ubuntu.main_archive, hoary_hppa)
-    >>> print test_build_hppa
-    None
-
-
-== Build lookup for sources & binaries copied across PPAs ==
-
-Launchpad also allows copies from published sources including
-corresponding binaries from PRIMARY archive to PPA or from one PPA to
-another.
-
-We will create a foo_1.0 source, build and i386 binary published in
-hoary PRIMARY archive.
-
-    >>> foo_pub_src = test_publisher.getPubSource(
-    ...     version="0.1", architecturehintlist='i386',
-    ...     distroseries=hoary, archive=ubuntu.main_archive,
-    ...     status=PackagePublishingStatus.PUBLISHED)
-
-    >>> foo_pub_binaries = test_publisher.getPubBinaries(
-    ...     distroseries=hoary, pub_source=foo_pub_src,
-    ...     status=PackagePublishingStatus.PUBLISHED)
-
-    >>> foo_source_release = foo_pub_src.sourcepackagerelease
-    >>> build_primary = bpbs.getRelevantToSourceAndLocation(
-    ...     foo_source_release, ubuntu.main_archive, hoary_i386)
-
-    >>> print build_primary.title
-    i386 build of foo 0.1 in ubuntu hoary RELEASE
-
-    >>> print build_primary.archive.displayname
-    Primary Archive for Ubuntu Linux
-
-Then we can copy source and binary from PRIMARY archive to Celso's PPA:
-
-    >>> cprov_src = foo_pub_src.copyTo(
-    ...    hoary, pocket_release, cprov.archive)
-    >>> [cprov_bin] = foo_pub_binaries[0].copyTo(
-    ...    hoary, pocket_release, cprov.archive)
-    >>> cprov_src.status = PackagePublishingStatus.PUBLISHED
-    >>> cprov_bin.status = PackagePublishingStatus.PUBLISHED
-    >>> from lp.services.database.sqlbase import flush_database_updates
-    >>> flush_database_updates()
-
-A build record is clearly not required here, since both, source and
-binary got copied from PRIMARY archive, thus the system is able to
-identify this situation and locate the original build. See the
-bug #181736 report for previous mistakes in this area.
-
-    >>> cprov_spr = cprov_src.sourcepackagerelease
-    >>> cprov_build = bpbs.getRelevantToSourceAndLocation(
-    ...     cprov_spr, cprov.archive, hoary_i386)
-
-    >>> print cprov_build.title
-    i386 build of foo 0.1 in ubuntu hoary RELEASE
-
-    >>> print cprov_build.archive.displayname
-    Primary Archive for Ubuntu Linux
-
-It's even possible to copy source and binaries from hoary to warty
-suite in Celso's PPA.
-
-    >>> cprov_foo_src = cprov.archive.getPublishedSources(
-    ...    name=u'foo', distroseries=hoary).first()
-    >>> cprov_foo_bin = cprov_foo_src.getPublishedBinaries()[0]
-
-    >>> warty = ubuntu.getSeries('warty')
-    >>> copied_source = cprov_foo_src.copyTo(
-    ...    warty, pocket_release, cprov.archive)
-    >>> [copied_binary] = cprov_foo_bin.copyTo(
-    ...    warty, pocket_release, cprov.archive)
-    >>> copied_source.status = PackagePublishingStatus.PUBLISHED
-    >>> copied_binary.status = PackagePublishingStatus.PUBLISHED
-    >>> flush_database_updates()
-
-In this case the system is also able to locate the original build by
-following the build path of the corresponding published binaries.
-
-    >>> copied_source_release = copied_source.sourcepackagerelease
-    >>> warty_i386 = warty['i386']
-    >>> copied_build_candidate = bpbs.getRelevantToSourceAndLocation(
-    ...     copied_source_release, cprov.archive, warty_i386)
-
-    >>> print copied_build_candidate.title
-    i386 build of foo 0.1 in ubuntu hoary RELEASE
-
-    >>> print copied_build_candidate.archive.displayname
-    Primary Archive for Ubuntu Linux
-
-Now we can also copy the hoary source and its binary from Celso's PPA
-to Mark Shuttleworth's PPA.
-
-    >>> cprov_foo_src = cprov.archive.getPublishedSources(
-    ...    name=u'foo', distroseries=hoary).first()
-    >>> cprov_foo_bin = cprov_foo_src.getPublishedBinaries()[0]
-
-    >>> mark = getUtility(IPersonSet).getByName('mark')
-    >>> mark_src = cprov_foo_src.copyTo(
-    ...    hoary, pocket_release, mark.archive)
-    >>> [mark_bin] = cprov_foo_bin.copyTo(
-    ...    hoary, pocket_release, mark.archive)
-    >>> mark_src.status = PackagePublishingStatus.PUBLISHED
-    >>> mark_bin.status = PackagePublishingStatus.PUBLISHED
-    >>> flush_database_updates()
-
-The published binaries build path is followed again to find the
-original build that happened in the primary archive.
-
-    >>> mark_spr = mark_src.sourcepackagerelease
-    >>> mark_build = bpbs.getRelevantToSourceAndLocation(
-    ...     mark_spr, mark.archive, hoary_i386)
-
-    >>> print mark_build.title
-    i386 build of foo 0.1 in ubuntu hoary RELEASE
-
-    >>> print mark_build.archive.displayname
-    Primary Archive for Ubuntu Linux
-

=== modified file 'lib/lp/soyuz/interfaces/binarypackagebuild.py'
--- lib/lp/soyuz/interfaces/binarypackagebuild.py	2014-11-05 11:20:23 +0000
+++ lib/lp/soyuz/interfaces/binarypackagebuild.py	2014-11-06 02:41:13 +0000
@@ -380,14 +380,16 @@
         :return: a list of `IBuild` records not target to PPA archives.
         """
 
-    def getRelevantToSourceAndLocation(sourcepackagerelease, archive,
-                                       distroarchseries):
-        """Return build for the given source, archive and distroarchseries.
-
-        It looks for a build in any state registered *directly* for the
-        given distroarchseries and archive.
-
-        Returns None if a suitable build could not be found.
+    def findBuiltOrPublishedBySourceAndArchive(sourcepackagerelease, archive,
+                                               distroseries):
+        """Find all successful builds for source relevant to an Archive.
+
+        This includes all successful builds for the source directly in
+        this archive, and any that had their binaries copied into this
+        archive.
+
+        :return: A dict mapping architecture tags (in string form,
+            e.g. 'i386') to `BinaryPackageBuild`s for that build.
         """
 
     def getStatusSummaryForBuilds(builds):

=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
--- lib/lp/soyuz/model/binarypackagebuild.py	2014-11-05 11:25:28 +0000
+++ lib/lp/soyuz/model/binarypackagebuild.py	2014-11-06 02:41:13 +0000
@@ -19,12 +19,14 @@
 import pytz
 from sqlobject import SQLObjectNotFound
 from storm.expr import (
+    And,
     Desc,
+    Exists,
     Join,
     LeftJoin,
     Or,
+    Select,
     )
-from storm.info import ClassAlias
 from storm.locals import (
     Bool,
     DateTime,
@@ -1163,89 +1165,38 @@
             Desc(BinaryPackageBuild.date_created), BinaryPackageBuild.id)
         return resultset
 
-    def _findBySourceAndLocation(self, sourcepackagerelease, archive,
-                                 distroseries):
-        """Find builds for a SourcePackageRelease by series and archive.
-
-        Looks for `BinaryPackageBuild` records for this source package
-        release, with publication records in the given distroseries.
-        There should be at most one of these per architecture.
-
-        :param distroseries: `DistroSeries` to look for.
-        :return: A dict mapping architecture tags (in string form,
-            e.g. 'i386') to `BinaryPackageBuild`s for that build.
-        """
-        # Avoid circular imports.
-        from lp.soyuz.model.distroarchseries import DistroArchSeries
+    def findBuiltOrPublishedBySourceAndArchive(self, sourcepackagerelease,
+                                               archive):
+        """See `IBinaryPackageBuildSet`."""
         from lp.soyuz.model.publishing import BinaryPackagePublishingHistory
 
-        BuildDAS = ClassAlias(DistroArchSeries, 'BuildDAS')
-        PublishDAS = ClassAlias(DistroArchSeries, 'PublishDAS')
-
-        query = IStore(BinaryPackageBuild).find(
-            (BuildDAS.architecturetag, BinaryPackageBuild),
+        published_query = Select(
+            1,
+            tables=(
+                BinaryPackagePublishingHistory,
+                Join(
+                    BinaryPackageRelease,
+                    BinaryPackageRelease.id ==
+                        BinaryPackagePublishingHistory.binarypackagereleaseID)
+                ),
+            where=And(
+                BinaryPackagePublishingHistory.archive == archive,
+                BinaryPackageRelease.build == BinaryPackageBuild.id))
+        builds = list(IStore(BinaryPackageBuild).find(
+            BinaryPackageBuild,
+            BinaryPackageBuild.status == BuildStatus.FULLYBUILT,
             BinaryPackageBuild.source_package_release == sourcepackagerelease,
-            BinaryPackageRelease.buildID == BinaryPackageBuild.id,
-            BuildDAS.id == BinaryPackageBuild.distro_arch_series_id,
-            BinaryPackagePublishingHistory.binarypackagereleaseID ==
-                BinaryPackageRelease.id,
-            BinaryPackagePublishingHistory.archiveID == archive.id,
-            PublishDAS.id ==
-                BinaryPackagePublishingHistory.distroarchseriesID,
-            PublishDAS.distroseriesID == distroseries.id,
-            # Architecture-independent binary package releases are built
-            # in the nominated arch-indep architecture but published in
-            # all architectures.  This condition makes sure we consider
-            # only builds that have been published in their own
-            # architecture.
-            PublishDAS.architecturetag == BuildDAS.architecturetag)
-        results = list(query.config(distinct=True))
-        mapped_results = dict(results)
-        assert len(mapped_results) == len(results), (
-            "Found multiple build candidates per architecture: %s.  "
-            "This may mean that we have a serious problem in our DB model.  "
-            "Further investigation is required."
-            % [(tag, build.id) for tag, build in results])
-        return mapped_results
-
-    def getRelevantToSourceAndLocation(self, sourcepackagerelease, archive,
-                                       distroarchseries):
-        """See IBinaryPackageBuildSet."""
-        # First we try to follow any binaries built from the given source
-        # in a distroarchseries with the given architecturetag and published
-        # in the given (distroarchseries, archive) location.
-        # (Querying all architectures and then picking the right one out
-        # of the result turns out to be much faster than querying for
-        # just the architecture we want).
-        builds_by_arch = self._findBySourceAndLocation(
-            sourcepackagerelease, archive, distroarchseries.distroseries)
-        build = builds_by_arch.get(distroarchseries.architecturetag)
-        if build is not None:
-            # If there was any published binary we can use its original build.
-            # This case covers the situations when both source and binaries
-            # got copied from another location.
-            return build
-
-        # If there was no published binary we have to try to find a
-        # suitable build in all possible location across the distroseries
-        # inheritance tree. See below.
-        clause_tables = ['DistroArchSeries']
-        queries = [
-            "DistroArchSeries.id = BinaryPackageBuild.distro_arch_series AND "
-            "BinaryPackageBuild.archive = %s AND "
-            "DistroArchSeries.architecturetag = %s AND "
-            "BinaryPackageBuild.source_package_release = %s" % (
-            sqlvalues(
-                archive.id, distroarchseries.architecturetag,
-                sourcepackagerelease))]
-
-        # Query only the last build record for this sourcerelease
-        # across all possible locations.
-        query = " AND ".join(queries)
-
-        return BinaryPackageBuild.selectFirst(
-            query, clauseTables=clause_tables,
-            orderBy=['-date_created'])
+            Or(
+                BinaryPackageBuild.archive == archive,
+                Exists(published_query))))
+        arch_map = {
+            build.distro_arch_series.architecturetag: build
+            for build in builds}
+        if len(arch_map) != len(builds):
+            raise AssertionError(
+                "Multiple successful builds for a single archtag. "
+                "Something is probably corrupt.")
+        return arch_map
 
     def getStatusSummaryForBuilds(self, builds):
         """See `IBinaryPackageBuildSet`."""
@@ -1440,14 +1391,14 @@
         Return the just-created `IBinaryPackageBuild` record already
         scored or None if a suitable build is already present.
         """
-        build_candidate = self.getRelevantToSourceAndLocation(
+        exact_build = self.getBySourceAndLocation(
             sourcepackagerelease, archive, arch)
+        if exact_build is not None:
+            return None
 
-        # Check DistroArchSeries database IDs because the object belongs
-        # to different transactions (architecture_available is cached).
-        if (build_candidate is not None and
-            (build_candidate.distro_arch_series.id == arch.id or
-             build_candidate.status == BuildStatus.FULLYBUILT)):
+        build_candidate = self.findBuiltOrPublishedBySourceAndArchive(
+            sourcepackagerelease, archive).get(arch.architecturetag)
+        if build_candidate is not None:
             return None
 
         build = self.new(

=== modified file 'lib/lp/soyuz/scripts/tests/test_initialize_distroseries.py'
--- lib/lp/soyuz/scripts/tests/test_initialize_distroseries.py	2014-11-05 12:10:10 +0000
+++ lib/lp/soyuz/scripts/tests/test_initialize_distroseries.py	2014-11-06 02:41:13 +0000
@@ -598,8 +598,8 @@
         self.assertEqual(udev_src.title, u'udev - 0.1-1')
         # The build of udev 0.1-1 has been copied across.
         bpbs = getUtility(IBinaryPackageBuildSet)
-        child_udev = bpbs.getRelevantToSourceAndLocation(
-            udev_src, child.main_archive, child[parent_das.architecturetag])
+        child_udev = bpbs.findBuiltOrPublishedBySourceAndArchive(
+            udev_src, child.main_archive).get(parent_das.architecturetag)
         parent_udev = bpbs.getBySourceAndLocation(
             udev_src, parent.main_archive, parent[parent_das.architecturetag])
         self.assertEqual(parent_udev.id, child_udev.id)

=== modified file 'lib/lp/soyuz/tests/test_build_set.py'
--- lib/lp/soyuz/tests/test_build_set.py	2014-11-06 02:29:29 +0000
+++ lib/lp/soyuz/tests/test_build_set.py	2014-11-06 02:41:13 +0000
@@ -360,53 +360,91 @@
         self.assertBuildsMatch({'sparc': True, 'avr': False}, builds)
 
 
-class TestFindBySourceAndLocation(TestCaseWithFactory):
-    """Tests for the _findBySourceAndLocation helper."""
-
-    layer = ZopelessDatabaseLayer
-
-    def test_finds_build_with_matching_pub(self):
-        # _findBySourceAndLocation finds builds for a source package
-        # release.  In particular, an arch-independent BPR is published in
-        # multiple architectures.  But findBuildsByArchitecture only counts
-        # the publication for the same architecture it was built in.
-        distroseries = self.factory.makeDistroSeries()
-        archive = distroseries.main_archive
-        # The series has a nominated arch-indep architecture.
-        distroseries.nominatedarchindep = self.factory.makeDistroArchSeries(
-            distroseries=distroseries)
-
-        bpb = self.factory.makeBinaryPackageBuild(
-            distroarchseries=distroseries.nominatedarchindep)
-        bpr = self.factory.makeBinaryPackageRelease(
-            build=bpb, architecturespecific=False)
-        spr = bpr.build.source_package_release
-
-        # The series also has other architectures.
-        self.factory.makeDistroArchSeries(distroseries=distroseries)
-
-        # makeBinaryPackagePublishingHistory will actually publish an
-        # arch-indep BPR everywhere.
-        self.factory.makeBinaryPackagePublishingHistory(
-            binarypackagerelease=bpr, archive=archive,
-            distroarchseries=distroseries.nominatedarchindep)
-
-        naked_spr = removeSecurityProxy(spr)
-        self.assertEqual(
-            {distroseries.nominatedarchindep.architecturetag: bpr.build},
-            BinaryPackageBuildSet()._findBySourceAndLocation(
-                naked_spr, archive, distroseries))
-
-
-class TestGetBySourceAndLocation(TestCaseWithFactory):
-    """Tests for BinaryPackageBuildSet.getRelevantToSourceAndLocation()."""
-
-    layer = ZopelessDatabaseLayer
+class TestFindBuiltOrPublishedBySourceAndArchive(TestCaseWithFactory):
+    """Tests for findBuiltOrPublishedBySourceAndArchive()."""
+
+    layer = ZopelessDatabaseLayer
+
+    def setUp(self):
+        super(TestFindBuiltOrPublishedBySourceAndArchive, self).setUp()
+        self.bpbs = getUtility(IBinaryPackageBuildSet)
+
+    def test_trivial(self):
+        # Builds with status FULLYBUILT with a matching
+        # SourcePackageRelease and Archive are returned.
+        bpb1 = self.factory.makeBinaryPackageBuild(
+            status=BuildStatus.FULLYBUILT)
+        bpb2 = self.factory.makeBinaryPackageBuild(
+            source_package_release=bpb1.source_package_release,
+            archive=bpb1.archive)
+        self.assertEqual(
+            {bpb1.distro_arch_series.architecturetag: bpb1},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, bpb1.archive))
+        bpb2.updateStatus(BuildStatus.FULLYBUILT)
+        self.assertEqual(
+            {bpb1.distro_arch_series.architecturetag: bpb1,
+             bpb2.distro_arch_series.architecturetag: bpb2},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, bpb1.archive))
+
+    def test_trivial_mismatch(self):
+        # Builds for other sources and archives are ignored.
+        bpb = self.factory.makeBinaryPackageBuild()
+        self.assertEqual(
+            {},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb.source_package_release, self.factory.makeArchive()))
+        self.assertEqual(
+            {},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                self.factory.makeSourcePackageRelease(), bpb.archive))
+
+    def test_copies_are_found(self):
+        # If a build's binaries are published (with a
+        # BinaryPackagePublishingHistory) in another archive, it shows
+        # up in requests for that archive.
+        bpb1 = self.factory.makeBinaryPackageBuild(
+            status=BuildStatus.FULLYBUILT)
+        bpr1 = self.factory.makeBinaryPackageRelease(build=bpb1)
+        bpb2 = self.factory.makeBinaryPackageBuild(
+            source_package_release=bpb1.source_package_release,
+            archive=bpb1.archive, status=BuildStatus.FULLYBUILT)
+        bpr2 = self.factory.makeBinaryPackageRelease(build=bpb2)
+
+        # A fresh archive sees no builds.
+        target = self.factory.makeArchive()
+        self.assertEqual(
+            {},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, target))
+
+        # But copying one build over makes it appear.
+        self.factory.makeBinaryPackagePublishingHistory(
+            binarypackagerelease=bpr1, archive=target)
+        self.assertEqual(
+            {bpb1.distro_arch_series.architecturetag: bpb1},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, target))
+
+        # Copying the second gives us both.
+        self.factory.makeBinaryPackagePublishingHistory(
+            binarypackagerelease=bpr2, archive=target)
+        self.assertEqual(
+            {bpb1.distro_arch_series.architecturetag: bpb1,
+             bpb2.distro_arch_series.architecturetag: bpb2},
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, target))
+        self.assertEqual(
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, bpb1.archive),
+            self.bpbs.findBuiltOrPublishedBySourceAndArchive(
+                bpb1.source_package_release, target))
 
     def test_can_find_build_in_derived_distro_parent(self):
         # If a derived distribution inherited its binaries from its
-        # parent then getRelevantToSourceAndLocation() should look in
-        # the parent to find the build.
+        # parent then findBuiltOrPublishedBySourceAndArchive() should
+        # look in the parent to find the build.
         dsp = self.factory.makeDistroSeriesParent()
         parent_archive = dsp.parent_series.main_archive
 
@@ -444,6 +482,6 @@
         # Searching for the build in the derived series architecture
         # should automatically pick it up from the parent.
         found_build = getUtility(
-            IBinaryPackageBuildSet).getRelevantToSourceAndLocation(
-                spr, derived_archive, das_derived)
+            IBinaryPackageBuildSet).findBuiltOrPublishedBySourceAndArchive(
+                spr, derived_archive).get(das_derived.architecturetag)
         self.assertEqual(orig_build, found_build)

=== modified file 'lib/lp/soyuz/tests/test_doc.py'
--- lib/lp/soyuz/tests/test_doc.py	2013-06-27 06:59:35 +0000
+++ lib/lp/soyuz/tests/test_doc.py	2014-11-06 02:41:13 +0000
@@ -134,10 +134,6 @@
         setUp=setUp,
         layer=LaunchpadZopelessLayer,
         ),
-    'sourcepackagerelease-build-lookup.txt': LayeredDocFileSuite(
-        '../doc/sourcepackagerelease-build-lookup.txt',
-        layer=LaunchpadZopelessLayer,
-        ),
     }
 
 


Follow ups