Construct package list and restart_map dynamically. Check-in tests.
This commit is contained in:
parent
8139e43440
commit
4b969f7722
10
charm-helpers.yaml
Normal file
10
charm-helpers.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
branch: lp:charm-helpers
|
||||
destination: hooks/charmhelpers
|
||||
include:
|
||||
- core
|
||||
- contrib.openstack|inc=*
|
||||
- contrib.storage
|
||||
- contrib.hahelpers:
|
||||
- apache
|
||||
- ceph
|
||||
- cluster
|
1
hooks/install
Symbolic link
1
hooks/install
Symbolic link
@ -0,0 +1 @@
|
||||
nova_compute_relations.py
|
@ -24,8 +24,7 @@ from charmhelpers.contrib.openstack.utils import (
|
||||
)
|
||||
|
||||
from nova_compute_utils import (
|
||||
PACKAGES,
|
||||
RESTART_MAP,
|
||||
determine_packages,
|
||||
import_authorized_keys,
|
||||
import_keystone_ca_cert,
|
||||
migration_enabled,
|
||||
@ -33,9 +32,11 @@ from nova_compute_utils import (
|
||||
configure_network_service,
|
||||
configure_volume_service,
|
||||
do_openstack_upgrade,
|
||||
quantum_attribute,
|
||||
quantum_enabled,
|
||||
quantum_plugin_config,
|
||||
quantum_plugin,
|
||||
public_ssh_key,
|
||||
restart_map,
|
||||
register_configs,
|
||||
)
|
||||
|
||||
@ -51,11 +52,11 @@ CONFIGS = register_configs()
|
||||
def install():
|
||||
configure_installation_source(config('openstack-origin'))
|
||||
apt_update()
|
||||
apt_install(PACKAGES, fatal=True)
|
||||
apt_install(determine_packages(), fatal=True)
|
||||
|
||||
|
||||
@hooks.hook('config-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def config_changed():
|
||||
if openstack_upgrade_available('nova-common'):
|
||||
do_openstack_upgrade()
|
||||
@ -68,13 +69,13 @@ def config_changed():
|
||||
|
||||
|
||||
@hooks.hook('amqp-relation-joined')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def amqp_joined():
|
||||
relation_set(username=config('rabbit-user'), vhost=config('rabbit-vhost'))
|
||||
|
||||
|
||||
@hooks.hook('amqp-relation-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def amqp_changed():
|
||||
if 'amqp' not in CONFIGS.complete_contexts():
|
||||
log('amqp relation incomplete. Peer not ready?')
|
||||
@ -91,18 +92,19 @@ def db_joined():
|
||||
|
||||
|
||||
@hooks.hook('shared-db-relation-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def db_changed():
|
||||
if 'shared-db' not in CONFIGS.complete_contexts():
|
||||
log('shared-db relation incomplete. Peer not ready?')
|
||||
return
|
||||
CONFIGS.write('/etc/nova/nova.conf')
|
||||
if quantum_enabled():
|
||||
CONFIGS.write(quantum_plugin_config())
|
||||
plugin = quantum_plugin()
|
||||
CONFIGS.write(quantum_attribute(plugin, 'config'))
|
||||
|
||||
|
||||
@hooks.hook('image-service-relation-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def image_service_changed():
|
||||
if 'image-service' not in CONFIGS.complete_contexts():
|
||||
log('image-service relation incomplete. Peer not ready?')
|
||||
@ -124,7 +126,7 @@ def compute_joined(rid=None):
|
||||
|
||||
|
||||
@hooks.hook('cloud-compute-relation-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def compute_changed():
|
||||
configure_network_service()
|
||||
configure_volume_service()
|
||||
@ -133,7 +135,7 @@ def compute_changed():
|
||||
|
||||
|
||||
@hooks.hook('ceph-relation-joined')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def ceph_joined():
|
||||
if not os.path.isdir('/etc/ceph'):
|
||||
os.mkdir('/etc/ceph')
|
||||
@ -141,7 +143,7 @@ def ceph_joined():
|
||||
|
||||
|
||||
@hooks.hook('ceph-relation-changed')
|
||||
@restart_on_change(RESTART_MAP)
|
||||
@restart_on_change(restart_map())
|
||||
def ceph_changed():
|
||||
if 'ceph' not in CONFIGS.complete_contexts():
|
||||
log('ceph relation incomplete. Peer not ready?')
|
||||
|
@ -1,12 +1,47 @@
|
||||
import copy
|
||||
from charmhelpers.core.hookenv import (
|
||||
config,
|
||||
log,
|
||||
related_units,
|
||||
relation_ids,
|
||||
relation_get,
|
||||
ERROR,
|
||||
)
|
||||
|
||||
PACKAGES = []
|
||||
BASE_PACKAGES = [
|
||||
'nova-compute',
|
||||
'genisoimage', # was missing as a package dependency until raring.
|
||||
]
|
||||
|
||||
RESTART_MAP = {
|
||||
BASE_RESTART_MAP = {
|
||||
'/etc/libvirt/qemu.conf': ['libvirt-bin'],
|
||||
'/etc/default/libvirt-bin': ['libvirt-bin']
|
||||
'/etc/default/libvirt-bin': ['libvirt-bin'],
|
||||
'/etc/nova/nova.conf': ['nova-compute'],
|
||||
'/etc/nova/nova-compute.conf': ['nova-compute'],
|
||||
}
|
||||
|
||||
|
||||
QUANTUM_PLUGINS = {
|
||||
'ovs': {
|
||||
'config': '/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini',
|
||||
'services': ['quantum-plugin-openvswitch-agent'],
|
||||
'packages': ['quantum-plugin-openvswitch-agent',
|
||||
'openvswitch-datapath-dkms'],
|
||||
},
|
||||
'nvp': {
|
||||
'config': '/etc/quantum/plugins/nicira/nvp.ini',
|
||||
'services': [],
|
||||
'packages': ['quantum-plugin-nicira'],
|
||||
}
|
||||
}
|
||||
|
||||
# Maps virt-type config to a compute package(s).
|
||||
VIRT_TYPES = {
|
||||
'kvm': ['nova-compute-kvm'],
|
||||
'qemu': ['nova-compute-qemu'],
|
||||
'xen': ['nova-compute-xen'],
|
||||
'uml': ['nova-compute-uml'],
|
||||
'lxc': ['nova-compute-lxc'],
|
||||
}
|
||||
|
||||
# This is just a label and it must be consistent across
|
||||
@ -14,6 +49,58 @@ RESTART_MAP = {
|
||||
CEPH_SECRET_UUID = '514c9fca-8cbe-11e2-9c52-3bc8c7819472'
|
||||
|
||||
|
||||
def restart_map():
|
||||
'''
|
||||
Constructs a restart map based on charm config settings and relation
|
||||
state.
|
||||
'''
|
||||
_restart_map = copy.copy(BASE_RESTART_MAP)
|
||||
|
||||
net_manager = network_manager()
|
||||
|
||||
if (net_manager in ['FlatManager', 'FlatDHCPManager'] and
|
||||
config('multi-host').lower() == 'yes'):
|
||||
_restart_map['/etc/nova/nova.conf'].extend(
|
||||
['nova-api', 'nova-network']
|
||||
)
|
||||
elif net_manager == 'Quantum':
|
||||
plugin = quantum_plugin()
|
||||
if plugin:
|
||||
conf = quantum_attribute(plugin, 'config')
|
||||
svcs = quantum_attribute(plugin, 'services')
|
||||
_restart_map[conf] = svcs
|
||||
_restart_map['/etc/quantum/quantum.conf'] = svcs
|
||||
return _restart_map
|
||||
|
||||
|
||||
def determine_packages():
|
||||
packages = [] + BASE_PACKAGES
|
||||
|
||||
net_manager = network_manager()
|
||||
if (net_manager in ['FlatManager', 'FlatDHCPManager'] and
|
||||
config('multi-host').lower() == 'yes'):
|
||||
packages.extend(['nova-api', 'nova-network'])
|
||||
elif net_manager == 'Quantum':
|
||||
plugin = quantum_plugin()
|
||||
packages.extend(quantum_attribute(plugin, 'packages'))
|
||||
|
||||
if relation_ids('ceph'):
|
||||
packages.append('ceph-common')
|
||||
|
||||
virt_type = config('virt-type')
|
||||
try:
|
||||
packages.extend(VIRT_TYPES[virt_type])
|
||||
except KeyError:
|
||||
log('Unsupported virt-type configured: %s' % virt_type)
|
||||
|
||||
raise
|
||||
return packages
|
||||
|
||||
|
||||
def register_configs():
|
||||
pass
|
||||
|
||||
|
||||
def migration_enabled():
|
||||
return config('enable-live-migration').lower() == 'true'
|
||||
|
||||
@ -22,8 +109,37 @@ def quantum_enabled():
|
||||
return config('network-manager').lower() == 'quantum'
|
||||
|
||||
|
||||
def quantum_plugin_config():
|
||||
pass
|
||||
def _network_config():
|
||||
'''
|
||||
Obtain all relevant network configuration settings from nova-c-c via
|
||||
cloud-compute interface.
|
||||
'''
|
||||
settings = ['network_manager', 'quantum_plugin']
|
||||
net_config = {}
|
||||
for rid in relation_ids('cloud-compute'):
|
||||
for unit in related_units(rid):
|
||||
for setting in settings:
|
||||
value = relation_get(setting, rid=rid, unit=unit)
|
||||
if value:
|
||||
net_config[setting] = value
|
||||
return net_config
|
||||
|
||||
|
||||
def quantum_plugin():
|
||||
return _network_config().get('quantum_plugin')
|
||||
|
||||
|
||||
def network_manager():
|
||||
return _network_config().get('network_manager')
|
||||
|
||||
|
||||
def quantum_attribute(plugin, attr):
|
||||
try:
|
||||
_plugin = QUANTUM_PLUGINS[plugin]
|
||||
except KeyError:
|
||||
log('Unrecognised plugin for quantum: %s' % plugin, level=ERROR)
|
||||
raise
|
||||
return _plugin[attr]
|
||||
|
||||
|
||||
def public_ssh_key(user='root'):
|
||||
@ -59,10 +175,6 @@ def do_openstack_upgrade():
|
||||
pass
|
||||
|
||||
|
||||
def register_configs():
|
||||
pass
|
||||
|
||||
|
||||
def import_keystone_ca_cert():
|
||||
pass
|
||||
|
||||
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
257
tests/test_nova_compute_relations.py
Normal file
257
tests/test_nova_compute_relations.py
Normal file
@ -0,0 +1,257 @@
|
||||
from mock import call, patch, MagicMock
|
||||
|
||||
from tests.test_utils import CharmTestCase
|
||||
|
||||
import hooks.nova_compute_utils as utils
|
||||
|
||||
_reg = utils.register_configs
|
||||
_map = utils.restart_map
|
||||
|
||||
utils.register_configs = MagicMock()
|
||||
utils.restart_map = MagicMock()
|
||||
|
||||
import hooks.nova_compute_relations as relations
|
||||
|
||||
utils.register_configs = _reg
|
||||
utils.restart_map = _map
|
||||
|
||||
TO_PATCH = [
|
||||
# charmhelpers.core.hookenv
|
||||
'Hooks',
|
||||
'config',
|
||||
'log',
|
||||
'relation_ids',
|
||||
'relation_set',
|
||||
'service_name',
|
||||
'unit_get',
|
||||
# charmhelpers.core.host
|
||||
'apt_install',
|
||||
'apt_update',
|
||||
'restart_on_change',
|
||||
#charmhelpers.contrib.openstack.utils
|
||||
'configure_installation_source',
|
||||
'openstack_upgrade_available',
|
||||
# nova_compute_utils
|
||||
#'PACKAGES',
|
||||
'restart_map',
|
||||
'determine_packages',
|
||||
'import_authorized_keys',
|
||||
'import_keystone_ca_cert',
|
||||
'migration_enabled',
|
||||
'configure_live_migration',
|
||||
'configure_network_service',
|
||||
'configure_volume_service',
|
||||
'do_openstack_upgrade',
|
||||
'quantum_attribute',
|
||||
'quantum_enabled',
|
||||
'quantum_plugin',
|
||||
'public_ssh_key',
|
||||
'register_configs',
|
||||
# misc_utils
|
||||
'ensure_ceph_keyring',
|
||||
]
|
||||
|
||||
|
||||
class NovaComputeRelationsTests(CharmTestCase):
|
||||
def setUp(self):
|
||||
super(NovaComputeRelationsTests, self).setUp(relations,
|
||||
TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
|
||||
def test_install_hook(self):
|
||||
repo = 'cloud:precise-grizzly'
|
||||
self.test_config.set('openstack-origin', repo)
|
||||
self.determine_packages.return_value = ['foo', 'bar']
|
||||
relations.install()
|
||||
self.configure_installation_source.assert_called_with(repo)
|
||||
self.assertTrue(self.apt_update.called)
|
||||
self.apt_install.assert_called_with(['foo', 'bar'], fatal=True)
|
||||
|
||||
def test_config_changed_with_upgrade(self):
|
||||
self.openstack_upgrade_available.return_value = True
|
||||
relations.config_changed()
|
||||
self.assertTrue(self.do_openstack_upgrade.called)
|
||||
|
||||
@patch.object(relations, 'compute_joined')
|
||||
def test_config_changed_with_migration(self, compute_joined):
|
||||
self.migration_enabled.return_value = True
|
||||
self.test_config.set('migration-auth-type', 'ssh')
|
||||
self.relation_ids.return_value = [
|
||||
'cloud-compute:0',
|
||||
'cloud-compute:1'
|
||||
]
|
||||
relations.config_changed()
|
||||
ex = [
|
||||
call('cloud-compute:0'),
|
||||
call('cloud-compute:1'),
|
||||
]
|
||||
self.assertEquals(ex, compute_joined.call_args_list)
|
||||
|
||||
@patch.object(relations, 'compute_joined')
|
||||
def test_config_changed_no_upgrade_no_migration(self, compute_joined):
|
||||
self.openstack_upgrade_available.return_value = False
|
||||
self.migration_enabled.return_value = False
|
||||
relations.config_changed()
|
||||
self.assertFalse(self.do_openstack_upgrade.called)
|
||||
self.assertTrue(self.configure_live_migration)
|
||||
self.assertFalse(compute_joined.called)
|
||||
|
||||
def test_amqp_joined(self):
|
||||
relations.amqp_joined()
|
||||
self.relation_set.assert_called_with(username='nova', vhost='nova')
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_amqp_changed_missing_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = []
|
||||
relations.amqp_changed()
|
||||
self.log.assert_called_with(
|
||||
'amqp relation incomplete. Peer not ready?'
|
||||
)
|
||||
|
||||
def _amqp_test(self, configs, quantum=False):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['amqp']
|
||||
configs.write = MagicMock()
|
||||
self.quantum_enabled.return_value = quantum
|
||||
relations.amqp_changed()
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_amqp_changed_with_data_no_quantum(self, configs):
|
||||
self._amqp_test(configs, quantum=False)
|
||||
self.assertEquals([call('/etc/nova/nova.conf')],
|
||||
configs.write.call_args_list)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_amqp_changed_with_data_and_quantum(self, configs):
|
||||
self._amqp_test(configs, quantum=True)
|
||||
self.assertEquals([call('/etc/nova/nova.conf'),
|
||||
call('/etc/quantum/quantum.conf')],
|
||||
configs.write.call_args_list)
|
||||
|
||||
def test_db_joined(self):
|
||||
self.unit_get.return_value = 'nova.foohost.com'
|
||||
relations.db_joined()
|
||||
self.relation_set.assert_called_with(database='nova', username='nova',
|
||||
hostname='nova.foohost.com')
|
||||
self.unit_get.assert_called_with('private-address')
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_db_changed_missing_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = []
|
||||
relations.db_changed()
|
||||
self.log.assert_called_with(
|
||||
'shared-db relation incomplete. Peer not ready?'
|
||||
)
|
||||
|
||||
def _shared_db_test(self, configs, quantum=False):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['shared-db']
|
||||
configs.write = MagicMock()
|
||||
self.quantum_enabled.return_value = quantum
|
||||
relations.db_changed()
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_db_changed_with_data_no_quantum(self, configs):
|
||||
self._shared_db_test(configs, quantum=False)
|
||||
self.assertEquals([call('/etc/nova/nova.conf')],
|
||||
configs.write.call_args_list)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_db_changed_with_data_and_quantum(self, configs):
|
||||
self.quantum_attribute.return_value = '/etc/quantum/plugin.conf'
|
||||
self._shared_db_test(configs, quantum=True)
|
||||
ex = [call('/etc/nova/nova.conf'), call('/etc/quantum/plugin.conf')]
|
||||
self.assertEquals(ex, configs.write.call_args_list)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_image_service_missing_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = []
|
||||
relations.image_service_changed()
|
||||
self.log.assert_called_with(
|
||||
'image-service relation incomplete. Peer not ready?'
|
||||
)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_image_service_with_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.write = MagicMock()
|
||||
configs.complete_contexts.return_value = ['image-service']
|
||||
relations.image_service_changed()
|
||||
configs.write.assert_called_with('/etc/nova/nova.conf')
|
||||
|
||||
def test_compute_joined_no_migration(self):
|
||||
self.migration_enabled.return_value = False
|
||||
relations.compute_joined()
|
||||
self.assertFalse(self.relation_set.called)
|
||||
|
||||
def test_compute_joined_with_ssh_migration(self):
|
||||
self.migration_enabled.return_value = True
|
||||
self.test_config.set('migration-auth-type', 'ssh')
|
||||
self.public_ssh_key.return_value = 'foo'
|
||||
relations.compute_joined()
|
||||
self.relation_set.assert_called_with(
|
||||
relation_id=None,
|
||||
ssh_public_key='foo',
|
||||
migration_auth_type='ssh'
|
||||
)
|
||||
relations.compute_joined(rid='cloud-compute:2')
|
||||
self.relation_set.assert_called_with(
|
||||
relation_id='cloud-compute:2',
|
||||
ssh_public_key='foo',
|
||||
migration_auth_type='ssh'
|
||||
)
|
||||
|
||||
def test_compute_changed(self):
|
||||
relations.compute_changed()
|
||||
expected_funcs = [
|
||||
self.configure_network_service,
|
||||
self.configure_volume_service,
|
||||
self.import_authorized_keys,
|
||||
self.import_keystone_ca_cert,
|
||||
]
|
||||
for func in expected_funcs:
|
||||
self.assertTrue(func.called)
|
||||
|
||||
@patch('os.mkdir')
|
||||
@patch('os.path.isdir')
|
||||
def test_ceph_joined(self, isdir, mkdir):
|
||||
isdir.return_value = False
|
||||
relations.ceph_joined()
|
||||
mkdir.assert_called_with('/etc/ceph')
|
||||
self.apt_install.assert_called_with('ceph-common')
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_ceph_changed_missing_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = []
|
||||
relations.ceph_changed()
|
||||
self.log.assert_called_with(
|
||||
'ceph relation incomplete. Peer not ready?'
|
||||
)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_ceph_changed_no_keyring(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['ceph']
|
||||
self.ensure_ceph_keyring.return_value = False
|
||||
relations.ceph_changed()
|
||||
self.log.assert_called_with(
|
||||
'Could not create ceph keyring: peer not ready?'
|
||||
)
|
||||
|
||||
@patch.object(relations, 'CONFIGS')
|
||||
def test_ceph_changed_with_key_and_relation_data(self, configs):
|
||||
configs.complete_contexts = MagicMock()
|
||||
configs.complete_contexts.return_value = ['ceph']
|
||||
configs.write = MagicMock()
|
||||
self.ensure_ceph_keyring.return_value = True
|
||||
relations.ceph_changed()
|
||||
ex = [
|
||||
call('/etc/ceph/ceph.conf'),
|
||||
call('/etc/ceph/secret.xml'),
|
||||
call('/etc/nova/nova.conf'),
|
||||
]
|
||||
self.assertEquals(ex, configs.write.call_args_list)
|
105
tests/test_nova_compute_utils.py
Normal file
105
tests/test_nova_compute_utils.py
Normal file
@ -0,0 +1,105 @@
|
||||
from mock import patch
|
||||
|
||||
from tests.test_utils import CharmTestCase
|
||||
|
||||
|
||||
import hooks.nova_compute_utils as utils
|
||||
|
||||
TO_PATCH = [
|
||||
'config',
|
||||
'log',
|
||||
'related_units',
|
||||
'relation_ids',
|
||||
'relation_get',
|
||||
]
|
||||
|
||||
|
||||
class NovaComputeUtilsTests(CharmTestCase):
|
||||
def setUp(self):
|
||||
super(NovaComputeUtilsTests, self).setUp(utils, TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_determine_packages_nova_network(self, net_man):
|
||||
net_man.return_value = 'FlatDHCPManager'
|
||||
self.relation_ids.return_value = []
|
||||
result = utils.determine_packages()
|
||||
ex = utils.BASE_PACKAGES + [
|
||||
'nova-api',
|
||||
'nova-network',
|
||||
'nova-compute-kvm'
|
||||
]
|
||||
self.assertEquals(ex, result)
|
||||
|
||||
@patch.object(utils, 'quantum_plugin')
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_determine_packages_quantum(self, net_man, q_plugin):
|
||||
net_man.return_value = 'Quantum'
|
||||
q_plugin.return_value = 'ovs'
|
||||
self.relation_ids.return_value = []
|
||||
result = utils.determine_packages()
|
||||
ex = utils.BASE_PACKAGES + [
|
||||
'quantum-plugin-openvswitch-agent',
|
||||
'openvswitch-datapath-dkms',
|
||||
'nova-compute-kvm'
|
||||
]
|
||||
self.assertEquals(ex, result)
|
||||
|
||||
@patch.object(utils, 'quantum_plugin')
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_determine_packages_quantum_ceph(self, net_man, q_plugin):
|
||||
net_man.return_value = 'Quantum'
|
||||
q_plugin.return_value = 'ovs'
|
||||
self.relation_ids.return_value = ['ceph:0']
|
||||
result = utils.determine_packages()
|
||||
ex = utils.BASE_PACKAGES + [
|
||||
'quantum-plugin-openvswitch-agent',
|
||||
'openvswitch-datapath-dkms',
|
||||
'ceph-common',
|
||||
'nova-compute-kvm'
|
||||
]
|
||||
self.assertEquals(ex, result)
|
||||
|
||||
# NOTE: These tests faill if run together, something is holding
|
||||
# a reference to BASE_RESOURCE_MAP ?
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_resource_map_nova_network_no_multihost(self, net_man):
|
||||
self.test_config.set('multi-host', 'no')
|
||||
net_man.return_value = 'FlatDHCPManager'
|
||||
result = utils.restart_map()
|
||||
ex = {
|
||||
'/etc/default/libvirt-bin': ['libvirt-bin'],
|
||||
'/etc/libvirt/qemu.conf': ['libvirt-bin'],
|
||||
'/etc/nova/nova-compute.conf': ['nova-compute'],
|
||||
'/etc/nova/nova.conf': ['nova-compute']
|
||||
}
|
||||
self.assertEquals(ex, result)
|
||||
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_resource_map_nova_network(self, net_man):
|
||||
net_man.return_value = 'FlatDHCPManager'
|
||||
result = utils.restart_map()
|
||||
ex = {
|
||||
'/etc/default/libvirt-bin': ['libvirt-bin'],
|
||||
'/etc/libvirt/qemu.conf': ['libvirt-bin'],
|
||||
'/etc/nova/nova-compute.conf': ['nova-compute'],
|
||||
'/etc/nova/nova.conf': ['nova-compute', 'nova-api', 'nova-network']
|
||||
}
|
||||
self.assertEquals(ex, result)
|
||||
|
||||
@patch.object(utils, 'quantum_plugin')
|
||||
@patch.object(utils, 'network_manager')
|
||||
def test_resource_map_quantum_ovs(self, net_man, _plugin):
|
||||
net_man.return_value = 'Quantum'
|
||||
_plugin.return_value = 'ovs'
|
||||
result = utils.restart_map()
|
||||
ex = {
|
||||
'/etc/default/libvirt-bin': ['libvirt-bin'],
|
||||
'/etc/libvirt/qemu.conf': ['libvirt-bin'],
|
||||
'/etc/nova/nova-compute.conf': ['nova-compute'],
|
||||
'/etc/nova/nova.conf': ['nova-compute'],
|
||||
'/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini':
|
||||
['quantum-plugin-openvswitch-agent'],
|
||||
'/etc/quantum/quantum.conf': ['quantum-plugin-openvswitch-agent']
|
||||
}
|
||||
self.assertEquals(ex, result)
|
101
tests/test_utils.py
Normal file
101
tests/test_utils.py
Normal file
@ -0,0 +1,101 @@
|
||||
import logging
|
||||
import unittest
|
||||
import os
|
||||
import yaml
|
||||
|
||||
from mock import patch
|
||||
|
||||
|
||||
def load_config():
|
||||
'''
|
||||
Walk backwords from __file__ looking for config.yaml, load and return the
|
||||
'options' section'
|
||||
'''
|
||||
config = None
|
||||
f = __file__
|
||||
while config is None:
|
||||
d = os.path.dirname(f)
|
||||
if os.path.isfile(os.path.join(d, 'config.yaml')):
|
||||
config = os.path.join(d, 'config.yaml')
|
||||
break
|
||||
f = d
|
||||
|
||||
if not config:
|
||||
logging.error('Could not find config.yaml in any parent directory '
|
||||
'of %s. ' % file)
|
||||
raise Exception
|
||||
|
||||
return yaml.safe_load(open(config).read())['options']
|
||||
|
||||
|
||||
def get_default_config():
|
||||
'''
|
||||
Load default charm config from config.yaml return as a dict.
|
||||
If no default is set in config.yaml, its value is None.
|
||||
'''
|
||||
default_config = {}
|
||||
config = load_config()
|
||||
for k, v in config.iteritems():
|
||||
if 'default' in v:
|
||||
default_config[k] = v['default']
|
||||
else:
|
||||
default_config[k] = None
|
||||
return default_config
|
||||
|
||||
|
||||
class CharmTestCase(unittest.TestCase):
|
||||
def setUp(self, obj, patches):
|
||||
super(CharmTestCase, self).setUp()
|
||||
self.patches = patches
|
||||
self.obj = obj
|
||||
self.test_config = TestConfig()
|
||||
self.test_relation = TestRelation()
|
||||
self.patch_all()
|
||||
|
||||
def patch(self, method):
|
||||
_m = patch.object(self.obj, method)
|
||||
mock = _m.start()
|
||||
self.addCleanup(_m.stop)
|
||||
return mock
|
||||
|
||||
def patch_all(self):
|
||||
for method in self.patches:
|
||||
setattr(self, method, self.patch(method))
|
||||
|
||||
|
||||
class TestConfig(object):
|
||||
def __init__(self):
|
||||
self.config = get_default_config()
|
||||
|
||||
def get(self, attr=None):
|
||||
if not attr:
|
||||
return self.get_all()
|
||||
try:
|
||||
return self.config[attr]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def get_all(self):
|
||||
return self.config
|
||||
|
||||
def set(self, attr, value):
|
||||
if attr not in self.config:
|
||||
raise KeyError
|
||||
self.config[attr] = value
|
||||
|
||||
|
||||
class TestRelation(object):
|
||||
def __init__(self, relation_data={}):
|
||||
self.relation_data = relation_data
|
||||
|
||||
def set(self, relation_data):
|
||||
self.relation_data = relation_data
|
||||
|
||||
def get(self, attr=None, unit=None, rid=None):
|
||||
if attr == None:
|
||||
return self.relation_data
|
||||
elif attr in self.relation_data:
|
||||
return self.relation_data[attr]
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user