← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/archive-processors into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/archive-processors into lp:launchpad.

Commit message:
Add Archive.processors and explicitly enable default architectures when creating an archive.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/archive-processors/+merge/259346

As part of making all architecture toggleable, this branch adds Archive.processors and Archive.setProcessors in a transitional way.

Archive.processors returns all unrestricted architectures plus any enabled restricted architectures, and setProcessors will only add or remove rows for restricted architectures. Both will change to directly reflect ArchiveArch rows once that table has been backfilled.

ArchiveSet.new creates ArchiveArch rows for build_by_default architectures, except for copy archives which actually already used the future meaning of ArchiveArch (that's how ARM-only rebuilds work). The missing ones will be inserted with a hot DB patch.

Once Archive.processors represents exactly what's in ArchiveArch, ArchiveArch will be accessed exclusively via that property.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/archive-processors into lp:launchpad.
=== modified file 'lib/lp/_schema_circular_imports.py'
--- lib/lp/_schema_circular_imports.py	2015-04-24 12:58:46 +0000
+++ lib/lp/_schema_circular_imports.py	2015-05-18 06:37:58 +0000
@@ -58,7 +58,6 @@
     )
 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
 from lp.buildmaster.interfaces.buildqueue import IBuildQueue
-from lp.buildmaster.interfaces.processor import IProcessor
 from lp.code.interfaces.branch import (
     IBranch,
     IBranchSet,
@@ -385,8 +384,6 @@
 # IArchive apocalypse.
 patch_reference_property(IArchive, 'distribution', IDistribution)
 patch_collection_property(IArchive, 'dependencies', IArchiveDependency)
-patch_collection_property(
-    IArchive, 'enabled_restricted_processors', IProcessor)
 patch_collection_return_type(IArchive, 'getAllPermissions', IArchivePermission)
 patch_collection_return_type(
     IArchive, 'getPermissionsForPerson', IArchivePermission)
@@ -484,8 +481,6 @@
     IArchive, '_addArchiveDependency', 'pocket', PackagePublishingPocket)
 patch_entry_return_type(
     IArchive, '_addArchiveDependency', IArchiveDependency)
-patch_plain_parameter_type(
-    IArchive, 'enableRestrictedProcessor', 'processor', IProcessor)
 
 # IBuildFarmJob
 patch_choice_property(IBuildFarmJob, 'status', BuildStatus)

=== modified file 'lib/lp/soyuz/browser/tests/test_archive_webservice.py'
--- lib/lp/soyuz/browser/tests/test_archive_webservice.py	2014-08-07 06:46:31 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_webservice.py	2015-05-18 06:37:58 +0000
@@ -18,6 +18,7 @@
 
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
 from lp.registry.interfaces.pocket import PackagePublishingPocket
+from lp.services.webapp.interfaces import OAuthPermission
 from lp.soyuz.enums import (
     ArchivePermissionType,
     ArchivePurpose,
@@ -28,6 +29,7 @@
 from lp.soyuz.model.archivepermission import ArchivePermission
 from lp.testing import (
     admin_logged_in,
+    api_url,
     launchpadlib_for,
     person_logged_in,
     record_two_runs,
@@ -265,6 +267,48 @@
         self.assertEqual('New ARM Title', ws_proc.title)
         self.assertEqual('New ARM Description', ws_proc.description)
 
+    def test_setProcessors(self):
+        """A new processor can be added to the enabled restricted set."""
+        commercial = getUtility(ILaunchpadCelebrities).commercial_admin
+        commercial_admin = self.factory.makePerson(member_of=[commercial])
+        self.factory.makeProcessor(
+            'arm', 'ARM', 'ARM', restricted=True, build_by_default=False)
+        ppa_url = api_url(self.factory.makeArchive(purpose=ArchivePurpose.PPA))
+
+        body = webservice_for_person(commercial_admin).get(
+            ppa_url + '/processors', api_version='devel').jsonBody()
+        self.assertContentEqual(
+            ['386', 'hppa', 'amd64'],
+            [entry['name'] for entry in body['entries']])
+
+        response = webservice_for_person(
+                commercial_admin,
+                permission=OAuthPermission.WRITE_PUBLIC).named_post(
+            ppa_url, 'setProcessors',
+            processors=['/+processors/386', '/+processors/arm'],
+            api_version='devel')
+        self.assertEqual(200, response.status)
+
+        body = webservice_for_person(commercial_admin).get(
+            ppa_url + '/processors', api_version='devel').jsonBody()
+        self.assertContentEqual(
+            ['386', 'hppa', 'amd64', 'arm'],
+            [entry['name'] for entry in body['entries']])
+
+    def test_setProcessors_owner_forbidden(self):
+        """Only commercial admins can call setProcessors."""
+        self.factory.makeProcessor(
+            'arm', 'ARM', 'ARM', restricted=True, build_by_default=False)
+        archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
+        ppa_url = api_url(archive)
+        owner = archive.owner
+
+        response = webservice_for_person(owner).named_post(
+            ppa_url, 'setProcessors',
+            processors=['/+processors/386', '/+processors/arm'],
+            api_version='devel')
+        self.assertEqual(401, response.status)
+
     def test_enableRestrictedProcessor(self):
         """A new processor can be added to the enabled restricted set."""
         self.ws_version = 'devel'

=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml	2015-05-07 10:52:10 +0000
+++ lib/lp/soyuz/configure.zcml	2015-05-18 06:37:58 +0000
@@ -392,7 +392,7 @@
             interface="lp.soyuz.interfaces.archive.IArchiveAdmin"
             set_attributes="authorized_size build_debug_symbols
                             buildd_secret enabled_restricted_processors
-                            external_dependencies name
+                            processors external_dependencies name
                             permit_obsolete_series_uploads
                             private publish_debug_symbols
                             require_virtualized"/>

=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py	2015-04-24 14:25:12 +0000
+++ lib/lp/soyuz/interfaces/archive.py	2015-05-18 06:37:58 +0000
@@ -94,6 +94,7 @@
 from lp.app.errors import NameLookupFailed
 from lp.app.interfaces.launchpad import IPrivacy
 from lp.app.validators.name import name_validator
+from lp.buildmaster.interfaces.processor import IProcessor
 from lp.registry.interfaces.gpg import IGPGKey
 from lp.registry.interfaces.person import IPerson
 from lp.registry.interfaces.role import IHasOwner
@@ -622,14 +623,19 @@
             "context build.\n"
             "NOTE: This is for migration of OEM PPAs only!")))
 
+    processors = exported(
+        CollectionField(
+            title=_("Processors"),
+            description=_("The architectures on which the archive can build."),
+            value_type=Reference(schema=IProcessor),
+            readonly=True),
+        as_of='devel')
+
     enabled_restricted_processors = exported(
         CollectionField(
             title=_("Enabled restricted processors"),
-            description=_(
-                "The restricted architectures on which the archive "
-                "can build."),
-            value_type=Reference(schema=Interface),
-            # Really IProcessor.
+            description=_("DEPRECATED. Use processors instead."),
+            value_type=Reference(schema=IProcessor),
             readonly=True),
         as_of='devel')
 
@@ -2030,14 +2036,24 @@
     """Archive interface for operations restricted by commercial."""
 
     @operation_parameters(
-        processor=Reference(schema=Interface, required=True),
-        # Really IProcessor.
+        processors=List(
+            value_type=Reference(schema=IProcessor), required=True),
+    )
+    @export_write_operation()
+    @operation_for_version('devel')
+    def setProcessors(processors):
+        """Set the architectures on which the archive can build."""
+
+    @operation_parameters(
+        processor=Reference(schema=IProcessor, required=True),
     )
     @export_write_operation()
     @operation_for_version('devel')
     def enableRestrictedProcessor(processor):
         """Add the processor to the set of enabled restricted processors.
 
+        DEPRECATED. Use setProcessors instead.
+
         :param processor: is an `IProcessor` object.
         """
 
@@ -2087,7 +2103,8 @@
 
     def new(purpose, owner, name=None, displayname=None, distribution=None,
             description=None, enabled=True, require_virtualized=True,
-            private=False, suppress_subscription_notifications=False):
+            private=False, suppress_subscription_notifications=False,
+            processors=None):
         """Create a new archive.
 
         On named-ppa creation, the signing key for the default PPA for the
@@ -2112,6 +2129,8 @@
         :param private: whether or not to make the PPA private
         :param suppress_subscription_notifications: whether to suppress
             emails to subscribers about new subscriptions.
+        :param processors: list of `IProcessors` for which the archive should
+            build. If omitted, processors with `build_by_default` will be used.
 
         :return: an `IArchive` object.
         :raises AssertionError if name is already taken within distribution.

=== modified file 'lib/lp/soyuz/interfaces/archivearch.py'
--- lib/lp/soyuz/interfaces/archivearch.py	2015-04-20 09:48:57 +0000
+++ lib/lp/soyuz/interfaces/archivearch.py	2015-05-18 06:37:58 +0000
@@ -60,13 +60,3 @@
 
         :return: A (potentially empty) result set of `IArchiveArch` instances.
         """
-
-    def getRestrictedProcessors(archive):
-        """All restricted processor, paired with `ArchiveArch`
-        instances if associated with `archive`.
-
-        :return: A sequence containing a (`Processor`, `ArchiveArch`)
-            2-tuple for each processor.
-            The second value in the tuple will be None if the given `archive`
-            is not associated with the `Processor` yet.
-        """

=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2015-05-12 05:45:08 +0000
+++ lib/lp/soyuz/model/archive.py	2015-05-18 06:37:58 +0000
@@ -62,6 +62,7 @@
     BuildStatus,
     )
 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSet
+from lp.buildmaster.interfaces.processor import IProcessorSet
 from lp.registry.enums import (
     INCLUSIVE_TEAM_POLICY,
     PersonVisibility,
@@ -2059,28 +2060,48 @@
 
     def _getEnabledRestrictedProcessors(self):
         """Retrieve the restricted architectures this archive can build on."""
-        processors = getUtility(IArchiveArchSet).getRestrictedProcessors(self)
-        return [
-            processor for (processor, archive_arch) in processors
-            if archive_arch is not None]
+        return [proc for proc in self.processors if proc.restricted]
 
     def _setEnabledRestrictedProcessors(self, value):
         """Set the restricted architectures this archive can build on."""
-        archive_arch_set = getUtility(IArchiveArchSet)
-        restricted_processors = archive_arch_set.getRestrictedProcessors(self)
-        for (processor, archive_arch) in restricted_processors:
-            if processor in value and archive_arch is None:
-                archive_arch_set.new(self, processor)
-            if processor not in value and archive_arch is not None:
-                Store.of(self).remove(archive_arch)
+        self.processors = (
+            [proc for proc in self.processors if not proc.restricted]
+            + list(value))
 
     enabled_restricted_processors = property(
         _getEnabledRestrictedProcessors, _setEnabledRestrictedProcessors)
 
     def enableRestrictedProcessor(self, processor):
         """See `IArchive`."""
-        self.enabled_restricted_processors = set(
-            self.enabled_restricted_processors + [processor])
+        self.processors = set(self.processors + [processor])
+
+    def _getProcessors(self):
+        # To match existing behaviour we always include non-restricted
+        # processors during the transition.
+        enabled = [
+            aa.processor for aa in
+            getUtility(IArchiveArchSet).getByArchive(self)]
+        return [
+            proc for proc in getUtility(IProcessorSet).getAll()
+            if not proc.restricted or proc in enabled]
+
+    def setProcessors(self, processors):
+        """See `IArchive`."""
+        enablements = {
+            aa.processor: aa for aa in
+            getUtility(IArchiveArchSet).getByArchive(self)}
+        # Remove any enabled restricted processors that aren't in the
+        # new set. _getProcessors currently always includes
+        # non-restricted processors, but this'll change later.
+        for proc in enablements:
+            if proc.restricted and proc not in processors:
+                Store.of(self).remove(enablements[proc])
+        # Add any new processors regardless of restrictedness.
+        for proc in processors:
+            if proc not in self.processors:
+                getUtility(IArchiveArchSet).new(self, proc)
+
+    processors = property(_getProcessors, setProcessors)
 
     def getPockets(self):
         """See `IArchive`."""
@@ -2352,7 +2373,7 @@
     def new(self, purpose, owner, name=None, displayname=None,
             distribution=None, description=None, enabled=True,
             require_virtualized=True, private=False,
-            suppress_subscription_notifications=False):
+            suppress_subscription_notifications=False, processors=None):
         """See `IArchiveSet`."""
         if distribution is None:
             distribution = getUtility(ILaunchpadCelebrities).ubuntu
@@ -2431,6 +2452,13 @@
         new_archive.suppress_subscription_notifications = (
             suppress_subscription_notifications)
 
+        if processors is None:
+            processors = [
+                p for p in getUtility(IProcessorSet).getAll()
+                if p.build_by_default]
+        for processor in processors:
+            getUtility(IArchiveArchSet).new(new_archive, processor)
+
         return new_archive
 
     def __iter__(self):

=== modified file 'lib/lp/soyuz/model/archivearch.py'
--- lib/lp/soyuz/model/archivearch.py	2015-04-20 09:48:57 +0000
+++ lib/lp/soyuz/model/archivearch.py	2015-05-18 06:37:58 +0000
@@ -7,10 +7,6 @@
     'ArchiveArchSet'
     ]
 
-from storm.expr import (
-    And,
-    LeftJoin,
-    )
 from storm.locals import (
     Int,
     Reference,
@@ -58,15 +54,3 @@
 
         return IStore(ArchiveArch).find(ArchiveArch, *clauses).order_by(
             ArchiveArch.id)
-
-    def getRestrictedProcessors(self, archive):
-        """See `IArchiveArchSet`."""
-        origin = (
-            Processor,
-            LeftJoin(
-                ArchiveArch,
-                And(ArchiveArch.archive == archive.id,
-                    ArchiveArch.processor == Processor.id)))
-        return IStore(ArchiveArch).using(*origin).find(
-            (Processor, ArchiveArch),
-            Processor.restricted == True).order_by(Processor.name)

=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
--- lib/lp/soyuz/model/binarypackagebuild.py	2015-05-14 12:45:06 +0000
+++ lib/lp/soyuz/model/binarypackagebuild.py	2015-05-18 06:37:58 +0000
@@ -1392,9 +1392,7 @@
             das for das in available_archs
             if (
                 das.enabled
-                and (
-                    not das.processor.restricted
-                    or das.processor in archive.enabled_restricted_processors)
+                and das.processor in archive.processors
                 and (
                     das.processor.supports_virtualized
                     or not archive.require_virtualized))]

=== modified file 'lib/lp/soyuz/scripts/populate_archive.py'
--- lib/lp/soyuz/scripts/populate_archive.py	2015-04-20 09:48:57 +0000
+++ lib/lp/soyuz/scripts/populate_archive.py	2015-05-18 06:37:58 +0000
@@ -22,7 +22,6 @@
 from lp.soyuz.adapters.packagelocation import build_package_location
 from lp.soyuz.enums import ArchivePurpose
 from lp.soyuz.interfaces.archive import IArchiveSet
-from lp.soyuz.interfaces.archivearch import IArchiveArchSet
 from lp.soyuz.interfaces.component import IComponentSet
 from lp.soyuz.interfaces.packagecloner import IPackageCloner
 from lp.soyuz.interfaces.packagecopyrequest import IPackageCopyRequestSet
@@ -104,12 +103,6 @@
                         "Invalid architecture tag: '%s'" % name)
             return processors
 
-        def set_archive_architectures(archive, processors):
-            """Associate the archive with the processors."""
-            aa_set = getUtility(IArchiveArchSet)
-            for processor in processors:
-                aa_set.new(archive, processor)
-
         def build_location(distro, suite, component, packageset_names=None):
             """Build and return package location."""
             location = build_package_location(
@@ -213,11 +206,8 @@
                 ArchivePurpose.COPY, registrant, name=to_archive,
                 distribution=the_destination.distribution,
                 description=reason, enabled=False,
-                require_virtualized=virtual)
+                require_virtualized=virtual, processors=processors)
             the_destination.archive = copy_archive
-            # Associate the newly created copy archive with the processors
-            # specified by the user.
-            set_archive_architectures(copy_archive, processors)
         else:
             # Archive name clash! Creation requested for existing archive with
             # the same name and distribution.

=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py	2015-04-20 09:48:57 +0000
+++ lib/lp/soyuz/tests/test_archive.py	2015-05-18 06:37:58 +0000
@@ -1002,7 +1002,7 @@
         self.assertEqual(3, self.archive.getPackageDownloadTotal(self.bpr_2))
 
 
-class TestEnabledRestrictedBuilds(TestCaseWithFactory):
+class TestProcessors(TestCaseWithFactory):
     """Ensure that restricted architectures builds can be allowed and
     disallowed correctly."""
 
@@ -1010,39 +1010,123 @@
 
     def setUp(self):
         """Setup an archive with relevant publications."""
-        super(TestEnabledRestrictedBuilds, self).setUp()
+        super(TestProcessors, self).setUp()
         self.publisher = SoyuzTestPublisher()
         self.publisher.prepareBreezyAutotest()
         self.archive = self.factory.makeArchive()
         self.archive_arch_set = getUtility(IArchiveArchSet)
+        self.default_procs = [
+            getUtility(IProcessorSet).getByName("386"),
+            getUtility(IProcessorSet).getByName("amd64")]
+        self.unrestricted_procs = (
+            self.default_procs + [getUtility(IProcessorSet).getByName("hppa")])
         self.arm = self.factory.makeProcessor(name='arm', restricted=True)
 
+    def test_new_default_processors(self):
+        # ArchiveSet.new creates an ArchiveArch for each Processor with
+        # build_by_default set.
+        archive = getUtility(IArchiveSet).new(
+            owner=self.factory.makePerson(), purpose=ArchivePurpose.PPA,
+            distribution=self.factory.makeDistribution(), name='ppa')
+        self.assertContentEqual(
+            ['386', 'amd64'],
+            [aa.processor.name for aa in
+             self.archive_arch_set.getByArchive(archive)])
+
+    def test_new_override_processors(self):
+        # ArchiveSet.new can be given a custom set of processors.
+        archive = getUtility(IArchiveSet).new(
+            owner=self.factory.makePerson(), purpose=ArchivePurpose.PPA,
+            distribution=self.factory.makeDistribution(), name='ppa',
+            processors=[self.arm])
+        self.assertContentEqual(
+            ['arm'],
+            [aa.processor.name for aa in
+             self.archive_arch_set.getByArchive(archive)])
+
     def test_default(self):
         """By default, ARM builds are not allowed as ARM is restricted."""
         self.assertEqual(0,
             self.archive_arch_set.getByArchive(
                 self.archive, self.arm).count())
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
         self.assertContentEqual([], self.archive.enabled_restricted_processors)
 
     def test_get_uses_archivearch(self):
         """Adding an entry to ArchiveArch for ARM and an archive will
         enable enabled_restricted_processors for arm for that archive."""
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
         self.assertContentEqual([], self.archive.enabled_restricted_processors)
         self.archive_arch_set.new(self.archive, self.arm)
-        self.assertEqual(
-            [self.arm], list(self.archive.enabled_restricted_processors))
+        self.assertContentEqual(
+            [self.arm] + self.unrestricted_procs, self.archive.processors)
+        self.assertContentEqual(
+            [self.arm], self.archive.enabled_restricted_processors)
 
     def test_get_returns_restricted_only(self):
         """Adding an entry to ArchiveArch for something that is not
         restricted does not make it show up in enabled_restricted_processors.
         """
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
         self.assertContentEqual([], self.archive.enabled_restricted_processors)
-        self.archive_arch_set.new(
-            self.archive, getUtility(IProcessorSet).getByName('amd64'))
+        new_proc = self.factory.makeProcessor(
+            restricted=False, build_by_default=True)
+        self.archive_arch_set.new(self.archive, new_proc)
+        self.assertContentEqual(
+            self.unrestricted_procs + [new_proc], self.archive.processors)
         self.assertContentEqual([], self.archive.enabled_restricted_processors)
 
     def test_set(self):
-        """The property remembers its value correctly and sets ArchiveArch."""
+        """The property remembers its value correctly and sets ArchiveArch.
+
+        It's not yet possible to remove the default processors from the set.
+        """
+        self.archive.processors = [self.arm]
+        allowed_restricted_processors = self.archive_arch_set.getByArchive(
+            self.archive, self.arm)
+        self.assertEqual(1, allowed_restricted_processors.count())
+        self.assertEqual(
+            self.arm, allowed_restricted_processors[0].processor)
+        self.assertContentEqual(
+            [self.arm] + self.unrestricted_procs, self.archive.processors)
+        self.archive.processors = []
+        self.assertEqual(
+            0,
+            self.archive_arch_set.getByArchive(self.archive, self.arm).count())
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
+
+    def test_set_doesnt_remove_default(self):
+        """During the data migration the property must not remove defaults.
+
+        _getProcessors doesn't yet rely on ArchiveArches for
+        non-restricted processors, since the rows don't exist on
+        production yet, but if they do exist then they won't be removed
+        on set. We'll backfill them while this version of the code is
+        running.
+        """
+        i386 = getUtility(IProcessorSet).getByName("386")
+        self.archive.processors = [i386, self.arm]
+        self.assertContentEqual(
+            self.default_procs + [self.arm],
+            [aa.processor for aa in
+             self.archive_arch_set.getByArchive(self.archive)])
+        self.archive.processors = []
+        self.assertContentEqual(
+            self.default_procs,
+            [aa.processor for aa in
+             self.archive_arch_set.getByArchive(self.archive)])
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
+
+    def test_set_enabled_restricted_processors(self):
+        """The deprecated enabled_restricted_processors property still works.
+
+        It's like processors, but only including those that are restricted.
+        """
         self.archive.enabled_restricted_processors = [self.arm]
         allowed_restricted_processors = self.archive_arch_set.getByArchive(
             self.archive, self.arm)
@@ -1055,6 +1139,8 @@
         self.assertEqual(
             0,
             self.archive_arch_set.getByArchive(self.archive, self.arm).count())
+        self.assertContentEqual(
+            self.unrestricted_procs, self.archive.processors)
         self.assertContentEqual([], self.archive.enabled_restricted_processors)
 
 

=== modified file 'lib/lp/soyuz/tests/test_archivearch.py'
--- lib/lp/soyuz/tests/test_archivearch.py	2013-09-27 06:29:02 +0000
+++ lib/lp/soyuz/tests/test_archivearch.py	2015-05-18 06:37:58 +0000
@@ -31,33 +31,6 @@
             'omap', 'Multimedia applications processor',
             'Does all your sound & video', True)
 
-    def test_getRestrictedProcessors_no_restricted_associations(self):
-        # Our archive is not associated with any restricted processors yet.
-        result_set = list(
-            self.archive_arch_set.getRestrictedProcessors(self.ppa))
-        archivearches = [row[1] for row in result_set]
-        self.assertTrue(all(aa is None for aa in archivearches))
-
-    def test_getRestrictedProcessors_single_restricted_association(self):
-        # Our archive is now associated with one of the restricted processors.
-        self.archive_arch_set.new(self.ppa, self.cell_proc)
-        result_set = list(
-            self.archive_arch_set.getRestrictedProcessors(self.ppa))
-        results = dict(
-            (row[0].name, row[1] is not None) for row in result_set)
-        self.assertEqual({'cell-proc': True, 'omap': False}, results)
-
-    def test_getRestrictedProcessors_archive_only(self):
-        # Test that only the associated archs for the archive itself are
-        # returned.
-        self.archive_arch_set.new(self.ppa, self.cell_proc)
-        self.archive_arch_set.new(self.ubuntu_archive, self.omap)
-        result_set = list(
-            self.archive_arch_set.getRestrictedProcessors(self.ppa))
-        results = dict(
-            (row[0].name, row[1] is not None) for row in result_set)
-        self.assertEqual({'cell-proc': True, 'omap': False}, results)
-
     def test_getByArchive_no_other_archives(self):
         # Test ArchiveArchSet.getByArchive returns no other archives.
         self.archive_arch_set.new(self.ppa, self.cell_proc)

=== modified file 'lib/lp/soyuz/tests/test_packagecloner.py'
--- lib/lp/soyuz/tests/test_packagecloner.py	2015-04-20 15:59:52 +0000
+++ lib/lp/soyuz/tests/test_packagecloner.py	2015-05-18 06:37:58 +0000
@@ -14,7 +14,6 @@
     ArchivePurpose,
     PackagePublishingStatus,
     )
-from lp.soyuz.interfaces.archivearch import IArchiveArchSet
 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
 from lp.soyuz.interfaces.component import IComponentSet
 from lp.soyuz.interfaces.packagecloner import IPackageCloner
@@ -82,11 +81,11 @@
         distroseries.nominatedarchindep = das
         return distroseries
 
-    def getTargetArchive(self, distribution):
+    def getTargetArchive(self, distribution, processors=None):
         """Get a target archive for copying in to."""
         return self.factory.makeArchive(
             name="test-copy-archive", purpose=ArchivePurpose.COPY,
-            distribution=distribution)
+            distribution=distribution, processors=processors)
 
     def createSourcePublication(self, info, distroseries):
         """Create a SourcePackagePublishingHistory based on a PackageInfo."""
@@ -116,7 +115,8 @@
                         processors=None):
         """Make a copy archive based on a new distribution."""
         distroseries = self.createSourceDistribution(package_infos)
-        copy_archive = self.getTargetArchive(distroseries.distribution)
+        copy_archive = self.getTargetArchive(
+            distroseries.distribution, processors=processors)
         to_component = getUtility(IComponentSet).ensure(component)
         self.copyArchive(
             copy_archive, distroseries, from_pocket=source_pocket,
@@ -588,12 +588,6 @@
         self.checkCopiedSources(
             copy_archive, distroseries, [package_infos[1]] + package_infos2)
 
-    def setArchiveArchitectures(self, archive, processors):
-        """Associate the archive with the processors."""
-        aa_set = getUtility(IArchiveArchSet)
-        for processor in processors:
-            aa_set.new(archive, processor)
-
     def testMergeCopyCreatesBuilds(self):
         package_infos = [
             PackageInfo(
@@ -604,7 +598,6 @@
         processors = [getUtility(IProcessorSet).getByName('386')]
         copy_archive, distroseries = self.makeCopyArchive(
             package_infos, processors=processors)
-        self.setArchiveArchitectures(copy_archive, processors)
         package_infos2 = [
             PackageInfo(
             "bzr", "2.2", status=PackagePublishingStatus.PUBLISHED),
@@ -651,7 +644,6 @@
         # per source.
         processors = [getUtility(IProcessorSet).getByName('386'), amd64]
         copy_archive = self.getTargetArchive(distroseries.distribution)
-        self.setArchiveArchitectures(copy_archive, processors)
         self.copyArchive(
             copy_archive, distroseries, processors=processors)
         package_infos2 = [

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2015-05-13 08:27:03 +0000
+++ lib/lp/testing/factory.py	2015-05-18 06:37:58 +0000
@@ -2756,7 +2756,8 @@
     def makeArchive(self, distribution=None, owner=None, name=None,
                     purpose=None, enabled=True, private=False,
                     virtualized=True, description=None, displayname=None,
-                    suppress_subscription_notifications=False):
+                    suppress_subscription_notifications=False,
+                    processors=None):
         """Create and return a new arbitrary archive.
 
         :param distribution: Supply IDistribution, defaults to a new one
@@ -2803,7 +2804,7 @@
                 owner=owner, purpose=purpose,
                 distribution=distribution, name=name, displayname=displayname,
                 enabled=enabled, require_virtualized=virtualized,
-                description=description)
+                description=description, processors=processors)
 
         if private:
             naked_archive = removeSecurityProxy(archive)


Follow ups