Added openstack upgrade, unit tests and lint fixes

This commit is contained in:
Liam Young 2014-06-20 11:02:09 +01:00
parent 651a2f033e
commit 6d3fc4e7a2
7 changed files with 118 additions and 32 deletions

7
.coveragerc Normal file
View File

@ -0,0 +1,7 @@
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
if __name__ == .__main__.:
except UnregisteredHookError as e:
include=
hooks/neutron_*

View File

@ -43,6 +43,7 @@ from neutron_api_utils import (
NEUTRON_CONF,
api_port,
CLUSTER_RES,
do_openstack_upgrade,
)
from charmhelpers.contrib.hahelpers.cluster import (
@ -71,6 +72,8 @@ def install():
@restart_on_change(restart_map(), stopstart=True)
def config_changed():
global CONFIGS
if openstack_upgrade_available('neutron-server'):
do_openstack_upgrade(CONFIGS)
CONFIGS.write_all()
for r_id in relation_ids('neutron-api'):
neutron_api_relation_joined(rid=r_id)

View File

@ -8,12 +8,15 @@ from charmhelpers.contrib.openstack.neutron import (
from charmhelpers.contrib.openstack.utils import (
os_release,
get_os_codename_install_source,
configure_installation_source,
)
from charmhelpers.core.hookenv import (
config,
log,
)
from charmhelpers.fetch import apt_update, apt_install, apt_upgrade
import neutron_api_context
TEMPLATES = 'templates/'
@ -160,3 +163,34 @@ def keystone_ca_cert_b64():
return None
with open(CA_CERT_PATH) as _in:
return b64encode(_in.read())
def do_openstack_upgrade(configs):
"""
Perform an upgrade. Takes care of upgrading packages, rewriting
configs, database migrations and potentially any other post-upgrade
actions.
:param configs: The charms main OSConfigRenderer object.
"""
new_src = config('openstack-origin')
new_os_rel = get_os_codename_install_source(new_src)
log('Performing OpenStack upgrade to %s.' % (new_os_rel))
configure_installation_source(new_src)
dpkg_opts = [
'--option', 'Dpkg::Options::=--force-confnew',
'--option', 'Dpkg::Options::=--force-confdef',
]
apt_update(fatal=True)
apt_upgrade(options=dpkg_opts, fatal=True, dist=True)
pkgs = determine_packages()
# Sort packages just to make unit tests easier
pkgs.sort()
apt_install(packages=pkgs,
options=dpkg_opts,
fatal=True)
# set CONFIGS to load templates from new release
configs.set_release(openstack_release=new_os_rel)

5
setup.cfg Normal file
View File

@ -0,0 +1,5 @@
[nosetests]
verbosity=1
with-coverage=1
cover-erase=1
cover-package=hooks

View File

@ -46,6 +46,7 @@ class IdentityServiceContext(CharmTestCase):
ids_ctxt = context.IdentityServiceContext()
self.assertEquals(ids_ctxt(), None)
class NeutronAPIContextsTest(CharmTestCase):
def setUp(self):

View File

@ -21,7 +21,6 @@ TO_PATCH = [
'api_port',
'apt_update',
'apt_install',
# 'charm_dir',
'canonical_url',
'config',
'CONFIGS',
@ -29,6 +28,7 @@ TO_PATCH = [
'determine_endpoints',
'determine_packages',
'determine_ports',
'do_openstack_upgrade',
'execd_preinstall',
'is_leader',
'is_relation_made',
@ -36,6 +36,7 @@ TO_PATCH = [
'network_manager',
'neutron_plugin_attribute',
'open_port',
'openstack_upgrade_available',
'relation_get',
'relation_ids',
'relation_set',
@ -48,6 +49,7 @@ NEUTRON_CONF = '%s/neutron.conf' % NEUTRON_CONF_DIR
from random import randrange
class NeutronAPIHooksTests(CharmTestCase):
def setUp(self):
@ -57,12 +59,9 @@ class NeutronAPIHooksTests(CharmTestCase):
self.relation_get.side_effect = self.test_relation.get
self.test_config.set('openstack-origin', 'distro')
self.test_config.set('neutron-plugin', 'ovs')
# self.test_config.set('neutron-external-network', 'ext_net')
# self.lsb_release.return_value = {'DISTRIB_CODENAME': 'trusty'}
# self.charm_dir.return_value = '/var/lib/juju/charms/neutron/charm'
def _fake_relids(self, rel_name):
return [ randrange(100) for _count in range(2) ]
return [randrange(100) for _count in range(2)]
def _call_hook(self, hookname):
hooks.hooks.execute([
@ -71,7 +70,7 @@ class NeutronAPIHooksTests(CharmTestCase):
def test_install_hook(self):
_pkgs = ['foo', 'bar']
_ports = [80, 81, 82]
_port_calls = [ call(port) for port in _ports ]
_port_calls = [call(port) for port in _ports]
self.determine_packages.return_value = _pkgs
self.determine_ports.return_value = _ports
self._call_hook('install')
@ -86,9 +85,11 @@ class NeutronAPIHooksTests(CharmTestCase):
self.assertTrue(self.execd_preinstall.called)
def test_config_changed(self):
self.openstack_upgrade_available.return_value = True
self.relation_ids.side_effect = self._fake_relids
_n_api_rel_joined = self.patch('neutron_api_relation_joined')
_n_plugin_api_rel_joined = self.patch('neutron_plugin_api_relation_joined')
_n_plugin_api_rel_joined =\
self.patch('neutron_plugin_api_relation_joined')
_amqp_rel_joined = self.patch('amqp_joined')
_id_rel_joined = self.patch('identity_joined')
self._call_hook('config-changed')
@ -97,6 +98,7 @@ class NeutronAPIHooksTests(CharmTestCase):
self.assertTrue(_amqp_rel_joined.called)
self.assertTrue(_id_rel_joined.called)
self.assertTrue(self.CONFIGS.write_all.called)
self.assertTrue(self.do_openstack_upgrade.called)
def test_amqp_joined(self):
self._call_hook('amqp-relation-joined')
@ -200,7 +202,7 @@ class NeutronAPIHooksTests(CharmTestCase):
self._call_hook('identity-service-relation-changed')
self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))
self.assertTrue(_api_rel_joined.called)
@patch.object(hooks, '_get_keystone_info')
def test_neutron_api_relation_no_id_joined(self, _get_ks_info):
_get_ks_info.return_value = None
@ -239,11 +241,11 @@ class NeutronAPIHooksTests(CharmTestCase):
@patch.object(hooks, '_get_keystone_info')
def test_neutron_api_relation_joined(self, _get_ks_info):
_ks_info = {
'service_tenant': 'bob',
'service_username': 'bob',
'service_password': 'bob',
'auth_url': 'http://127.0.0.2',
}
'service_tenant': 'bob',
'service_username': 'bob',
'service_password': 'bob',
'auth_url': 'http://127.0.0.2',
}
_get_ks_info.return_value = _ks_info
manager = 'neutron'
host = 'http://127.0.0.1'
@ -292,25 +294,29 @@ class NeutronAPIHooksTests(CharmTestCase):
@patch.object(hooks, 'get_hacluster_config')
def test_ha_joined(self, _get_ha_config):
_ha_config = {
'vip': '10.0.0.1',
'vip_cidr': '24',
'vip_iface': 'eth0',
'ha-bindiface': 'eth1',
'ha-mcastport': '5405',
}
'vip': '10.0.0.1',
'vip_cidr': '24',
'vip_iface': 'eth0',
'ha-bindiface': 'eth1',
'ha-mcastport': '5405',
}
vip_params = 'params ip="%s" cidr_netmask="%s" nic="%s"' % \
(_ha_config['vip'], _ha_config['vip_cidr'], _ha_config['vip_iface'])
(_ha_config['vip'], _ha_config['vip_cidr'],
_ha_config['vip_iface'])
_get_ha_config.return_value = _ha_config
_relation_data = {
'init_services': {'res_neutron_haproxy': 'haproxy'},
'corosync_bindiface': _ha_config['ha-bindiface'],
'corosync_mcastport': _ha_config['ha-mcastport'],
'resources': {'res_neutron_vip': 'ocf:heartbeat:IPaddr2',
'res_neutron_haproxy': 'lsb:haproxy'},
'resource_params': { 'res_neutron_vip': vip_params,
'res_neutron_haproxy': 'op monitor interval="5s"'},
'clones': { 'cl_nova_haproxy': 'res_neutron_haproxy' }
'resources': {
'res_neutron_vip': 'ocf:heartbeat:IPaddr2',
'res_neutron_haproxy': 'lsb:haproxy'
},
'resource_params': {
'res_neutron_vip': vip_params,
'res_neutron_haproxy': 'op monitor interval="5s"'
},
'clones': {'cl_nova_haproxy': 'res_neutron_haproxy'}
}
self._call_hook('ha-relation-joined')
self.relation_set.assert_called_with(

View File

@ -1,5 +1,5 @@
from mock import MagicMock, call, patch
from mock import MagicMock, patch
from collections import OrderedDict
import charmhelpers.contrib.openstack.templating as templating
@ -16,11 +16,18 @@ import charmhelpers.core.hookenv as hookenv
TO_PATCH = [
'apt_install',
'apt_update',
'apt_upgrade',
'b64encode',
'config',
'configure_installation_source',
'get_os_codename_install_source',
'log',
'neutron_plugin_attribute',
]
def _mock_npa(plugin, attr, net_manager=None):
plugins = {
'ovs': {
@ -36,9 +43,8 @@ def _mock_npa(plugin, attr, net_manager=None):
}
return plugins[plugin][attr]
class TestNeutronAPIUtils(CharmTestCase):
def setUp(self):
super(TestNeutronAPIUtils, self).setUp(nutils, TO_PATCH)
self.config.side_effect = self.test_config.get
@ -57,7 +63,7 @@ class TestNeutronAPIUtils(CharmTestCase):
test_url = 'http://127.0.0.1'
endpoints = nutils.determine_endpoints(test_url)
neutron_url = '%s:%s' % (test_url,
nutils.api_port('neutron-server'))
nutils.api_port('neutron-server'))
expect = {
'quantum_service': 'quantum',
'quantum_region': 'region101',
@ -125,5 +131,29 @@ class TestNeutronAPIUtils(CharmTestCase):
def test_keystone_ca_cert_b64(self, _isfile):
_isfile.return_value = True
with patch_open() as (_open, _file):
cert = nutils.keystone_ca_cert_b64()
nutils.keystone_ca_cert_b64()
self.assertTrue(self.b64encode.called)
def test_do_openstack_upgrade(self):
self.config.side_effect = self.test_config.get
self.test_config.set('openstack-origin', 'cloud:precise-havana')
self.get_os_codename_install_source.return_value = 'havana'
configs = MagicMock()
nutils.do_openstack_upgrade(configs)
configs.set_release.assert_called_with(openstack_release='havana')
self.log.assert_called()
self.apt_update.assert_called_with(fatal=True)
dpkg_opts = [
'--option', 'Dpkg::Options::=--force-confnew',
'--option', 'Dpkg::Options::=--force-confdef',
]
pkgs = nutils.BASE_PACKAGES
pkgs.sort()
self.apt_install.assert_called_with(
options=dpkg_opts,
packages=pkgs,
fatal=True
)
self.configure_installation_source.assert_called_with(
'cloud:precise-havana'
)