charm-nova-cloud-controller/tests/basic_deployment.py
Corey Bryant 902224c44b Update config templates for Mitaka
Update api-paste.ini to align with the upstream Mitaka version.

Add nova.conf for Mitaka, dropping all EC2 config options as the
EC2 API was dropped from the nova source tree in Mitaka.

Change-Id: I341d0043d2580db2aa7974537321913dac70c3b7
2016-04-08 15:40:59 +00:00

767 lines
31 KiB
Python

import amulet
import os
import yaml
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 NovaCCBasicDeployment(OpenStackAmuletDeployment):
"""Amulet tests on a basic nova cloud controller deployment."""
def __init__(self, series=None, openstack=None, source=None, git=False,
stable=False):
"""Deploy the entire test environment."""
super(NovaCCBasicDeployment, self).__init__(series, openstack,
source, stable)
self.git = git
self._add_services()
self._add_relations()
self._configure_services()
self._deploy()
u.log.info('Waiting on extended status checks...')
exclude_services = ['mysql']
self._auto_wait_for_status(exclude_services=exclude_services)
self._initialize_tests()
def _assert_services(self, should_run):
services = ("nova-api-os-compute", "nova-cert", "nova-conductor",
"nova-scheduler", "apache2", "haproxy")
u.get_unit_process_ids(
{self.nova_cc_sentry: services},
expect_success=should_run)
def _add_services(self):
"""Add services
Add the services that we're testing, where nova-cc is local,
and the rest of the service are from lp branches that are
compatible with the local charm (e.g. stable or next).
"""
this_service = {'name': 'nova-cloud-controller'}
other_services = [{'name': 'mysql'},
{'name': 'rabbitmq-server'},
{'name': 'nova-compute', 'units': 2},
{'name': 'keystone'},
{'name': 'glance'}]
super(NovaCCBasicDeployment, self)._add_services(this_service,
other_services)
def _add_relations(self):
"""Add all of the relations for the services."""
relations = {
'nova-cloud-controller:shared-db': 'mysql:shared-db',
'nova-cloud-controller:identity-service': 'keystone:'
'identity-service',
'nova-cloud-controller:amqp': 'rabbitmq-server:amqp',
'nova-cloud-controller:cloud-compute': 'nova-compute:'
'cloud-compute',
'nova-cloud-controller:image-service': 'glance:image-service',
'nova-compute:image-service': 'glance:image-service',
'nova-compute:shared-db': 'mysql:shared-db',
'nova-compute:amqp': 'rabbitmq-server:amqp',
'keystone:shared-db': 'mysql:shared-db',
'glance:identity-service': 'keystone:identity-service',
'glance:shared-db': 'mysql:shared-db',
'glance:amqp': 'rabbitmq-server:amqp'
}
super(NovaCCBasicDeployment, self)._add_relations(relations)
def _configure_services(self):
"""Configure all of the services."""
nova_cc_config = {}
nova_config = {}
if self.git:
amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY')
reqs_repo = 'git://github.com/openstack/requirements'
neutron_repo = 'git://github.com/openstack/neutron'
nova_repo = 'git://github.com/openstack/nova'
if self._get_openstack_release() == self.trusty_icehouse:
reqs_repo = 'git://github.com/coreycb/requirements'
neutron_repo = 'git://github.com/coreycb/neutron'
nova_repo = 'git://github.com/coreycb/nova'
branch = 'stable/' + self._get_openstack_release_string()
openstack_origin_git = {
'repositories': [
{'name': 'requirements',
'repository': reqs_repo,
'branch': branch},
{'name': 'neutron',
'repository': neutron_repo,
'branch': branch},
{'name': 'nova',
'repository': nova_repo,
'branch': branch},
],
'directory': '/mnt/openstack-git',
'http_proxy': amulet_http_proxy,
'https_proxy': amulet_http_proxy,
}
nova_cc_config['openstack-origin-git'] = \
yaml.dump(openstack_origin_git)
nova_config['openstack-origin-git'] = \
yaml.dump(openstack_origin_git)
# Add some rate-limiting options to the charm. These will noop before
# icehouse.
nova_cc_config['api-rate-limit-rules'] = \
"( POST, '*', .*, 9999, MINUTE );"
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
configs = {'nova-cloud-controller': nova_cc_config,
'keystone': keystone_config, 'nova-compute': nova_config}
super(NovaCCBasicDeployment, self)._configure_services(configs)
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
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.nova_cc_sentry = self.d.sentry.unit['nova-cloud-controller/0']
self.nova_compute_sentry = self.d.sentry.unit['nova-compute/0']
self.glance_sentry = self.d.sentry.unit['glance/0']
u.log.debug('openstack release val: {}'.format(
self._get_openstack_release()))
u.log.debug('openstack release str: {}'.format(
self._get_openstack_release_string()))
# Authenticate admin with keystone
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
user='admin',
password='openstack',
tenant='admin')
# Authenticate admin with glance endpoint
self.glance = u.authenticate_glance_admin(self.keystone)
# Create a demo tenant/role/user
self.demo_tenant = 'demoTenant'
self.demo_role = 'demoRole'
self.demo_user = 'demoUser'
if not u.tenant_exists(self.keystone, self.demo_tenant):
tenant = self.keystone.tenants.create(tenant_name=self.demo_tenant,
description='demo tenant',
enabled=True)
self.keystone.roles.create(name=self.demo_role)
self.keystone.users.create(name=self.demo_user,
password='password',
tenant_id=tenant.id,
email='demo@demo.com')
# Authenticate demo user with keystone
self.keystone_demo = \
u.authenticate_keystone_user(self.keystone, user=self.demo_user,
password='password',
tenant=self.demo_tenant)
# Authenticate demo user with nova-api
self.nova_demo = u.authenticate_nova_user(self.keystone,
user=self.demo_user,
password='password',
tenant=self.demo_tenant)
def test_100_services(self):
"""Verify the expected services are running on the corresponding
service units."""
u.log.debug('Checking system services on units...')
services = {
self.mysql_sentry: ['mysql'],
self.rabbitmq_sentry: ['rabbitmq-server'],
self.nova_cc_sentry: ['nova-api-ec2',
'nova-api-os-compute',
'nova-conductor',
'nova-objectstore',
'nova-cert',
'nova-scheduler'],
self.nova_compute_sentry: ['nova-compute',
'nova-network',
'nova-api'],
self.keystone_sentry: ['keystone'],
self.glance_sentry: ['glance-registry', 'glance-api']
}
if self._get_openstack_release_string() >= 'liberty':
services[self.nova_cc_sentry].remove('nova-api-ec2')
services[self.nova_cc_sentry].remove('nova-objectstore')
if self._get_openstack_release() >= self.trusty_liberty:
services[self.keystone_sentry] = ['apache2']
ret = u.validate_services_by_name(services)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
def test_102_service_catalog(self):
"""Verify that the service catalog endpoint data is valid."""
u.log.debug('Checking keystone service catalog...')
endpoint_vol = {'adminURL': u.valid_url,
'region': 'RegionOne',
'publicURL': u.valid_url,
'internalURL': u.valid_url}
endpoint_id = {'adminURL': u.valid_url,
'region': 'RegionOne',
'publicURL': u.valid_url,
'internalURL': u.valid_url}
if self._get_openstack_release() >= self.precise_folsom:
endpoint_vol['id'] = u.not_null
endpoint_id['id'] = u.not_null
if self._get_openstack_release() >= self.trusty_kilo:
expected = {'compute': [endpoint_vol], 'identity': [endpoint_id]}
else:
expected = {'s3': [endpoint_vol], 'compute': [endpoint_vol],
'ec2': [endpoint_vol], 'identity': [endpoint_id]}
actual = self.keystone_demo.service_catalog.get_endpoints()
ret = u.validate_svc_catalog_endpoint_data(expected, actual)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
def test_104_openstack_compute_api_endpoint(self):
"""Verify the openstack compute api (osapi) endpoint data."""
u.log.debug('Checking compute endpoint data...')
endpoints = self.keystone.endpoints.list()
admin_port = internal_port = public_port = '8774'
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 = 'osapi endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_106_ec2_api_endpoint(self):
"""Verify the EC2 api endpoint data."""
if self._get_openstack_release() >= self.trusty_kilo:
return
u.log.debug('Checking ec2 endpoint data...')
endpoints = self.keystone.endpoints.list()
admin_port = internal_port = public_port = '8773'
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 = 'EC2 endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_108_s3_api_endpoint(self):
"""Verify the S3 api endpoint data."""
if self._get_openstack_release() >= self.trusty_kilo:
return
u.log.debug('Checking s3 endpoint data...')
endpoints = self.keystone.endpoints.list()
admin_port = internal_port = public_port = '3333'
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 = 'S3 endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_200_nova_cc_shared_db_relation(self):
"""Verify the nova-cc to mysql shared-db relation data"""
u.log.debug('Checking n-c-c:mysql db relation data...')
unit = self.nova_cc_sentry
relation = ['shared-db', 'mysql:shared-db']
expected = {
'private-address': u.valid_ip,
'nova_database': 'nova',
'nova_username': 'nova',
'nova_hostname': u.valid_ip
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-cc shared-db', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_202_mysql_shared_db_relation(self):
"""Verify the mysql to nova-cc shared-db relation data"""
u.log.debug('Checking mysql:n-c-c db relation data...')
unit = self.mysql_sentry
relation = ['shared-db', 'nova-cloud-controller:shared-db']
expected = {
'private-address': u.valid_ip,
'nova_password': u.not_null,
'db_host': u.valid_ip
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('mysql shared-db', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_204_nova_cc_identity_service_relation(self):
"""Verify the nova-cc to keystone identity-service relation data"""
u.log.debug('Checking n-c-c:keystone identity relation data...')
unit = self.nova_cc_sentry
relation = ['identity-service', 'keystone:identity-service']
expected = {
'nova_internal_url': u.valid_url,
'nova_public_url': u.valid_url,
'nova_service': 'nova',
'private-address': u.valid_ip,
'nova_region': 'RegionOne',
'nova_admin_url': u.valid_url,
}
if self._get_openstack_release() < self.trusty_kilo:
expected['s3_admin_url'] = u.valid_url
expected['s3_internal_url'] = u.valid_url
expected['s3_public_url'] = u.valid_url
expected['s3_region'] = 'RegionOne'
expected['s3_service'] = 's3'
expected['ec2_admin_url'] = u.valid_url
expected['ec2_internal_url'] = u.valid_url
expected['ec2_public_url'] = u.valid_url
expected['ec2_region'] = 'RegionOne'
expected['ec2_service'] = 'ec2'
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-cc identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_206_keystone_identity_service_relation(self):
"""Verify the keystone to nova-cc identity-service relation data"""
u.log.debug('Checking keystone:n-c-c identity relation data...')
unit = self.keystone_sentry
relation = ['identity-service',
'nova-cloud-controller:identity-service']
expected = {
'service_protocol': 'http',
'service_tenant': 'services',
'admin_token': 'ubuntutesting',
'service_password': u.not_null,
'service_port': '5000',
'auth_port': '35357',
'auth_protocol': 'http',
'private-address': u.valid_ip,
'auth_host': u.valid_ip,
'service_username': 's3_ec2_nova',
'service_tenant_id': u.not_null,
'service_host': u.valid_ip
}
if self._get_openstack_release() >= self.trusty_kilo:
expected['service_username'] = 'nova'
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_208_nova_cc_amqp_relation(self):
"""Verify the nova-cc to rabbitmq-server amqp relation data"""
u.log.debug('Checking n-c-c:rmq amqp relation data...')
unit = self.nova_cc_sentry
relation = ['amqp', 'rabbitmq-server:amqp']
expected = {
'username': 'nova',
'private-address': u.valid_ip,
'vhost': 'openstack'
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-cc amqp', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_210_rabbitmq_amqp_relation(self):
"""Verify the rabbitmq-server to nova-cc amqp relation data"""
u.log.debug('Checking rmq:n-c-c amqp relation data...')
unit = self.rabbitmq_sentry
relation = ['amqp', 'nova-cloud-controller:amqp']
expected = {
'private-address': u.valid_ip,
'password': u.not_null,
'hostname': u.valid_ip
}
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_212_nova_cc_cloud_compute_relation(self):
"""Verify the nova-cc to nova-compute cloud-compute relation data"""
u.log.debug('Checking n-c-c:nova-compute '
'cloud-compute relation data...')
unit = self.nova_cc_sentry
relation = ['cloud-compute', 'nova-compute:cloud-compute']
expected = {
'volume_service': 'cinder',
'network_manager': 'flatdhcpmanager',
'ec2_host': u.valid_ip,
'private-address': u.valid_ip,
'restart_trigger': u.not_null
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-cc cloud-compute', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_214_nova_cloud_compute_relation(self):
"""Verify the nova-compute to nova-cc cloud-compute relation data"""
u.log.debug('Checking nova-compute:n-c-c '
'cloud-compute relation data...')
unit = self.nova_compute_sentry
relation = ['cloud-compute', 'nova-cloud-controller:cloud-compute']
expected = {
'private-address': u.valid_ip,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-compute cloud-compute', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_216_nova_cc_image_service_relation(self):
"""Verify the nova-cc to glance image-service relation data"""
u.log.debug('Checking n-c-c:glance image-service relation data...')
unit = self.nova_cc_sentry
relation = ['image-service', 'glance:image-service']
expected = {
'private-address': u.valid_ip,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('nova-cc image-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_218_glance_image_service_relation(self):
"""Verify the glance to nova-cc image-service relation data"""
u.log.debug('Checking glance:n-c-c image-service relation data...')
unit = self.glance_sentry
relation = ['image-service', 'nova-cloud-controller:image-service']
expected = {
'private-address': u.valid_ip,
'glance-api-server': u.valid_url
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('glance image-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_300_nova_default_config(self):
"""Verify the data in the nova config file's default section."""
u.log.debug('Checking nova config file data...')
unit = self.nova_cc_sentry
conf = '/etc/nova/nova.conf'
rmq_ncc_rel = self.rabbitmq_sentry.relation(
'amqp', 'nova-cloud-controller:amqp')
gl_ncc_rel = self.glance_sentry.relation(
'image-service', 'nova-cloud-controller:image-service')
ks_ep = self.keystone_demo.service_catalog.url_for(
service_type='identity', endpoint_type='publicURL')
ks_ec2 = "{}/ec2tokens".format(ks_ep)
ks_ncc_rel = self.keystone_sentry.relation(
'identity-service', 'nova-cloud-controller:identity-service')
ks_uri = "http://{}:{}/".format(ks_ncc_rel['service_host'],
ks_ncc_rel['service_port'])
id_uri = "{}://{}:{}/".format(ks_ncc_rel['auth_protocol'],
ks_ncc_rel['service_host'],
ks_ncc_rel['auth_port'])
db_ncc_rel = self.mysql_sentry.relation(
'shared-db', 'nova-cloud-controller:shared-db')
db_uri = "mysql://{}:{}@{}/{}".format('nova',
db_ncc_rel['nova_password'],
db_ncc_rel['db_host'],
'nova')
expected = {
'DEFAULT': {
'dhcpbridge_flagfile': '/etc/nova/nova.conf',
'dhcpbridge': '/usr/bin/nova-dhcpbridge',
'logdir': '/var/log/nova',
'state_path': '/var/lib/nova',
'force_dhcp_release': 'True',
'iscsi_helper': 'tgtadm',
'libvirt_use_virtio_for_bridges': 'True',
'connection_type': 'libvirt',
'root_helper': 'sudo nova-rootwrap /etc/nova/rootwrap.conf',
'verbose': 'False',
'debug': 'False',
'api_paste_config': '/etc/nova/api-paste.ini',
'volumes_path': '/var/lib/nova/volumes',
'auth_strategy': 'keystone',
'compute_driver': 'libvirt.LibvirtDriver',
'network_manager': 'nova.network.manager.FlatDHCPManager',
's3_listen_port': '3323',
'osapi_compute_listen_port': '8764',
}
}
if self._get_openstack_release() < self.trusty_kilo:
# Juno and earlier
expected['database'] = {
'connection': db_uri
}
expected['keystone_authtoken'] = {
'auth_uri': ks_uri,
'auth_host': ks_ncc_rel['service_host'],
'auth_port': ks_ncc_rel['auth_port'],
'auth_protocol': ks_ncc_rel['auth_protocol'],
'admin_tenant_name': ks_ncc_rel['service_tenant'],
'admin_user': ks_ncc_rel['service_username'],
'admin_password': ks_ncc_rel['service_password'],
}
expected['DEFAULT'].update({
'lock_path': '/var/lock/nova',
'libvirt_use_virtio_for_bridges': 'True',
'compute_driver': 'libvirt.LibvirtDriver',
'rabbit_userid': 'nova',
'rabbit_virtual_host': 'openstack',
'rabbit_password': rmq_ncc_rel['password'],
'rabbit_host': rmq_ncc_rel['hostname'],
'glance_api_servers': gl_ncc_rel['glance-api-server']
})
else:
# Kilo and later
expected['database'] = {
'connection': db_uri,
'max_pool_size': '2',
}
expected['glance'] = {
'api_servers': gl_ncc_rel['glance-api-server'],
}
expected['keystone_authtoken'] = {
'identity_uri': id_uri.rstrip('/'),
'auth_uri': ks_uri,
'admin_tenant_name': ks_ncc_rel['service_tenant'],
'admin_user': ks_ncc_rel['service_username'],
'admin_password': ks_ncc_rel['service_password'],
'signing_dir': '/var/cache/nova',
}
expected['osapi_v3'] = {
'enabled': 'True',
}
expected['conductor'] = {
'workers': '2',
}
expected['oslo_messaging_rabbit'] = {
'rabbit_userid': 'nova',
'rabbit_virtual_host': 'openstack',
'rabbit_password': rmq_ncc_rel['password'],
'rabbit_host': rmq_ncc_rel['hostname'],
}
expected['oslo_concurrency'] = {
'lock_path': '/var/lock/nova',
}
if self._get_openstack_release() >= self.trusty_liberty:
# Liberty
expected['keystone_authtoken'] = {
'auth_uri': ks_uri.rstrip('/'),
'auth_url': id_uri.rstrip('/'),
'auth_plugin': 'password',
'project_domain_id': 'default',
'user_domain_id': 'default',
'project_name': 'services',
'username': 'nova',
'password': ks_ncc_rel['service_password'],
'signing_dir': '/var/cache/nova',
}
if self._get_openstack_release() < self.trusty_mitaka:
expected['DEFAULT'].update({
'ec2_private_dns_show_ip': 'True',
'enabled_apis': 'ec2,osapi_compute,metadata',
'keystone_ec2_url': ks_ec2,
'ec2_listen_port': '8763'
})
elif self._get_openstack_release() >= self.trusty_mitaka:
expected['DEFAULT'].update({
'enabled_apis': 'osapi_compute,metadata',
})
for section, pairs in expected.iteritems():
ret = u.validate_config_data(unit, conf, section, pairs)
if ret:
message = "nova config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_302_api_rate_limiting_is_enabled(self):
"""
Check that API rate limiting is enabled.
"""
u.log.debug('Checking api-paste config file data...')
unit = self.nova_cc_sentry
conf = '/etc/nova/api-paste.ini'
if self._get_openstack_release() >= self.trusty_mitaka:
section = "filter:legacy_ratelimit"
else:
section = "filter:ratelimit"
factory = ("nova.api.openstack.compute.limits:RateLimitingMiddleware"
".factory")
if self._get_openstack_release() >= self.precise_icehouse:
expected = {"paste.filter_factory": factory,
"limits": "( POST, '*', .*, 9999, MINUTE );"}
else:
expected = {"paste.filter_factory": factory}
ret = u.validate_config_data(unit, conf, section, expected)
if ret:
message = "api paste config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_400_image_instance_create(self):
"""Create an image/instance, verify they exist, and delete them."""
u.log.debug('Checking nova instance creation...')
image = u.create_cirros_image(self.glance, "cirros-image")
if not image:
amulet.raise_status(amulet.FAIL, msg="Image create failed")
instance = u.create_instance(self.nova_demo, "cirros-image", "cirros",
"m1.tiny")
if not instance:
amulet.raise_status(amulet.FAIL, msg="Instance create failed")
found = False
for instance in self.nova_demo.servers.list():
if instance.name == 'cirros':
found = True
if instance.status != 'ACTIVE':
msg = "cirros instance is not active"
amulet.raise_status(amulet.FAIL, msg=msg)
if not found:
message = "nova cirros instance does not exist"
amulet.raise_status(amulet.FAIL, msg=message)
u.delete_resource(self.glance.images, image.id,
msg="glance image")
u.delete_resource(self.nova_demo.servers, instance.id,
msg="nova instance")
def test_900_restart_on_config_change(self):
"""Verify that the specified services are restarted when the config
is changed."""
u.log.info('Checking that conf files and system services respond '
'to a charm config change...')
sentry = self.nova_cc_sentry
juju_service = 'nova-cloud-controller'
# Process names, corresponding conf files
conf_file = '/etc/nova/nova.conf'
services = {
'nova-api-ec2': conf_file,
'nova-api-os-compute': conf_file,
'nova-objectstore': conf_file,
'nova-cert': conf_file,
'nova-scheduler': conf_file,
'nova-conductor': conf_file
}
if self._get_openstack_release_string() >= 'liberty':
del services['nova-api-ec2']
del services['nova-objectstore']
# Expected default and alternate values
flags_default = 'quota_cores=20,quota_instances=40,quota_ram=102400'
flags_alt = 'quota_cores=10,quota_instances=20,quota_ram=51200'
set_default = {'config-flags': flags_default}
set_alternate = {'config-flags': flags_alt}
# Make config change, check for service restarts
u.log.debug('Making config change on {}...'.format(juju_service))
mtime = u.get_sentry_time(sentry)
self.d.configure(juju_service, set_alternate)
sleep_time = 60
for s, conf_file in services.iteritems():
u.log.debug("Checking that service restarted: {}".format(s))
if not u.validate_service_config_changed(sentry, mtime, s,
conf_file,
sleep_time=sleep_time):
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)
def test_901_pause_resume(self):
"""Test pause and resume actions."""
self._assert_services(should_run=True)
action_id = u.run_action(self.nova_cc_sentry, "pause")
assert u.wait_on_action(action_id), "Pause action failed."
self._assert_services(should_run=False)
action_id = u.run_action(self.nova_cc_sentry, "resume")
assert u.wait_on_action(action_id), "Resume action failed"
self._assert_services(should_run=True)