add amulet tests

This commit is contained in:
Ryan Beisner 2015-06-26 17:41:54 +00:00
parent 4e004cfc16
commit 51cf8d9074
17 changed files with 745 additions and 6 deletions

View File

@ -2,16 +2,27 @@
PYTHON := /usr/bin/env python
lint:
@flake8 --exclude hooks/charmhelpers hooks
@flake8 --exclude hooks/charmhelpers,tests/charmhelpers \
hooks tests unit_tests
@charm proof
test:
@# Bundletester expects unit tests here.
@$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests
functional_test:
@echo Starting Amulet tests...
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
bin/charm_helpers_sync.py:
@mkdir -p bin
@bzr cat lp:charm-helpers/tools/charm_helpers_sync/charm_helpers_sync.py \
> bin/charm_helpers_sync.py
sync: bin/charm_helpers_sync.py
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers.yaml
# @$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-tests.yaml
unit_test:
@$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests
publish: lint
@bzr push lp:charms/ceilometer-agent
@bzr push lp:charms/trusty/ceilometer-agent

6
charm-helpers-tests.yaml Normal file
View File

@ -0,0 +1,6 @@
#branch: lp:charm-helpers
branch: lp:~1chb1n/charm-helpers/amulet-ceph-cinder-updates/
destination: tests/charmhelpers
include:
- contrib.amulet
- contrib.openstack.amulet

View File

@ -11,7 +11,7 @@ description: |
.
This charm should be used in conjunction with the ceilometer and nova charm to collect
Openstack measures.
categories:
tags:
- miscellaneous
- openstack
provides:

10
tests/00-setup Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
set -ex
sudo add-apt-repository --yes ppa:juju/stable
sudo apt-get update --yes
sudo apt-get install --yes python-amulet \
python-distro-info \
python-keystoneclient \
python-ceilometerclient

View File

@ -0,0 +1,11 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on precise-icehouse."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='precise',
openstack='cloud:precise-icehouse',
source='cloud:precise-updates/icehouse')
deployment.run_tests()

View File

@ -0,0 +1,9 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on trusty-icehouse."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='trusty')
deployment.run_tests()

11
tests/016-basic-trusty-juno Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on trusty-juno."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='trusty',
openstack='cloud:trusty-juno',
source='cloud:trusty-updates/juno')
deployment.run_tests()

11
tests/017-basic-trusty-kilo Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on trusty-kilo."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='trusty',
openstack='cloud:trusty-kilo',
source='cloud:trusty-updates/kilo')
deployment.run_tests()

9
tests/018-basic-utopic-juno Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on utopic-juno."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='utopic')
deployment.run_tests()

9
tests/019-basic-vivid-kilo Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on vivid-kilo."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='vivid')
deployment.run_tests()

View File

@ -0,0 +1,11 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on trusty-liberty."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='trusty',
openstack='cloud:trusty-liberty',
source='cloud:trusty-updates/liberty')
deployment.run_tests()

View File

@ -0,0 +1,9 @@
#!/usr/bin/python
"""Amulet tests on a basic ceilometer deployment on wily-liberty."""
from basic_deployment import CeiloAgentBasicDeployment
if __name__ == '__main__':
deployment = CeiloAgentBasicDeployment(series='wily')
deployment.run_tests()

62
tests/README Normal file
View File

@ -0,0 +1,62 @@
This directory provides Amulet tests that focus on verification of
ceilometer-agent deployments.
test_* methods are called in lexical sort order.
Test name convention to ensure desired test order:
1xx service and endpoint checks
2xx relation checks
3xx config checks
4xx functional checks
9xx restarts and other final checks
In order to run tests, you'll need charm-tools installed (in addition to
juju, of course):
sudo add-apt-repository ppa:juju/stable
sudo apt-get update
sudo apt-get install charm-tools
If you use a web proxy server to access the web, you'll need to set the
AMULET_HTTP_PROXY environment variable to the http URL of the proxy server.
The following examples demonstrate different ways that tests can be executed.
All examples are run from the charm's root directory.
* To run all tests (starting with 00-setup):
make test
* To run a specific test module (or modules):
juju test -v -p AMULET_HTTP_PROXY 15-basic-trusty-icehouse
* To run a specific test module (or modules), and keep the environment
deployed after a failure:
juju test --set-e -v -p AMULET_HTTP_PROXY 15-basic-trusty-icehouse
* To re-run a test module against an already deployed environment (one
that was deployed by a previous call to 'juju test --set-e'):
./tests/15-basic-trusty-icehouse
For debugging and test development purposes, all code should be idempotent.
In other words, the code should have the ability to be re-run without changing
the results beyond the initial run. This enables editing and re-running of a
test module against an already deployed environment, as described above.
Manual debugging tips:
* Set the following env vars before using the OpenStack CLI as admin:
export OS_AUTH_URL=http://`juju-deployer -f keystone 2>&1 | tail -n 1`:5000/v2.0
export OS_TENANT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_REGION_NAME=RegionOne
* Set the following env vars before using the OpenStack CLI as demoUser:
export OS_AUTH_URL=http://`juju-deployer -f keystone 2>&1 | tail -n 1`:5000/v2.0
export OS_TENANT_NAME=demoTenant
export OS_USERNAME=demoUser
export OS_PASSWORD=password
export OS_REGION_NAME=RegionOne

556
tests/basic_deployment.py Normal file
View File

@ -0,0 +1,556 @@
#!/usr/bin/python
import amulet
import time
from ceilometerclient.v2 import client as ceilclient
from charmhelpers.contrib.openstack.amulet.deployment import (
OpenStackAmuletDeployment
)
from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils,
DEBUG,
#ERROR
)
# Use DEBUG to turn on debug logging
u = OpenStackAmuletUtils(DEBUG)
class CeiloAgentBasicDeployment(OpenStackAmuletDeployment):
"""Amulet tests on a basic ceilometer-agent deployment."""
def __init__(self, series, openstack=None, source=None, stable=False):
"""Deploy the entire test environment."""
super(CeiloAgentBasicDeployment, self).__init__(series, openstack,
source, stable)
self._add_services()
self._add_relations()
self._configure_services()
self._deploy()
self._initialize_tests()
def _add_services(self):
"""Add services
Add the services that we're testing, where ceilometer is local,
and the rest of the service are from lp branches that are
compatible with the local charm (e.g. stable or next).
"""
# Note: ceilometer-agent becomes a subordinate of nova-compute
this_service = {'name': 'ceilometer-agent'}
other_services = [{'name': 'mysql'},
{'name': 'rabbitmq-server'},
{'name': 'keystone'},
{'name': 'mongodb'},
{'name': 'ceilometer'},
{'name': 'nova-compute'}]
super(CeiloAgentBasicDeployment, self)._add_services(this_service,
other_services)
def _add_relations(self):
"""Add all of the relations for the services."""
relations = {
'ceilometer:shared-db': 'mongodb:database',
'ceilometer:amqp': 'rabbitmq-server:amqp',
'ceilometer:identity-service': 'keystone:identity-service',
'ceilometer:identity-notifications': 'keystone:'
'identity-notifications',
'keystone:shared-db': 'mysql:shared-db',
'ceilometer:ceilometer-service': 'ceilometer-agent:'
'ceilometer-service',
'nova-compute:nova-ceilometer': 'ceilometer-agent:nova-ceilometer',
'nova-compute:shared-db': 'mysql:shared-db',
'nova-compute:amqp': 'rabbitmq-server:amqp'
}
super(CeiloAgentBasicDeployment, self)._add_relations(relations)
def _configure_services(self):
"""Configure all of the services."""
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
configs = {'keystone': keystone_config}
super(CeiloAgentBasicDeployment, self)._configure_services(configs)
def _get_token(self):
return self.keystone.service_catalog.catalog['token']['id']
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
self.ceil_agent_sentry = self.d.sentry.unit['ceilometer-agent/0']
self.ceil_sentry = self.d.sentry.unit['ceilometer/0']
self.mysql_sentry = self.d.sentry.unit['mysql/0']
self.keystone_sentry = self.d.sentry.unit['keystone/0']
self.rabbitmq_sentry = self.d.sentry.unit['rabbitmq-server/0']
self.mongodb_sentry = self.d.sentry.unit['mongodb/0']
self.nova_sentry = self.d.sentry.unit['nova-compute/0']
u.log.debug('openstack release val: {}'.format(
self._get_openstack_release()))
u.log.debug('openstack release str: {}'.format(
self._get_openstack_release_string()))
# Let things settle a bit before moving forward
time.sleep(30)
# Authenticate admin with keystone endpoint
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
user='admin',
password='openstack',
tenant='admin')
# Authenticate admin with ceilometer endpoint
ep = self.keystone.service_catalog.url_for(service_type='metering',
endpoint_type='publicURL')
self.ceil = ceilclient.Client(endpoint=ep, token=self._get_token)
def test_100_services(self):
"""Verify the expected services are running on the corresponding
service units."""
ceilometer_svcs = [
'ceilometer-collector',
'ceilometer-api',
'ceilometer-alarm-evaluator',
'ceilometer-alarm-notifier',
'ceilometer-agent-notification',
]
service_names = {
self.ceil_sentry: ceilometer_svcs,
self.mysql_sentry: ['mysql'],
self.keystone_sentry: ['keystone'],
self.rabbitmq_sentry: ['rabbitmq-server'],
self.mongodb_sentry: ['mongodb'],
}
ret = u.validate_services_by_name(service_names)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
def test_110_service_catalog(self):
"""Verify that the service catalog endpoint data is valid."""
endpoint_check = {
'adminURL': u.valid_url,
'id': u.not_null,
'region': 'RegionOne',
'publicURL': u.valid_url,
'internalURL': u.valid_url
}
expected = {
'metering': [endpoint_check],
'identity': [endpoint_check]
}
actual = self.keystone.service_catalog.get_endpoints()
ret = u.validate_svc_catalog_endpoint_data(expected, actual)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
def test_112_keystone_api_endpoint(self):
"""Verify the ceilometer api endpoint data."""
endpoints = self.keystone.endpoints.list()
u.log.debug(endpoints)
internal_port = public_port = '5000'
admin_port = '35357'
expected = {'id': u.not_null,
'region': 'RegionOne',
'adminurl': u.valid_url,
'internalurl': u.valid_url,
'publicurl': u.valid_url,
'service_id': u.not_null}
ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
public_port, expected)
if ret:
message = 'Keystone endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_114_ceilometer_api_endpoint(self):
"""Verify the ceilometer api endpoint data."""
endpoints = self.keystone.endpoints.list()
u.log.debug(endpoints)
admin_port = internal_port = public_port = '8777'
expected = {'id': u.not_null,
'region': 'RegionOne',
'adminurl': u.valid_url,
'internalurl': u.valid_url,
'publicurl': u.valid_url,
'service_id': u.not_null}
ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
public_port, expected)
if ret:
message = 'Ceilometer endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_200_ceilometer_identity_relation(self):
"""Verify the ceilometer to keystone identity-service relation data"""
u.log.debug('Checking service catalog endpoint data...')
unit = self.ceil_sentry
relation = ['identity-service', 'keystone:identity-service']
ceil_ip = unit.relation('identity-service',
'keystone:identity-service')['private-address']
ceil_endpoint = "http://%s:8777" % (ceil_ip)
expected = {
'admin_url': ceil_endpoint,
'internal_url': ceil_endpoint,
'private-address': ceil_ip,
'public_url': ceil_endpoint,
'region': 'RegionOne',
'requested_roles': 'ResellerAdmin',
'service': 'ceilometer',
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_201_keystone_ceilometer_identity_relation(self):
"""Verify the keystone to ceilometer identity-service relation data"""
u.log.debug('Checking keystone:ceilometer identity relation data...')
unit = self.keystone_sentry
relation = ['identity-service', 'ceilometer:identity-service']
id_relation = unit.relation('identity-service',
'ceilometer:identity-service')
id_ip = id_relation['private-address']
expected = {
'admin_token': 'ubuntutesting',
'auth_host': id_ip,
'auth_port': "35357",
'auth_protocol': 'http',
'private-address': id_ip,
'service_host': id_ip,
'service_password': u.not_null,
'service_port': "5000",
'service_protocol': 'http',
'service_tenant': 'services',
'service_tenant_id': u.not_null,
'service_username': 'ceilometer',
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('keystone identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_202_keystone_ceilometer_identity_notes_relation(self):
"""Verify ceilometer to keystone identity-notifications relation"""
u.log.debug('Checking keystone:ceilometer '
'identity-notifications relation data...')
unit = self.keystone_sentry
relation = ['identity-service', 'ceilometer:identity-notifications']
expected = {
'ceilometer-endpoint-changed': u.not_null,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('keystone identity-notifications', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_203_ceilometer_amqp_relation(self):
"""Verify the ceilometer to rabbitmq-server amqp relation data"""
u.log.debug('Checking ceilometer:rabbitmq amqp relation data...')
unit = self.ceil_sentry
relation = ['amqp', 'rabbitmq-server:amqp']
expected = {
'username': 'ceilometer',
'private-address': u.valid_ip,
'vhost': 'openstack'
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer amqp', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_204_amqp_ceilometer_relation(self):
"""Verify the rabbitmq-server to ceilometer amqp relation data"""
u.log.debug('Checking rabbitmq:ceilometer amqp relation data...')
unit = self.rabbitmq_sentry
relation = ['amqp', 'ceilometer:amqp']
expected = {
'hostname': u.valid_ip,
'private-address': u.valid_ip,
'password': u.not_null,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('rabbitmq amqp', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_205_ceilometer_to_mongodb_relation(self):
"""Verify the ceilometer to mongodb relation data"""
u.log.debug('Checking ceilometer:mongodb relation data...')
unit = self.ceil_sentry
relation = ['shared-db', 'mongodb:database']
expected = {
'ceilometer_database': 'ceilometer',
'private-address': u.valid_ip,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer shared-db', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_206_mongodb_to_ceilometer_relation(self):
"""Verify the mongodb to ceilometer relation data"""
u.log.debug('Checking mongodb:ceilometer relation data...')
unit = self.mongodb_sentry
relation = ['database', 'ceilometer:shared-db']
expected = {
'hostname': u.valid_ip,
'port': '27017',
'private-address': u.valid_ip,
'type': 'database',
}
if self._get_openstack_release() == self.precise_icehouse:
expected['replset'] = 'myset'
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('mongodb database', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_207_ceilometer_ceilometer_agent_relation(self):
"""Verify the ceilometer to ceilometer-agent relation data"""
u.log.debug('Checking ceilometer:ceilometer-agent relation data...')
unit = self.ceil_sentry
relation = ['ceilometer-service',
'ceilometer-agent:ceilometer-service']
expected = {
'rabbitmq_user': 'ceilometer',
'verbose': 'False',
'rabbitmq_host': u.valid_ip,
'service_ports': "{'ceilometer_api': [8777, 8767]}",
'use_syslog': 'False',
'metering_secret': u.not_null,
'rabbitmq_virtual_host': 'openstack',
'db_port': '27017',
'private-address': u.valid_ip,
'db_name': 'ceilometer',
'db_host': u.valid_ip,
'debug': 'False',
'rabbitmq_password': u.not_null,
'port': '8767'
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_208_ceilometer_agent_ceilometer_relation(self):
"""Verify the ceilometer-agent to ceilometer relation data"""
u.log.debug('Checking ceilometer-agent:ceilometer relation data...')
unit = self.ceil_agent_sentry
relation = ['ceilometer-service', 'ceilometer:ceilometer-service']
expected = {'private-address': u.valid_ip}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_209_nova_compute_ceilometer_agent_relation(self):
"""Verify the nova-compute to ceilometer relation data"""
u.log.debug('Checking nova-compute:ceilometer relation data...')
unit = self.nova_sentry
relation = ['nova-ceilometer', 'ceilometer-agent:nova-ceilometer']
expected = {'private-address': u.valid_ip}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_210_ceilometer_agent_nova_compute_relation(self):
"""Verify the ceilometer to nova-compute relation data"""
u.log.debug('Checking ceilometer:nova-compute relation data...')
unit = self.ceil_agent_sentry
relation = ['nova-ceilometer', 'nova-compute:nova-ceilometer']
sub = ('{"nova": {"/etc/nova/nova.conf": {"sections": {"DEFAULT": '
'[["instance_usage_audit", "True"], '
'["instance_usage_audit_period", "hour"], '
'["notify_on_state_change", "vm_and_task_state"], '
'["notification_driver", "ceilometer.compute.nova_notifier"], '
'["notification_driver", '
'"nova.openstack.common.notifier.rpc_notifier"]]}}}}')
expected = {
'subordinate_configuration': sub,
'private-address': u.valid_ip
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_300_ceilometer_config(self):
"""Verify the data in the ceilometer config file."""
u.log.debug('Checking ceilometer config file data...')
unit = self.ceil_sentry
rmq_rel = self.rabbitmq_sentry.relation('amqp',
'ceilometer:amqp')
ks_rel = self.keystone_sentry.relation('identity-service',
'ceilometer:identity-service')
auth_uri = '%s://%s:%s/' % (ks_rel['service_protocol'],
ks_rel['service_host'],
ks_rel['service_port'])
db_relation = self.mongodb_sentry.relation('database',
'ceilometer:shared-db')
db_conn = 'mongodb://%s:%s/ceilometer' % (db_relation['hostname'],
db_relation['port'])
conf = '/etc/ceilometer/ceilometer.conf'
expected = {
'DEFAULT': {
'verbose': 'False',
'debug': 'False',
'use_syslog': 'False',
'rabbit_userid': 'ceilometer',
'rabbit_virtual_host': 'openstack',
'rabbit_password': rmq_rel['password'],
'rabbit_host': rmq_rel['hostname'],
},
'api': {
'port': '8767',
},
'service_credentials': {
'os_auth_url': auth_uri + 'v2.0',
'os_tenant_name': 'services',
'os_username': 'ceilometer',
'os_password': ks_rel['service_password'],
},
'database': {
'connection': db_conn,
},
'keystone_authtoken': {
'auth_uri': auth_uri,
'auth_host': ks_rel['auth_host'],
'auth_port': ks_rel['auth_port'],
'auth_protocol': ks_rel['auth_protocol'],
'admin_tenant_name': 'services',
'admin_user': 'ceilometer',
'admin_password': ks_rel['service_password'],
},
}
for section, pairs in expected.iteritems():
ret = u.validate_config_data(unit, conf, section, pairs)
if ret:
message = "ceilometer config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_301_nova_config(self):
"""Verify data in the nova compute nova config file"""
unit = self.nova_sentry
conf = '/etc/nova/nova.conf'
mysql_rel = self.mysql_sentry.relation('shared-db',
'nova-compute:shared-db')
db_uri = "mysql://{}:{}@{}/{}".format('nova',
mysql_rel['nova_password'],
mysql_rel['db_host'],
'nova')
expected = {
'DEFAULT': {
'verbose': 'False',
'debug': 'False',
'use_syslog': 'False',
'my_ip': u.valid_ip,
'dhcpbridge_flagfile': '/etc/nova/nova.conf',
'dhcpbridge': '/usr/bin/nova-dhcpbridge',
'logdir': '/var/log/nova',
'state_path': '/var/lib/nova',
'lock_path': '/var/lock/nova',
'api_paste_config': '/etc/nova/api-paste.ini',
'enabled_apis': 'ec2,osapi_compute,metadata',
'auth_strategy': 'keystone',
'compute_driver': 'libvirt.LibvirtDriver',
'sql_connection': db_uri,
'instance_usage_audit': 'True',
'instance_usage_audit_period': 'hour',
'notify_on_state_change': 'vm_and_task_state',
'notification_driver': 'ceilometer.compute.nova_notifier',
'notification_driver': 'nova.openstack.common'
'.notifier.rpc_notifier'
}
}
for section, pairs in expected.iteritems():
ret = u.validate_config_data(unit, conf, section, pairs)
if ret:
message = "ceilometer config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_302_nova_ceilometer_config(self):
"""Verify data in the ceilometer config file on the
nova-compute (ceilometer-agent) unit."""
unit = self.nova_sentry
conf = '/etc/ceilometer/ceilometer.conf'
expected = {
'DEFAULT': {
'logdir': '/var/log/ceilometer'
},
'database': {
'backend': 'sqlalchemy',
'connection': 'sqlite:////var/lib/ceilometer/$sqlite_db'
}
}
for section, pairs in expected.iteritems():
ret = u.validate_config_data(unit, conf, section, pairs)
if ret:
message = "ceilometer config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_400_api_connection(self):
"""Simple api calls to check service is up and responding"""
u.log.debug('Checking api functionality...')
assert(self.ceil.samples.list() == [])
assert(self.ceil.meters.list() == [])
# NOTE(beisner): need to add more functional tests
def test_900_restart_on_config_change(self):
"""Verify that the specified services are restarted when the config
is changed.
"""
sentry = self.ceil_sentry
juju_service = 'ceilometer'
# Expected default and alternate values
set_default = {'debug': 'False'}
set_alternate = {'debug': 'True'}
# Config file affected by juju set config change
conf_file = '/etc/ceilometer/ceilometer.conf'
# Services which are expected to restart upon config change
services = [
'ceilometer-agent-central',
'ceilometer-collector',
'ceilometer-api',
'ceilometer-alarm-evaluator',
'ceilometer-alarm-notifier',
'ceilometer-agent-notification',
]
# Make config change, check for service restarts
u.log.debug('Making config change on {}...'.format(juju_service))
self.d.configure(juju_service, set_alternate)
sleep_time = 40
for s in services:
u.log.debug("Checking that service restarted: {}".format(s))
if not u.service_restarted(sentry, s,
conf_file, sleep_time=sleep_time,
pgrep_full=True):
self.d.configure(juju_service, set_default)
msg = "service {} didn't restart after config change".format(s)
amulet.raise_status(amulet.FAIL, msg=msg)
sleep_time = 0
self.d.configure(juju_service, set_default)

14
tests/tests.yaml Normal file
View File

@ -0,0 +1,14 @@
bootstrap: true
reset: true
virtualenv: true
makefile:
- lint
- test
sources:
- ppa:juju/stable
packages:
- amulet
- python-amulet
- python-distro-info
- python-keystoneclient
- python-ceilometerclient

View File

@ -1,4 +1,4 @@
from mock import patch, call, MagicMock
from mock import call, MagicMock
import ceilometer_utils as utils