4
from tests.helpers import patch_open
5
from testtools import TestCase
11
from charmhelpers.fetch import centos as fetch
14
def getenv(update=None):
15
# return a copy of os.environ with update applied.
16
# this was necessary because some modules modify os.environment directly
17
copy = os.environ.copy()
18
if update is not None:
23
class FetchTest(TestCase):
25
@patch("charmhelpers.fetch.log")
26
@patch('yum.YumBase.doPackageLists')
27
def test_filter_packages_missing_centos(self, yumBase, log):
30
def __init__(self, name):
31
self.base_package_name = name
42
yum.YumBase.return_value.doPackageLists.return_value = yum_dict
43
result = fetch.filter_installed_packages(['vim', 'emacs'])
44
self.assertEquals(result, ['emacs'])
46
@patch("charmhelpers.fetch.log")
47
def test_filter_packages_none_missing_centos(self, log):
50
def __init__(self, name):
51
self.base_package_name = name
62
yum.yumBase.return_value.doPackageLists.return_value = yum_dict
63
result = fetch.filter_installed_packages(['vim'])
64
self.assertEquals(result, [])
66
@patch('charmhelpers.fetch.centos.log')
67
@patch('yum.YumBase.doPackageLists')
68
def test_filter_packages_not_available_centos(self, yumBase, log):
71
def __init__(self, name):
72
self.base_package_name = name
80
yum.YumBase.return_value.doPackageLists.return_value = yum_dict
82
result = fetch.filter_installed_packages(['vim', 'joe'])
83
self.assertEquals(result, ['joe'])
85
@patch('charmhelpers.fetch.centos.log')
86
def test_add_source_none_centos(self, log):
87
fetch.add_source(source=None)
88
self.assertTrue(log.called)
90
@patch('charmhelpers.fetch.centos.log')
92
def test_add_source_http_centos(self, listdir, log):
93
source = "http://archive.ubuntu.com/ubuntu raring-backports main"
94
with patch_open() as (mock_open, mock_file):
95
fetch.add_source(source=source)
96
listdir.assert_called_with('/etc/yum.repos.d/')
97
mock_file.write.assert_has_calls([
98
call("[archive.ubuntu.com_ubuntu raring-backports main]\n"),
99
call("name=archive.ubuntu.com/ubuntu raring-backports main\n"),
100
call("baseurl=http://archive.ubuntu.com/ubuntu raring"
101
"-backports main\n\n")])
103
@patch('charmhelpers.fetch.centos.log')
105
@patch('subprocess.check_call')
106
def test_add_source_http_and_key_id_centos(self, check_call,
108
source = "http://archive.ubuntu.com/ubuntu raring-backports main"
110
with patch_open() as (mock_open, mock_file):
111
fetch.add_source(source=source, key=key_id)
112
listdir.assert_called_with('/etc/yum.repos.d/')
113
mock_file.write.assert_has_calls([
114
call("[archive.ubuntu.com_ubuntu raring-backports main]\n"),
115
call("name=archive.ubuntu.com/ubuntu raring-backports main\n"),
116
call("baseurl=http://archive.ubuntu.com/ubuntu raring"
117
"-backports main\n\n")])
118
check_call.assert_called_with(['rpm', '--import', key_id])
120
@patch('charmhelpers.fetch.centos.log')
122
@patch('subprocess.check_call')
123
def test_add_source_https_and_key_id_centos(self, check_call,
125
source = "https://USER:PASS@private-ppa.launchpad.net/project/awesome"
127
with patch_open() as (mock_open, mock_file):
128
fetch.add_source(source=source, key=key_id)
129
listdir.assert_called_with('/etc/yum.repos.d/')
130
mock_file.write.assert_has_calls([
131
call("[_USER:PASS@private-ppa.launchpad"
132
".net_project_awesome]\n"),
133
call("name=/USER:PASS@private-ppa.launchpad.net"
134
"/project/awesome\n"),
135
call("baseurl=https://USER:PASS@private-ppa.launchpad.net"
136
"/project/awesome\n\n")])
137
check_call.assert_called_with(['rpm', '--import', key_id])
139
@patch('charmhelpers.fetch.centos.log')
140
@patch.object(fetch, 'NamedTemporaryFile')
142
@patch('subprocess.check_call')
143
def test_add_source_http_and_key_centos(self, check_call,
144
listdir, temp_file, log):
145
source = "http://archive.ubuntu.com/ubuntu raring-backports main"
147
-----BEGIN PGP PUBLIC KEY BLOCK-----
149
-----END PGP PUBLIC KEY BLOCK-----
151
file_mock = MagicMock()
152
file_mock.name = 'temporary_file'
153
temp_file.return_value.__enter__.return_value = file_mock
154
listdir.return_value = []
156
with patch_open() as (mock_open, mock_file):
157
fetch.add_source(source=source, key=key)
158
listdir.assert_called_with('/etc/yum.repos.d/')
159
self.assertTrue(log.called)
160
check_call.assert_called_with(['rpm', '--import', file_mock.name])
161
file_mock.write.assert_called_once_with(key)
162
file_mock.flush.assert_called_once_with()
163
file_mock.seek.assert_called_once_with(0)
166
class YumTests(TestCase):
168
@patch('subprocess.call')
169
@patch('charmhelpers.fetch.centos.log')
170
def test_yum_upgrade_non_fatal(self, log, mock_call):
171
options = ['--foo', '--bar']
172
fetch.upgrade(options)
174
mock_call.assert_called_with(['yum', '--assumeyes',
175
'--foo', '--bar', 'upgrade'],
178
@patch('subprocess.check_call')
179
@patch('charmhelpers.fetch.centos.log')
180
def test_yum_upgrade_fatal(self, log, mock_call):
181
options = ['--foo', '--bar']
182
fetch.upgrade(options, fatal=True)
184
mock_call.assert_called_with(['yum', '--assumeyes',
185
'--foo', '--bar', 'upgrade'],
188
@patch('subprocess.call')
189
@patch('charmhelpers.fetch.centos.log')
190
def test_installs_yum_packages(self, log, mock_call):
191
packages = ['foo', 'bar']
192
options = ['--foo', '--bar']
194
fetch.install(packages, options)
196
mock_call.assert_called_with(['yum', '--assumeyes',
197
'--foo', '--bar', 'install',
201
@patch('subprocess.call')
202
@patch('charmhelpers.fetch.centos.log')
203
def test_installs_yum_packages_without_options(self, log, mock_call):
204
packages = ['foo', 'bar']
205
fetch.install(packages)
207
mock_call.assert_called_with(['yum', '--assumeyes',
208
'install', 'foo', 'bar'],
211
@patch('subprocess.call')
212
@patch('charmhelpers.fetch.centos.log')
213
def test_installs_yum_packages_as_string(self, log, mock_call):
215
fetch.install(packages)
217
mock_call.assert_called_with(['yum', '--assumeyes',
218
'install', 'foo bar'],
221
@patch('subprocess.check_call')
222
@patch('charmhelpers.fetch.centos.log')
223
def test_installs_yum_packages_with_possible_errors(self, log, mock_call):
224
packages = ['foo', 'bar']
225
options = ['--foo', '--bar']
227
fetch.install(packages, options, fatal=True)
229
mock_call.assert_called_with(['yum', '--assumeyes',
231
'install', 'foo', 'bar'],
234
@patch('subprocess.check_call')
235
@patch('charmhelpers.fetch.centos.log')
236
def test_purges_yum_packages_as_string_fatal(self, log, mock_call):
237
packages = 'irrelevant names'
238
mock_call.side_effect = OSError('fail')
240
self.assertRaises(OSError, fetch.purge, packages, fatal=True)
241
self.assertTrue(log.called)
243
@patch('subprocess.check_call')
244
@patch('charmhelpers.fetch.centos.log')
245
def test_purges_yum_packages_fatal(self, log, mock_call):
246
packages = ['irrelevant', 'names']
247
mock_call.side_effect = OSError('fail')
249
self.assertRaises(OSError, fetch.purge, packages, fatal=True)
250
self.assertTrue(log.called)
252
@patch('subprocess.call')
253
@patch('charmhelpers.fetch.centos.log')
254
def test_purges_yum_packages_as_string_nofatal(self, log, mock_call):
256
fetch.purge(packages)
258
self.assertTrue(log.called)
259
mock_call.assert_called_with(['yum', '--assumeyes',
260
'remove', 'foo bar'],
263
@patch('subprocess.call')
264
@patch('charmhelpers.fetch.centos.log')
265
def test_purges_yum_packages_nofatal(self, log, mock_call):
266
packages = ['foo', 'bar']
267
fetch.purge(packages)
269
self.assertTrue(log.called)
270
mock_call.assert_called_with(['yum', '--assumeyes',
271
'remove', 'foo', 'bar'],
274
@patch('subprocess.check_call')
275
@patch('charmhelpers.fetch.centos.log')
276
def test_yum_update_fatal(self, log, check_call):
277
fetch.update(fatal=True)
278
check_call.assert_called_with(['yum', '--assumeyes', 'update'],
280
self.assertTrue(log.called)
282
@patch('subprocess.check_output')
283
@patch('charmhelpers.fetch.centos.log')
284
def test_yum_search(self, log, check_output):
285
package = ['irrelevant']
287
from charmhelpers.fetch.centos import yum_search
289
check_output.assert_called_with(['yum', 'search', 'irrelevant'])
290
self.assertTrue(log.called)
292
@patch('subprocess.check_call')
294
def test_run_yum_command_retries_if_fatal(self, check_call, sleep):
295
"""The _run_yum_command function retries the command if it can't get
299
def side_effect(*args, **kwargs):
301
First, raise an exception (can't acquire lock), then return 0
302
(the lock is grabbed).
306
raise subprocess.CalledProcessError(
307
returncode=1, cmd="some command")
311
check_call.side_effect = side_effect
312
check_call.return_value = 0
313
from charmhelpers.fetch.centos import _run_yum_command
314
_run_yum_command(["some", "command"], fatal=True)
315
self.assertTrue(sleep.called)