249
240
mocked_err.assert_called_with(_er)
251
242
def test_os_codename_from_version(self):
252
'''Test mapping OpenStack numerical versions to code name'''
243
"""Test mapping OpenStack numerical versions to code name"""
253
244
self.assertEquals(openstack.get_os_codename_version('2013.1'),
256
247
@patch('charmhelpers.contrib.openstack.utils.error_out')
257
248
def test_os_codename_from_bad_version(self, mocked_error):
258
'''Test mapping a bad OpenStack numerical versions to code name'''
249
"""Test mapping a bad OpenStack numerical versions to code name"""
259
250
openstack.get_os_codename_version('2014.5.5')
260
251
expected_err = ('Could not determine OpenStack codename for '
261
252
'version 2014.5.5')
262
253
mocked_error.assert_called_with(expected_err)
264
255
def test_os_version_from_codename(self):
265
'''Test mapping a OpenStack codename to numerical version'''
256
"""Test mapping a OpenStack codename to numerical version"""
266
257
self.assertEquals(openstack.get_os_version_codename('folsom'),
269
260
@patch('charmhelpers.contrib.openstack.utils.error_out')
270
261
def test_os_version_from_bad_codename(self, mocked_error):
271
'''Test mapping a bad OpenStack codename to numerical version'''
262
"""Test mapping a bad OpenStack codename to numerical version"""
272
263
openstack.get_os_version_codename('foo')
273
264
expected_err = 'Could not derive OpenStack version for codename: foo'
274
265
mocked_error.assert_called_with(expected_err)
276
267
def test_os_version_swift_from_codename(self):
277
'''Test mapping a swift codename to numerical version'''
268
"""Test mapping a swift codename to numerical version"""
278
269
self.assertEquals(openstack.get_os_version_codename_swift('liberty'),
420
411
self.assertEquals('folsom', openstack.os_release('nova-common'))
422
413
def test_os_release_cached(self):
423
openstack.os_rel = 'foo'
414
openstack._os_rel = 'foo'
424
415
self.assertEquals('foo', openstack.os_release('nova-common'))
426
417
@patch.object(openstack, 'juju_log')
427
418
@patch('sys.exit')
428
419
def test_error_out(self, mocked_exit, juju_log):
429
'''Test erroring out'''
420
"""Test erroring out"""
430
421
openstack.error_out('Everything broke.')
431
422
_log = 'FATAL ERROR: Everything broke.'
432
423
juju_log.assert_called_with(_log, level='ERROR')
433
424
mocked_exit.assert_called_with(1)
426
def test_get_source_and_pgp_key(self):
428
"source|key": ('source', 'key'),
429
"source|": ('source', None),
431
"source": ('source', None),
433
for k, v in six.iteritems(tests):
434
self.assertEqual(openstack.get_source_and_pgp_key(k), v)
436
# These should still work, even though the bulk of the functionality has
437
# moved to charmhelpers.fetch.add_source()
435
438
def test_configure_install_source_distro(self):
436
'''Test configuring installation from distro'''
439
"""Test configuring installation from distro"""
437
440
self.assertIsNone(openstack.configure_installation_source('distro'))
439
442
def test_configure_install_source_ppa(self):
440
'''Test configuring installation source from PPA'''
443
"""Test configuring installation source from PPA"""
441
444
with patch('subprocess.check_call') as mock:
442
445
src = 'ppa:gandelman-a/openstack'
443
446
openstack.configure_installation_source(src)
444
ex_cmd = ['add-apt-repository', '-y', 'ppa:gandelman-a/openstack']
448
'add-apt-repository', '--yes', 'ppa:gandelman-a/openstack']
445
449
mock.assert_called_with(ex_cmd)
448
@patch('charmhelpers.contrib.openstack.utils.juju_log')
449
@patch('charmhelpers.contrib.openstack.utils.import_key')
450
def test_configure_install_source_deb_url(self, _import, _log, _open):
451
'''Test configuring installation source from deb repo url'''
452
_file = MagicMock(spec=io.FileIO)
453
_open.return_value = _file
451
@patch('subprocess.check_call')
452
@patch.object(fetch, 'import_key')
453
def test_configure_install_source_deb_url(self, _import, _spcc):
454
"""Test configuring installation source from deb repo url"""
454
455
src = ('deb http://ubuntu-cloud.archive.canonical.com/ubuntu '
455
456
'precise-havana main|KEYID')
456
457
openstack.configure_installation_source(src)
457
458
_import.assert_called_with('KEYID')
458
_file.__enter__().write.assert_called_with(src.split('|')[0])
459
src = ('deb http://ubuntu-cloud.archive.canonical.com/ubuntu '
460
'precise-havana main')
461
openstack.configure_installation_source(src)
462
_file.__enter__().write.assert_called_with(src)
459
_spcc.assert_called_once_with(
460
['add-apt-repository', '--yes',
461
'deb http://ubuntu-cloud.archive.canonical.com/ubuntu '
462
'precise-havana main'])
464
@patch('charmhelpers.contrib.openstack.utils.lsb_release')
464
@patch.object(fetch, 'lsb_release')
465
465
@patch(builtin_open)
466
@patch('charmhelpers.contrib.openstack.utils.juju_log')
467
def test_configure_install_source_distro_proposed(self, _log, _open, _lsb):
468
'''Test configuring installation source from deb repo url'''
466
@patch('subprocess.check_call')
467
def test_configure_install_source_distro_proposed(
468
self, _spcc, _open, _lsb):
469
"""Test configuring installation source from deb repo url"""
469
470
_lsb.return_value = FAKE_RELEASE
470
471
_file = MagicMock(spec=io.FileIO)
471
472
_open.return_value = _file
472
473
openstack.configure_installation_source('distro-proposed')
474
_file.__enter__().write.assert_called_once_with(
475
'# Proposed\ndeb http://archive.ubuntu.com/ubuntu '
476
'precise-proposed main universe multiverse restricted\n')
473
477
src = ('deb http://archive.ubuntu.com/ubuntu/ precise-proposed '
474
478
'restricted main multiverse universe')
475
479
openstack.configure_installation_source(src)
476
_file.__enter__().write.assert_called_with(src)
480
_spcc.assert_called_once_with(
481
['add-apt-repository', '--yes',
482
'deb http://archive.ubuntu.com/ubuntu/ precise-proposed '
483
'restricted main multiverse universe'])
485
@patch('charmhelpers.fetch.filter_installed_packages')
486
@patch('charmhelpers.fetch.apt_install')
487
@patch.object(openstack, 'error_out')
488
@patch.object(openstack, 'juju_log')
489
def test_add_source_cloud_invalid_pocket(self, _log, _out,
490
apt_install, filter_pkg):
491
openstack.configure_installation_source("cloud:havana-updates")
492
_e = ('Invalid Cloud Archive release specified: '
493
'havana-updates on this Ubuntuversion')
494
_s = _out.call_args[0][0]
495
self.assertTrue(_s.startswith(_e))
497
@patch.object(fetch, 'filter_installed_packages')
498
@patch.object(fetch, 'apt_install')
499
@patch.object(fetch, 'lsb_release')
500
def test_add_source_cloud_pocket_style(self, lsb_release,
501
apt_install, filter_pkg):
502
source = "cloud:precise-updates/havana"
503
lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}
505
"# Ubuntu Cloud Archive\n"
506
"deb http://ubuntu-cloud.archive.canonical.com/ubuntu "
507
"precise-updates/havana main\n")
508
with patch_open() as (mock_open, mock_file):
509
openstack.configure_installation_source(source)
510
mock_file.write.assert_called_with(result)
511
filter_pkg.assert_called_with(['ubuntu-cloud-keyring'])
513
@patch.object(fetch, 'filter_installed_packages')
514
@patch.object(fetch, 'apt_install')
515
@patch.object(fetch, 'lsb_release')
516
def test_add_source_cloud_os_style(self, lsb_release,
517
apt_install, filter_pkg):
518
source = "cloud:precise-havana"
519
lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}
521
"# Ubuntu Cloud Archive\n"
522
"deb http://ubuntu-cloud.archive.canonical.com/ubuntu "
523
"precise-updates/havana main\n")
524
with patch_open() as (mock_open, mock_file):
525
openstack.configure_installation_source(source)
526
mock_file.write.assert_called_with(result)
527
filter_pkg.assert_called_with(['ubuntu-cloud-keyring'])
529
@patch.object(fetch, 'filter_installed_packages')
530
@patch.object(fetch, 'apt_install')
531
def test_add_source_cloud_distroless_style(self, apt_install, filter_pkg):
532
source = "cloud:havana"
534
"# Ubuntu Cloud Archive\n"
535
"deb http://ubuntu-cloud.archive.canonical.com/ubuntu "
536
"precise-updates/havana main\n")
537
with patch_open() as (mock_open, mock_file):
538
openstack.configure_installation_source(source)
539
mock_file.write.assert_called_with(result)
540
filter_pkg.assert_called_with(['ubuntu-cloud-keyring'])
478
542
@patch('charmhelpers.contrib.openstack.utils.error_out')
479
543
def test_configure_bad_install_source(self, _error):
480
544
openstack.configure_installation_source('foo')
481
_error.assert_called_with('Invalid openstack-release specified: foo')
545
_error.assert_called_with("Unknown source: 'foo'")
483
@patch('charmhelpers.contrib.openstack.utils.lsb_release')
547
@patch.object(fetch, 'lsb_release')
484
548
def test_configure_install_source_uca_staging(self, _lsb):
485
'''Test configuring installation source from UCA staging sources'''
549
"""Test configuring installation source from UCA staging sources"""
486
550
_lsb.return_value = FAKE_RELEASE
487
551
# staging pockets are configured as PPAs
488
552
with patch('subprocess.check_call') as _subp:
493
557
_subp.assert_called_with(cmd)
495
559
@patch(builtin_open)
496
@patch('charmhelpers.contrib.openstack.utils.apt_install')
497
@patch('charmhelpers.contrib.openstack.utils.lsb_release')
498
def test_configure_install_source_uca_repos(self, _lsb, _install, _open):
499
'''Test configuring installation source from UCA sources'''
560
@patch.object(fetch, 'apt_install')
561
@patch.object(fetch, 'lsb_release')
562
@patch.object(fetch, 'filter_installed_packages')
563
def test_configure_install_source_uca_repos(
564
self, _fip, _lsb, _install, _open):
565
"""Test configuring installation source from UCA sources"""
500
566
_lsb.return_value = FAKE_RELEASE
501
567
_file = MagicMock(spec=io.FileIO)
502
568
_open.return_value = _file
569
_fip.side_effect = lambda x: x
503
570
for src, url in UCA_SOURCES:
571
actual_url = "# Ubuntu Cloud Archive\n{}\n".format(url)
504
572
openstack.configure_installation_source(src)
505
_install.assert_called_with('ubuntu-cloud-keyring',
573
_install.assert_called_with(['ubuntu-cloud-keyring'],
507
575
_open.assert_called_with(
508
576
'/etc/apt/sources.list.d/cloud-archive.list',
511
_file.__enter__().write.assert_called_with(url)
579
_file.__enter__().write.assert_called_with(actual_url)
513
581
@patch('charmhelpers.contrib.openstack.utils.error_out')
514
582
def test_configure_install_source_bad_uca(self, mocked_error):
515
'''Test configuring installation source from bad UCA source'''
583
"""Test configuring installation source from bad UCA source"""
517
585
openstack.configure_installation_source('cloud:foo-bar')
519
587
# ignore exceptions that raise when error_out is mocked
520
588
# and doesn't sys.exit(1)
522
_e = 'Invalid Cloud Archive release specified: foo-bar'
523
mocked_error.assert_called_with(_e)
525
@patch.object(openstack, 'juju_log', lambda *args, **kwargs: None)
526
def test_import_apt_key_radix(self):
527
'''Ensure shell out apt-key during key import'''
528
with patch('subprocess.check_call') as _subp:
529
openstack.import_key('foo')
530
cmd = ['apt-key', 'adv', '--keyserver',
531
'hkp://keyserver.ubuntu.com:80', '--recv-keys', 'foo']
532
_subp.assert_called_with(cmd)
534
@patch.object(openstack, 'juju_log', lambda *args, **kwargs: None)
535
def test_import_apt_key_ascii_armor(self):
536
with tempfile.NamedTemporaryFile() as tmp:
537
with patch.object(openstack, 'tempfile') as \
539
tmpfile = mock_tmpfile.NamedTemporaryFile.return_value
540
tmpfile.__enter__.return_value = tmpfile
541
tmpfile.name = tmp.name
542
with patch('subprocess.check_call') as _subp:
543
openstack.import_key(PGP_KEY_ASCII_ARMOR)
544
cmd = ['apt-key', 'add', tmp.name]
545
_subp.assert_called_with(cmd)
547
@patch.object(openstack, 'juju_log', lambda *args, **kwargs: None)
548
@patch('charmhelpers.contrib.openstack.utils.error_out')
549
def test_import_bad_apt_key(self, mocked_error):
550
'''Ensure error when importing apt key fails'''
551
with patch('subprocess.check_call') as _subp:
552
cmd = ['apt-key', 'adv', '--keyserver',
553
'hkp://keyserver.ubuntu.com:80', '--recv-keys', 'foo']
554
_subp.side_effect = subprocess.CalledProcessError(1, cmd, '')
555
openstack.import_key('foo')
556
cmd = ['apt-key', 'adv', '--keyserver',
557
'hkp://keyserver.ubuntu.com:80', '--recv-keys', 'foo']
558
mocked_error.assert_called_with("Error importing PGP key 'foo'")
590
_e = ('Invalid Cloud Archive release specified: foo-bar'
591
' on this Ubuntuversion')
592
_s = mocked_error.call_args[0][0]
593
self.assertTrue(_s.startswith(_e))
595
@patch.object(openstack, 'fetch_import_key')
596
def test_import_key_calls_fetch_import_key(self, fetch_import_key):
597
openstack.import_key('random-string')
598
fetch_import_key.assert_called_once_with('random-string')
600
@patch.object(openstack, 'fetch_import_key')
601
@patch.object(openstack, 'sys')
602
def test_import_key_calls_sys_exit_on_error(self, mock_sys,
606
raise openstack.GPGKeyError("an error occurred")
607
fetch_import_key.side_effect = raiser
608
openstack.import_key('random failure')
609
mock_sys.exit.assert_called_once_with(1)
560
611
@patch('os.mkdir')
561
612
@patch('os.path.exists')
562
613
@patch('charmhelpers.contrib.openstack.utils.charm_dir')
563
614
@patch(builtin_open)
564
615
def test_save_scriptrc(self, _open, _charm_dir, _exists, _mkdir):
565
'''Test generation of scriptrc from environment'''
616
"""Test generation of scriptrc from environment"""
566
617
scriptrc = ['#!/bin/bash\n',
567
618
'export setting1=foo\n',
568
619
'export setting2=bar\n']