~joeborg/charm-helpers/apache-config

« back to all changes in this revision

Viewing changes to tests/fetch/test_fetch_centos.py

  • Committer: james.page at ubuntu
  • Date: 2017-05-25 13:46:14 UTC
  • mfrom: (618.3.25 charm-helpers)
  • Revision ID: james.page@ubuntu.com-20170525134614-nq74bhih9e9iquw2
[tinwood,r=*] Support for Ubuntu ports and refactoring of OpenStack utils to have a single source of truth for 'source' configuration options.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import subprocess
 
2
import os
 
3
 
 
4
from tests.helpers import patch_open
 
5
from testtools import TestCase
 
6
from mock import (
 
7
    patch,
 
8
    MagicMock,
 
9
    call,
 
10
)
 
11
from charmhelpers.fetch import centos as fetch
 
12
 
 
13
 
 
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:
 
19
        copy.update(update)
 
20
    return copy
 
21
 
 
22
 
 
23
class FetchTest(TestCase):
 
24
 
 
25
    @patch("charmhelpers.fetch.log")
 
26
    @patch('yum.YumBase.doPackageLists')
 
27
    def test_filter_packages_missing_centos(self, yumBase, log):
 
28
 
 
29
        class MockPackage:
 
30
            def __init__(self, name):
 
31
                self.base_package_name = name
 
32
 
 
33
        yum_dict = {
 
34
            'installed': {
 
35
                MockPackage('vim')
 
36
            },
 
37
            'available': {
 
38
                MockPackage('vim')
 
39
            }
 
40
        }
 
41
        import yum
 
42
        yum.YumBase.return_value.doPackageLists.return_value = yum_dict
 
43
        result = fetch.filter_installed_packages(['vim', 'emacs'])
 
44
        self.assertEquals(result, ['emacs'])
 
45
 
 
46
    @patch("charmhelpers.fetch.log")
 
47
    def test_filter_packages_none_missing_centos(self, log):
 
48
 
 
49
        class MockPackage:
 
50
            def __init__(self, name):
 
51
                self.base_package_name = name
 
52
 
 
53
        yum_dict = {
 
54
            'installed': {
 
55
                MockPackage('vim')
 
56
            },
 
57
            'available': {
 
58
                MockPackage('vim')
 
59
            }
 
60
        }
 
61
        import yum
 
62
        yum.yumBase.return_value.doPackageLists.return_value = yum_dict
 
63
        result = fetch.filter_installed_packages(['vim'])
 
64
        self.assertEquals(result, [])
 
65
 
 
66
    @patch('charmhelpers.fetch.centos.log')
 
67
    @patch('yum.YumBase.doPackageLists')
 
68
    def test_filter_packages_not_available_centos(self, yumBase, log):
 
69
 
 
70
        class MockPackage:
 
71
            def __init__(self, name):
 
72
                self.base_package_name = name
 
73
 
 
74
        yum_dict = {
 
75
            'installed': {
 
76
                MockPackage('vim')
 
77
            }
 
78
        }
 
79
        import yum
 
80
        yum.YumBase.return_value.doPackageLists.return_value = yum_dict
 
81
 
 
82
        result = fetch.filter_installed_packages(['vim', 'joe'])
 
83
        self.assertEquals(result, ['joe'])
 
84
 
 
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)
 
89
 
 
90
    @patch('charmhelpers.fetch.centos.log')
 
91
    @patch('os.listdir')
 
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")])
 
102
 
 
103
    @patch('charmhelpers.fetch.centos.log')
 
104
    @patch('os.listdir')
 
105
    @patch('subprocess.check_call')
 
106
    def test_add_source_http_and_key_id_centos(self, check_call,
 
107
                                               listdir, log):
 
108
        source = "http://archive.ubuntu.com/ubuntu raring-backports main"
 
109
        key_id = "akey"
 
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])
 
119
 
 
120
    @patch('charmhelpers.fetch.centos.log')
 
121
    @patch('os.listdir')
 
122
    @patch('subprocess.check_call')
 
123
    def test_add_source_https_and_key_id_centos(self, check_call,
 
124
                                                listdir, log):
 
125
        source = "https://USER:PASS@private-ppa.launchpad.net/project/awesome"
 
126
        key_id = "GPGPGP"
 
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])
 
138
 
 
139
    @patch('charmhelpers.fetch.centos.log')
 
140
    @patch.object(fetch, 'NamedTemporaryFile')
 
141
    @patch('os.listdir')
 
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"
 
146
        key = '''
 
147
            -----BEGIN PGP PUBLIC KEY BLOCK-----
 
148
            [...]
 
149
            -----END PGP PUBLIC KEY BLOCK-----
 
150
            '''
 
151
        file_mock = MagicMock()
 
152
        file_mock.name = 'temporary_file'
 
153
        temp_file.return_value.__enter__.return_value = file_mock
 
154
        listdir.return_value = []
 
155
 
 
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)
 
164
 
 
165
 
 
166
class YumTests(TestCase):
 
167
 
 
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)
 
173
 
 
174
        mock_call.assert_called_with(['yum', '--assumeyes',
 
175
                                      '--foo', '--bar', 'upgrade'],
 
176
                                     env=getenv())
 
177
 
 
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)
 
183
 
 
184
        mock_call.assert_called_with(['yum', '--assumeyes',
 
185
                                      '--foo', '--bar', 'upgrade'],
 
186
                                     env=getenv())
 
187
 
 
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']
 
193
 
 
194
        fetch.install(packages, options)
 
195
 
 
196
        mock_call.assert_called_with(['yum', '--assumeyes',
 
197
                                      '--foo', '--bar', 'install',
 
198
                                      'foo', 'bar'],
 
199
                                     env=getenv())
 
200
 
 
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)
 
206
 
 
207
        mock_call.assert_called_with(['yum', '--assumeyes',
 
208
                                      'install', 'foo', 'bar'],
 
209
                                     env=getenv())
 
210
 
 
211
    @patch('subprocess.call')
 
212
    @patch('charmhelpers.fetch.centos.log')
 
213
    def test_installs_yum_packages_as_string(self, log, mock_call):
 
214
        packages = 'foo bar'
 
215
        fetch.install(packages)
 
216
 
 
217
        mock_call.assert_called_with(['yum', '--assumeyes',
 
218
                                      'install', 'foo bar'],
 
219
                                     env=getenv())
 
220
 
 
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']
 
226
 
 
227
        fetch.install(packages, options, fatal=True)
 
228
 
 
229
        mock_call.assert_called_with(['yum', '--assumeyes',
 
230
                                      '--foo', '--bar',
 
231
                                      'install', 'foo', 'bar'],
 
232
                                     env=getenv())
 
233
 
 
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')
 
239
 
 
240
        self.assertRaises(OSError, fetch.purge, packages, fatal=True)
 
241
        self.assertTrue(log.called)
 
242
 
 
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')
 
248
 
 
249
        self.assertRaises(OSError, fetch.purge, packages, fatal=True)
 
250
        self.assertTrue(log.called)
 
251
 
 
252
    @patch('subprocess.call')
 
253
    @patch('charmhelpers.fetch.centos.log')
 
254
    def test_purges_yum_packages_as_string_nofatal(self, log, mock_call):
 
255
        packages = 'foo bar'
 
256
        fetch.purge(packages)
 
257
 
 
258
        self.assertTrue(log.called)
 
259
        mock_call.assert_called_with(['yum', '--assumeyes',
 
260
                                      'remove', 'foo bar'],
 
261
                                     env=getenv())
 
262
 
 
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)
 
268
 
 
269
        self.assertTrue(log.called)
 
270
        mock_call.assert_called_with(['yum', '--assumeyes',
 
271
                                      'remove', 'foo', 'bar'],
 
272
                                     env=getenv())
 
273
 
 
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'],
 
279
                                      env=getenv())
 
280
        self.assertTrue(log.called)
 
281
 
 
282
    @patch('subprocess.check_output')
 
283
    @patch('charmhelpers.fetch.centos.log')
 
284
    def test_yum_search(self, log, check_output):
 
285
        package = ['irrelevant']
 
286
 
 
287
        from charmhelpers.fetch.centos import yum_search
 
288
        yum_search(package)
 
289
        check_output.assert_called_with(['yum', 'search', 'irrelevant'])
 
290
        self.assertTrue(log.called)
 
291
 
 
292
    @patch('subprocess.check_call')
 
293
    @patch('time.sleep')
 
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
 
296
        the YUM lock."""
 
297
        self.called = False
 
298
 
 
299
        def side_effect(*args, **kwargs):
 
300
            """
 
301
            First, raise an exception (can't acquire lock), then return 0
 
302
            (the lock is grabbed).
 
303
            """
 
304
            if not self.called:
 
305
                self.called = True
 
306
                raise subprocess.CalledProcessError(
 
307
                    returncode=1, cmd="some command")
 
308
            else:
 
309
                return 0
 
310
 
 
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)