Merge lp:~cjwatson/launchpad/product-release-finder-ftp into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 19047
Proposed branch: lp:~cjwatson/launchpad/product-release-finder-ftp
Merge into: lp:launchpad
Diff against target: 149 lines (+37/-21)
2 files modified
lib/lp/registry/scripts/productreleasefinder/finder.py (+2/-1)
lib/lp/registry/tests/test_prf_finder.py (+35/-20)
To merge this branch: bzr merge lp:~cjwatson/launchpad/product-release-finder-ftp
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+372161@code.launchpad.net

Commit message

Allow ProductReleaseFinder to use ftp:// URLs.

Description of the change

This was already set up correctly for the walker, but not for the finder.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/scripts/productreleasefinder/finder.py'
2--- lib/lp/registry/scripts/productreleasefinder/finder.py 2019-07-25 15:00:18 +0000
3+++ lib/lp/registry/scripts/productreleasefinder/finder.py 2019-09-02 15:54:38 +0000
4@@ -227,7 +227,8 @@
5 self.log.info("Downloading %s", url)
6 with tempfile.TemporaryFile(prefix="product-release-finder") as fp:
7 try:
8- response = urlfetch(url, use_proxy=True, output_file=fp)
9+ response = urlfetch(
10+ url, use_proxy=True, allow_ftp=True, output_file=fp)
11 # XXX cjwatson 2018-06-26: This will all change with
12 # requests 3.x. See:
13 # https://blog.petrzemek.net/2018/04/22/
14
15=== modified file 'lib/lp/registry/tests/test_prf_finder.py'
16--- lib/lp/registry/tests/test_prf_finder.py 2018-06-26 19:17:19 +0000
17+++ lib/lp/registry/tests/test_prf_finder.py 2019-09-02 15:54:38 +0000
18@@ -6,9 +6,9 @@
19 import shutil
20 from StringIO import StringIO
21 import tempfile
22-import unittest
23
24 import responses
25+from testtools import ExpectedException
26 import transaction
27 from zope.component import getUtility
28 from zope.interface.verify import verifyObject
29@@ -28,13 +28,14 @@
30 from lp.services.config import config
31 from lp.testing import (
32 reset_logging,
33+ TestCase,
34 TestCaseWithFactory,
35 )
36 from lp.testing.dbuser import switch_dbuser
37 from lp.testing.layers import LaunchpadZopelessLayer
38
39
40-class FindReleasesTestCase(unittest.TestCase):
41+class FindReleasesTestCase(TestCase):
42
43 def test_findReleases(self):
44 # test that the findReleases() method behaves as expected
45@@ -147,16 +148,15 @@
46 self.assertEqual(filters[0].key, 'trunk')
47
48
49-class HandleProductTestCase(unittest.TestCase):
50+class HandleProductTestCase(TestCase):
51
52 def setUp(self):
53+ super(HandleProductTestCase, self).setUp()
54 # path for release tree
55 self.release_root = tempfile.mkdtemp()
56+ self.addCleanup(shutil.rmtree, self.release_root, ignore_errors=True)
57 self.release_url = 'file://' + self.release_root
58-
59- def tearDown(self):
60- shutil.rmtree(self.release_root, ignore_errors=True)
61- reset_logging()
62+ self.addCleanup(reset_logging)
63
64 def test_handleProduct(self):
65 # test that handleProduct() correctly calls handleRelease()
66@@ -213,7 +213,7 @@
67 ('product', 'series2', 'product-2.1.tar.gz'))
68
69
70-class HandleReleaseTestCase(unittest.TestCase):
71+class HandleReleaseTestCase(TestCase):
72
73 layer = LaunchpadZopelessLayer
74
75@@ -224,23 +224,22 @@
76 fp.write('foo')
77 return file_path, file_name
78
79- def add_tarball_response(self, file_path):
80+ def add_tarball_response(self, file_path, scheme='http'):
81 def callback(request):
82 with open(file_path, 'rb') as f:
83 file_size = os.fstat(f.fileno()).st_size
84 return 200, {'Content-Length': str(file_size)}, f.read()
85
86- url = 'http://example.com/' + file_path.lstrip('/')
87+ url = scheme + '://example.com/' + file_path.lstrip('/')
88 responses.add_callback('GET', url, callback)
89 return url
90
91 def setUp(self):
92+ super(HandleReleaseTestCase, self).setUp()
93 switch_dbuser(config.productreleasefinder.dbuser)
94 self.release_root = tempfile.mkdtemp()
95-
96- def tearDown(self):
97- shutil.rmtree(self.release_root, ignore_errors=True)
98- reset_logging()
99+ self.addCleanup(shutil.rmtree, self.release_root, ignore_errors=True)
100+ self.addCleanup(reset_logging)
101
102 @responses.activate
103 def test_handleRelease(self):
104@@ -368,6 +367,24 @@
105 self.assertTrue(file_name in release_filenames)
106 self.assertTrue(alt_file_name in release_filenames)
107
108+ @responses.activate
109+ def test_handleRelease_ftp(self):
110+ """handleRelease copes with ftp:// URLs."""
111+ ztm = self.layer.txn
112+ logging.basicConfig(level=logging.CRITICAL)
113+ prf = ProductReleaseFinder(ztm, logging.getLogger())
114+ file_path, file_name = self.create_tarball('evolution-45.0.tar.gz')
115+ file_names = set()
116+ url = self.add_tarball_response(file_path, scheme='ftp')
117+ self.assertStartsWith(url, 'ftp://')
118+ prf.handleRelease('evolution', 'trunk', url, file_names)
119+ evo = getUtility(IProductSet).getByName('evolution')
120+ trunk = evo.getSeries('trunk')
121+ release = trunk.getRelease('45.0')
122+ release_filenames = [file_info.libraryfile.filename
123+ for file_info in release.files]
124+ self.assertEqual([file_name], release_filenames)
125+
126 def test_handleReleaseUnableToParseVersion(self):
127 # Test that handleRelease() handles the case where a version can't be
128 # parsed from the url given.
129@@ -408,16 +425,14 @@
130
131 url = 'http://example.com/' + file_path.lstrip('/')
132 responses.add_callback('GET', url, callback)
133- with self.assertRaises(IOError) as ctx:
134+ expected_re = r'^Incomplete read: got %d, expected %d$' % (
135+ file_size, file_size + 1)
136+ with ExpectedException(IOError, expected_re):
137 prf.handleRelease('evolution', 'trunk', url, file_names)
138- self.assertEqual(
139- 'Incomplete read: got %d, expected %d' % (
140- file_size, file_size + 1),
141- str(ctx.exception))
142 self.assertNotIn(file_name, file_names)
143
144
145-class ExtractVersionTestCase(unittest.TestCase):
146+class ExtractVersionTestCase(TestCase):
147 """Verify that release version names are correctly extracted."""
148
149 def test_extract_version_common_name(self):