Merge lp:~jacekn/charm-helpers/charm-helpers into lp:charm-helpers

Proposed by Jacek Nykis
Status: Merged
Merged at revision: 70
Proposed branch: lp:~jacekn/charm-helpers/charm-helpers
Merge into: lp:charm-helpers
Diff against target: 253 lines (+189/-2)
5 files modified
charmhelpers/fetch/__init__.py (+16/-0)
charmhelpers/fetch/bzrurl.py (+44/-0)
tests/core/test_host.py (+44/-0)
tests/fetch/test_bzrurl.py (+80/-0)
tests/fetch/test_fetch.py (+5/-2)
To merge this branch: bzr merge lp:~jacekn/charm-helpers/charm-helpers
Reviewer Review Type Date Requested Status
Charm Helper Maintainers Pending
Review via email: mp+181245@code.launchpad.net

Description of the change

Added apt_purge function and tests

To post a comment you must log in.
71. By Jacek Nykis

Added BzrUrlFetchHandler class and tests

Revision history for this message
Jacek Nykis (jacekn) wrote :

Now the proposal also includes new BzrUrlFetchHandler class and small bugfix in fetch/__init__.py

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/fetch/__init__.py'
2--- charmhelpers/fetch/__init__.py 2013-08-07 23:14:14 +0000
3+++ charmhelpers/fetch/__init__.py 2013-08-21 11:46:14 +0000
4@@ -65,6 +65,20 @@
5 subprocess.call(cmd)
6
7
8+def apt_purge(packages, fatal=False):
9+ """Purge one or more packages"""
10+ cmd = ['apt-get', '-y', 'purge']
11+ if isinstance(packages, basestring):
12+ cmd.append(packages)
13+ else:
14+ cmd.extend(packages)
15+ log("Purging {}".format(packages))
16+ if fatal:
17+ subprocess.check_call(cmd)
18+ else:
19+ subprocess.call(cmd)
20+
21+
22 def add_source(source, key=None):
23 if ((source.startswith('ppa:') or
24 source.startswith('http:'))):
25@@ -120,6 +134,7 @@
26 # least- to most-specific URL matching.
27 FETCH_HANDLERS = (
28 'charmhelpers.fetch.archiveurl.ArchiveUrlFetchHandler',
29+ 'charmhelpers.fetch.bzrurl.BzrUrlFetchHandler',
30 )
31
32
33@@ -139,6 +154,7 @@
34 # We ONLY check for True here because can_handle may return a string
35 # explaining why it can't handle a given source.
36 handlers = [h for h in plugins() if h.can_handle(source) is True]
37+ installed_to = None
38 for handler in handlers:
39 try:
40 installed_to = handler.install(source)
41
42=== added file 'charmhelpers/fetch/bzrurl.py'
43--- charmhelpers/fetch/bzrurl.py 1970-01-01 00:00:00 +0000
44+++ charmhelpers/fetch/bzrurl.py 2013-08-21 11:46:14 +0000
45@@ -0,0 +1,44 @@
46+import os
47+from bzrlib.branch import Branch
48+from charmhelpers.fetch import (
49+ BaseFetchHandler,
50+ UnhandledSource
51+)
52+from charmhelpers.core.host import mkdir
53+
54+
55+class BzrUrlFetchHandler(BaseFetchHandler):
56+ """Handler for bazaar branches via generic and lp URLs"""
57+ def can_handle(self, source):
58+ url_parts = self.parse_url(source)
59+ if url_parts.scheme not in ('bzr+ssh', 'lp'):
60+ return False
61+ else:
62+ return True
63+
64+ def branch(self, source, dest):
65+ url_parts = self.parse_url(source)
66+ # If we use lp:branchname scheme we need to load plugins
67+ if not self.can_handle(source):
68+ raise UnhandledSource("Cannot handle {}".format(source))
69+ if url_parts.scheme == "lp":
70+ from bzrlib.plugin import load_plugins
71+ load_plugins()
72+ try:
73+ remote_branch = Branch.open(source)
74+ remote_branch.bzrdir.sprout(dest).open_branch()
75+ except Exception as e:
76+ raise e
77+
78+ def install(self, source):
79+ url_parts = self.parse_url(source)
80+ branch_name = url_parts.path.strip("/").split("/")[-1]
81+ dest_dir = os.path.join(os.environ.get('CHARM_DIR'), "fetched", branch_name)
82+ if not os.path.exists(dest_dir):
83+ mkdir(dest_dir, perms=0755)
84+ try:
85+ self.branch(source, dest_dir)
86+ except OSError as e:
87+ raise UnhandledSource(e.strerror)
88+ return dest_dir
89+
90
91=== modified file 'tests/core/test_host.py'
92--- tests/core/test_host.py 2013-08-07 23:14:14 +0000
93+++ tests/core/test_host.py 2013-08-21 11:46:14 +0000
94@@ -447,6 +447,50 @@
95 check_call.assert_called_with(['apt-get', '-y', '--foo', '--bar',
96 'install', 'foo', 'bar'])
97
98+
99+ @patch('subprocess.check_call')
100+ @patch.object(host, 'log')
101+ def test_purges_apt_packages_as_string_fatal(self, log, mock_call):
102+ packages = 'irrelevant names'
103+ mock_call.side_effect = OSError('fail')
104+
105+ mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True )
106+ log.assert_called()
107+
108+
109+ @patch('subprocess.check_call')
110+ @patch.object(host, 'log')
111+ def test_purges_apt_packages_fatal(self, log, mock_call):
112+ packages = ['irrelevant', 'names']
113+ mock_call.side_effect = OSError('fail')
114+
115+ mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True )
116+ log.assert_called()
117+
118+
119+ @patch('subprocess.call')
120+ @patch.object(host, 'log')
121+ def test_purges_apt_packages_as_string_nofatal(self, log, mock_call):
122+ packages = 'foo bar'
123+
124+ fetch.apt_purge(packages)
125+
126+ log.assert_called()
127+ mock_call.assert_called_with(['apt-get', '-y', 'purge', 'foo bar'])
128+
129+
130+ @patch('subprocess.call')
131+ @patch.object(host, 'log')
132+ def test_purges_apt_packages_nofatal(self, log, mock_call):
133+ packages = ['foo', 'bar']
134+
135+ fetch.apt_purge(packages)
136+
137+ log.assert_called()
138+ mock_call.assert_called_with(['apt-get', '-y', 'purge', 'foo',
139+ 'bar'])
140+
141+
142 @patch('subprocess.check_call')
143 def test_apt_update_fatal(self, check_call):
144 fetch.apt_update(fatal=True)
145
146=== added file 'tests/fetch/test_bzrurl.py'
147--- tests/fetch/test_bzrurl.py 1970-01-01 00:00:00 +0000
148+++ tests/fetch/test_bzrurl.py 2013-08-21 11:46:14 +0000
149@@ -0,0 +1,80 @@
150+import os
151+from testtools import TestCase
152+from urlparse import urlparse
153+from mock import (
154+ MagicMock,
155+ patch,
156+)
157+from charmhelpers.fetch import (
158+ bzrurl,
159+ UnhandledSource,
160+)
161+
162+
163+class BzrUrlFetchHandlerTest(TestCase):
164+
165+ def setUp(self):
166+ super(BzrUrlFetchHandlerTest, self).setUp()
167+ self.valid_urls = (
168+ "bzr+ssh://example.com/branch-name",
169+ "bzr+ssh://example.com/branch-name/",
170+ "lp:lp-branch-name",
171+ "lp:example/lp-branch-name",
172+ )
173+ self.invalid_urls = (
174+ "http://example.com/foo.tar.gz",
175+ "http://example.com/foo.tgz",
176+ "http://example.com/foo.tar.bz2",
177+ "http://example.com/foo.tbz2",
178+ "http://example.com/foo.zip",
179+ "http://example.com/foo.zip?bar=baz&x=y#whee",
180+ "ftp://example.com/foo.tar.gz",
181+ "https://example.com/foo.tgz",
182+ "file://example.com/foo.tar.bz2",
183+ "git://example.com/foo.tar.gz",
184+ "http://example.com/foo",
185+ "http://example.com/foobar=baz&x=y#tar.gz",
186+ "http://example.com/foobar?h=baz.zip",
187+ "abc:example",
188+ "file//example.com/foo.tar.bz2",
189+ "garbage",
190+ )
191+ self.fh = bzrurl.BzrUrlFetchHandler()
192+
193+
194+ def test_handles_bzr_urls(self):
195+ for url in self.valid_urls:
196+ result = self.fh.can_handle(url)
197+ self.assertEqual(result, True, url)
198+ for url in self.invalid_urls:
199+ result = self.fh.can_handle(url)
200+ self.assertNotEqual(result, True, url)
201+
202+
203+ @patch('bzrlib.branch.Branch.open')
204+ def test_branch(self, _open):
205+ dest_path = "/destination/path"
206+ for url in self.valid_urls:
207+ self.fh.remote_branch = MagicMock()
208+ self.fh.load_plugins = MagicMock()
209+ self.fh.branch(url, dest_path)
210+
211+ _open.assert_called_with(url)
212+
213+ for url in self.invalid_urls:
214+ with patch.dict('os.environ', {'CHARM_DIR': 'foo'}):
215+ self.assertRaises(UnhandledSource, self.fh.branch, url, dest_path)
216+
217+
218+ @patch('charmhelpers.fetch.bzrurl.mkdir')
219+ def test_installs(self, _mkdir):
220+ self.fh.branch = MagicMock()
221+
222+ for url in self.valid_urls:
223+ branch_name = urlparse(url).path.strip("/").split("/")[-1]
224+ dest = os.path.join('foo', 'fetched', os.path.basename(branch_name))
225+ with patch.dict('os.environ', {'CHARM_DIR': 'foo'}):
226+ where = self.fh.install(url)
227+ self.assertEqual(where, dest)
228+ _mkdir.assert_called_with(where, perms=0755)
229+
230
231=== modified file 'tests/fetch/test_fetch.py'
232--- tests/fetch/test_fetch.py 2013-08-07 23:14:14 +0000
233+++ tests/fetch/test_fetch.py 2013-08-21 11:46:14 +0000
234@@ -183,14 +183,17 @@
235 "ftp://example.com/foo.tar.gz",
236 "https://example.com/foo.tgz",
237 "file://example.com/foo.tar.bz2",
238+ "bzr+ssh://example.com/branch-name",
239+ "bzr+ssh://example.com/branch-name/",
240+ "lp:branch-name",
241+ "lp:example/branch-name",
242 )
243 self.invalid_urls = (
244 "git://example.com/foo.tar.gz",
245 "http://example.com/foo",
246 "http://example.com/foobar=baz&x=y#tar.gz",
247 "http://example.com/foobar?h=baz.zip",
248- "bzr+ssh://example.com/foo.tar.gz",
249- "lp:example/foo.tgz",
250+ "abc:example",
251 "file//example.com/foo.tar.bz2",
252 "garbage",
253 )

Subscribers

People subscribed via source and target branches