← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~julian-edwards/launchpad/override-class into lp:launchpad/db-devel

 

Julian Edwards has proposed merging lp:~julian-edwards/launchpad/override-class into lp:launchpad/db-devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~julian-edwards/launchpad/override-class/+merge/63221

This branch replaces the awkward tuple used to represent overrides with a nice class instead.  It also adds a addSourceOverride() to PlainPackageCopyJob which takes one of these overrides and adds it to the metadata on the job.
-- 
https://code.launchpad.net/~julian-edwards/launchpad/override-class/+merge/63221
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/launchpad/override-class into lp:launchpad/db-devel.
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg	2011-05-30 16:23:53 +0000
+++ database/schema/security.cfg	2011-06-02 11:24:48 +0000
@@ -218,7 +218,7 @@
 public.openidrpconfig                   = SELECT, INSERT, UPDATE, DELETE
 public.packagebugsupervisor             = SELECT, INSERT, UPDATE, DELETE
 public.packagebuild                     = DELETE
-public.packagecopyjob                   = SELECT, INSERT
+public.packagecopyjob                   = SELECT, INSERT, UPDATE
 public.packagecopyrequest               = SELECT, INSERT, UPDATE
 public.packagediff                      = SELECT, INSERT, UPDATE, DELETE
 public.packageset                       = SELECT, INSERT, UPDATE, DELETE
@@ -1015,7 +1015,7 @@
 public.message                                = SELECT, INSERT, UPDATE
 public.messagechunk                           = SELECT, INSERT, UPDATE
 public.packagebuild                           = SELECT, INSERT
-public.packagecopyjob                         = SELECT
+public.packagecopyjob                         = SELECT, UPDATE
 public.packageset                             = SELECT, INSERT
 public.packagesetgroup                        = SELECT, INSERT
 public.packagesetinclusion                    = SELECT, INSERT

=== modified file 'lib/lp/soyuz/adapters/overrides.py'
--- lib/lp/soyuz/adapters/overrides.py	2011-05-23 07:22:57 +0000
+++ lib/lp/soyuz/adapters/overrides.py	2011-06-02 11:24:48 +0000
@@ -7,7 +7,11 @@
 __metaclass__ = type
 
 __all__ = [
+    'BinaryOverride',
     'FromExistingOverridePolicy',
+    'IBinaryOverride',
+    'ISourceOverride',
+    'SourceOverride',
     'UbuntuOverridePolicy',
     'UnknownOverridePolicy',
     ]
@@ -17,10 +21,10 @@
     And,
     Desc,
     Or,
-    SQL,
     )
 from zope.component import getUtility
 from zope.interface import (
+    Attribute,
     implements,
     Interface,
     )
@@ -45,6 +49,82 @@
 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
 
 
+class IOverride(Interface):
+    """Override data class.
+
+    This class represents all the basic overridable data on a publication.
+    """
+
+    component = Attribute("The IComponent override")
+    section = Attribute("The ISection override")
+
+
+class ISourceOverride(IOverride):
+    """Source-specific overrides on a publication."""
+
+    source_package_name = Attribute("The ISourcePackageName that's being overridden")
+
+
+class IBinaryOverride(IOverride):
+    """Binary-specific overrides on a publication."""
+
+    binary_package_name = Attribute("The IBinaryPackageName that's being overridden")
+    distro_arch_series = Attribute("The IDistroArchSeries for the publication")
+    priority = Attribute("The PackagePublishingPriority that's being overridden")
+
+
+class Override:
+    """See `IOverride`."""
+
+    def __init__(self, component, section):
+        self.component = component
+        self.section = section
+
+    def __ne__(self, other):
+        return not self == other
+
+
+class SourceOverride(Override):
+    """See `ISourceOverride`."""
+    implements(ISourceOverride)
+
+    def __init__(self, source_package_name, component, section):
+        super(SourceOverride, self).__init__(component, section)
+        self.source_package_name = source_package_name
+
+    def __eq__(self, other):
+        if (
+            self.source_package_name == other.source_package_name and
+            self.component == other.component and
+            self.section == other.section):
+            return True
+
+        return False
+
+
+class BinaryOverride(Override):
+    """See `IBinaryOverride`."""
+    implements(IBinaryOverride)
+
+    def __init__(self, binary_package_name, distro_arch_series, component,
+                 section, priority):
+        super(BinaryOverride, self).__init__(component, section)
+        self.binary_package_name = binary_package_name
+        self.distro_arch_series = distro_arch_series
+        self.priority = priority
+
+    def __eq__(self, other):
+        if (
+            self.binary_package_name == other.binary_package_name and
+            self.distro_arch_series == other.distro_arch_series and
+            self.component == other.component and
+            self.section == other.section and
+            self.priority == other.priority):
+            return True
+
+        return False
+
+
 class IOverridePolicy(Interface):
     """Override policy.
 
@@ -63,8 +143,7 @@
         :param pocket: The target `PackagePublishingPocket`.
         :param sources: A tuple of `ISourcePackageName`s.
 
-        :return: A list of tuples containing `ISourcePackageName`,
-            `IComponent` and `ISection`.
+        :return: A list of `ISourceOverride`
         """
         pass
 
@@ -78,9 +157,7 @@
             pairs. Architecturetag can be None for architecture-independent
             publications.
 
-        :return: A list of tuples containing `IBinaryPackageName`,
-            `IDistroArchSeries`, `IComponent`, `ISection` and
-            `PackagePublishingPriority`.
+        :return: A list of `IBinaryOverride`
         """
         pass
 
@@ -133,7 +210,9 @@
                     distinct=(SourcePackageRelease.sourcepackagenameID,)),
             id_resolver((SourcePackageName, Component, Section)),
             pre_iter_hook=eager_load)
-        return list(already_published)
+        return [
+            SourceOverride(name, component, section)
+            for (name, component, section) in already_published]
 
     def calculateBinaryOverrides(self, archive, distroseries, pocket,
                                  binaries):
@@ -170,7 +249,9 @@
                 (BinaryPackageName, DistroArchSeries, Component, Section,
                 None)),
             pre_iter_hook=eager_load)
-        return list(already_published)
+        return [
+            BinaryOverride(name, das, component, section, priority)
+            for name, das, component, section, priority in already_published]
 
 
 class UnknownOverridePolicy(BaseOverridePolicy):
@@ -184,14 +265,16 @@
                                  sources):
         default_component = archive.default_component or getUtility(
             IComponentSet)['universe']
-        return [(source, default_component, None) for source in sources]
+        return [
+            SourceOverride(source, default_component, None)
+            for source in sources]
 
     def calculateBinaryOverrides(self, archive, distroseries, pocket,
                                  binaries):
         default_component = archive.default_component or getUtility(
             IComponentSet)['universe']
         return [
-            (binary, das, default_component, None, None)
+            BinaryOverride(binary, das, default_component, None, None)
             for binary, das in calculate_target_das(distroseries, binaries)]
 
 
@@ -208,7 +291,7 @@
         total = set(sources)
         overrides = FromExistingOverridePolicy.calculateSourceOverrides(
             self, archive, distroseries, pocket, sources)
-        existing = set(override[0] for override in overrides)
+        existing = set(override.source_package_name for override in overrides)
         missing = total.difference(existing)
         if missing:
             unknown = UnknownOverridePolicy.calculateSourceOverrides(
@@ -222,7 +305,7 @@
         overrides = FromExistingOverridePolicy.calculateBinaryOverrides(
             self, archive, distroseries, pocket, binaries)
         existing = set((
-            overide[0], overide[1].architecturetag)
+            overide.binary_package_name, overide.distro_arch_series.architecturetag)
                 for overide in overrides)
         missing = total.difference(existing)
         if missing:

=== modified file 'lib/lp/soyuz/adapters/tests/test_overrides.py'
--- lib/lp/soyuz/adapters/tests/test_overrides.py	2011-05-17 03:14:48 +0000
+++ lib/lp/soyuz/adapters/tests/test_overrides.py	2011-06-02 11:24:48 +0000
@@ -3,6 +3,7 @@
 
 """Test generic override policy classes."""
 
+from operator import attrgetter
 from testtools.matchers import Equals
 from zope.component import getUtility
 
@@ -10,7 +11,9 @@
 from canonical.testing.layers import LaunchpadZopelessLayer
 from lp.services.database import bulk
 from lp.soyuz.adapters.overrides import (
+    BinaryOverride,
     FromExistingOverridePolicy,
+    SourceOverride,
     UbuntuOverridePolicy,
     UnknownOverridePolicy,
     )
@@ -46,7 +49,7 @@
         overrides = policy.calculateSourceOverrides(
             spph.distroseries.main_archive, spph.distroseries, spph.pocket,
             (spph.sourcepackagerelease.sourcepackagename,))
-        expected = [(
+        expected = [SourceOverride(
             spph.sourcepackagerelease.sourcepackagename,
             spph.component, spph.section)]
         self.assertEqual(expected, overrides)
@@ -69,7 +72,8 @@
         policy = FromExistingOverridePolicy()
         overrides = policy.calculateSourceOverrides(
             distroseries.main_archive, distroseries, spph.pocket, (spn,))
-        self.assertEqual([(spn, spph.component, spph.section)], overrides)
+        self.assertEqual(
+            [SourceOverride(spn, spph.component, spph.section)], overrides)
 
     def test_source_overrides_constant_query_count(self):
         # The query count is constant, no matter how many sources are
@@ -115,10 +119,11 @@
         overrides = policy.calculateBinaryOverrides(
             distroseries.main_archive, distroseries, bpph.pocket,
             ((bpph.binarypackagerelease.binarypackagename, None),))
-        expected = [(
-            bpph.binarypackagerelease.binarypackagename,
-            bpph.distroarchseries, bpph.component, bpph.section,
-            bpph.priority)]
+        expected = [
+            BinaryOverride(
+                bpph.binarypackagerelease.binarypackagename,
+                bpph.distroarchseries, bpph.component, bpph.section,
+                bpph.priority)]
         self.assertEqual(expected, overrides)
 
     def test_binary_overrides_constant_query_count(self):
@@ -152,8 +157,10 @@
             spph.distroseries.main_archive, spph.distroseries, spph.pocket,
             (spph.sourcepackagerelease.sourcepackagename,))
         universe = getUtility(IComponentSet)['universe']
-        expected = [(spph.sourcepackagerelease.sourcepackagename, universe,
-            None)]
+        expected = [
+            SourceOverride(
+                spph.sourcepackagerelease.sourcepackagename, universe,
+                None)]
         self.assertEqual(expected, overrides)
 
     def test_unknown_binaries(self):
@@ -167,8 +174,10 @@
             distroseries.main_archive, distroseries, bpph.pocket,
             ((bpph.binarypackagerelease.binarypackagename, None),))
         universe = getUtility(IComponentSet)['universe']
-        expected = [(bpph.binarypackagerelease.binarypackagename,
-            bpph.distroarchseries, universe, None, None)]
+        expected = [
+            BinaryOverride(
+                bpph.binarypackagerelease.binarypackagename,
+                bpph.distroarchseries, universe, None, None)]
         self.assertEqual(expected, overrides)
 
     def test_ubuntu_override_policy_sources(self):
@@ -176,7 +185,7 @@
         # policy.
         universe = getUtility(IComponentSet)['universe']
         spns = [self.factory.makeSourcePackageName()]
-        expected = [(spns[0], universe, None)]
+        expected = [SourceOverride(spns[0], universe, None)]
         distroseries = self.factory.makeDistroSeries()
         pocket = self.factory.getAnyPocket()
         for i in xrange(8):
@@ -184,16 +193,21 @@
                 distroseries=distroseries, archive=distroseries.main_archive,
                 pocket=pocket)
             spns.append(spph.sourcepackagerelease.sourcepackagename)
-            expected.append((
-                spph.sourcepackagerelease.sourcepackagename, spph.component,
-                spph.section))
+            expected.append(
+                SourceOverride(
+                    spph.sourcepackagerelease.sourcepackagename,
+                    spph.component, spph.section))
         spns.append(self.factory.makeSourcePackageName())
-        expected.append((spns[-1], universe, None))
+        expected.append(SourceOverride(spns[-1], universe, None))
         policy = UbuntuOverridePolicy()
         overrides = policy.calculateSourceOverrides(
             distroseries.main_archive, distroseries, pocket, spns)
         self.assertEqual(10, len(overrides))
-        self.assertContentEqual(expected, overrides)
+        sorted_expected = sorted(
+            expected, key=attrgetter("source_package_name.name"))
+        sorted_overrides = sorted(
+            overrides, key=attrgetter("source_package_name.name"))
+        self.assertEqual(sorted_expected, sorted_overrides)
 
     def test_ubuntu_override_policy_binaries(self):
         # The Ubuntu policy incorporates both the existing and the unknown
@@ -213,17 +227,23 @@
                 binarypackagerelease=bpr, distroarchseries=distroarchseries,
                 archive=distroseries.main_archive, pocket=pocket)
             bpns.append((bpn, distroarchseries.architecturetag))
-            expected.append((
-                bpn, distroarchseries, bpph.component, bpph.section,
-                bpph.priority))
+            expected.append(
+                BinaryOverride(
+                    bpn, distroarchseries, bpph.component, bpph.section,
+                    bpph.priority))
         for i in xrange(2):
             distroarchseries = self.factory.makeDistroArchSeries(
                 distroseries=distroseries)
             bpns.append((bpn, distroarchseries.architecturetag))
-            expected.append((bpn, distroarchseries, universe, None, None))
+            expected.append(
+                BinaryOverride(bpn, distroarchseries, universe, None, None))
         distroseries.nominatedarchindep = distroarchseries
         policy = UbuntuOverridePolicy()
         overrides = policy.calculateBinaryOverrides(
             distroseries.main_archive, distroseries, pocket, bpns)
         self.assertEqual(5, len(overrides))
-        self.assertContentEqual(expected, overrides)
+        sorted_expected = sorted(
+            expected, key=attrgetter("binary_package_name.name"))
+        sorted_overrides = sorted(
+            overrides, key=attrgetter("binary_package_name.name"))
+        self.assertEqual(expected, overrides)

=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml	2011-05-29 21:18:09 +0000
+++ lib/lp/soyuz/configure.zcml	2011-06-02 11:24:48 +0000
@@ -946,6 +946,14 @@
       <allow interface="lp.soyuz.interfaces.packagerelationship.IPackageRelationshipSet"/>
     </class>
 
+   <!-- Overrides -->
+   <class class="lp.soyuz.adapters.overrides.SourceOverride">
+        <allow interface="lp.soyuz.adapters.overrides.ISourceOverride" />
+   </class>
+   <class class="lp.soyuz.adapters.overrides.BinaryOverride">
+        <allow interface="lp.soyuz.adapters.overrides.IBinaryOverride" />
+   </class>
+
    <!-- OverridePolicy -->
    <class class="lp.soyuz.adapters.overrides.UbuntuOverridePolicy">
         <allow interface="lp.soyuz.adapters.overrides.IOverridePolicy" />

=== modified file 'lib/lp/soyuz/interfaces/packagecopyjob.py'
--- lib/lp/soyuz/interfaces/packagecopyjob.py	2011-05-19 09:53:13 +0000
+++ lib/lp/soyuz/interfaces/packagecopyjob.py	2011-06-02 11:24:48 +0000
@@ -134,3 +134,6 @@
     include_binaries = Bool(
         title=_("Copy binaries"),
         required=False, readonly=True)
+
+    def addSourceOverride(override):
+        """Add an `ISourceOverride` to the metadata."""

=== modified file 'lib/lp/soyuz/model/packagecopyjob.py'
--- lib/lp/soyuz/model/packagecopyjob.py	2011-05-31 13:31:05 +0000
+++ lib/lp/soyuz/model/packagecopyjob.py	2011-06-02 11:24:48 +0000
@@ -251,6 +251,13 @@
     def include_binaries(self):
         return self.metadata['include_binaries']
 
+    def addSourceOverride(self, override):
+        """Add an `ISourceOverride` to the metadata."""
+        metadata_dict = dict(
+            component_override=override.component.name,
+            section_override=override.section.name)
+        self.context.extendMetadata(metadata_dict)
+
     def run(self):
         """See `IRunnableJob`."""
         try:

=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py	2011-05-30 22:16:13 +0000
+++ lib/lp/soyuz/model/publishing.py	2011-06-02 11:24:48 +0000
@@ -800,16 +800,15 @@
             section=new_section,
             archive=current.archive)
 
-    def copyTo(self, distroseries, pocket, archive, overrides=None):
+    def copyTo(self, distroseries, pocket, archive, override=None):
         """See `ISourcePackagePublishingHistory`."""
         component = self.component
         section = self.section
-        if overrides is not None:
-            [spn, new_component, new_section] = overrides[0]
-            if new_component is not None:
-                component = new_component
-            if new_section is not None:
-                section = new_section
+        if override is not None:
+            if override.component is not None:
+                component = override.component
+            if override.section is not None:
+                section = override.section
         return getUtility(IPublishingSet).newSourcePublication(
             archive,
             self.sourcepackagerelease,
@@ -1346,11 +1345,13 @@
             with_overrides = {}
             overrides = policy.calculateBinaryOverrides(
                 archive, distroseries, pocket, bpn_archtag.keys())
-            for bpn, das, component, section, priority in overrides:
-                bpph = bpn_archtag[(bpn, das.architecturetag)]
-                new_component = component or bpph.component
-                new_section = section or bpph.section
-                new_priority = priority or bpph.priority
+            for override in overrides:
+                bpph = bpn_archtag[
+                    (override.binary_package_name,
+                     override.distro_arch_series.architecturetag)]
+                new_component = override.component or bpph.component
+                new_section = override.section or bpph.section
+                new_priority = override.priority or bpph.priority
                 calculated = (new_component, new_section, new_priority)
                 with_overrides[bpph.binarypackagerelease] = calculated
         else:

=== modified file 'lib/lp/soyuz/scripts/packagecopier.py'
--- lib/lp/soyuz/scripts/packagecopier.py	2011-05-30 22:31:02 +0000
+++ lib/lp/soyuz/scripts/packagecopier.py	2011-06-02 11:24:48 +0000
@@ -613,12 +613,14 @@
         distroseries=series, pocket=pocket)
     policy = archive.getOverridePolicy()
     if source_in_destination.is_empty():
-        overrides = None
+        override = None
         if policy is not None:
             package_names = (source.sourcepackagerelease.sourcepackagename,)
-            overrides = policy.calculateSourceOverrides(
-                archive, series, pocket, package_names)
-        source_copy = source.copyTo(series, pocket, archive, overrides)
+            # Only one override can be returned so take the first
+            # element of the returned list.
+            override = policy.calculateSourceOverrides(
+                archive, series, pocket, package_names)[0]
+        source_copy = source.copyTo(series, pocket, archive, override)
         close_bugs_for_sourcepublication(source_copy)
         copies.append(source_copy)
     else:

=== modified file 'lib/lp/soyuz/tests/test_packagecopyjob.py'
--- lib/lp/soyuz/tests/test_packagecopyjob.py	2011-05-30 07:56:15 +0000
+++ lib/lp/soyuz/tests/test_packagecopyjob.py	2011-06-02 11:24:48 +0000
@@ -4,6 +4,10 @@
 """Tests for sync package jobs."""
 
 from testtools.content import text_content
+from testtools.matchers import (
+    Equals,
+    MatchesStructure,
+    )
 import transaction
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
@@ -17,6 +21,7 @@
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.services.features.testing import FeatureFixture
 from lp.services.job.interfaces.job import JobStatus
+from lp.soyuz.adapters.overrides import SourceOverride
 from lp.soyuz.enums import (
     ArchivePurpose,
     SourcePackageFormat,
@@ -25,11 +30,13 @@
     FEATURE_FLAG_ENABLE_MODULE,
     )
 from lp.soyuz.interfaces.archive import CannotCopy
+from lp.soyuz.interfaces.component import IComponentSet
 from lp.soyuz.interfaces.packagecopyjob import (
     IPackageCopyJob,
     IPlainPackageCopyJobSource,
     )
 from lp.soyuz.interfaces.publishing import PackagePublishingStatus
+from lp.soyuz.interfaces.section import ISectionSet
 from lp.soyuz.interfaces.sourcepackageformat import (
     ISourcePackageFormatSelectionSet,
     )
@@ -428,6 +435,31 @@
         naked_job = removeSecurityProxy(self.makeJob(dsd))
         self.assertContentEqual([dsd], naked_job.findMatchingDSDs())
 
+    def test_addSourceOverride(self):
+        # Test the addOverride method which adds an ISourceOverride to the
+        # metadata.
+        name = self.factory.makeSourcePackageName()
+        component = self.factory.makeComponent()
+        section=self.factory.makeSection()
+        pcj = self.factory.makePlainPackageCopyJob()
+        self.layer.txn.commit()
+        self.layer.switchDbUser('sync_packages')
+
+        override = SourceOverride(
+            source_package_name=name,
+            component=component,
+            section=section)
+        pcj.addSourceOverride(override)
+
+        metadata_component = getUtility(
+            IComponentSet)[pcj.metadata["component_override"]]
+        metadata_section = getUtility(
+            ISectionSet)[pcj.metadata["section_override"]]
+        matcher = MatchesStructure(
+            component=Equals(metadata_component),
+            section=Equals(metadata_section))
+        self.assertThat(override, matcher)
+
 
 class TestPlainPackageCopyJobPrivileges(TestCaseWithFactory, LocalTestHelper):
     """Test that `PlainPackageCopyJob` has the privileges it needs.