~cloud-init-dev/cloud-init/trunk

« back to all changes in this revision

Viewing changes to tests/unittests/test_handler/test_handler_apt_source.py

  • Committer: Scott Moser
  • Date: 2016-08-10 15:06:15 UTC
  • Revision ID: smoser@ubuntu.com-20160810150615-ma2fv107w3suy1ma
README: Mention move of revision control to git.

cloud-init development has moved its revision control to git.
It is available at 
  https://code.launchpad.net/cloud-init

Clone with 
  git clone https://git.launchpad.net/cloud-init
or
  git clone git+ssh://git.launchpad.net/cloud-init

For more information see
  https://git.launchpad.net/cloud-init/tree/HACKING.rst

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
""" test_handler_apt_source
2
 
Testing various config variations of the apt_source config
3
 
"""
4
 
import os
5
 
import re
6
 
import shutil
7
 
import tempfile
8
 
 
9
 
try:
10
 
    from unittest import mock
11
 
except ImportError:
12
 
    import mock
13
 
from mock import call
14
 
 
15
 
from cloudinit.config import cc_apt_configure
16
 
from cloudinit import gpg
17
 
from cloudinit import util
18
 
 
19
 
from ..helpers import TestCase
20
 
 
21
 
EXPECTEDKEY = """-----BEGIN PGP PUBLIC KEY BLOCK-----
22
 
Version: GnuPG v1
23
 
 
24
 
mI0ESuZLUgEEAKkqq3idtFP7g9hzOu1a8+v8ImawQN4TrvlygfScMU1TIS1eC7UQ
25
 
NUA8Qqgr9iUaGnejb0VciqftLrU9D6WYHSKz+EITefgdyJ6SoQxjoJdsCpJ7o9Jy
26
 
8PQnpRttiFm4qHu6BVnKnBNxw/z3ST9YMqW5kbMQpfxbGe+obRox59NpABEBAAG0
27
 
HUxhdW5jaHBhZCBQUEEgZm9yIFNjb3R0IE1vc2VyiLYEEwECACAFAkrmS1ICGwMG
28
 
CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRAGILvPA2g/d3aEA/9tVjc10HOZwV29
29
 
OatVuTeERjjrIbxflO586GLA8cp0C9RQCwgod/R+cKYdQcHjbqVcP0HqxveLg0RZ
30
 
FJpWLmWKamwkABErwQLGlM/Hwhjfade8VvEQutH5/0JgKHmzRsoqfR+LMO6OS+Sm
31
 
S0ORP6HXET3+jC8BMG4tBWCTK/XEZw==
32
 
=ACB2
33
 
-----END PGP PUBLIC KEY BLOCK-----"""
34
 
 
35
 
 
36
 
def load_tfile_or_url(*args, **kwargs):
37
 
    """load_tfile_or_url
38
 
    load file and return content after decoding
39
 
    """
40
 
    return util.decode_binary(util.read_file_or_url(*args, **kwargs).contents)
41
 
 
42
 
 
43
 
class TestAptSourceConfig(TestCase):
44
 
    """TestAptSourceConfig
45
 
    Main Class to test apt_source configs
46
 
    """
47
 
    release = "fantastic"
48
 
 
49
 
    def setUp(self):
50
 
        super(TestAptSourceConfig, self).setUp()
51
 
        self.tmp = tempfile.mkdtemp()
52
 
        self.addCleanup(shutil.rmtree, self.tmp)
53
 
        self.aptlistfile = os.path.join(self.tmp, "single-deb.list")
54
 
        self.aptlistfile2 = os.path.join(self.tmp, "single-deb2.list")
55
 
        self.aptlistfile3 = os.path.join(self.tmp, "single-deb3.list")
56
 
        self.join = os.path.join
57
 
        # mock fallback filename into writable tmp dir
58
 
        self.fallbackfn = os.path.join(self.tmp, "etc/apt/sources.list.d/",
59
 
                                       "cloud_config_sources.list")
60
 
 
61
 
        patcher = mock.patch("cloudinit.config.cc_apt_configure.get_release")
62
 
        get_rel = patcher.start()
63
 
        get_rel.return_value = self.release
64
 
        self.addCleanup(patcher.stop)
65
 
 
66
 
    @staticmethod
67
 
    def _get_default_params():
68
 
        """get_default_params
69
 
        Get the most basic default mrror and release info to be used in tests
70
 
        """
71
 
        params = {}
72
 
        params['RELEASE'] = cc_apt_configure.get_release()
73
 
        params['MIRROR'] = "http://archive.ubuntu.com/ubuntu"
74
 
        return params
75
 
 
76
 
    def myjoin(self, *args, **kwargs):
77
 
        """myjoin - redir into writable tmpdir"""
78
 
        if (args[0] == "/etc/apt/sources.list.d/" and
79
 
                args[1] == "cloud_config_sources.list" and
80
 
                len(args) == 2):
81
 
            return self.join(self.tmp, args[0].lstrip("/"), args[1])
82
 
        else:
83
 
            return self.join(*args, **kwargs)
84
 
 
85
 
    def apt_src_basic(self, filename, cfg):
86
 
        """apt_src_basic
87
 
        Test Fix deb source string, has to overwrite mirror conf in params
88
 
        """
89
 
        params = self._get_default_params()
90
 
 
91
 
        cc_apt_configure.add_apt_sources(cfg, params)
92
 
 
93
 
        self.assertTrue(os.path.isfile(filename))
94
 
 
95
 
        contents = load_tfile_or_url(filename)
96
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
97
 
                                  ("deb", "http://archive.ubuntu.com/ubuntu",
98
 
                                   "karmic-backports",
99
 
                                   "main universe multiverse restricted"),
100
 
                                  contents, flags=re.IGNORECASE))
101
 
 
102
 
    def test_apt_src_basic(self):
103
 
        """Test deb source string, overwrite mirror and filename"""
104
 
        cfg = {'source': ('deb http://archive.ubuntu.com/ubuntu'
105
 
                          ' karmic-backports'
106
 
                          ' main universe multiverse restricted'),
107
 
               'filename': self.aptlistfile}
108
 
        self.apt_src_basic(self.aptlistfile, [cfg])
109
 
 
110
 
    def test_apt_src_basic_dict(self):
111
 
        """Test deb source string, overwrite mirror and filename (dict)"""
112
 
        cfg = {self.aptlistfile: {'source':
113
 
                                  ('deb http://archive.ubuntu.com/ubuntu'
114
 
                                   ' karmic-backports'
115
 
                                   ' main universe multiverse restricted')}}
116
 
        self.apt_src_basic(self.aptlistfile, cfg)
117
 
 
118
 
    def apt_src_basic_tri(self, cfg):
119
 
        """apt_src_basic_tri
120
 
        Test Fix three deb source string, has to overwrite mirror conf in
121
 
        params. Test with filenames provided in config.
122
 
        generic part to check three files with different content
123
 
        """
124
 
        self.apt_src_basic(self.aptlistfile, cfg)
125
 
 
126
 
        # extra verify on two extra files of this test
127
 
        contents = load_tfile_or_url(self.aptlistfile2)
128
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
129
 
                                  ("deb", "http://archive.ubuntu.com/ubuntu",
130
 
                                   "precise-backports",
131
 
                                   "main universe multiverse restricted"),
132
 
                                  contents, flags=re.IGNORECASE))
133
 
        contents = load_tfile_or_url(self.aptlistfile3)
134
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
135
 
                                  ("deb", "http://archive.ubuntu.com/ubuntu",
136
 
                                   "lucid-backports",
137
 
                                   "main universe multiverse restricted"),
138
 
                                  contents, flags=re.IGNORECASE))
139
 
 
140
 
    def test_apt_src_basic_tri(self):
141
 
        """Test Fix three deb source string with filenames"""
142
 
        cfg1 = {'source': ('deb http://archive.ubuntu.com/ubuntu'
143
 
                           ' karmic-backports'
144
 
                           ' main universe multiverse restricted'),
145
 
                'filename': self.aptlistfile}
146
 
        cfg2 = {'source': ('deb http://archive.ubuntu.com/ubuntu'
147
 
                           ' precise-backports'
148
 
                           ' main universe multiverse restricted'),
149
 
                'filename': self.aptlistfile2}
150
 
        cfg3 = {'source': ('deb http://archive.ubuntu.com/ubuntu'
151
 
                           ' lucid-backports'
152
 
                           ' main universe multiverse restricted'),
153
 
                'filename': self.aptlistfile3}
154
 
        self.apt_src_basic_tri([cfg1, cfg2, cfg3])
155
 
 
156
 
    def test_apt_src_basic_dict_tri(self):
157
 
        """Test Fix three deb source string with filenames (dict)"""
158
 
        cfg = {self.aptlistfile: {'source':
159
 
                                  ('deb http://archive.ubuntu.com/ubuntu'
160
 
                                   ' karmic-backports'
161
 
                                   ' main universe multiverse restricted')},
162
 
               self.aptlistfile2: {'source':
163
 
                                   ('deb http://archive.ubuntu.com/ubuntu'
164
 
                                    ' precise-backports'
165
 
                                    ' main universe multiverse restricted')},
166
 
               self.aptlistfile3: {'source':
167
 
                                   ('deb http://archive.ubuntu.com/ubuntu'
168
 
                                    ' lucid-backports'
169
 
                                    ' main universe multiverse restricted')}}
170
 
        self.apt_src_basic_tri(cfg)
171
 
 
172
 
    def test_apt_src_basic_nofn(self):
173
 
        """Test Fix three deb source string without filenames (dict)"""
174
 
        cfg = {'source': ('deb http://archive.ubuntu.com/ubuntu'
175
 
                          ' karmic-backports'
176
 
                          ' main universe multiverse restricted')}
177
 
        with mock.patch.object(os.path, 'join', side_effect=self.myjoin):
178
 
            self.apt_src_basic(self.fallbackfn, [cfg])
179
 
 
180
 
    def apt_src_replacement(self, filename, cfg):
181
 
        """apt_src_replace
182
 
        Test Autoreplacement of MIRROR and RELEASE in source specs
183
 
        """
184
 
        params = self._get_default_params()
185
 
        cc_apt_configure.add_apt_sources(cfg, params)
186
 
 
187
 
        self.assertTrue(os.path.isfile(filename))
188
 
 
189
 
        contents = load_tfile_or_url(filename)
190
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
191
 
                                  ("deb", params['MIRROR'], params['RELEASE'],
192
 
                                   "multiverse"),
193
 
                                  contents, flags=re.IGNORECASE))
194
 
 
195
 
    def test_apt_src_replace(self):
196
 
        """Test Autoreplacement of MIRROR and RELEASE in source specs"""
197
 
        cfg = {'source': 'deb $MIRROR $RELEASE multiverse',
198
 
               'filename': self.aptlistfile}
199
 
        self.apt_src_replacement(self.aptlistfile, [cfg])
200
 
 
201
 
    def apt_src_replace_tri(self, cfg):
202
 
        """apt_src_replace_tri
203
 
        Test three autoreplacements of MIRROR and RELEASE in source specs with
204
 
        generic part
205
 
        """
206
 
        self.apt_src_replacement(self.aptlistfile, cfg)
207
 
 
208
 
        # extra verify on two extra files of this test
209
 
        params = self._get_default_params()
210
 
        contents = load_tfile_or_url(self.aptlistfile2)
211
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
212
 
                                  ("deb", params['MIRROR'], params['RELEASE'],
213
 
                                   "main"),
214
 
                                  contents, flags=re.IGNORECASE))
215
 
        contents = load_tfile_or_url(self.aptlistfile3)
216
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
217
 
                                  ("deb", params['MIRROR'], params['RELEASE'],
218
 
                                   "universe"),
219
 
                                  contents, flags=re.IGNORECASE))
220
 
 
221
 
    def test_apt_src_replace_tri(self):
222
 
        """Test triple Autoreplacement of MIRROR and RELEASE in source specs"""
223
 
        cfg1 = {'source': 'deb $MIRROR $RELEASE multiverse',
224
 
                'filename': self.aptlistfile}
225
 
        cfg2 = {'source': 'deb $MIRROR $RELEASE main',
226
 
                'filename': self.aptlistfile2}
227
 
        cfg3 = {'source': 'deb $MIRROR $RELEASE universe',
228
 
                'filename': self.aptlistfile3}
229
 
        self.apt_src_replace_tri([cfg1, cfg2, cfg3])
230
 
 
231
 
    def test_apt_src_replace_dict_tri(self):
232
 
        """Test triple Autoreplacement in source specs (dict)"""
233
 
        cfg = {self.aptlistfile: {'source': 'deb $MIRROR $RELEASE multiverse'},
234
 
               'notused': {'source': 'deb $MIRROR $RELEASE main',
235
 
                           'filename': self.aptlistfile2},
236
 
               self.aptlistfile3: {'source': 'deb $MIRROR $RELEASE universe'}}
237
 
        self.apt_src_replace_tri(cfg)
238
 
 
239
 
    def test_apt_src_replace_nofn(self):
240
 
        """Test Autoreplacement of MIRROR and RELEASE in source specs nofile"""
241
 
        cfg = {'source': 'deb $MIRROR $RELEASE multiverse'}
242
 
        with mock.patch.object(os.path, 'join', side_effect=self.myjoin):
243
 
            self.apt_src_replacement(self.fallbackfn, [cfg])
244
 
 
245
 
    def apt_src_keyid(self, filename, cfg, keynum):
246
 
        """apt_src_keyid
247
 
        Test specification of a source + keyid
248
 
        """
249
 
        params = self._get_default_params()
250
 
 
251
 
        with mock.patch.object(util, 'subp',
252
 
                               return_value=('fakekey 1234', '')) as mockobj:
253
 
            cc_apt_configure.add_apt_sources(cfg, params)
254
 
 
255
 
        # check if it added the right ammount of keys
256
 
        calls = []
257
 
        for _ in range(keynum):
258
 
            calls.append(call(('apt-key', 'add', '-'), 'fakekey 1234'))
259
 
        mockobj.assert_has_calls(calls, any_order=True)
260
 
 
261
 
        self.assertTrue(os.path.isfile(filename))
262
 
 
263
 
        contents = load_tfile_or_url(filename)
264
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
265
 
                                  ("deb",
266
 
                                   ('http://ppa.launchpad.net/smoser/'
267
 
                                    'cloud-init-test/ubuntu'),
268
 
                                   "xenial", "main"),
269
 
                                  contents, flags=re.IGNORECASE))
270
 
 
271
 
    def test_apt_src_keyid(self):
272
 
        """Test specification of a source + keyid with filename being set"""
273
 
        cfg = {'source': ('deb '
274
 
                          'http://ppa.launchpad.net/'
275
 
                          'smoser/cloud-init-test/ubuntu'
276
 
                          ' xenial main'),
277
 
               'keyid': "03683F77",
278
 
               'filename': self.aptlistfile}
279
 
        self.apt_src_keyid(self.aptlistfile, [cfg], 1)
280
 
 
281
 
    def test_apt_src_keyid_tri(self):
282
 
        """Test 3x specification of a source + keyid with filename being set"""
283
 
        cfg1 = {'source': ('deb '
284
 
                           'http://ppa.launchpad.net/'
285
 
                           'smoser/cloud-init-test/ubuntu'
286
 
                           ' xenial main'),
287
 
                'keyid': "03683F77",
288
 
                'filename': self.aptlistfile}
289
 
        cfg2 = {'source': ('deb '
290
 
                           'http://ppa.launchpad.net/'
291
 
                           'smoser/cloud-init-test/ubuntu'
292
 
                           ' xenial universe'),
293
 
                'keyid': "03683F77",
294
 
                'filename': self.aptlistfile2}
295
 
        cfg3 = {'source': ('deb '
296
 
                           'http://ppa.launchpad.net/'
297
 
                           'smoser/cloud-init-test/ubuntu'
298
 
                           ' xenial multiverse'),
299
 
                'keyid': "03683F77",
300
 
                'filename': self.aptlistfile3}
301
 
 
302
 
        self.apt_src_keyid(self.aptlistfile, [cfg1, cfg2, cfg3], 3)
303
 
        contents = load_tfile_or_url(self.aptlistfile2)
304
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
305
 
                                  ("deb",
306
 
                                   ('http://ppa.launchpad.net/smoser/'
307
 
                                    'cloud-init-test/ubuntu'),
308
 
                                   "xenial", "universe"),
309
 
                                  contents, flags=re.IGNORECASE))
310
 
        contents = load_tfile_or_url(self.aptlistfile3)
311
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
312
 
                                  ("deb",
313
 
                                   ('http://ppa.launchpad.net/smoser/'
314
 
                                    'cloud-init-test/ubuntu'),
315
 
                                   "xenial", "multiverse"),
316
 
                                  contents, flags=re.IGNORECASE))
317
 
 
318
 
    def test_apt_src_keyid_nofn(self):
319
 
        """Test specification of a source + keyid without filename being set"""
320
 
        cfg = {'source': ('deb '
321
 
                          'http://ppa.launchpad.net/'
322
 
                          'smoser/cloud-init-test/ubuntu'
323
 
                          ' xenial main'),
324
 
               'keyid': "03683F77"}
325
 
        with mock.patch.object(os.path, 'join', side_effect=self.myjoin):
326
 
            self.apt_src_keyid(self.fallbackfn, [cfg], 1)
327
 
 
328
 
    def apt_src_key(self, filename, cfg):
329
 
        """apt_src_key
330
 
        Test specification of a source + key
331
 
        """
332
 
        params = self._get_default_params()
333
 
 
334
 
        with mock.patch.object(util, 'subp') as mockobj:
335
 
            cc_apt_configure.add_apt_sources([cfg], params)
336
 
 
337
 
        mockobj.assert_called_with(('apt-key', 'add', '-'), 'fakekey 4321')
338
 
 
339
 
        self.assertTrue(os.path.isfile(filename))
340
 
 
341
 
        contents = load_tfile_or_url(filename)
342
 
        self.assertTrue(re.search(r"%s %s %s %s\n" %
343
 
                                  ("deb",
344
 
                                   ('http://ppa.launchpad.net/smoser/'
345
 
                                    'cloud-init-test/ubuntu'),
346
 
                                   "xenial", "main"),
347
 
                                  contents, flags=re.IGNORECASE))
348
 
 
349
 
    def test_apt_src_key(self):
350
 
        """Test specification of a source + key with filename being set"""
351
 
        cfg = {'source': ('deb '
352
 
                          'http://ppa.launchpad.net/'
353
 
                          'smoser/cloud-init-test/ubuntu'
354
 
                          ' xenial main'),
355
 
               'key': "fakekey 4321",
356
 
               'filename': self.aptlistfile}
357
 
        self.apt_src_key(self.aptlistfile, cfg)
358
 
 
359
 
    def test_apt_src_key_nofn(self):
360
 
        """Test specification of a source + key without filename being set"""
361
 
        cfg = {'source': ('deb '
362
 
                          'http://ppa.launchpad.net/'
363
 
                          'smoser/cloud-init-test/ubuntu'
364
 
                          ' xenial main'),
365
 
               'key': "fakekey 4321"}
366
 
        with mock.patch.object(os.path, 'join', side_effect=self.myjoin):
367
 
            self.apt_src_key(self.fallbackfn, cfg)
368
 
 
369
 
    def test_apt_src_keyonly(self):
370
 
        """Test specifying key without source"""
371
 
        params = self._get_default_params()
372
 
        cfg = {'key': "fakekey 4242",
373
 
               'filename': self.aptlistfile}
374
 
 
375
 
        with mock.patch.object(util, 'subp') as mockobj:
376
 
            cc_apt_configure.add_apt_sources([cfg], params)
377
 
 
378
 
        mockobj.assert_called_once_with(('apt-key', 'add', '-'),
379
 
                                        'fakekey 4242')
380
 
 
381
 
        # filename should be ignored on key only
382
 
        self.assertFalse(os.path.isfile(self.aptlistfile))
383
 
 
384
 
    def test_apt_src_keyidonly(self):
385
 
        """Test specification of a keyid without source"""
386
 
        params = self._get_default_params()
387
 
        cfg = {'keyid': "03683F77",
388
 
               'filename': self.aptlistfile}
389
 
 
390
 
        with mock.patch.object(util, 'subp',
391
 
                               return_value=('fakekey 1212', '')) as mockobj:
392
 
            cc_apt_configure.add_apt_sources([cfg], params)
393
 
 
394
 
        mockobj.assert_called_with(('apt-key', 'add', '-'), 'fakekey 1212')
395
 
 
396
 
        # filename should be ignored on key only
397
 
        self.assertFalse(os.path.isfile(self.aptlistfile))
398
 
 
399
 
    def apt_src_keyid_real(self, cfg, expectedkey):
400
 
        """apt_src_keyid_real
401
 
        Test specification of a keyid without source including
402
 
        up to addition of the key (add_apt_key_raw mocked to keep the
403
 
        environment as is)
404
 
        """
405
 
        params = self._get_default_params()
406
 
 
407
 
        with mock.patch.object(cc_apt_configure, 'add_apt_key_raw') as mockkey:
408
 
            with mock.patch.object(gpg, 'get_key_by_id',
409
 
                                   return_value=expectedkey) as mockgetkey:
410
 
                cc_apt_configure.add_apt_sources([cfg], params)
411
 
 
412
 
        mockgetkey.assert_called_with(cfg['keyid'],
413
 
                                      cfg.get('keyserver',
414
 
                                              'keyserver.ubuntu.com'))
415
 
        mockkey.assert_called_with(expectedkey)
416
 
 
417
 
        # filename should be ignored on key only
418
 
        self.assertFalse(os.path.isfile(self.aptlistfile))
419
 
 
420
 
    def test_apt_src_keyid_real(self):
421
 
        """test_apt_src_keyid_real - Test keyid including key add"""
422
 
        keyid = "03683F77"
423
 
        cfg = {'keyid': keyid,
424
 
               'filename': self.aptlistfile}
425
 
 
426
 
        self.apt_src_keyid_real(cfg, EXPECTEDKEY)
427
 
 
428
 
    def test_apt_src_longkeyid_real(self):
429
 
        """test_apt_src_longkeyid_real - Test long keyid including key add"""
430
 
        keyid = "B59D 5F15 97A5 04B7 E230  6DCA 0620 BBCF 0368 3F77"
431
 
        cfg = {'keyid': keyid,
432
 
               'filename': self.aptlistfile}
433
 
 
434
 
        self.apt_src_keyid_real(cfg, EXPECTEDKEY)
435
 
 
436
 
    def test_apt_src_longkeyid_ks_real(self):
437
 
        """test_apt_src_longkeyid_ks_real - Test long keyid from other ks"""
438
 
        keyid = "B59D 5F15 97A5 04B7 E230  6DCA 0620 BBCF 0368 3F77"
439
 
        cfg = {'keyid': keyid,
440
 
               'keyserver': 'keys.gnupg.net',
441
 
               'filename': self.aptlistfile}
442
 
 
443
 
        self.apt_src_keyid_real(cfg, EXPECTEDKEY)
444
 
 
445
 
    def test_apt_src_ppa(self):
446
 
        """Test adding a ppa"""
447
 
        params = self._get_default_params()
448
 
        cfg = {'source': 'ppa:smoser/cloud-init-test',
449
 
               'filename': self.aptlistfile}
450
 
 
451
 
        # default matcher needed for ppa
452
 
        matcher = re.compile(r'^[\w-]+:\w').search
453
 
 
454
 
        with mock.patch.object(util, 'subp') as mockobj:
455
 
            cc_apt_configure.add_apt_sources([cfg], params,
456
 
                                             aa_repo_match=matcher)
457
 
        mockobj.assert_called_once_with(['add-apt-repository',
458
 
                                         'ppa:smoser/cloud-init-test'])
459
 
 
460
 
        # adding ppa should ignore filename (uses add-apt-repository)
461
 
        self.assertFalse(os.path.isfile(self.aptlistfile))
462
 
 
463
 
    def test_apt_src_ppa_tri(self):
464
 
        """Test adding three ppa's"""
465
 
        params = self._get_default_params()
466
 
        cfg1 = {'source': 'ppa:smoser/cloud-init-test',
467
 
                'filename': self.aptlistfile}
468
 
        cfg2 = {'source': 'ppa:smoser/cloud-init-test2',
469
 
                'filename': self.aptlistfile2}
470
 
        cfg3 = {'source': 'ppa:smoser/cloud-init-test3',
471
 
                'filename': self.aptlistfile3}
472
 
 
473
 
        # default matcher needed for ppa
474
 
        matcher = re.compile(r'^[\w-]+:\w').search
475
 
 
476
 
        with mock.patch.object(util, 'subp') as mockobj:
477
 
            cc_apt_configure.add_apt_sources([cfg1, cfg2, cfg3], params,
478
 
                                             aa_repo_match=matcher)
479
 
        calls = [call(['add-apt-repository', 'ppa:smoser/cloud-init-test']),
480
 
                 call(['add-apt-repository', 'ppa:smoser/cloud-init-test2']),
481
 
                 call(['add-apt-repository', 'ppa:smoser/cloud-init-test3'])]
482
 
        mockobj.assert_has_calls(calls, any_order=True)
483
 
 
484
 
        # adding ppa should ignore all filenames (uses add-apt-repository)
485
 
        self.assertFalse(os.path.isfile(self.aptlistfile))
486
 
        self.assertFalse(os.path.isfile(self.aptlistfile2))
487
 
        self.assertFalse(os.path.isfile(self.aptlistfile3))
488
 
 
489
 
    def test_convert_to_new_format(self):
490
 
        """Test the conversion of old to new format"""
491
 
        cfg1 = {'source': 'deb $MIRROR $RELEASE multiverse',
492
 
                'filename': self.aptlistfile}
493
 
        cfg2 = {'source': 'deb $MIRROR $RELEASE main',
494
 
                'filename': self.aptlistfile2}
495
 
        cfg3 = {'source': 'deb $MIRROR $RELEASE universe',
496
 
                'filename': self.aptlistfile3}
497
 
        checkcfg = {self.aptlistfile: {'filename': self.aptlistfile,
498
 
                                       'source': 'deb $MIRROR $RELEASE '
499
 
                                                 'multiverse'},
500
 
                    self.aptlistfile2: {'filename': self.aptlistfile2,
501
 
                                        'source': 'deb $MIRROR $RELEASE main'},
502
 
                    self.aptlistfile3: {'filename': self.aptlistfile3,
503
 
                                        'source': 'deb $MIRROR $RELEASE '
504
 
                                                  'universe'}}
505
 
 
506
 
        newcfg = cc_apt_configure.convert_to_new_format([cfg1, cfg2, cfg3])
507
 
        self.assertEqual(newcfg, checkcfg)
508
 
 
509
 
        newcfg2 = cc_apt_configure.convert_to_new_format(newcfg)
510
 
        self.assertEqual(newcfg2, checkcfg)
511
 
 
512
 
        with self.assertRaises(ValueError):
513
 
            cc_apt_configure.convert_to_new_format(5)
514
 
 
515
 
 
516
 
# vi: ts=4 expandtab