Beispiel #1
0
    def _prepareMergeCopy(self):
        """Add a fresher and a new package to ubuntu/hoary.

        This is used to test merge copy functionality."""
        test_publisher = SoyuzTestPublisher()
        ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
        hoary = ubuntu.getSeries('hoary')
        test_publisher.addFakeChroots(hoary)
        test_publisher.setUpDefaultDistroSeries(hoary)
        test_publisher.getPubSource(sourcename="new-in-second-round",
                                    version="1.0",
                                    distroseries=hoary,
                                    archive=ubuntu.main_archive)
        test_publisher.getPubSource(sourcename="alsa-utils",
                                    version="2.0",
                                    distroseries=hoary,
                                    archive=ubuntu.main_archive)
        sources = ubuntu.main_archive.getPublishedSources(
            distroseries=hoary,
            status=self.pending_statuses,
            name=u'alsa-utils')
        for src in sources:
            if src.source_package_version != '2.0':
                src.supersede()
        LaunchpadZopelessLayer.txn.commit()
    def _prepareMergeCopy(self):
        """Add a fresher and a new package to ubuntu/hoary.

        This is used to test merge copy functionality."""
        test_publisher = SoyuzTestPublisher()
        ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
        hoary = ubuntu.getSeries('hoary')
        test_publisher.addFakeChroots(hoary)
        test_publisher.setUpDefaultDistroSeries(hoary)
        test_publisher.getPubSource(
            sourcename="new-in-second-round", version="1.0",
            distroseries=hoary, archive=ubuntu.main_archive)
        test_publisher.getPubSource(
            sourcename="alsa-utils", version="2.0", distroseries=hoary,
            archive=ubuntu.main_archive)
        sources = ubuntu.main_archive.getPublishedSources(
            distroseries=hoary, status=self.pending_statuses,
            name=u'alsa-utils')
        for src in sources:
            if src.source_package_version != '2.0':
                src.supersede()
        LaunchpadZopelessLayer.txn.commit()
Beispiel #3
0
    def test_can_run_twice(self):
        test_publisher = SoyuzTestPublisher()
        distroseries = test_publisher.setUpDefaultDistroSeries()
        distro = distroseries.distribution
        self.factory.makeComponentSelection(distroseries=distroseries,
                                            component="main")
        self.factory.makeArchive(distribution=distro,
                                 purpose=ArchivePurpose.PARTNER)
        test_publisher.getPubSource()

        self.setUpForScriptRun(distro)
        self.makeScript(distro).main()
        self.makeScript(distro).main()
    def test_can_run_twice(self):
        test_publisher = SoyuzTestPublisher()
        distroseries = test_publisher.setUpDefaultDistroSeries()
        distro = distroseries.distribution
        self.factory.makeComponentSelection(
            distroseries=distroseries, component="main")
        self.factory.makeArchive(
            distribution=distro, purpose=ArchivePurpose.PARTNER)
        test_publisher.getPubSource()

        self.setUpForScriptRun(distro)
        self.makeScript(distro).main()
        self.makeScript(distro).main()
Beispiel #5
0
    def test_publishes_package(self):
        test_publisher = SoyuzTestPublisher()
        distroseries = test_publisher.setUpDefaultDistroSeries()
        distro = distroseries.distribution
        pub_config = get_pub_config(distro)
        self.factory.makeComponentSelection(distroseries=distroseries,
                                            component="main")
        self.factory.makeArchive(distribution=distro,
                                 purpose=ArchivePurpose.PARTNER)
        test_publisher.getPubSource()

        self.setUpForScriptRun(distro)
        self.makeScript(distro).main()

        archive_root = get_archive_root(pub_config)
        dists_root = get_dists_root(pub_config)

        dsc = os.path.join(archive_root, 'pool', 'main', 'f', 'foo',
                           'foo_666.dsc')
        self.assertEqual("I do not care about sources.", file(dsc).read())
        overrides = os.path.join(archive_root + '-overrides',
                                 distroseries.name + '_main_source')
        self.assertEqual(dsc, file(overrides).read().rstrip())
        self.assertTrue(
            path_exists(dists_root, distroseries.name, 'main', 'source',
                        'Sources.gz'))
        self.assertTrue(
            path_exists(dists_root, distroseries.name, 'main', 'source',
                        'Sources.bz2'))

        distcopyseries = os.path.join(dists_root, distroseries.name)
        release = self.readReleaseFile(os.path.join(distcopyseries, "Release"))
        self.assertEqual(distro.displayname, release['Origin'])
        self.assertEqual(distro.displayname, release['Label'])
        self.assertEqual(distroseries.name, release['Suite'])
        self.assertEqual(distroseries.name, release['Codename'])
        self.assertEqual("main", release['Components'])
        self.assertEqual("", release["Architectures"])
        self.assertIn("Date", release)
        self.assertIn("Description", release)
        self.assertNotEqual("", release["MD5Sum"])
        self.assertNotEqual("", release["SHA1"])
        self.assertNotEqual("", release["SHA256"])

        main_release = self.readReleaseFile(
            os.path.join(distcopyseries, 'main', 'source', "Release"))
        self.assertEqual(distroseries.name, main_release["Archive"])
        self.assertEqual("main", main_release["Component"])
        self.assertEqual(distro.displayname, main_release["Origin"])
        self.assertEqual(distro.displayname, main_release["Label"])
        self.assertEqual("source", main_release["Architecture"])
    def test_publishes_package(self):
        test_publisher = SoyuzTestPublisher()
        distroseries = test_publisher.setUpDefaultDistroSeries()
        distro = distroseries.distribution
        pub_config = get_pub_config(distro)
        self.factory.makeComponentSelection(
            distroseries=distroseries, component="main")
        self.factory.makeArchive(
            distribution=distro, purpose=ArchivePurpose.PARTNER)
        test_publisher.getPubSource()

        self.setUpForScriptRun(distro)
        self.makeScript(distro).main()

        archive_root = get_archive_root(pub_config)
        dists_root = get_dists_root(pub_config)

        dsc = os.path.join(
            archive_root, 'pool', 'main', 'f', 'foo', 'foo_666.dsc')
        self.assertEqual("I do not care about sources.", file(dsc).read())
        overrides = os.path.join(
            archive_root + '-overrides', distroseries.name + '_main_source')
        self.assertEqual(dsc, file(overrides).read().rstrip())
        self.assertTrue(path_exists(
            dists_root, distroseries.name, 'main', 'source', 'Sources.gz'))
        self.assertTrue(path_exists(
            dists_root, distroseries.name, 'main', 'source', 'Sources.bz2'))

        distcopyseries = os.path.join(dists_root, distroseries.name)
        release = self.readReleaseFile(
            os.path.join(distcopyseries, "Release"))
        self.assertEqual(distro.displayname, release['Origin'])
        self.assertEqual(distro.displayname, release['Label'])
        self.assertEqual(distroseries.name, release['Suite'])
        self.assertEqual(distroseries.name, release['Codename'])
        self.assertEqual("main", release['Components'])
        self.assertEqual("", release["Architectures"])
        self.assertIn("Date", release)
        self.assertIn("Description", release)
        self.assertNotEqual("", release["MD5Sum"])
        self.assertNotEqual("", release["SHA1"])
        self.assertNotEqual("", release["SHA256"])

        main_release = self.readReleaseFile(
            os.path.join(distcopyseries, 'main', 'source', "Release"))
        self.assertEqual(distroseries.name, main_release["Archive"])
        self.assertEqual("main", main_release["Component"])
        self.assertEqual(distro.displayname, main_release["Origin"])
        self.assertEqual(distro.displayname, main_release["Label"])
        self.assertEqual("source", main_release["Architecture"])
 def setUp(self):
     super(TestDistroSourcePackageReleaseFiles, self).setUp()
     # The package must be published for the page to render.
     stp = SoyuzTestPublisher()
     distroseries = stp.setUpDefaultDistroSeries()
     naked_distroseries = remove_security_proxy_and_shout_at_engineer(
         distroseries)
     # XXX Abel Deuring, 2010-07-21, bug 608240. This is scary. But
     # if we use distroseries.distribution instead,
     # test_spr_files_deleted() and test_spr_files_one() fail.
     distro = naked_distroseries.distribution
     source_package_release = stp.getPubSource().sourcepackagerelease
     self.dspr = DistributionSourcePackageRelease(
         distro, source_package_release)
     self.library_file = self.factory.makeLibraryFileAlias(
         filename='test_file.dsc', content='0123456789')
     source_package_release.addFile(self.library_file)
Beispiel #8
0
 def test_script_creates_indexes(self):
     # End-to-end test: the script creates indexes for distroseries
     # that need them.
     test_publisher = SoyuzTestPublisher()
     series = test_publisher.setUpDefaultDistroSeries()
     series.status = SeriesStatus.FROZEN
     self.factory.makeComponentSelection(distroseries=series,
                                         component="main")
     self.layer.txn.commit()
     self.setUpForScriptRun(series.distribution)
     script = self.makeScript(series.distribution)
     script.main()
     self.assertEqual([], script.listSuitesNeedingIndexes(series))
     sources = os.path.join(
         getPubConfig(series.main_archive).distsroot, series.name, "main",
         "source", "Sources")
     self.assertTrue(file_exists(sources))
Beispiel #9
0
 def setUp(self):
     super(TestDistroSourcePackageReleaseFiles, self).setUp()
     # The package must be published for the page to render.
     stp = SoyuzTestPublisher()
     distroseries = stp.setUpDefaultDistroSeries()
     naked_distroseries = remove_security_proxy_and_shout_at_engineer(
         distroseries)
     # XXX Abel Deuring, 2010-07-21, bug 608240. This is scary. But
     # if we use distroseries.distribution instead,
     # test_spr_files_deleted() and test_spr_files_one() fail.
     distro = naked_distroseries.distribution
     source_package_release = stp.getPubSource().sourcepackagerelease
     self.dspr = DistributionSourcePackageRelease(distro,
                                                  source_package_release)
     self.library_file = self.factory.makeLibraryFileAlias(
         filename='test_file.dsc', content='0123456789')
     source_package_release.addFile(self.library_file)
 def test_script_creates_indexes(self):
     # End-to-end test: the script creates indexes for distroseries
     # that need them.
     test_publisher = SoyuzTestPublisher()
     series = test_publisher.setUpDefaultDistroSeries()
     series.status = SeriesStatus.FROZEN
     self.factory.makeComponentSelection(
         distroseries=series, component="main")
     self.layer.txn.commit()
     self.setUpForScriptRun(series.distribution)
     script = self.makeScript(series.distribution)
     script.main()
     self.assertEqual([], script.listSuitesNeedingIndexes(series))
     sources = os.path.join(
         getPubConfig(series.main_archive).distsroot,
         series.name, "main", "source", "Sources")
     self.assertTrue(file_exists(sources))
Beispiel #11
0
 def getTestPublisher(self, distroseries):
     """Return an `SoyuzTestPublisher`instance."""
     stp = SoyuzTestPublisher()
     stp.addFakeChroots(distroseries)
     stp.setUpDefaultDistroSeries(distroseries)
     return stp
class CurrentSourceReleasesMixin:
    """Mixin class for current source release tests.

    Used by tests of DistroSeries and Distribution.  The mixin must not extend
    TestCase or it will be run by other modules when imported.
    """
    def setUp(self):
        # Log in as an admin, so that we can create distributions.
        super(CurrentSourceReleasesMixin, self).setUp()
        login('*****@*****.**')
        self.publisher = SoyuzTestPublisher()
        self.factory = self.publisher.factory
        self.development_series = self.publisher.setUpDefaultDistroSeries()
        self.distribution = self.development_series.distribution
        self.published_package = self.target.getSourcePackage(
            self.publisher.default_package_name)
        login(ANONYMOUS)

    def assertCurrentVersion(self, expected_version, package_name=None):
        """Assert the current version of a package is the expected one.

        It uses getCurrentSourceReleases() to get the version.

        If package_name isn't specified, the test publisher's default
        name is used.
        """
        if package_name is None:
            package_name = self.publisher.default_package_name
        package = self.target.getSourcePackage(package_name)
        releases = self.target.getCurrentSourceReleases(
            [package.sourcepackagename])
        self.assertEqual(releases[package].version, expected_version)

    def test_one_release(self):
        # If there is one published version, that one will be returned.
        self.publisher.getPubSource(version='0.9')
        self.assertCurrentVersion('0.9')

    def test_return_value(self):
        # getCurrentSourceReleases() returns a dict. The corresponding
        # source package is used as the key, with
        # a DistributionSourcePackageRelease as the values.
        self.publisher.getPubSource(version='0.9')
        releases = self.target.getCurrentSourceReleases(
            [self.published_package.sourcepackagename])
        self.assertTrue(self.published_package in releases)
        self.assertTrue(
            self.release_interface.providedBy(
                releases[self.published_package]))

    def test_latest_version(self):
        # If more than one version is published, the latest one is
        # returned.
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(version='1.0')
        self.assertCurrentVersion('1.0')

    def test_active_publishing_status(self):
        # Every status defined in active_publishing_status is considered
        # when checking for the current release.
        self.publisher.getPubSource(version='0.9')
        for minor_version, status in enumerate(active_publishing_status):
            latest_version = '1.%s' % minor_version
            self.publisher.getPubSource(version=latest_version, status=status)
            self.assertCurrentVersion(latest_version)

    def test_not_active_publishing_status(self):
        # Every status not defined in active_publishing_status is
        # ignored when checking for the current release.
        self.publisher.getPubSource(version='0.9')
        for minor_version, status in enumerate(PackagePublishingStatus.items):
            if status in active_publishing_status:
                continue
            self.publisher.getPubSource(version='1.%s' % minor_version,
                                        status=status)
            self.assertCurrentVersion('0.9')

    def test_ignore_other_package_names(self):
        # Packages with different names don't affect the returned
        # version.
        self.publisher.getPubSource(version='0.9', sourcename='foo')
        self.publisher.getPubSource(version='1.0', sourcename='bar')
        self.assertCurrentVersion('0.9', package_name='foo')

    def ignore_other_distributions(self):
        # Packages with the same name in other distributions don't
        # affect the returned version.
        series_in_other_distribution = self.factory.makeDistroSeries()
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(version='1.0',
                                    distroseries=series_in_other_distribution)
        self.assertCurrentVersion('0.9')

    def test_ignore_ppa(self):
        # PPA packages having the same name don't affect the returned
        # version.
        ppa_uploader = self.factory.makePerson()
        ppa_archive = getUtility(IArchiveSet).new(
            purpose=ArchivePurpose.PPA,
            owner=ppa_uploader,
            distribution=self.distribution)
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(version='1.0', archive=ppa_archive)
        self.assertCurrentVersion('0.9')

    def test_get_multiple(self):
        # getCurrentSourceReleases() allows you to get information about
        # the current release for multiple packages at the same time.
        # This is done using a single DB query, making it more efficient
        # than using IDistributionSource.currentrelease.
        self.publisher.getPubSource(version='0.9', sourcename='foo')
        self.publisher.getPubSource(version='1.0', sourcename='bar')
        foo_package = self.distribution.getSourcePackage('foo')
        bar_package = self.distribution.getSourcePackage('bar')
        releases = self.distribution.getCurrentSourceReleases(
            [foo_package.sourcepackagename, bar_package.sourcepackagename])
        self.assertEqual(releases[foo_package].version, '0.9')
        self.assertEqual(releases[bar_package].version, '1.0')
 def getTestPublisher(self, distroseries):
     """Return an `SoyuzTestPublisher`instance."""
     stp = SoyuzTestPublisher()
     stp.addFakeChroots(distroseries)
     stp.setUpDefaultDistroSeries(distroseries)
     return stp
class CurrentSourceReleasesMixin:
    """Mixin class for current source release tests.

    Used by tests of DistroSeries and Distribution.  The mixin must not extend
    TestCase or it will be run by other modules when imported.
    """
    def setUp(self):
        # Log in as an admin, so that we can create distributions.
        super(CurrentSourceReleasesMixin, self).setUp()
        login('*****@*****.**')
        self.publisher = SoyuzTestPublisher()
        self.factory = self.publisher.factory
        self.development_series = self.publisher.setUpDefaultDistroSeries()
        self.distribution = self.development_series.distribution
        self.published_package = self.target.getSourcePackage(
            self.publisher.default_package_name)
        login(ANONYMOUS)

    def assertCurrentVersion(self, expected_version, package_name=None):
        """Assert the current version of a package is the expected one.

        It uses getCurrentSourceReleases() to get the version.

        If package_name isn't specified, the test publisher's default
        name is used.
        """
        if package_name is None:
            package_name = self.publisher.default_package_name
        package = self.target.getSourcePackage(package_name)
        releases = self.target.getCurrentSourceReleases(
            [package.sourcepackagename])
        self.assertEqual(releases[package].version, expected_version)

    def test_one_release(self):
        # If there is one published version, that one will be returned.
        self.publisher.getPubSource(version='0.9')
        self.assertCurrentVersion('0.9')

    def test_return_value(self):
        # getCurrentSourceReleases() returns a dict. The corresponding
        # source package is used as the key, with
        # a DistroSeriesSourcePackageRelease as the values.
        self.publisher.getPubSource(version='0.9')
        releases = self.target.getCurrentSourceReleases(
            [self.published_package.sourcepackagename])
        self.assertTrue(self.published_package in releases)
        self.assertTrue(self.release_interface.providedBy(
            releases[self.published_package]))

    def test_latest_version(self):
        # If more than one version is published, the latest one is
        # returned.
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(version='1.0')
        self.assertCurrentVersion('1.0')

    def test_active_publishing_status(self):
        # Every status defined in active_publishing_status is considered
        # when checking for the current release.
        self.publisher.getPubSource(version='0.9')
        for minor_version, status in enumerate(active_publishing_status):
            latest_version = '1.%s' % minor_version
            self.publisher.getPubSource(version=latest_version, status=status)
            self.assertCurrentVersion(latest_version)

    def test_not_active_publishing_status(self):
        # Every status not defined in active_publishing_status is
        # ignored when checking for the current release.
        self.publisher.getPubSource(version='0.9')
        for minor_version, status in enumerate(PackagePublishingStatus.items):
            if status in active_publishing_status:
                continue
            self.publisher.getPubSource(
                version='1.%s' % minor_version, status=status)
            self.assertCurrentVersion('0.9')

    def test_ignore_other_package_names(self):
        # Packages with different names don't affect the returned
        # version.
        self.publisher.getPubSource(version='0.9', sourcename='foo')
        self.publisher.getPubSource(version='1.0', sourcename='bar')
        self.assertCurrentVersion('0.9', package_name='foo')

    def ignore_other_distributions(self):
        # Packages with the same name in other distributions don't
        # affect the returned version.
        series_in_other_distribution = self.factory.makeDistroSeries()
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(
            version='1.0', distroseries=series_in_other_distribution)
        self.assertCurrentVersion('0.9')

    def test_ignore_ppa(self):
        # PPA packages having the same name don't affect the returned
        # version.
        ppa_uploader = self.factory.makePerson()
        ppa_archive = getUtility(IArchiveSet).new(
            purpose=ArchivePurpose.PPA, owner=ppa_uploader,
            distribution=self.distribution)
        self.publisher.getPubSource(version='0.9')
        self.publisher.getPubSource(version='1.0', archive=ppa_archive)
        self.assertCurrentVersion('0.9')

    def test_get_multiple(self):
        # getCurrentSourceReleases() allows you to get information about
        # the current release for multiple packages at the same time.
        # This is done using a single DB query, making it more efficient
        # than using IDistributionSource.currentrelease.
        self.publisher.getPubSource(version='0.9', sourcename='foo')
        self.publisher.getPubSource(version='1.0', sourcename='bar')
        foo_package = self.distribution.getSourcePackage('foo')
        bar_package = self.distribution.getSourcePackage('bar')
        releases = self.distribution.getCurrentSourceReleases(
            [foo_package.sourcepackagename, bar_package.sourcepackagename])
        self.assertEqual(releases[foo_package].version, '0.9')
        self.assertEqual(releases[bar_package].version, '1.0')
class TestSourcesList(TestCaseWithFactory):
    """Test sources.list contents for building, and related mechanisms."""

    layer = LaunchpadZopelessLayer
    run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=10)

    ubuntu_components = [
        "main", "restricted", "universe", "multiverse", "partner"]

    fingerprints = {
        "*****@*****.**": "0D57E99656BEFB0897606EE9A022DD1F5001B46D",
        "*****@*****.**": (
            "B7B1966662BA8D3F5A6ED89BD640F4A593B2CF67"),
        }

    def setUp(self):
        super(TestSourcesList, self).setUp()
        self.publisher = SoyuzTestPublisher()
        self.ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
        self.hoary = self.ubuntu.getSeries("hoary")
        self.publisher.addFakeChroots(self.hoary)
        self.publisher.setUpDefaultDistroSeries(self.hoary)
        for component_name in self.ubuntu_components:
            component = getUtility(IComponentSet)[component_name]
            if component not in self.hoary.components:
                self.factory.makeComponentSelection(self.hoary, component)

    def test_defaults(self):
        # Non-primary archives by default use the Release, Security and
        # Updates pockets from the primary archive, and all its available
        # components.
        self.assertEqual(
            PackagePublishingPocket.UPDATES, default_pocket_dependency)
        self.assertEqual("multiverse", default_component_dependency_name)
        self.assertEqual(
            (PackagePublishingPocket.RELEASE,
             PackagePublishingPocket.SECURITY,
             PackagePublishingPocket.UPDATES),
            pocket_dependencies[default_pocket_dependency])

    @defer.inlineCallbacks
    def makeArchive(self, signing_key_name="*****@*****.**",
                    publish_binary=False, **kwargs):
        try:
            getattr(config, "in-process-key-server-fixture")
        except AttributeError:
            yield self.useFixture(InProcessKeyServerFixture()).start()
        archive = self.factory.makeArchive(distribution=self.ubuntu, **kwargs)
        if signing_key_name is not None:
            key_path = os.path.join(gpgkeysdir, "%s.sec" % signing_key_name)
            yield IArchiveSigningKey(archive).setSigningKey(
                key_path, async_keyserver=True)
        if publish_binary:
            self.publisher.getPubBinaries(
                archive=archive, status=PackagePublishingStatus.PUBLISHED)
        defer.returnValue(archive)

    def makeBuild(self, **kwargs):
        pub_source = self.publisher.getPubSource(**kwargs)
        [build] = pub_source.createMissingBuilds()
        return build

    def assertPrimaryCurrentComponent(self, expected, build):
        self.assertEqual(
            expected,
            get_primary_current_component(
                build.archive, build.distro_series,
                build.source_package_release.name).name)

    @defer.inlineCallbacks
    def assertSourcesListAndKeys(self, expected_sources_list,
                                 expected_key_names, build, **kwargs):
        expected_lines = []
        for archive_or_prefix, suffixes in expected_sources_list:
            if IArchive.providedBy(archive_or_prefix):
                prefix = "deb %s " % archive_or_prefix.archive_url
            else:
                prefix = archive_or_prefix + " "
            expected_lines.extend([prefix + suffix for suffix in suffixes])
        sources_list, trusted_keys = yield get_sources_list_for_building(
            build, build.distro_arch_series, build.source_package_release.name,
            **kwargs)
        self.assertEqual(expected_lines, sources_list)
        key_matchers = [
            Base64KeyMatches(self.fingerprints[key_name])
            for key_name in expected_key_names]
        self.assertThat(trusted_keys, MatchesSetwise(*key_matchers))

    @defer.inlineCallbacks
    def test_ppa_with_no_binaries(self):
        # If there are no published binaries in a PPA, only its primary
        # archive dependencies need to be considered.
        ppa = yield self.makeArchive()
        build = self.makeBuild(archive=ppa)
        self.assertEqual(
            0, ppa.getAllPublishedBinaries(
                distroarchseries=build.distro_arch_series,
                status=PackagePublishingStatus.PUBLISHED).count())
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_ppa_with_binaries(self):
        # If there are binaries published in a PPA, then the PPA is
        # considered as well as its primary dependencies.
        ppa = yield self.makeArchive(publish_binary=True)
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], ["*****@*****.**"], build)

    @defer.inlineCallbacks
    def test_dependent_ppa_with_no_binaries(self):
        # A depended-upon PPA is not considered if it has no published
        # binaries.
        lower_ppa = yield self.makeArchive(
            signing_key_name="*****@*****.**")
        upper_ppa = yield self.makeArchive(publish_binary=True)
        upper_ppa.addArchiveDependency(
            lower_ppa, PackagePublishingPocket.RELEASE,
            getUtility(IComponentSet)["main"])
        build = self.makeBuild(archive=upper_ppa)
        yield self.assertSourcesListAndKeys(
            [(upper_ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], ["*****@*****.**"], build)

    @defer.inlineCallbacks
    def test_dependent_ppa_with_binaries(self):
        # A depended-upon PPA is considered if it has published binaries.
        lower_ppa = yield self.makeArchive(
            signing_key_name="*****@*****.**",
            publish_binary=True)
        upper_ppa = yield self.makeArchive(publish_binary=True)
        upper_ppa.addArchiveDependency(
            lower_ppa, PackagePublishingPocket.RELEASE,
            getUtility(IComponentSet)["main"])
        build = self.makeBuild(archive=upper_ppa)
        yield self.assertSourcesListAndKeys(
            [(upper_ppa, ["hoary main"]),
             (lower_ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ],
            ["*****@*****.**", "*****@*****.**"],
            build)

    @defer.inlineCallbacks
    def test_lax_supported_component_dependencies(self):
        # Dependencies for series with
        # strict_supported_component_dependencies=False are reasonable.
        # PPAs only have the "main" component.
        lower_ppa = yield self.makeArchive(
            signing_key_name="*****@*****.**",
            publish_binary=True)
        upper_ppa = yield self.makeArchive(publish_binary=True)
        upper_ppa.addArchiveDependency(
            lower_ppa, PackagePublishingPocket.RELEASE,
            getUtility(IComponentSet)["main"])
        upper_ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.UPDATES,
            getUtility(IComponentSet)["restricted"])
        build = self.makeBuild(archive=upper_ppa)
        yield self.assertSourcesListAndKeys(
            [(upper_ppa, ["hoary main"]),
             (lower_ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted",
                 "hoary-security main restricted",
                 "hoary-updates main restricted",
                 ]),
             ],
            ["*****@*****.**", "*****@*****.**"],
            build)
        self.hoary.strict_supported_component_dependencies = False
        transaction.commit()
        yield self.assertSourcesListAndKeys(
            [(upper_ppa, ["hoary main"]),
             (lower_ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ],
            ["*****@*****.**", "*****@*****.**"],
            build)

    @defer.inlineCallbacks
    def test_no_op_primary_archive_dependency(self):
        # Overriding the default primary archive dependencies with exactly
        # the same values has no effect.
        ppa = yield self.makeArchive()
        ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.UPDATES,
            getUtility(IComponentSet)["multiverse"])
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_primary_archive_dependency_security(self):
        # The primary archive dependency can be modified to behave as an
        # embargoed archive that builds security updates.  This is done by
        # setting the SECURITY pocket dependencies (RELEASE and SECURITY)
        # and following the component dependencies of the component where
        # the source was last published in the primary archive.
        ppa = yield self.makeArchive()
        ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.SECURITY)
        build = self.makeBuild(archive=ppa)
        self.assertPrimaryCurrentComponent("universe", build)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main universe",
                 "hoary-security main universe",
                 ]),
             ], [], build)
        self.publisher.getPubSource(
            sourcename="with-ancestry", version="1.0",
            archive=self.ubuntu.main_archive)
        [build_with_ancestry] = self.publisher.getPubSource(
            sourcename="with-ancestry", version="1.1",
            archive=ppa).createMissingBuilds()
        self.assertPrimaryCurrentComponent("main", build_with_ancestry)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main",
                 "hoary-security main",
                 ]),
             ], [], build_with_ancestry)

    @defer.inlineCallbacks
    def test_primary_archive_dependency_release(self):
        # The primary archive dependency can be modified to behave as a
        # pristine build environment based only on what was included in the
        # original release of the corresponding series.
        ppa = yield self.makeArchive()
        ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.RELEASE,
            getUtility(IComponentSet)["restricted"])
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, ["hoary main restricted"])], [], build)

    @defer.inlineCallbacks
    def test_primary_archive_dependency_proposed(self):
        # The primary archive dependency can be modified to extend the build
        # environment for PROPOSED.
        ppa = yield self.makeArchive()
        ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.PROPOSED,
            getUtility(IComponentSet)["multiverse"])
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 "hoary-proposed main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_primary_archive_dependency_backports(self):
        # The primary archive dependency can be modified to extend the build
        # environment for PROPOSED.
        ppa = yield self.makeArchive()
        ppa.addArchiveDependency(
            self.ubuntu.main_archive, PackagePublishingPocket.BACKPORTS,
            getUtility(IComponentSet)["multiverse"])
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 "hoary-backports main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_partner(self):
        # Similarly to what happens with PPA builds, partner builds may
        # depend on any component in the primary archive.  This behaviour
        # allows scenarios where partner packages may use other
        # restricted/non-free applications from multiverse, and also other
        # partner applications.
        primary, partner = self.ubuntu.all_distro_archives
        self.publisher.getPubBinaries(
            archive=partner, component="partner",
            status=PackagePublishingStatus.PUBLISHED)
        build = self.makeBuild(archive=partner, component="partner")
        yield self.assertSourcesListAndKeys(
            [(partner, ["hoary partner"]),
             (primary, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_partner_proposed(self):
        # The partner archive's PROPOSED pocket builds against itself, but
        # still uses the default UPDATES dependency for the primary archive
        # unless overridden by ArchiveDependency.
        primary, partner = self.ubuntu.all_distro_archives
        self.publisher.getPubBinaries(
            archive=partner, component="partner",
            status=PackagePublishingStatus.PUBLISHED)
        self.publisher.getPubBinaries(
            archive=partner, component="partner",
            status=PackagePublishingStatus.PUBLISHED,
            pocket=PackagePublishingPocket.PROPOSED)
        build = self.makeBuild(
            archive=partner, component="partner",
            pocket=PackagePublishingPocket.PROPOSED)
        yield self.assertSourcesListAndKeys(
            [(partner, [
                 "hoary partner",
                 "hoary-proposed partner",
                 ]),
             (primary, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], [], build)

    @defer.inlineCallbacks
    def test_archive_external_dependencies(self):
        # An archive can be manually given additional external dependencies.
        # If present, "%(series)s" is replaced with the series name for the
        # build being dispatched.
        ppa = yield self.makeArchive(publish_binary=True)
        ppa.external_dependencies = (
            "deb http://user:pass@repository zoing everything\n"
            "deb http://user:pass@repository %(series)s public private\n"
            "deb http://user:pass@repository %(series)s-extra public")
        build = self.makeBuild(archive=ppa)
        yield self.assertSourcesListAndKeys(
            [(ppa, ["hoary main"]),
             ("deb http://user:pass@repository", [
                 "zoing everything",
                 "hoary public private",
                 "hoary-extra public",
                 ]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], ["*****@*****.**"], build)

    @defer.inlineCallbacks
    def test_build_external_dependencies(self):
        # A single build can be manually given additional external
        # dependencies.
        ppa = yield self.makeArchive(publish_binary=True)
        build = self.makeBuild(archive=ppa)
        build.api_external_dependencies = (
            "deb http://user:pass@repository foo bar")
        yield self.assertSourcesListAndKeys(
            [(ppa, ["hoary main"]),
             ("deb http://user:pass@repository", ["foo bar"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ], ["*****@*****.**"], build)

    @defer.inlineCallbacks
    def test_build_tools(self):
        # We can force an extra build tools line to be added to
        # sources.list, which is useful for specialised build types.
        ppa = yield self.makeArchive(publish_binary=True)
        build = self.makeBuild(archive=ppa)

        # Upload the tools archive key to the keyserver.
        tools_key_name = "*****@*****.**"
        tools_key_path = os.path.join(gpgkeysdir, "%s.sec" % tools_key_name)
        with open(tools_key_path) as tools_key_file:
            secret_key_export = tools_key_file.read()
        # Remove security proxy to avoid problems with running in a thread.
        gpghandler = removeSecurityProxy(getUtility(IGPGHandler))
        gpghandler.importSecretKey(secret_key_export)
        yield deferToThread(
            gpghandler.uploadPublicKey, self.fingerprints[tools_key_name])

        yield self.assertSourcesListAndKeys(
            [(ppa, ["hoary main"]),
             ("deb http://example.org", ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ],
            ["*****@*****.**", tools_key_name], build,
            tools_source="deb http://example.org %(series)s main",
            tools_fingerprint=self.fingerprints[tools_key_name])

    @defer.inlineCallbacks
    def test_build_tools_bad_formatting(self):
        # If tools_source is badly formatted, we log the error but don't
        # blow up.  (Note the missing "s" at the end of "%(series)".)
        ppa = yield self.makeArchive(publish_binary=True)
        build = self.makeBuild(archive=ppa)
        logger = BufferLogger()
        yield self.assertSourcesListAndKeys(
            [(ppa, ["hoary main"]),
             (self.ubuntu.main_archive, [
                 "hoary main restricted universe multiverse",
                 "hoary-security main restricted universe multiverse",
                 "hoary-updates main restricted universe multiverse",
                 ]),
             ],
            ["*****@*****.**"], build,
            tools_source="deb http://example.org %(series) main",
            logger=logger)
        self.assertThat(logger.getLogBuffer(), StartsWith(
            "ERROR Exception processing build tools sources.list entry:\n"))

    @defer.inlineCallbacks
    def test_overlay(self):
        # An overlay distroseries is a derived distribution which works like
        # a PPA.  This means that the parent's details gets added to the
        # sources.list passed to the builders.
        depdistro = self.factory.makeDistribution(
            "depdistro", publish_base_url="http://archive.launchpad.dev/")
        depseries = self.factory.makeDistroSeries(
            distribution=depdistro, name="depseries")
        self.factory.makeDistroArchSeries(
            distroseries=depseries, architecturetag="i386")
        self.publisher.addFakeChroots(depseries)
        for component_name in self.ubuntu_components:
            component = getUtility(IComponentSet)[component_name]
            self.factory.makeComponentSelection(depseries, component)
        self.factory.makeDistroSeriesParent(
            derived_series=self.hoary, parent_series=depseries,
            initialized=True, is_overlay=True,
            pocket=PackagePublishingPocket.SECURITY,
            component=getUtility(IComponentSet)["universe"])
        build = self.makeBuild()
        yield self.assertSourcesListAndKeys(
            [(self.ubuntu.main_archive, ["hoary main"]),
             (depdistro.main_archive, [
                 "depseries main universe",
                 "depseries-security main universe",
                 ]),
             ], [], build)