Ceilometer switched to using wsgi_script to generate the ceilometer-api binary; this resulted in a few packaging changes, including one which means the listen port for Ceilometer API is set via the systemd unit, rather than the ceilometer.conf configuration file. Add systemd override file handling for ceilometer-api, including a small workaround which ensures that the systemd daemon loads the override configuration file when it changes (only possible during config-changed with enabling SSL support). This charm should switch to using Apache + mod_wsgi next cycle, at which point all of that can just be dropped. Change-Id: Ic8b359d0b91fda144925f5c75044f919e73aadd9 Closes-Bug: 1629796
230 lines
9.1 KiB
Python
230 lines
9.1 KiB
Python
# Copyright 2016 Canonical Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from mock import patch, call, MagicMock
|
|
|
|
import ceilometer_utils as utils
|
|
|
|
from test_utils import CharmTestCase
|
|
|
|
TO_PATCH = [
|
|
'get_os_codename_package',
|
|
'get_os_codename_install_source',
|
|
'configure_installation_source',
|
|
'templating',
|
|
'LoggingConfigContext',
|
|
'MongoDBContext',
|
|
'CeilometerContext',
|
|
'config',
|
|
'log',
|
|
'apt_install',
|
|
'apt_update',
|
|
'apt_upgrade',
|
|
'os_application_version_set',
|
|
'init_is_systemd',
|
|
'os',
|
|
]
|
|
|
|
|
|
class CeilometerUtilsTest(CharmTestCase):
|
|
|
|
def setUp(self):
|
|
super(CeilometerUtilsTest, self).setUp(utils, TO_PATCH)
|
|
self.config.side_effect = self.test_config.get
|
|
|
|
def tearDown(self):
|
|
super(CeilometerUtilsTest, self).tearDown()
|
|
|
|
def test_register_configs(self):
|
|
self.os.path.exists.return_value = True
|
|
self.init_is_systemd.return_value = False
|
|
configs = utils.register_configs()
|
|
calls = []
|
|
for conf in (utils.CEILOMETER_CONF, utils.HAPROXY_CONF,
|
|
utils.HTTPS_APACHE_24_CONF):
|
|
calls.append(call(conf,
|
|
utils.CONFIG_FILES[conf]['hook_contexts']))
|
|
configs.register.assert_has_calls(calls, any_order=True)
|
|
|
|
def test_register_configs_apache22(self):
|
|
self.os.path.exists.return_value = False
|
|
self.init_is_systemd.return_value = False
|
|
configs = utils.register_configs()
|
|
calls = []
|
|
for conf in (utils.CEILOMETER_CONF, utils.HAPROXY_CONF,
|
|
utils.HTTPS_APACHE_CONF):
|
|
calls.append(call(conf,
|
|
utils.CONFIG_FILES[conf]['hook_contexts']))
|
|
configs.register.assert_has_calls(calls, any_order=True)
|
|
|
|
def test_register_configs_systemd(self):
|
|
self.os.path.exists.return_value = True
|
|
self.init_is_systemd.return_value = True
|
|
configs = utils.register_configs()
|
|
calls = []
|
|
for conf in (utils.CEILOMETER_CONF, utils.HAPROXY_CONF,
|
|
utils.HTTPS_APACHE_24_CONF):
|
|
calls.append(call(conf,
|
|
utils.CONFIG_FILES[conf]['hook_contexts']))
|
|
configs.register.assert_has_calls(calls, any_order=True)
|
|
|
|
def test_ceilometer_release_services(self):
|
|
"""Ensure that icehouse specific services are identified"""
|
|
self.get_os_codename_install_source.return_value = 'icehouse'
|
|
self.assertEqual(['ceilometer-alarm-notifier',
|
|
'ceilometer-alarm-evaluator',
|
|
'ceilometer-agent-notification'],
|
|
utils.ceilometer_release_services())
|
|
|
|
def test_ceilometer_release_services_mitaka(self):
|
|
"""Ensure that mitaka specific services are identified"""
|
|
self.get_os_codename_install_source.return_value = 'mitaka'
|
|
self.assertEqual(['ceilometer-agent-notification'],
|
|
utils.ceilometer_release_services())
|
|
|
|
def test_restart_map(self):
|
|
"""Ensure that alarming services are present for < OpenStack Mitaka"""
|
|
self.get_os_codename_install_source.return_value = 'icehouse'
|
|
restart_map = utils.restart_map()
|
|
self.assertEquals(
|
|
restart_map,
|
|
{'/etc/ceilometer/ceilometer.conf': [
|
|
'ceilometer-agent-central',
|
|
'ceilometer-collector',
|
|
'ceilometer-api',
|
|
'ceilometer-alarm-notifier',
|
|
'ceilometer-alarm-evaluator',
|
|
'ceilometer-agent-notification'],
|
|
'/etc/systemd/system/ceilometer-api.service.d/override.conf': [
|
|
'ceilometer-api'],
|
|
'/etc/haproxy/haproxy.cfg': ['haproxy'],
|
|
"/etc/apache2/sites-available/openstack_https_frontend": [
|
|
'apache2'],
|
|
"/etc/apache2/sites-available/openstack_https_frontend.conf": [
|
|
'apache2']
|
|
}
|
|
)
|
|
|
|
def test_restart_map_mitaka(self):
|
|
"""Ensure that alarming services are missing for OpenStack Mitaka"""
|
|
self.get_os_codename_install_source.return_value = 'mitaka'
|
|
restart_map = utils.restart_map()
|
|
self.assertEquals(
|
|
restart_map,
|
|
{'/etc/ceilometer/ceilometer.conf': [
|
|
'ceilometer-agent-central',
|
|
'ceilometer-collector',
|
|
'ceilometer-api',
|
|
'ceilometer-agent-notification'],
|
|
'/etc/systemd/system/ceilometer-api.service.d/override.conf': [
|
|
'ceilometer-api'],
|
|
'/etc/haproxy/haproxy.cfg': ['haproxy'],
|
|
"/etc/apache2/sites-available/openstack_https_frontend": [
|
|
'apache2'],
|
|
"/etc/apache2/sites-available/openstack_https_frontend.conf": [
|
|
'apache2']
|
|
}
|
|
)
|
|
|
|
def test_get_ceilometer_conf(self):
|
|
class TestContext():
|
|
|
|
def __call__(self):
|
|
return {'data': 'test'}
|
|
with patch.dict(utils.CONFIG_FILES,
|
|
{'/etc/ceilometer/ceilometer.conf': {
|
|
'hook_contexts': [TestContext()]
|
|
}}):
|
|
self.assertTrue(utils.get_ceilometer_context(),
|
|
{'data': 'test'})
|
|
|
|
def test_do_openstack_upgrade(self):
|
|
self.config.side_effect = self.test_config.get
|
|
self.test_config.set('openstack-origin', 'cloud:trusty-kilo')
|
|
self.get_os_codename_install_source.return_value = 'kilo'
|
|
configs = MagicMock()
|
|
utils.do_openstack_upgrade(configs)
|
|
configs.set_release.assert_called_with(openstack_release='kilo')
|
|
self.assertTrue(self.log.called)
|
|
self.apt_update.assert_called_with(fatal=True)
|
|
dpkg_opts = [
|
|
'--option', 'Dpkg::Options::=--force-confnew',
|
|
'--option', 'Dpkg::Options::=--force-confdef',
|
|
]
|
|
self.apt_install.assert_called_with(
|
|
packages=utils.CEILOMETER_BASE_PACKAGES + utils.ICEHOUSE_PACKAGES,
|
|
options=dpkg_opts, fatal=True
|
|
)
|
|
self.configure_installation_source.assert_called_with(
|
|
'cloud:trusty-kilo'
|
|
)
|
|
|
|
def test_get_packages_icehouse(self):
|
|
self.get_os_codename_install_source.return_value = 'icehouse'
|
|
self.assertEqual(utils.get_packages(),
|
|
utils.CEILOMETER_BASE_PACKAGES +
|
|
utils.ICEHOUSE_PACKAGES)
|
|
|
|
def test_get_packages_mitaka(self):
|
|
self.get_os_codename_install_source.return_value = 'mitaka'
|
|
self.assertEqual(utils.get_packages(),
|
|
utils.CEILOMETER_BASE_PACKAGES +
|
|
utils.MITAKA_PACKAGES)
|
|
|
|
def test_assess_status(self):
|
|
with patch.object(utils, 'assess_status_func') as asf:
|
|
callee = MagicMock()
|
|
asf.return_value = callee
|
|
utils.assess_status('test-config')
|
|
asf.assert_called_once_with('test-config')
|
|
callee.assert_called_once_with()
|
|
self.os_application_version_set.assert_called_with(
|
|
utils.VERSION_PACKAGE
|
|
)
|
|
|
|
@patch.object(utils, 'REQUIRED_INTERFACES')
|
|
@patch.object(utils, 'services')
|
|
@patch.object(utils, 'determine_ports')
|
|
@patch.object(utils, 'make_assess_status_func')
|
|
def test_assess_status_func(self,
|
|
make_assess_status_func,
|
|
determine_ports,
|
|
services,
|
|
REQUIRED_INTERFACES):
|
|
services.return_value = 's1'
|
|
determine_ports.return_value = 'p1'
|
|
utils.assess_status_func('test-config')
|
|
make_assess_status_func.assert_called_once_with(
|
|
'test-config', REQUIRED_INTERFACES, services='s1', ports='p1')
|
|
|
|
def test_pause_unit_helper(self):
|
|
with patch.object(utils, '_pause_resume_helper') as prh:
|
|
utils.pause_unit_helper('random-config')
|
|
prh.assert_called_once_with(utils.pause_unit, 'random-config')
|
|
with patch.object(utils, '_pause_resume_helper') as prh:
|
|
utils.resume_unit_helper('random-config')
|
|
prh.assert_called_once_with(utils.resume_unit, 'random-config')
|
|
|
|
@patch.object(utils, 'services')
|
|
@patch.object(utils, 'determine_ports')
|
|
def test_pause_resume_helper(self, determine_ports, services):
|
|
f = MagicMock()
|
|
services.return_value = 's1'
|
|
determine_ports.return_value = 'p1'
|
|
with patch.object(utils, 'assess_status_func') as asf:
|
|
asf.return_value = 'assessor'
|
|
utils._pause_resume_helper(f, 'some-config')
|
|
asf.assert_called_once_with('some-config')
|
|
f.assert_called_once_with('assessor', services='s1', ports='p1')
|