1133 lines
46 KiB
Python
1133 lines
46 KiB
Python
import base64
|
|
import mock
|
|
|
|
import unit_tests.utils as utils
|
|
from unit_tests.charms_openstack.charm.utils import BaseOpenStackCharmTest
|
|
from unit_tests.charms_openstack.charm.common import MyOpenStackCharm
|
|
|
|
import charms_openstack.charm.classes as chm
|
|
import charms_openstack.charm.core as chm_core
|
|
|
|
TEST_CONFIG = {'config': True,
|
|
'openstack-origin': None}
|
|
|
|
|
|
class TestOpenStackCharm__init__(BaseOpenStackCharmTest):
|
|
# Just test the __init__() function, as it takes some params which do some
|
|
# initalisation.
|
|
|
|
def setUp(self):
|
|
|
|
class NoOp(object):
|
|
pass
|
|
|
|
# bypass setting p the charm directly, as we want control over that.
|
|
super(TestOpenStackCharm__init__, self).setUp(NoOp, TEST_CONFIG)
|
|
|
|
def test_empty_init_args(self):
|
|
target = chm.OpenStackCharm()
|
|
self.assertIsNone(target.release)
|
|
# we expect target.adapters_instance to not be None as
|
|
# target.adapters_class is not None as a default
|
|
self.assertIsNotNone(target.adapters_instance)
|
|
# from mocked hookenv.config()
|
|
self.assertEqual(target.config, TEST_CONFIG)
|
|
|
|
def test_filled_init_args(self):
|
|
self.patch_object(chm_core, '_releases', new={})
|
|
|
|
class TestCharm(chm.OpenStackCharm):
|
|
release = 'mitaka'
|
|
adapters_class = mock.MagicMock()
|
|
|
|
target = TestCharm('interfaces', 'config', 'release')
|
|
self.assertEqual(target.release, 'release')
|
|
self.assertEqual(target.config, 'config')
|
|
self.assertIsInstance(target.adapters_instance, mock.MagicMock)
|
|
TestCharm.adapters_class.assert_called_once_with(
|
|
'interfaces', charm_instance=target)
|
|
|
|
|
|
class TestOpenStackCharm(BaseOpenStackCharmTest):
|
|
# Note that this only tests the OpenStackCharm() class, which has not very
|
|
# useful defaults for testing. In order to test all the code without too
|
|
# many mocks, a separate test dervied charm class is used below.
|
|
|
|
def setUp(self):
|
|
super(TestOpenStackCharm, self).setUp(chm.OpenStackCharm, TEST_CONFIG)
|
|
|
|
def test__init__(self):
|
|
# Note cls.setUpClass() creates an OpenStackCharm() instance
|
|
self.assertEqual(chm.hookenv.config(), TEST_CONFIG)
|
|
self.assertEqual(self.target.config, TEST_CONFIG)
|
|
# Note that we assume NO release unless given one.
|
|
self.assertEqual(self.target.release, None)
|
|
|
|
def test_install(self):
|
|
# only tests that the default set_state is called
|
|
self.patch_target('set_state')
|
|
self.patch_object(chm_core.charmhelpers.fetch,
|
|
'filter_installed_packages',
|
|
name='fip',
|
|
return_value=None)
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.target.install()
|
|
self.target.set_state.assert_called_once_with('charmname-installed')
|
|
self.fip.assert_called_once_with([])
|
|
|
|
def test_all_packages(self):
|
|
self.assertEqual(self.target.packages, self.target.all_packages)
|
|
|
|
def test_full_restart_map(self):
|
|
self.assertEqual(self.target.full_restart_map, self.target.restart_map)
|
|
|
|
def test_set_state(self):
|
|
# tests that OpenStackCharm.set_state() calls set_state() global
|
|
# self.patch_object(chm.reactive.bus, 'set_state')
|
|
self.patch('charms.reactive.bus.set_state', name='set_state')
|
|
self.target.set_state('hello')
|
|
self.set_state.assert_called_once_with('hello', None)
|
|
self.set_state.reset_mock()
|
|
self.target.set_state('hello', 'there')
|
|
self.set_state.assert_called_once_with('hello', 'there')
|
|
|
|
def test_remove_state(self):
|
|
# tests that OpenStackCharm.remove_state() calls remove_state() global
|
|
self.patch('charms.reactive.bus.remove_state', name='remove_state')
|
|
self.target.remove_state('hello')
|
|
self.remove_state.assert_called_once_with('hello')
|
|
|
|
def test_configure_source(self):
|
|
self.patch_object(chm.os_utils,
|
|
'configure_installation_source',
|
|
name='cis')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
|
|
self.patch_target('config', new={'openstack-origin': 'an-origin'})
|
|
self.target.configure_source()
|
|
self.cis.assert_called_once_with('an-origin')
|
|
self.apt_update.assert_called_once_with(fatal=True)
|
|
|
|
def test_region(self):
|
|
self.patch_target('config', new={'region': 'a-region'})
|
|
self.assertEqual(self.target.region, 'a-region')
|
|
|
|
def test_restart_on_change(self):
|
|
from collections import OrderedDict
|
|
hashs = OrderedDict([
|
|
('path1', 100),
|
|
('path2', 200),
|
|
('path3', 300),
|
|
('path4', 400),
|
|
])
|
|
self.target.restart_map = {
|
|
'path1': ['s1'],
|
|
'path2': ['s2'],
|
|
'path3': ['s3'],
|
|
'path4': ['s2', 's4'],
|
|
}
|
|
self.patch_object(chm.ch_host, 'path_hash')
|
|
self.path_hash.side_effect = lambda x: hashs[x]
|
|
self.patch_object(chm.ch_host, 'service_stop')
|
|
self.patch_object(chm.ch_host, 'service_start')
|
|
# slightly awkard, in that we need to test a context manager
|
|
with self.target.restart_on_change():
|
|
# test with no restarts
|
|
pass
|
|
self.assertEqual(self.service_stop.call_count, 0)
|
|
self.assertEqual(self.service_start.call_count, 0)
|
|
|
|
with self.target.restart_on_change():
|
|
# test with path1 and path3 restarts
|
|
for k in ['path1', 'path3']:
|
|
hashs[k] += 1
|
|
self.assertEqual(self.service_stop.call_count, 2)
|
|
self.assertEqual(self.service_start.call_count, 2)
|
|
self.service_stop.assert_any_call('s1')
|
|
self.service_stop.assert_any_call('s3')
|
|
self.service_start.assert_any_call('s1')
|
|
self.service_start.assert_any_call('s3')
|
|
|
|
# test with path2 and path4 and that s2 only gets restarted once
|
|
self.service_stop.reset_mock()
|
|
self.service_start.reset_mock()
|
|
with self.target.restart_on_change():
|
|
for k in ['path2', 'path4']:
|
|
hashs[k] += 1
|
|
self.assertEqual(self.service_stop.call_count, 2)
|
|
self.assertEqual(self.service_start.call_count, 2)
|
|
calls = [mock.call('s2'), mock.call('s4')]
|
|
self.service_stop.assert_has_calls(calls)
|
|
self.service_start.assert_has_calls(calls)
|
|
|
|
def test_restart_all(self):
|
|
self.patch_object(chm.ch_host, 'service_restart')
|
|
self.patch_target('services', new=['s1', 's2'])
|
|
self.target.restart_all()
|
|
self.assertEqual(self.service_restart.call_args_list,
|
|
[mock.call('s1'), mock.call('s2')])
|
|
|
|
def test_db_sync_done(self):
|
|
self.patch_object(chm.hookenv, 'leader_get')
|
|
self.leader_get.return_value = True
|
|
self.assertTrue(self.target.db_sync_done())
|
|
self.leader_get.return_value = False
|
|
self.assertFalse(self.target.db_sync_done())
|
|
|
|
def test_db_sync(self):
|
|
self.patch_object(chm.hookenv, 'is_leader')
|
|
self.patch_object(chm.hookenv, 'leader_get')
|
|
self.patch_object(chm.hookenv, 'leader_set')
|
|
self.patch_object(chm_core, 'subprocess', name='subprocess')
|
|
self.patch_target('restart_all')
|
|
# first check with leader_get returning True
|
|
self.leader_get.return_value = True
|
|
self.is_leader.return_value = True
|
|
self.target.db_sync()
|
|
self.leader_get.assert_called_once_with(attribute='db-sync-done')
|
|
self.subprocess.check_call.assert_not_called()
|
|
self.leader_set.assert_not_called()
|
|
# Now check with leader_get returning False
|
|
self.leader_get.reset_mock()
|
|
self.leader_get.return_value = False
|
|
self.target.sync_cmd = ['a', 'cmd']
|
|
self.target.db_sync()
|
|
self.leader_get.assert_called_once_with(attribute='db-sync-done')
|
|
self.subprocess.check_call.assert_called_once_with(['a', 'cmd'])
|
|
self.leader_set.assert_called_once_with({'db-sync-done': True})
|
|
# Now check with is_leader returning False
|
|
self.leader_set.reset_mock()
|
|
self.subprocess.check_call.reset_mock()
|
|
self.leader_get.return_value = True
|
|
self.is_leader.return_value = False
|
|
self.target.db_sync()
|
|
self.subprocess.check_call.assert_not_called()
|
|
self.leader_set.assert_not_called()
|
|
|
|
def test_resource_install_map(self):
|
|
self.assertEqual(
|
|
self.target.resource_install_map,
|
|
{
|
|
'driver-deb': self.target.install_deb})
|
|
|
|
def test_install_deb(self):
|
|
self.patch_object(chm.subprocess, 'check_call')
|
|
self.target.install_deb('mydeb')
|
|
self.check_call.assert_called_once_with(['dpkg', '-i', 'mydeb'])
|
|
|
|
def test_install_resources(self):
|
|
self.patch_target('install_deb')
|
|
self.patch_object(
|
|
chm.hookenv,
|
|
'resource_get',
|
|
return_value='/tmp/my.deb')
|
|
self.target.install_resources()
|
|
self.install_deb.assert_called_once_with('/tmp/my.deb')
|
|
|
|
def test_install_resources_no_resources(self):
|
|
self.patch_target('install_deb')
|
|
self.patch_object(
|
|
chm.hookenv,
|
|
'resource_get',
|
|
return_value=None)
|
|
self.target.install_resources()
|
|
self.assertFalse(self.install_deb.called)
|
|
|
|
|
|
class TestMyOpenStackCharm(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
def make_open_stack_charm():
|
|
charm = MyOpenStackCharm(['interface1', 'interface2'])
|
|
charm.services = ['svc1', 'sv2']
|
|
return charm
|
|
|
|
super(TestMyOpenStackCharm, self).setUp(make_open_stack_charm,
|
|
TEST_CONFIG)
|
|
|
|
def test_public_url(self):
|
|
self.patch_object(chm.os_ip,
|
|
'canonical_url',
|
|
return_value='my-ip-address')
|
|
self.assertEqual(self.target.public_url, 'my-ip-address:1234')
|
|
self.canonical_url.assert_called_once_with(chm.os_ip.PUBLIC)
|
|
|
|
def test_admin_url(self):
|
|
self.patch_object(chm.os_ip,
|
|
'canonical_url',
|
|
return_value='my-ip-address')
|
|
self.assertEqual(self.target.admin_url, 'my-ip-address:2468')
|
|
self.canonical_url.assert_called_once_with(chm.os_ip.ADMIN)
|
|
|
|
def test_internal_url(self):
|
|
self.patch_object(chm.os_ip,
|
|
'canonical_url',
|
|
return_value='my-ip-address')
|
|
self.assertEqual(self.target.internal_url, 'my-ip-address:3579')
|
|
self.canonical_url.assert_called_once_with(chm.os_ip.INTERNAL)
|
|
|
|
def test_application_version_unspecified(self):
|
|
self.patch_object(chm.os_utils, 'os_release')
|
|
self.patch_object(chm, 'get_upstream_version',
|
|
return_value='1.2.3')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.version_package = None
|
|
self.assertEqual(self.target.application_version, '1.2.3')
|
|
self.get_upstream_version.assert_called_once_with('p1')
|
|
|
|
def test_application_version_package(self):
|
|
self.patch_object(chm.os_utils, 'os_release')
|
|
self.patch_object(chm, 'get_upstream_version',
|
|
return_value='1.2.3')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(self.target.application_version, '1.2.3')
|
|
self.get_upstream_version.assert_called_once_with('p2')
|
|
|
|
def test_application_version_snap(self):
|
|
self.patch_object(chm, 'get_snap_version',
|
|
return_value='4.0.3')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=True)
|
|
self.assertEqual(self.target.application_version, '4.0.3')
|
|
self.get_snap_version.assert_called_once_with('mysnap', fatal=False)
|
|
|
|
def test_application_version_dfs(self):
|
|
self.patch_object(chm.os_utils, 'os_release',
|
|
return_value='mitaka')
|
|
self.patch_object(chm, 'get_upstream_version',
|
|
return_value=None)
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(self.target.application_version, 'mitaka')
|
|
self.get_upstream_version.assert_called_once_with('p2')
|
|
self.os_release.assert_called_once_with('p2')
|
|
|
|
def test_restart_services(self):
|
|
self.patch_target('haproxy_enabled', return_value=False)
|
|
self.patch_object(chm.os_utils, 'manage_payload_services')
|
|
self.target.restart_services()
|
|
svcs = ['svc1', 'sv2']
|
|
self.manage_payload_services.assert_has_calls([
|
|
mock.call('stop', svcs),
|
|
mock.call('start', svcs)])
|
|
|
|
def test_restart_services_haproxy(self):
|
|
self.patch_target('haproxy_enabled', return_value=True)
|
|
self.patch_object(chm.os_utils, 'manage_payload_services')
|
|
self.target.restart_services()
|
|
svcs = ['svc1', 'sv2', 'haproxy']
|
|
self.manage_payload_services.assert_has_calls([
|
|
mock.call('stop', svcs),
|
|
mock.call('start', svcs)])
|
|
|
|
|
|
class TestOpenStackAPICharm(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
super(TestOpenStackAPICharm, self).setUp(chm.OpenStackAPICharm,
|
|
TEST_CONFIG)
|
|
|
|
def test_upgrade_charm(self):
|
|
self.patch_target('setup_token_cache')
|
|
self.patch_target('update_api_ports')
|
|
self.target.upgrade_charm()
|
|
self.target.setup_token_cache.assert_called_once_with()
|
|
|
|
def test_install(self):
|
|
# Test set_state and configure_source are called
|
|
self.patch_target('set_state')
|
|
self.patch_target('configure_source')
|
|
self.patch_target('enable_memcache', return_value=False)
|
|
self.patch_object(chm_core.charmhelpers.fetch,
|
|
'filter_installed_packages',
|
|
name='fip',
|
|
return_value=None)
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.target.install()
|
|
# self.target.set_state.assert_called_once_with('charmname-installed')
|
|
self.target.configure_source.assert_called_once_with()
|
|
self.fip.assert_called_once_with([])
|
|
|
|
def test_setup_token_cache(self):
|
|
self.patch_target('token_cache_pkgs')
|
|
self.patch_target('install')
|
|
self.patch_object(chm_core.charmhelpers.fetch,
|
|
'filter_installed_packages',
|
|
name='fip',
|
|
return_value=['memcached'])
|
|
self.target.setup_token_cache()
|
|
self.install.assert_called_once_with()
|
|
self.fip.return_value = []
|
|
self.install.reset_mock()
|
|
self.target.setup_token_cache()
|
|
self.assertFalse(self.install.called)
|
|
|
|
def test_enable_memcache(self):
|
|
self.assertFalse(self.target.enable_memcache(release='liberty'))
|
|
self.assertTrue(self.target.enable_memcache(release='newton'))
|
|
self.patch_target('config', new={'openstack-origin': 'distro'})
|
|
self.patch_object(chm.os_utils,
|
|
'get_os_codename_install_source',
|
|
name='gocis')
|
|
self.gocis.return_value = 'liberty'
|
|
self.assertFalse(self.target.enable_memcache())
|
|
self.gocis.return_value = 'newton'
|
|
self.assertTrue(self.target.enable_memcache())
|
|
|
|
def test_token_cache_pkgs(self):
|
|
self.patch_target('enable_memcache')
|
|
self.enable_memcache.return_value = True
|
|
self.assertEqual(self.target.token_cache_pkgs(), ['memcached',
|
|
'python-memcache'])
|
|
self.enable_memcache.return_value = False
|
|
self.assertEqual(self.target.token_cache_pkgs(), [])
|
|
|
|
def test_get_amqp_credentials(self):
|
|
# verify that the instance throws an error if not overridden
|
|
with self.assertRaises(RuntimeError):
|
|
self.target.get_amqp_credentials()
|
|
|
|
def test_get_database_setup(self):
|
|
# verify that the instance throws an error if not overridden
|
|
with self.assertRaises(RuntimeError):
|
|
self.target.get_database_setup()
|
|
|
|
def test_get_certificate_requests(self):
|
|
self.patch_object(
|
|
chm.cert_utils,
|
|
'get_certificate_request',
|
|
return_value={'cert_requests': {'test.e.c': {'sans': ['san1']}}})
|
|
self.assertEqual(
|
|
self.target.get_certificate_requests(),
|
|
{'test.e.c': {'sans': ['san1']}})
|
|
|
|
def test_get_certificate_requests_empty(self):
|
|
self.patch_object(
|
|
chm.cert_utils,
|
|
'get_certificate_request',
|
|
return_value={})
|
|
self.assertEqual(
|
|
self.target.get_certificate_requests(),
|
|
{})
|
|
|
|
def test_all_packages(self):
|
|
self.patch_target('enable_memcache')
|
|
self.patch_target('packages', new=['pkg1', 'pkg2'])
|
|
self.enable_memcache.return_value = True
|
|
self.assertEqual(self.target.all_packages,
|
|
['pkg1', 'pkg2', 'memcached', 'python-memcache'])
|
|
self.enable_memcache.return_value = False
|
|
self.assertEqual(self.target.all_packages, ['pkg1', 'pkg2'])
|
|
|
|
def test_full_restart_map(self):
|
|
self.patch_target('enable_memcache')
|
|
base_restart_map = {
|
|
'conf1': ['svc1'],
|
|
'conf2': ['svc1']}
|
|
self.patch_target('restart_map', new=base_restart_map)
|
|
self.enable_memcache.return_value = True
|
|
self.assertEqual(self.target.full_restart_map,
|
|
{'conf1': ['svc1'],
|
|
'conf2': ['svc1'],
|
|
'/etc/memcached.conf': ['memcached']})
|
|
self.enable_memcache.return_value = False
|
|
self.assertEqual(self.target.full_restart_map, base_restart_map)
|
|
|
|
|
|
class TestHAOpenStackCharm(BaseOpenStackCharmTest):
|
|
# Note that this only tests the OpenStackCharm() class, which has not very
|
|
# useful defaults for testing. In order to test all the code without too
|
|
# many mocks, a separate test dervied charm class is used below.
|
|
|
|
def setUp(self):
|
|
super(TestHAOpenStackCharm, self).setUp(chm.HAOpenStackCharm,
|
|
TEST_CONFIG)
|
|
|
|
def test_all_packages(self):
|
|
self.patch_target('packages', new=['pkg1'])
|
|
self.patch_target('token_cache_pkgs', return_value=[])
|
|
self.patch_target('haproxy_enabled', return_value=False)
|
|
self.patch_target('apache_enabled', return_value=False)
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(['pkg1'], self.target.all_packages)
|
|
self.token_cache_pkgs.return_value = ['memcache']
|
|
self.haproxy_enabled.return_value = True
|
|
self.apache_enabled.return_value = True
|
|
self.assertEqual(['pkg1', 'memcache', 'haproxy', 'apache2'],
|
|
self.target.all_packages)
|
|
|
|
def test_full_restart_map_disabled(self):
|
|
base_restart_map = {
|
|
'conf1': ['svc1'],
|
|
'conf2': ['svc1']}
|
|
self.patch_target('restart_map', new=base_restart_map)
|
|
self.patch_target('enable_memcache', return_value=False)
|
|
self.patch_target('haproxy_enabled', return_value=False)
|
|
self.patch_target('apache_enabled', return_value=False)
|
|
self.assertEqual(base_restart_map, self.target.full_restart_map)
|
|
|
|
def test_full_restart_map_enabled(self):
|
|
base_restart_map = {
|
|
'conf1': ['svc1'],
|
|
'conf2': ['svc1']}
|
|
self.patch_target('restart_map', new=base_restart_map)
|
|
self.patch_target('enable_memcache', return_value=True)
|
|
self.patch_target('haproxy_enabled', return_value=True)
|
|
self.patch_target('apache_enabled', return_value=True)
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(
|
|
self.target.full_restart_map,
|
|
{'/etc/apache2/sites-available/openstack_https_frontend.conf':
|
|
['apache2'],
|
|
'/etc/haproxy/haproxy.cfg': ['haproxy'],
|
|
'/etc/memcached.conf': ['memcached'],
|
|
'conf1': ['svc1'],
|
|
'conf2': ['svc1']})
|
|
|
|
def test_haproxy_enabled(self):
|
|
self.patch_target('ha_resources', new=['haproxy'])
|
|
self.assertTrue(self.target.haproxy_enabled())
|
|
|
|
def test__init__(self):
|
|
# Note cls.setUpClass() creates an OpenStackCharm() instance
|
|
self.assertEqual(chm.hookenv.config(), TEST_CONFIG)
|
|
self.assertEqual(self.target.config, TEST_CONFIG)
|
|
# Note that we assume NO release unless given one.
|
|
self.assertEqual(self.target.release, None)
|
|
|
|
def test_configure_ha_resources(self):
|
|
interface_mock = mock.Mock()
|
|
self.patch_target('config', new={'vip_iface': 'ens12'})
|
|
self.patch_target('ha_resources', new=['haproxy', 'vips'])
|
|
self.patch_target('_add_ha_vips_config')
|
|
self.patch_target('_add_ha_haproxy_config')
|
|
self.target.configure_ha_resources(interface_mock)
|
|
self._add_ha_vips_config.assert_called_once_with(interface_mock)
|
|
self._add_ha_haproxy_config.assert_called_once_with(interface_mock)
|
|
interface_mock.bind_resources.assert_called_once_with(iface='ens12')
|
|
|
|
def test__add_ha_vips_config(self):
|
|
nics = {
|
|
'vip1': ('eth1', 'netmask1', False),
|
|
'vip2': ('eth2', 'netmask2', False)}
|
|
interface_mock = mock.Mock()
|
|
self.patch_target('name', new='myservice')
|
|
self.patch_target('config', new={'vip': 'vip1 vip2'})
|
|
self.patch_object(chm.os_ha_utils, 'get_vip_settings')
|
|
self.get_vip_settings.side_effect = lambda x: nics[x]
|
|
self.target._add_ha_vips_config(interface_mock)
|
|
add_vip_calls = [
|
|
mock.call('myservice', 'vip1'),
|
|
mock.call('myservice', 'vip2')]
|
|
interface_mock.add_vip.assert_has_calls(add_vip_calls)
|
|
add_vip_calls = [
|
|
mock.call('res_myservice_eth1_vip'),
|
|
mock.call('res_myservice_eth2_vip')]
|
|
interface_mock.delete_resource.assert_has_calls(add_vip_calls)
|
|
|
|
def test__add_ha_vips_config_fallback(self):
|
|
nics = {
|
|
'vip1': ('eth1', 'netmask1', True),
|
|
'vip2': ('eth2', 'netmask2', True)}
|
|
interface_mock = mock.Mock()
|
|
self.patch_target('name', new='myservice')
|
|
self.patch_target('config', new={'vip': 'vip1 vip2'})
|
|
self.patch_object(chm.os_ha_utils, 'get_vip_settings')
|
|
self.get_vip_settings.side_effect = lambda x: nics[x]
|
|
self.target._add_ha_vips_config(interface_mock)
|
|
add_vip_calls = [
|
|
mock.call('myservice', 'vip1', 'eth1', 'netmask1'),
|
|
mock.call('myservice', 'vip2', 'eth2', 'netmask2')]
|
|
interface_mock.add_vip.assert_has_calls(add_vip_calls)
|
|
self.assertFalse(interface_mock.delete_resource.called)
|
|
|
|
def test__add_ha_vips_config_novip(self):
|
|
config = {'vip': None}
|
|
self.patch_target('config', new=config)
|
|
interface_mock = mock.Mock()
|
|
self.target._add_ha_vips_config(interface_mock)
|
|
self.assertFalse(interface_mock.add_vip.called)
|
|
|
|
def test__add_ha_haproxy_config(self):
|
|
self.patch_target('name', new='myservice')
|
|
interface_mock = mock.Mock()
|
|
self.target._add_ha_haproxy_config(interface_mock)
|
|
interface_mock.add_init_service.assert_called_once_with(
|
|
'myservice',
|
|
'haproxy')
|
|
|
|
def test__add_dnsha_config_single_dns_entry(self):
|
|
config = {
|
|
'dns-ha': True,
|
|
'os-admin-hostname': 'myservice-admin.maas'}
|
|
self.patch_target('config', new=config)
|
|
self.patch_target('name', new='myservice')
|
|
self.patch_object(chm.os_ip, 'resolve_address', '10.0.0.10')
|
|
interface_mock = mock.Mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
interface_mock.add_dnsha.assert_called_once_with(
|
|
'myservice',
|
|
'10.0.0.10',
|
|
'myservice-admin.maas',
|
|
'admin')
|
|
|
|
def test__add_dnsha_config_multi_dns_entries(self):
|
|
config = {
|
|
'dns-ha': True,
|
|
'os-public-hostname': 'myservice-public.maas',
|
|
'os-admin-hostname': 'myservice-admin.maas'}
|
|
addr = {
|
|
'public': '10.10.0.10',
|
|
'admin': '10.0.0.10'}
|
|
self.patch_target('config', new=config)
|
|
self.patch_target('name', new='myservice')
|
|
self.patch_object(
|
|
chm.os_ip,
|
|
'resolve_address',
|
|
new=lambda endpoint_type, override=False: addr[endpoint_type])
|
|
interface_mock = mock.Mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
calls = [
|
|
mock.call(
|
|
'myservice',
|
|
'10.0.0.10',
|
|
'myservice-admin.maas',
|
|
'admin'),
|
|
mock.call(
|
|
'myservice',
|
|
'10.10.0.10',
|
|
'myservice-public.maas',
|
|
'public')]
|
|
interface_mock.add_dnsha.assert_has_calls(calls)
|
|
|
|
def test__add_dnsha_config_single_internal_dns_entry(self):
|
|
config = {
|
|
'dns-ha': True,
|
|
'os-internal-hostname': 'myservice-internal.maas'}
|
|
self.patch_target('config', new=config)
|
|
self.patch_target('name', new='myservice')
|
|
self.patch_object(chm.os_ip, 'resolve_address', '10.0.0.10')
|
|
interface_mock = mock.Mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
interface_mock.add_dnsha.assert_called_once_with(
|
|
'myservice',
|
|
'10.0.0.10',
|
|
'myservice-internal.maas',
|
|
'int')
|
|
|
|
def test__add_dnsha_config_dns_ha_false(self):
|
|
config = {
|
|
'os-internal-hostname': 'myservice-internal.maas'
|
|
}
|
|
self.patch_target('config', new=config)
|
|
interface_mock = mock.Mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
self.assertFalse(interface_mock.add_dnsha.called)
|
|
config['dns-ha'] = None
|
|
interface_mock.reset_mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
self.assertFalse(interface_mock.add_dnsha.called)
|
|
config['dns-ha'] = False
|
|
interface_mock.reset_mock()
|
|
self.target._add_dnsha_config(interface_mock)
|
|
self.assertFalse(interface_mock.add_dnsha.called)
|
|
|
|
def test_set_haproxy_stat_password(self):
|
|
self.patch('charms.reactive.bus.get_state', name='get_state')
|
|
self.patch('charms.reactive.bus.set_state', name='set_state')
|
|
self.get_state.return_value = None
|
|
self.target.set_haproxy_stat_password()
|
|
self.set_state.assert_called_once_with('haproxy.stat.password',
|
|
mock.ANY)
|
|
|
|
def test_hacharm_all_packages_enabled(self):
|
|
self.patch_target('enable_memcache', return_value=False)
|
|
self.patch_target('haproxy_enabled', return_value=True)
|
|
self.assertTrue('haproxy' in self.target.all_packages)
|
|
|
|
def test_hacharm_all_packages_disabled(self):
|
|
self.patch_target('enable_memcache', return_value=False)
|
|
self.patch_target('haproxy_enabled', return_value=False)
|
|
self.assertFalse('haproxy' in self.target.all_packages)
|
|
|
|
def test_hacharm_full_restart_map(self):
|
|
self.patch_target('enable_memcache', return_value=False)
|
|
self.patch_target('haproxy_enabled', return_value=True)
|
|
self.assertTrue(
|
|
self.target.full_restart_map.get(
|
|
'/etc/haproxy/haproxy.cfg', False))
|
|
|
|
def test_enable_apache_ssl_vhost(self):
|
|
self.patch_object(chm.os.path, 'exists', return_value=True)
|
|
self.patch_object(chm.subprocess, 'call', return_value=1)
|
|
self.patch_object(chm.subprocess, 'check_call')
|
|
self.target.enable_apache_ssl_vhost()
|
|
self.check_call.assert_called_once_with(
|
|
['a2ensite', 'openstack_https_frontend'])
|
|
self.check_call.reset_mock()
|
|
self.patch_object(chm.subprocess, 'call', return_value=0)
|
|
self.target.enable_apache_ssl_vhost()
|
|
self.assertFalse(self.check_call.called)
|
|
|
|
def test_enable_apache_modules(self):
|
|
apache_mods = {
|
|
'ssl': 0,
|
|
'proxy': 0,
|
|
'proxy_http': 1,
|
|
'headers': 0}
|
|
self.patch_object(chm.ch_host, 'service_restart')
|
|
self.patch_object(chm.subprocess, 'check_call')
|
|
self.patch_object(
|
|
chm.subprocess, 'call',
|
|
new=lambda x: apache_mods[x.pop()])
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.enable_apache_modules()
|
|
self.check_call.assert_called_once_with(
|
|
['a2enmod', 'proxy_http'])
|
|
self.service_restart.assert_called_once_with('apache2')
|
|
|
|
def test_configure_cert(self):
|
|
self.patch_object(chm.ch_host, 'mkdir')
|
|
self.patch_object(chm.ch_host, 'write_file')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.configure_cert('mycert', 'mykey', cn='mycn')
|
|
self.mkdir.assert_called_once_with(path='/etc/apache2/ssl/charmname')
|
|
calls = [
|
|
mock.call(
|
|
path='/etc/apache2/ssl/charmname/cert_mycn',
|
|
content=b'mycert'),
|
|
mock.call(
|
|
path='/etc/apache2/ssl/charmname/key_mycn',
|
|
content=b'mykey')]
|
|
self.write_file.assert_has_calls(calls)
|
|
self.write_file.reset_mock()
|
|
self.patch_object(chm.os_ip, 'resolve_address', 'addr')
|
|
self.target.configure_cert('mycert', 'mykey')
|
|
calls = [
|
|
mock.call(
|
|
path='/etc/apache2/ssl/charmname/cert_addr',
|
|
content=b'mycert'),
|
|
mock.call(
|
|
path='/etc/apache2/ssl/charmname/key_addr',
|
|
content=b'mykey')]
|
|
self.write_file.assert_has_calls(calls)
|
|
|
|
def test_get_local_addresses(self):
|
|
self.patch_object(chm.os_utils, 'get_host_ip', return_value='privaddr')
|
|
self.patch_object(chm.os_ip, 'resolve_address')
|
|
addresses = {
|
|
'admin': 'admin_addr',
|
|
'int': 'internal_addr',
|
|
'public': 'public_addr'}
|
|
self.resolve_address.side_effect = \
|
|
lambda endpoint_type=None: addresses[endpoint_type]
|
|
self.assertEqual(
|
|
self.target.get_local_addresses(),
|
|
['admin_addr', 'internal_addr', 'privaddr', 'public_addr'])
|
|
|
|
def test_get_certs_and_keys(self):
|
|
config = {
|
|
'ssl_key': base64.b64encode(b'key'),
|
|
'ssl_cert': base64.b64encode(b'cert'),
|
|
'ssl_ca': base64.b64encode(b'ca')}
|
|
addresses = {
|
|
'admin': 'adm_addr',
|
|
'int': 'int_addr',
|
|
'public': 'pub_addr'}
|
|
self.patch_target('config', new=config)
|
|
self.patch_object(chm.os_ip, 'resolve_address', 'addr')
|
|
self.resolve_address.side_effect = \
|
|
lambda endpoint_type=None: addresses[endpoint_type]
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(
|
|
self.target.get_certs_and_keys(),
|
|
[
|
|
{'key': 'key', 'cert': 'cert', 'ca': 'ca', 'cn': 'int_addr'},
|
|
{'key': 'key', 'cert': 'cert', 'ca': 'ca', 'cn': 'adm_addr'},
|
|
{'key': 'key', 'cert': 'cert', 'ca': 'ca', 'cn': 'pub_addr'}])
|
|
|
|
def test_get_certs_and_keys_noca(self):
|
|
config = {
|
|
'ssl_key': base64.b64encode(b'key'),
|
|
'ssl_cert': base64.b64encode(b'cert')}
|
|
addresses = {
|
|
'admin': 'adm_addr',
|
|
'int': 'int_addr',
|
|
'public': 'pub_addr'}
|
|
self.patch_target('config', new=config)
|
|
self.patch_object(chm.os_ip, 'resolve_address', 'addr')
|
|
self.resolve_address.side_effect = \
|
|
lambda endpoint_type=None: addresses[endpoint_type]
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.assertEqual(
|
|
self.target.get_certs_and_keys(),
|
|
[
|
|
{'key': 'key', 'cert': 'cert', 'ca': None, 'cn': 'int_addr'},
|
|
{'key': 'key', 'cert': 'cert', 'ca': None, 'cn': 'adm_addr'},
|
|
{'key': 'key', 'cert': 'cert', 'ca': None, 'cn': 'pub_addr'}])
|
|
|
|
def test_get_certs_and_keys_ks_interface(self):
|
|
class KSInterface(object):
|
|
def get_ssl_key(self, key):
|
|
keys = {
|
|
'int_addr': 'int_key',
|
|
'priv_addr': 'priv_key',
|
|
'pub_addr': 'pub_key',
|
|
'admin_addr': 'admin_key'}
|
|
return keys[key]
|
|
|
|
def get_ssl_cert(self, key):
|
|
certs = {
|
|
'int_addr': 'int_cert',
|
|
'priv_addr': 'priv_cert',
|
|
'pub_addr': 'pub_cert',
|
|
'admin_addr': 'admin_cert'}
|
|
return certs[key]
|
|
|
|
def get_ssl_ca(self):
|
|
return 'ca'
|
|
|
|
self.patch_target(
|
|
'get_local_addresses',
|
|
return_value=['int_addr', 'priv_addr', 'pub_addr', 'admin_addr'])
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
expect = [
|
|
{
|
|
'ca': 'ca',
|
|
'cert': 'int_cert',
|
|
'cn': 'int_addr',
|
|
'key': 'int_key'},
|
|
{
|
|
'ca': 'ca',
|
|
'cert': 'priv_cert',
|
|
'cn': 'priv_addr',
|
|
'key': 'priv_key'},
|
|
{
|
|
'ca': 'ca',
|
|
'cert': 'pub_cert',
|
|
'cn': 'pub_addr',
|
|
'key': 'pub_key'},
|
|
{
|
|
'ca': 'ca',
|
|
'cert': 'admin_cert',
|
|
'cn': 'admin_addr',
|
|
'key': 'admin_key'}]
|
|
|
|
self.assertEqual(
|
|
self.target.get_certs_and_keys(keystone_interface=KSInterface()),
|
|
expect)
|
|
|
|
def test_get_certs_and_keys_certs_interface(self):
|
|
class CertsInterface(object):
|
|
|
|
def get_batch_requests(self):
|
|
req = {
|
|
'int_addr': {
|
|
'cert': 'int_cert',
|
|
'key': 'int_key'},
|
|
'priv_addr': {
|
|
'cert': 'priv_cert',
|
|
'key': 'priv_key'},
|
|
'pub_addr': {
|
|
'cert': 'pub_cert',
|
|
'key': 'pub_key'},
|
|
'admin_addr': {
|
|
'cert': 'admin_cert',
|
|
'key': 'admin_key'}}
|
|
return req
|
|
|
|
def get_ca(self):
|
|
return 'CA'
|
|
|
|
def get_chain(self):
|
|
return 'CHAIN'
|
|
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
expect = [
|
|
{
|
|
'ca': 'CA',
|
|
'cert': 'admin_cert\nCHAIN',
|
|
'cn': 'admin_addr',
|
|
'key': 'admin_key'},
|
|
{
|
|
'ca': 'CA',
|
|
'cert': 'int_cert\nCHAIN',
|
|
'cn': 'int_addr',
|
|
'key': 'int_key'},
|
|
{
|
|
'ca': 'CA',
|
|
'cert': 'priv_cert\nCHAIN',
|
|
'cn': 'priv_addr',
|
|
'key': 'priv_key'},
|
|
{
|
|
'ca': 'CA',
|
|
'cert': 'pub_cert\nCHAIN',
|
|
'cn': 'pub_addr',
|
|
'key': 'pub_key'},
|
|
]
|
|
|
|
self.assertEqual(
|
|
self.target.get_certs_and_keys(
|
|
certificates_interface=CertsInterface()),
|
|
expect)
|
|
|
|
def test_config_defined_certs_and_keys(self):
|
|
# test that the cached parameters do what we expect
|
|
config = {
|
|
'ssl_key': base64.b64encode(b'confkey'),
|
|
'ssl_cert': base64.b64encode(b'confcert'),
|
|
'ssl_ca': base64.b64encode(b'confca')}
|
|
self.patch_target('config', new=config)
|
|
self.assertEqual(self.target.config_defined_ssl_key, b'confkey')
|
|
self.assertEqual(self.target.config_defined_ssl_cert, b'confcert')
|
|
self.assertEqual(self.target.config_defined_ssl_ca, b'confca')
|
|
|
|
def test_configure_ssl(self):
|
|
ssl_objs = [
|
|
{
|
|
'cert': 'cert1',
|
|
'key': 'key1',
|
|
'ca': 'ca1',
|
|
'cn': 'cn1'},
|
|
{
|
|
'cert': 'cert2',
|
|
'key': 'key2',
|
|
'ca': 'ca2',
|
|
'cn': 'cn2'}]
|
|
self.patch_target('get_certs_and_keys', return_value=ssl_objs)
|
|
self.patch_target('configure_apache')
|
|
self.patch_target('configure_cert')
|
|
self.patch_target('configure_ca')
|
|
self.patch('charms.reactive.bus.set_state', name='set_state')
|
|
self.patch_object(chm.relations, 'endpoint_from_flag',
|
|
return_value=None)
|
|
self.patch_object(chm_core.charmhelpers.fetch,
|
|
'filter_installed_packages',
|
|
name='fip',
|
|
return_value=['apache2'])
|
|
self.patch_object(chm_core.charmhelpers.fetch,
|
|
'apt_install',
|
|
name='apt_install')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.configure_ssl()
|
|
cert_calls = [
|
|
mock.call('cert1', 'key1', cn='cn1'),
|
|
mock.call('cert2', 'key2', cn='cn2')]
|
|
ca_calls = [
|
|
mock.call('ca1'),
|
|
mock.call('ca2')]
|
|
set_state_calls = [
|
|
mock.call('ssl.requested', True),
|
|
mock.call('ssl.enabled', True)]
|
|
self.configure_cert.assert_has_calls(cert_calls)
|
|
self.configure_ca.assert_has_calls(ca_calls)
|
|
self.configure_apache.assert_called_once_with()
|
|
self.set_state.assert_has_calls(set_state_calls)
|
|
|
|
def test_configure_ssl_off(self):
|
|
self.patch_target('get_certs_and_keys', return_value=[])
|
|
self.patch('charms.reactive.bus.set_state', name='set_state')
|
|
self.patch_object(chm.relations, 'endpoint_from_flag',
|
|
return_value=None)
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.configure_ssl()
|
|
self.set_state.assert_called_once_with('ssl.enabled', False)
|
|
|
|
def test_configure_ssl_rabbit(self):
|
|
self.patch_target('get_certs_and_keys', return_value=[])
|
|
self.patch_target('configure_rabbit_cert')
|
|
self.patch('charms.reactive.bus.set_state', name='set_state')
|
|
self.patch_object(chm.relations, 'endpoint_from_flag',
|
|
return_value='ssl_int')
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
self.target.configure_ssl()
|
|
self.set_state.assert_called_once_with('ssl.enabled', False)
|
|
self.configure_rabbit_cert.assert_called_once_with('ssl_int')
|
|
|
|
def test_configure_rabbit_cert(self):
|
|
rabbit_int_mock = mock.MagicMock()
|
|
rabbit_int_mock.get_ssl_cert.return_value = 'rabbit_cert'
|
|
self.patch_object(chm.os.path, 'exists', return_value=True)
|
|
self.patch_object(chm.os, 'mkdir')
|
|
self.patch_object(chm.hookenv, 'service_name', return_value='svc1')
|
|
with utils.patch_open() as (mock_open, mock_file):
|
|
self.target.configure_rabbit_cert(rabbit_int_mock)
|
|
mock_open.assert_called_with(
|
|
'/var/lib/charm/svc1/rabbit-client-ca.pem',
|
|
'w')
|
|
mock_file.write.assert_called_with('rabbit_cert')
|
|
|
|
def test_configure_ca(self):
|
|
self.patch_target('run_update_certs')
|
|
self.patch_target('install_snap_certs')
|
|
with utils.patch_open() as (mock_open, mock_file):
|
|
self.target.configure_ca('myca')
|
|
mock_open.assert_called_with(
|
|
'/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
|
|
'w')
|
|
mock_file.write.assert_called_with('myca')
|
|
|
|
def test_run_update_certs(self):
|
|
self.patch_object(chm.subprocess, 'check_call')
|
|
self.target.run_update_certs()
|
|
self.check_call.assert_called_once_with(
|
|
['update-ca-certificates', '--fresh'])
|
|
|
|
def test_install_snap_certs(self):
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=True)
|
|
self.patch_object(chm.shutil, 'copyfile')
|
|
self.patch_object(chm.ch_host, 'mkdir')
|
|
self.patch_object(chm.os.path, 'exists', return_value=True)
|
|
self.target.snaps = ['mysnap']
|
|
|
|
self.target.install_snap_certs()
|
|
|
|
self.exists.assert_called_with('/etc/ssl/certs/ca-certificates.crt')
|
|
self.copyfile.assert_called_with(
|
|
'/etc/ssl/certs/ca-certificates.crt',
|
|
'/var/snap/mysnap/common/etc/ssl/certs/ca-certificates.crt',
|
|
)
|
|
self.mkdir.assert_called_with('/var/snap/mysnap/common/etc/ssl/certs')
|
|
|
|
self.snap_install_requested.reset_mock()
|
|
self.snap_install_requested.return_value = True
|
|
self.exists.reset_mock()
|
|
self.exists.return_value = False
|
|
self.copyfile.reset_mock()
|
|
self.mkdir.reset_mock()
|
|
|
|
self.target.install_snap_certs()
|
|
|
|
self.exists.assert_called_with('/etc/ssl/certs/ca-certificates.crt')
|
|
self.mkdir.assert_not_called()
|
|
self.copyfile.assert_not_called()
|
|
|
|
self.snap_install_requested.reset_mock()
|
|
self.snap_install_requested.return_value = False
|
|
self.exists.reset_mock()
|
|
self.exists.return_value = True
|
|
self.copyfile.reset_mock()
|
|
self.mkdir.reset_mock()
|
|
|
|
self.target.install_snap_certs()
|
|
|
|
self.exists.assert_not_called()
|
|
self.mkdir.assert_not_called()
|
|
self.copyfile.assert_not_called()
|
|
|
|
def test_update_central_cacerts(self):
|
|
self.patch_target('run_update_certs')
|
|
change_hashes = ['hash1', 'hash2']
|
|
nochange_hashes = ['hash1', 'hash1']
|
|
|
|
def fake_hash(hash_dict):
|
|
def fake_hash_inner(filename):
|
|
return hash_dict.pop()
|
|
return fake_hash_inner
|
|
self.patch_object(chm.ch_host, 'path_hash')
|
|
self.path_hash.side_effect = fake_hash(change_hashes)
|
|
self.patch_object(chm.os_utils, 'snap_install_requested',
|
|
return_value=False)
|
|
with self.target.update_central_cacerts(['file1']):
|
|
pass
|
|
self.run_update_certs.assert_called_with()
|
|
self.run_update_certs.reset_mock()
|
|
self.path_hash.side_effect = fake_hash(nochange_hashes)
|
|
with self.target.update_central_cacerts(['file1']):
|
|
pass
|
|
self.assertFalse(self.run_update_certs.called)
|
|
|
|
|
|
class TestCinderStoragePluginCharm(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
super(TestCinderStoragePluginCharm, self).setUp(
|
|
chm.CinderStoragePluginCharm,
|
|
TEST_CONFIG)
|
|
|
|
def test_install(self):
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'add_source')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
|
|
self.patch_target('config', new={'driver-source': 'ppa:user/ppa'})
|
|
self.patch_target('install_resources')
|
|
self.target.install()
|
|
self.add_source.assert_called_once_with('ppa:user/ppa', key=None)
|
|
self.apt_update.assert_called_once_with()
|
|
self.install_resources.assert_called_once_with()
|
|
|
|
def test_install_with_key(self):
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'add_source')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
|
|
self.patch_target('install_resources')
|
|
self.patch_target(
|
|
'config',
|
|
new={
|
|
'driver-source': 'ppa:user/ppa',
|
|
'driver-key': 'mykey'})
|
|
self.target.install()
|
|
self.add_source.assert_called_once_with('ppa:user/ppa', key='mykey')
|
|
self.apt_update.assert_called_once_with()
|
|
|
|
def test_install_no_additional_source(self):
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'add_source')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
|
|
self.patch_target('install_resources')
|
|
self.patch_target(
|
|
'config',
|
|
new={
|
|
'driver-source': '',
|
|
'driver-key': ''})
|
|
self.target.install()
|
|
self.assertFalse(self.add_source.called)
|
|
self.assertFalse(self.apt_update.called)
|
|
|
|
def test_install_source_undefined(self):
|
|
# A charm may be based from this class but not implement the
|
|
# additonal ppa option.
|
|
self.patch_object(chm.subprocess, 'check_output', return_value=b'\n')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'add_source')
|
|
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
|
|
self.patch_target('config', new={})
|
|
self.patch_target('install_resources')
|
|
self.target.install()
|
|
self.assertFalse(self.add_source.called)
|
|
self.assertFalse(self.apt_update.called)
|
|
|
|
def test_stateless(self):
|
|
with self.assertRaises(NotImplementedError):
|
|
self.target.stateless
|
|
|
|
def test_service_name(self):
|
|
self.patch_object(chm.hookenv, 'service_name', return_value='svc1')
|
|
self.assertEqual(self.target.service_name, 'svc1')
|
|
|
|
def test_cinder_configuration(self):
|
|
with self.assertRaises(NotImplementedError):
|
|
self.target.cinder_configuration()
|
|
|
|
def test_send_storage_backend_data(self):
|
|
self.patch_object(chm.hookenv, 'service_name', return_value='svc1')
|
|
ep_mock = mock.MagicMock()
|
|
self.patch_object(
|
|
chm.relations,
|
|
'endpoint_from_flag',
|
|
return_value=ep_mock)
|
|
with self.assertRaises(NotImplementedError):
|
|
self.target.send_storage_backend_data()
|