Colin Watson has proposed merging 
lp:~cjwatson/launchpad/weaken-xz-dpkg-requirement into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #905322 in Launchpad itself: "Lower required dpkg version for 
xz-compressed packages"
  https://bugs.launchpad.net/launchpad/+bug/905322

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/weaken-xz-dpkg-requirement/+merge/86056

== Summary ==

Bug 905322 reports that the required dpkg pre-dependency in NascentUploadFile 
for .debs with xz-compressed data members is slightly too strict.  Apparently 
some Debian uploads are using a suffixed ~ to permit installing with backports 
of that dpkg version, which is a common pattern for (build-)dependencies on 
packaging infrastructure.  We should weaken this restriction in Launchpad 
rather than changing packages.

== Proposed fix ==

The code fix is a trivial search-and-replace.

== Pre-implementation notes ==

None.

== Implementation details ==

While the code fix is trivial, this function wasn't well unit-tested, only 
really integration-tested by a .deb in 
lib/lp/archiveuploader/tests/data/suite/bar_1.0-1_xz_binary/bar_1.0-1_i386.deb, 
and that's annoying to modify.  I decided to extend 
lp.archiveuploader.tests.test_nascentuploadfile.DebBinaryUploadFileTests to 
unit-test this change instead.  NascentUploadFile could do with many more unit 
tests in the future, which I haven't attempted right now, but hopefully the 
helper method I introduced will help somebody working on that.

== Tests ==

bin/test -vvct archiveuploader

== Demo and Q/A ==

Upload the source package referenced in the bug to dogfood and let it build.  
It should upload successfully rather than failing.

(We can retry the builds on production after this lands.)

== lint ==

I cleaned up some pre-existing lint.  There's now none here.
-- 
https://code.launchpad.net/~cjwatson/launchpad/weaken-xz-dpkg-requirement/+merge/86056
Your team Launchpad code reviewers is requested to review the proposed merge of 
lp:~cjwatson/launchpad/weaken-xz-dpkg-requirement into lp:launchpad.
=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
--- lib/lp/archiveuploader/nascentuploadfile.py	2011-08-28 07:29:11 +0000
+++ lib/lp/archiveuploader/nascentuploadfile.py	2011-12-16 15:15:34 +0000
@@ -713,8 +713,8 @@
                 "data.tar.bz2, data.tar.lzma or data.tar.xz." %
                 (self.filename, data_tar))
 
-        # xz-compressed debs must pre-depend on dpkg >= 1.15.6.
-        XZ_REQUIRED_DPKG_VER = '1.15.6'
+        # xz-compressed debs must pre-depend on dpkg >= 1.15.6~.
+        XZ_REQUIRED_DPKG_VER = '1.15.6~'
         if data_tar == "data.tar.xz":
             parsed_deps = []
             try:

=== modified file 'lib/lp/archiveuploader/tests/test_nascentuploadfile.py'
--- lib/lp/archiveuploader/tests/test_nascentuploadfile.py	2010-12-20 06:46:09 +0000
+++ lib/lp/archiveuploader/tests/test_nascentuploadfile.py	2011-12-16 15:15:34 +0000
@@ -7,6 +7,7 @@
 
 import hashlib
 import os
+import subprocess
 
 from debian.deb822 import (
     Changes,
@@ -276,10 +277,32 @@
                 "protocols",
             }
 
+    def createDeb(self, filename, data_format):
+        """Return the contents of a dummy .deb file."""
+        tempdir = self.makeTemporaryDirectory()
+        members = [
+            "debian-binary",
+            "control.tar.gz",
+            "data.tar.%s" % data_format,
+            ]
+        for member in members:
+            with open(os.path.join(tempdir, member), "w") as f:
+                pass
+        retcode = subprocess.call(
+            ["ar", "rc", filename] + members, cwd=tempdir)
+        self.assertEqual(0, retcode)
+        with open(os.path.join(tempdir, filename)) as f:
+            return f.read()
+
     def createDebBinaryUploadFile(self, filename, component_and_section,
-                                  priority_name, package, version, changes):
+                                  priority_name, package, version, changes,
+                                  data_format=None):
         """Create a DebBinaryUploadFile."""
-        (path, digest, size) = self.writeUploadFile(filename, "DUMMY DATA")
+        if data_format:
+            data = self.createDeb(filename, data_format)
+        else:
+            data = "DUMMY DATA"
+        (path, digest, size) = self.writeUploadFile(filename, data)
         return DebBinaryUploadFile(
             path, digest, size, component_and_section, priority_name, package,
             version, changes, self.policy, self.logger)
@@ -302,6 +325,42 @@
         self.assertEquals("0.42", uploadfile.source_version)
         self.assertEquals("0.42", uploadfile.control_version)
 
+    def test_verifyFormat_xz_good_predep(self):
+        # verifyFormat accepts xz-compressed .debs with a sufficient dpkg
+        # pre-dependency.
+        uploadfile = self.createDebBinaryUploadFile(
+            "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
+            None, data_format="xz")
+        control = self.getBaseControl()
+        control["Pre-Depends"] = "dpkg (>= 1.15.6~)"
+        uploadfile.parseControl(control)
+        self.assertEqual([], list(uploadfile.verifyFormat()))
+
+    def test_verifyFormat_xz_bad_predep(self):
+        # verifyFormat rejects xz-compressed .debs with an insufficient dpkg
+        # pre-dependency.
+        uploadfile = self.createDebBinaryUploadFile(
+            "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
+            None, data_format="xz")
+        control = self.getBaseControl()
+        control["Pre-Depends"] = "dpkg (>= 1.15.5)"
+        uploadfile.parseControl(control)
+        errors = list(uploadfile.verifyFormat())
+        self.assertEqual(1, len(errors))
+        self.assertIsInstance(errors[0], UploadError)
+
+    def test_verifyFormat_xz_no_predep(self):
+        # verifyFormat rejects xz-compressed .debs with no dpkg
+        # pre-dependency.
+        uploadfile = self.createDebBinaryUploadFile(
+            "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
+            None, data_format="xz")
+        control = self.getBaseControl()
+        uploadfile.parseControl(control)
+        errors = list(uploadfile.verifyFormat())
+        self.assertEqual(1, len(errors))
+        self.assertIsInstance(errors[0], UploadError)
+
     def test_storeInDatabase(self):
         # storeInDatabase creates a BinaryPackageRelease.
         uploadfile = self.createDebBinaryUploadFile(
@@ -395,7 +454,7 @@
         # findSourcePackageRelease finds the matching SourcePackageRelease.
         das = self.factory.makeDistroArchSeries(
             distroseries=self.policy.distroseries, architecturetag="i386")
-        build = self.factory.makeBinaryPackageBuild(
+        self.factory.makeBinaryPackageBuild(
             distroarchseries=das,
             archive=self.policy.archive)
         uploadfile = self.createDebBinaryUploadFile(
@@ -416,7 +475,7 @@
         # SourcePackageRelease.
         das = self.factory.makeDistroArchSeries(
             distroseries=self.policy.distroseries, architecturetag="i386")
-        build = self.factory.makeBinaryPackageBuild(
+        self.factory.makeBinaryPackageBuild(
             distroarchseries=das,
             archive=self.policy.archive)
         uploadfile = self.createDebBinaryUploadFile(
@@ -433,14 +492,14 @@
         # package releases.
         das = self.factory.makeDistroArchSeries(
             distroseries=self.policy.distroseries, architecturetag="i386")
-        build = self.factory.makeBinaryPackageBuild(
+        self.factory.makeBinaryPackageBuild(
             distroarchseries=das,
             archive=self.policy.archive)
         uploadfile = self.createDebBinaryUploadFile(
             "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
             None)
         spn = self.factory.makeSourcePackageName("foo")
-        spph1 = self.factory.makeSourcePackagePublishingHistory(
+        self.factory.makeSourcePackagePublishingHistory(
             sourcepackagename=spn,
             distroseries=self.policy.distroseries,
             version="0.42", archive=self.policy.archive,

_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to